# Claude Code CLI

All documentation for Claude Code CLI.


---
## admin-setup-9ffdbf6b0c.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up Claude Code for your organization

> A decision map for administrators deploying Claude Code, covering API providers, managed settings, policy enforcement, usage monitoring, and data handling.

Claude Code enforces organization policy through managed settings that take precedence over local developer configuration. You deliver those settings from the Claude admin console, your mobile device management (MDM) system, or a file on disk. The settings control which tools, commands, servers, and network destinations Claude can reach.

This page walks through the deployment decisions in order. Each row links to the section below and to the reference page for that area.

<Note>
  SSO, SCIM provisioning, and seat assignment are configured at the Claude account level. See the [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide) and [seat assignment](../17-Billing-Plans/use-claude-code-with-your-team-or-enterprise-plan.md) for those steps.
</Note>

| Decision                                                                | What you're choosing                                | Reference                                                                                                                                |
| :---------------------------------------------------------------------- | :-------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
| [Choose your API provider](#choose-your-api-provider)                   | Where Claude Code authenticates and how it's billed | [Authentication](../13-Enterprise-Admin/authentication-claude-code-docs-2c6ada8385.md), [Bedrock](../20-Models/claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.md), [Vertex AI](../20-Models/claude-code-on-google-vertex-ai-claude-code-docs-2acd050a7a.md), [Foundry](../20-Models/claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.md) |
| [Decide how settings reach devices](#decide-how-settings-reach-devices) | How managed policy reaches developer machines       | [Server-managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md), [Settings files](/en/settings#settings-files)                                    |
| [Decide what to enforce](#decide-what-to-enforce)                       | Which tools, commands, and integrations are allowed | [Permissions](configure-permissions-claude-code-docs-7b0e64d485.md), [Sandboxing](../22-Safety-Policy/sandboxing-claude-code-docs-5f97cd27c4.md)                                                                             |
| [Set up usage visibility](#set-up-usage-visibility)                     | How you track spend and adoption                    | [Analytics](../13-Enterprise-Admin/track-team-usage-with-analytics-claude-code-docs-35e754aabf.md), [Monitoring](../13-Enterprise-Admin/monitoring-claude-code-docs-72c46f3dc8.md), [Costs](../17-Billing-Plans/manage-costs-effectively-claude-code-docs-7c26178a4f.md)                                                       |
| [Review data handling](#review-data-handling)                           | Data retention and compliance posture               | [Data usage](../22-Safety-Policy/data-usage-claude-code-docs-06b2864aaa.md), [Security](../22-Safety-Policy/security-claude-code-docs-7538e94c51.md)                                                                                   |

## Choose your API provider

Claude Code connects to Claude through one of several API providers. Your choice affects billing, authentication, and which compliance posture you inherit.

| Provider                      | Choose this when                                                                                                                      |
| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
| Claude for Teams / Enterprise | You want Claude Code and claude.ai under one per-seat subscription with no infrastructure to run. This is the default recommendation. |
| Claude Console                | You're API-first or want pay-as-you-go billing                                                                                        |
| Amazon Bedrock                | You want to inherit existing AWS compliance controls and billing                                                                      |
| Google Vertex AI              | You want to inherit existing GCP compliance controls and billing                                                                      |
| Microsoft Foundry             | You want to inherit existing Azure compliance controls and billing                                                                    |

For the full provider comparison covering authentication, regions, and feature parity, see the [enterprise deployment overview](enterprise-deployment-overview-claude-code-docs-6eae0ecba2.md). Each provider's auth setup is in [Authentication](../13-Enterprise-Admin/authentication-claude-code-docs-2c6ada8385.md).

Proxy and firewall requirements in [Network configuration](enterprise-network-configuration-claude-code-docs.md) apply regardless of provider. If you want a single endpoint in front of multiple providers or centralized request logging, see [LLM gateway](../13-Enterprise-Admin/llm-gateway-configuration-claude-code-docs-7a1628ac88.md).

## Decide how settings reach devices

Managed settings define policy that takes precedence over local developer configuration. Claude Code looks for them in four places and uses the first one it finds on a given device.

| Mechanism               | Delivery                                                                                                                                                                                              | Priority | Platforms      |
| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------- |
| Server-managed          | Claude.ai admin console                                                                                                                                                                               | Highest  | All            |
| plist / registry policy | macOS: `com.anthropic.claudecode` plist<br />Windows: `HKLM\SOFTWARE\Policies\ClaudeCode`                                                                                                             | High     | macOS, Windows |
| File-based managed      | macOS: `/Library/Application Support/ClaudeCode/managed-settings.json`<br />Linux and WSL: `/etc/claude-code/managed-settings.json`<br />Windows: `C:\Program Files\ClaudeCode\managed-settings.json` | Medium   | All            |
| Windows user registry   | `HKCU\SOFTWARE\Policies\ClaudeCode`                                                                                                                                                                   | Lowest   | Windows only   |

Server-managed settings reach devices at authentication time and refresh hourly during active sessions, with no endpoint infrastructure. They require a Claude for Teams or Enterprise plan, so deployments on other providers need one of the file-based or OS-level mechanisms instead.

If your organization mixes providers, configure [server-managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md) for Claude.ai users plus a [file-based or plist/registry fallback](/en/settings#settings-files) so other users still receive managed policy.

The plist and HKLM registry locations work with any provider and resist tampering because they require admin privileges to write. The Windows user registry at HKCU is writable without elevation, so treat it as a convenience default rather than an enforcement channel.

By default WSL reads only the Linux file path at `/etc/claude-code`. To extend your Windows registry and `C:\Program Files\ClaudeCode` policy to WSL on the same machine, set [`wslInheritsWindowsSettings: true`](/en/settings#available-settings) in either of those admin-only Windows sources.

Whichever mechanism you choose, managed values take precedence over user and project settings. Array settings such as `permissions.allow` and `permissions.deny` merge entries from all sources, so developers can extend managed lists but not remove from them.

See [Server-managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md) and [Settings files and precedence](/en/settings#settings-files).

## Decide what to enforce

Managed settings can lock down tools, sandbox execution, restrict MCP servers and plugin sources, and control which hooks run. Each row is a control surface with the setting keys that drive it.

| Control                                                                                | What it does                                                                  | Key settings                                                                  |
| :------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------- | :---------------------------------------------------------------------------- |
| [Permission rules](configure-permissions-claude-code-docs-7b0e64d485.md)                                                    | Allow, ask, or deny specific tools and commands                               | `permissions.allow`, `permissions.deny`                                       |
| [Permission lockdown](/en/permissions#managed-only-settings)                           | Only managed permission rules apply; disable `--dangerously-skip-permissions` | `allowManagedPermissionRulesOnly`, `permissions.disableBypassPermissionsMode` |
| [Sandboxing](../22-Safety-Policy/sandboxing-claude-code-docs-5f97cd27c4.md)                                                           | OS-level filesystem and network isolation with domain allowlists              | `sandbox.enabled`, `sandbox.network.allowedDomains`                           |
| [Managed policy CLAUDE.md](/en/memory#deploy-organization-wide-claude-md)              | Org-wide instructions loaded in every session, cannot be excluded             | File at the managed policy path                                               |
| [MCP server control](/en/mcp#managed-mcp-configuration)                                | Restrict which MCP servers users can add or connect to                        | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly`         |
| [Plugin marketplace control](/en/plugin-marketplaces#managed-marketplace-restrictions) | Restrict which marketplace sources users can add and install from             | `strictKnownMarketplaces`, `blockedMarketplaces`                              |
| [Hook restrictions](/en/settings#hook-configuration)                                   | Only managed hooks load; restrict HTTP hook URLs                              | `allowManagedHooksOnly`, `allowedHttpHookUrls`                                |
| [Version floor](claude-code-settings-claude-code-docs-d4420b4b52.md)                                                          | Prevent auto-update from installing below an org-wide minimum                 | `minimumVersion`                                                              |

Permission rules and sandboxing cover different layers. Denying WebFetch blocks Claude's fetch tool, but if Bash is allowed, `curl` and `wget` can still reach any URL. Sandboxing closes that gap with a network domain allowlist enforced at the OS level.

For the threat model these controls defend against, see [Security](../22-Safety-Policy/security-claude-code-docs-7538e94c51.md).

## Set up usage visibility

Choose monitoring based on what you need to report on.

| Capability          | What you get                                         | Availability   | Where to start                           |
| :------------------ | :--------------------------------------------------- | :------------- | :--------------------------------------- |
| Usage monitoring    | OpenTelemetry export of sessions, tools, and tokens  | All providers  | [Monitoring usage](../13-Enterprise-Admin/monitoring-claude-code-docs-72c46f3dc8.md) |
| Analytics dashboard | Per-user metrics, contribution tracking, leaderboard | Anthropic only | [Analytics](../13-Enterprise-Admin/track-team-usage-with-analytics-claude-code-docs-35e754aabf.md)               |
| Cost tracking       | Spend limits, rate limits, and usage attribution     | Anthropic only | [Costs](../17-Billing-Plans/manage-costs-effectively-claude-code-docs-7c26178a4f.md)                       |

Cloud providers expose spend through AWS Cost Explorer, GCP Billing, or Azure Cost Management. Claude for Teams and Enterprise plans include a usage dashboard at [claude.ai/analytics/claude-code](https://claude.ai/analytics/claude-code).

## Review data handling

On Team, Enterprise, Claude API, and cloud provider plans, Anthropic does not train models on your code or prompts. Your API provider determines retention and compliance posture.

| Topic                     | What to know                                                                    | Where to start                                 |
| :------------------------ | :------------------------------------------------------------------------------ | :--------------------------------------------- |
| Data usage policy         | What Anthropic collects, how long it's retained, what's never used for training | [Data usage](../22-Safety-Policy/data-usage-claude-code-docs-06b2864aaa.md)                   |
| Zero Data Retention (ZDR) | Nothing stored after the request completes. Available on Claude for Enterprise  | [Zero data retention](../22-Safety-Policy/zero-data-retention-claude-code-docs-6ec9ee63f1.md) |
| Security architecture     | Network model, encryption, authentication, audit trail                          | [Security](../22-Safety-Policy/security-claude-code-docs-7538e94c51.md)                       |

If you need request-level audit logging or to route traffic by data sensitivity, place an [LLM gateway](../13-Enterprise-Admin/llm-gateway-configuration-claude-code-docs-7a1628ac88.md) between developers and your provider. For regulatory requirements and certifications, see [Legal and compliance](../22-Safety-Policy/legal-and-compliance-claude-code-docs-2d64f2bee3.md).

## Verify and onboard

After configuring managed settings, have a developer run `/status` inside Claude Code. The output includes a line beginning with `Enterprise managed settings` followed by the source in parentheses, one of `(remote)`, `(plist)`, `(HKLM)`, `(HKCU)`, or `(file)`. See [Verify active settings](/en/settings#verify-active-settings).

Share these resources to help developers get started:

* [Quickstart](../01-Getting-Started/quickstart-claude-code-docs-a21b84bdea.md): first-session walkthrough from install to working with a project
* [Common workflows](common-workflows-c909406123.md): patterns for everyday tasks like code review, refactoring, and debugging
* [Claude 101](https://anthropic.skilljar.com/claude-101) and [Claude Code in Action](https://anthropic.skilljar.com/claude-code-in-action): self-paced Anthropic Academy courses

For login issues, point developers to [authentication troubleshooting](/en/troubleshooting#authentication-issues). The most common fixes are:

* Run `/logout` then `/login` to switch accounts
* Run `claude update` if the enterprise auth option is missing
* Restart the terminal after updating

If a developer sees "You haven't been added to your organization yet," their seat doesn't include Claude Code access and needs to be updated in the admin console.

## Next steps

With provider and delivery mechanism chosen, move on to detailed configuration:

* [Server-managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md): deliver managed policy from the Claude admin console
* [Settings reference](claude-code-settings-claude-code-docs-d4420b4b52.md): every setting key, file location, and precedence rule
* [Amazon Bedrock](../20-Models/claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.md), [Google Vertex AI](../20-Models/claude-code-on-google-vertex-ai-claude-code-docs-2acd050a7a.md), [Microsoft Foundry](../20-Models/claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.md): provider-specific deployment
* [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide): SSO, SCIM, seat management, and rollout playbook


---
## advanced-setup-claude-code-docs-0526bc1300.md

## On this page

- [System requirements](#system-requirements)
  - [Additional dependencies](#additional-dependencies)
- [Install Claude Code](#install-claude-code)
  - [Set up on Windows](#set-up-on-windows)
  - [Alpine Linux and musl-based distributions](#alpine-linux-and-musl-based-distributions)
- [Verify your installation](#verify-your-installation)
- [Authenticate](#authenticate)
- [Update Claude Code](#update-claude-code)
  - [Auto-updates](#auto-updates)
  - [Configure release channel](#configure-release-channel)
  - [Pin a minimum version](#pin-a-minimum-version)
  - [Disable auto-updates](#disable-auto-updates)
  - [Update manually](#update-manually)
- [Advanced installation options](#advanced-installation-options)
  - [Install a specific version](#install-a-specific-version)
  - [Install with Linux package managers](#install-with-linux-package-managers)
  - [Install with npm](#install-with-npm)
  - [Binary integrity and code signing](#binary-integrity-and-code-signing)
  - [Verify the manifest signature](#verify-the-manifest-signature)
  - [Platform code signatures](#platform-code-signatures)
- [Uninstall Claude Code](#uninstall-claude-code)
  - [Native installation](#native-installation)
  - [Homebrew installation](#homebrew-installation)
  - [WinGet installation](#winget-installation)
  - [apt / dnf / apk](#apt-%2F-dnf-%2F-apk)
  - [npm](#npm)
  - [Remove configuration files](#remove-configuration-files)

Setup and access

# Advanced setup

Copy pageCopy page

System requirements, platform-specific installation, version management, and uninstallation for Claude Code.

Copy pageCopy page

This page covers system requirements, platform-specific installation details, updates, and uninstallation. For a guided walkthrough of your first session, see the [quickstart](/docs/en/quickstart). If you’ve never used a terminal before, see the [terminal guide](/docs/en/terminal-guide).


[​](#system-requirements)

System requirements

Claude Code runs on the following platforms and configurations:

- **Operating system**:
  - macOS 13.0+
  - Windows 10 1809+ or Windows Server 2019+
  - Ubuntu 20.04+
  - Debian 10+
  - Alpine Linux 3.19+
- **Hardware**: 4 GB+ RAM, x64 or ARM64 processor
- **Network**: internet connection required. See [network configuration](/docs/en/network-config#network-access-requirements).
- **Shell**: Bash, Zsh, PowerShell, or CMD.
- **Location**: [Anthropic supported countries](https://www.anthropic.com/supported-countries)


[​](#additional-dependencies)

Additional dependencies

- **ripgrep**: usually included with Claude Code. If search fails, see [search troubleshooting](/docs/en/troubleshooting#search-and-discovery-issues).


[​](#install-claude-code)

Install Claude Code

Prefer a graphical interface? The [Desktop app](/docs/en/desktop-quickstart) lets you use Claude Code without the terminal. Download it for [macOS](https://claude.ai/api/desktop/darwin/universal/dmg/latest/redirect?utm_source=claude_code&utm_medium=docs), [Windows](https://claude.com/download?utm_source=claude_code&utm_medium=docs), or [Linux](/docs/en/desktop-linux).New to the terminal? See the [terminal guide](/docs/en/terminal-guide) for step-by-step instructions.

To install Claude Code, use one of the following methods:

- Native Install (Recommended)

- Homebrew

- WinGet

**macOS, Linux, WSL:**

```python
curl -fsSL https://claude.ai/install.sh | bash
```

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

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. Your prompt shows `PS C:\` when you’re in PowerShell and `C:\` without the `PS` when you’re in CMD.If the install command fails with `syntax error near unexpected token '<'`, a `403`, or another curl error, see [Troubleshoot installation](/docs/en/troubleshoot-install#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](/docs/en/setup#install-with-linux-package-managers) on Debian, Fedora, RHEL, and Alpine. After installation completes, open a terminal in the project you want to work in and start Claude Code:

```python
claude
```

Claude Code opens an interactive session in your terminal. If you encounter any issues during installation, see [Troubleshoot installation and login](/docs/en/troubleshoot-install).


[​](#set-up-on-windows)

Set up on Windows

You can run Claude Code natively on Windows or inside WSL. Pick based on where your projects are located and which features you need:

| Option         | Requires                                                               | [Sandboxing](/docs/en/sandboxing) | When to use                                     |
|----------------|------------------------------------------------------------------------|-----------------------------------|-------------------------------------------------|
| Native Windows | None; [Git for Windows](https://git-scm.com/downloads/win) is optional | Not supported                     | Windows-native projects and tools               |
| WSL 2          | WSL 2 enabled                                                          | Supported                         | Linux toolchains or sandboxed command execution |
| WSL 1          | WSL 1 enabled                                                          | Not supported                     | If WSL 2 is unavailable                         |

**Option 1: Native Windows** Run the install command from PowerShell or CMD. You do not need to run as Administrator. Installing [Git for Windows](https://git-scm.com/downloads/win) is optional. It enables the [Bash tool](/docs/en/tools-reference#bash-tool-behavior) by providing Git Bash. Whether you install from PowerShell or CMD only affects which install command you run. Your prompt shows `PS C:\Users\YourName>` in PowerShell and `C:\Users\YourName>` without the `PS` in CMD. If you’re new to the terminal, the [terminal guide](/docs/en/terminal-guide#windows) walks through each step. After installation, launch `claude` from any terminal.

- **Without Git for Windows**, Claude Code runs shell commands via the [PowerShell tool](/docs/en/tools-reference#powershell-tool).
- **With Git for Windows**, Claude Code uses Git Bash for the [Bash tool](/docs/en/tools-reference#bash-tool-behavior). If Claude Code can’t find Git Bash, set the path in your [settings.json file](/docs/en/settings):

  ``` shiki
  {
    "env": {
      "CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe"
    }
  }
  ```

When Git for Windows is installed, the PowerShell tool is rolling out progressively as an additional option alongside Bash. Set `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` to opt in or `0` to opt out. See [PowerShell tool](/docs/en/tools-reference#powershell-tool) for setup and limitations. **Option 2: WSL** Open your WSL distribution and run the Linux installer from the [install instructions](#install-claude-code) above. You install and launch `claude` inside the WSL terminal, not from PowerShell or CMD.


[​](#alpine-linux-and-musl-based-distributions)

Alpine Linux and musl-based distributions

Installing Claude Code on Alpine and other musl/uClibc-based distributions requires `bash` and `curl` for the install command, and `libgcc`, `libstdc++`, and `ripgrep` at runtime. Alpine doesn’t include `bash` or `curl` by default, so the documented install command fails with a `not found` error until you install them. Install these packages using your distribution’s package manager, then set `USE_BUILTIN_RIPGREP=0`. This example installs the required packages on Alpine:

```python
apk add bash curl libgcc libstdc++ ripgrep
```

On Alpine, `ripgrep` is in the community repository. If `apk` reports that the package is missing, add the community repository to `/etc/apk/repositories`, using your Alpine version:

```python
echo "https://dl-cdn.alpinelinux.org/alpine/v3.22/community" >> /etc/apk/repositories
```

Run `apk update` to refresh the package index, and retry the `apk add` command. Then set `USE_BUILTIN_RIPGREP` to `0` in your [`settings.json`](/docs/en/settings#available-settings) file:

```python
{
  "env": {
    "USE_BUILTIN_RIPGREP": "0"
  }
}
```


[​](#verify-your-installation)

Verify your installation

After installing, confirm Claude Code is working:

```python
claude --version
```

A working installation prints a version number such as `2.1.211 (Claude Code)`. If this fails with `command not found` or another error, see [Troubleshoot installation and login](/docs/en/troubleshoot-install). For a more detailed check of your installation and configuration, run [`claude doctor`](/docs/en/troubleshooting#get-more-help):

```python
claude doctor
```

`claude doctor` prints read-only installation and settings diagnostics without starting a session, including install health, settings-file validation errors, and any warnings with suggested fixes.


[​](#authenticate)

Authenticate

Claude Code requires a Pro, Max, Team, Enterprise, or Console account. The free Claude.ai plan does not include Claude Code access. You can also use Claude Code with a third-party API provider like [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud’s Agent Platform](/docs/en/google-vertex-ai), or [Microsoft Foundry](/docs/en/microsoft-foundry). After installing, log in by running `claude` and following the browser prompts. If the `ANTHROPIC_API_KEY` environment variable is set, Claude Code prompts you once to approve the key instead of opening a browser. See [Authentication](/docs/en/authentication) for all account types and team setup options.


[​](#update-claude-code)

Update Claude Code

Native installations automatically update in the background. You can [configure the release channel](#configure-release-channel) to control whether you receive updates immediately or on a delayed stable schedule, or [disable auto-updates](#disable-auto-updates) entirely. Homebrew, WinGet, and [Linux package manager](#install-with-linux-package-managers) installations require manual updates by default.


[​](#auto-updates)

Auto-updates

Claude Code checks for updates on startup and periodically while running. Updates download and install in the background, then take effect the next time you start Claude Code. Run `claude doctor` to see the result of the most recent update attempt. On macOS and Linux, the native installer manages the launcher at `~/.local/bin/claude` as a symlink into `~/.local/share/claude/versions/`. If you replace that launcher with your own script or symlink, auto-update and `claude update` leave it in place: new versions still install under the `versions/` directory, and your launcher decides which version runs. Before v2.1.207, the auto-updater replaced a custom launcher at that path with its own symlink on every update. With a custom launcher, Claude Code also keeps every installed version on disk because it can’t tell which version the launcher needs. `claude doctor` reports a launcher that the native installer didn’t create. To let Claude Code manage the launcher again, remove `~/.local/bin/claude` and run `claude update`. If an npm global install can’t auto-update because the npm global directory isn’t writable, Claude Code shows a one-time notice at startup, and `claude doctor` lists the available fixes. See [permission errors during installation](/docs/en/troubleshoot-install#permission-errors-during-installation) for details.

Homebrew, WinGet, apt, dnf, and apk installations do not auto-update by default; see below to opt in for Homebrew and WinGet. To upgrade Homebrew manually, run `brew upgrade claude-code` or `brew upgrade claude-code@latest`, depending on which cask you installed. For WinGet, run `winget upgrade Anthropic.ClaudeCode`. For Linux package managers, see the upgrade commands in [Install with Linux package managers](#install-with-linux-package-managers).To have Claude Code run the upgrade command for you on Homebrew or WinGet, set [`CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE`](/docs/en/env-vars) to `1`. Claude Code then runs the upgrade in the background when a new version is available and shows a restart prompt on success. The upgrade targets only the Claude Code package and does not affect other software you have installed.On WinGet the upgrade may fail while Claude Code is running because Windows locks the executable. In that case Claude Code shows the manual command instead. apt, dnf, and apk continue to require a manual upgrade because those commands need elevated privileges.**Known issue:** Claude Code may notify you of updates before the new version is available in these package managers. If an upgrade fails, wait and try again later.Homebrew keeps old versions on disk after upgrades. Run `brew cleanup` periodically to reclaim disk space.


[​](#configure-release-channel)

Configure release channel

Control which release channel Claude Code follows for auto-updates and `claude update` with the `autoUpdatesChannel` setting:

- `"latest"`, the default: receive new features as soon as they’re released
- `"stable"`: use a version that is typically about one week old, skipping releases with major regressions

Configure this via `/config` → **Auto-update channel**, or add it to your [settings.json file](/docs/en/settings):

```python
{
  "autoUpdatesChannel": "stable"
}
```

For enterprise deployments, you can enforce a consistent release channel across your organization using [managed settings](/docs/en/permissions#managed-settings). Homebrew installations choose a channel by cask name instead of this setting: `claude-code` tracks stable and `claude-code@latest` tracks latest.


[​](#pin-a-minimum-version)

Pin a minimum version

The `minimumVersion` setting establishes a floor. Background auto-updates and `claude update` refuse to install any version below this value, so moving to the `"stable"` channel does not downgrade you if you are already on a newer `"latest"` build. Switching from `"latest"` to `"stable"` via `/config` prompts you to either stay on the current version or allow the downgrade. Choosing to stay sets `minimumVersion` to that version. Switching back to `"latest"` clears it. Add it to your [settings.json file](/docs/en/settings) to pin a floor explicitly:

```python
{
  "autoUpdatesChannel": "stable",
  "minimumVersion": "2.1.100"
}
```

In [managed settings](/docs/en/permissions#managed-settings), this enforces an organization-wide minimum that user and project settings cannot override. The `minimumVersion` pin only constrains updates. To make Claude Code refuse to start outside a version range, use the managed settings `requiredMinimumVersion` and `requiredMaximumVersion` instead. Updates also respect the `requiredMaximumVersion` ceiling. See [available settings](/docs/en/settings#available-settings).


[​](#disable-auto-updates)

Disable auto-updates

Set `DISABLE_AUTOUPDATER` to `"1"` in the `env` key of your [`settings.json`](/docs/en/settings#available-settings) file:

```python
{
  "env": {
    "DISABLE_AUTOUPDATER": "1"
  }
}
```

`DISABLE_AUTOUPDATER` only stops the background check; `claude update` and `claude install` still work. To block all update paths, including manual updates, set [`DISABLE_UPDATES`](/docs/en/env-vars) instead. Use this when you distribute Claude Code through your own channels and need users to stay on the version you provide.


[​](#update-manually)

Update manually

To apply an update immediately without waiting for the next background check, run:

```python
claude update
```

When an update installs, the command reports `Successfully updated from <old version> to version <new version>`. If you’re already on the newest version, it reports `Claude Code is up to date (<version>)`. Installs managed by Homebrew, WinGet, or apk report `Claude is up to date!` instead.


[​](#advanced-installation-options)

Advanced installation options

These options are for version pinning, Linux package managers, npm, and verifying binary integrity.


[​](#install-a-specific-version)

Install a specific version

The native installer accepts either a specific version number or a release channel (`latest` or `stable`). The channel you choose at install time becomes your default for auto-updates. See [configure release channel](#configure-release-channel) for more information. To install the latest version (default):

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
curl -fsSL https://claude.ai/install.sh | bash
```

```python
irm https://claude.ai/install.ps1 | iex
```

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
```

To install the stable version:

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
curl -fsSL https://claude.ai/install.sh | bash -s stable
```

```python
& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) stable
```

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd stable && del install.cmd
```

To install a specific version number:

- macOS, Linux, WSL

- Windows PowerShell

- Windows CMD

```python
curl -fsSL https://claude.ai/install.sh | bash -s 2.1.89
```

```python
& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) 2.1.89
```

```python
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd 2.1.89 && del install.cmd
```

To confirm which version installed, run `claude --version`: the command prints the exact version you passed, such as `2.1.89 (Claude Code)`.


[​](#install-with-linux-package-managers)

Install with Linux package managers

Claude Code publishes signed apt, dnf, and apk repositories. Each repository offers two channels: `stable` serves a version that is typically about one week old, skipping releases with major regressions, and `latest` serves every release as soon as it ships. The commands below configure the `stable` channel, which fits most users; each tab also shows the `latest` repository URL. Package manager installations do not auto-update through Claude Code; updates arrive through your normal system upgrade workflow. All repositories are signed with the [Claude Code release signing key](#binary-integrity-and-code-signing). Before trusting the key, verify it as described in each tab.

- apt

- dnf

- apk

For Debian and Ubuntu. The install commands below download the signing key with `curl` and verify it with `gpg`, which fresh Debian and Ubuntu installations may not include. If either command reports `command not found`, install both first:

```python
sudo apt install curl gnupg
```

Download the signing key:

```python
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsSL https://downloads.claude.ai/keys/claude-code.asc \
  -o /etc/apt/keyrings/claude-code.asc
```

If this download fails, `apt update` later fails with `NO_PUBKEY BAA929FF1A7ECACE`. Confirm the key downloaded and belongs to Anthropic before continuing:

```python
gpg --show-keys /etc/apt/keyrings/claude-code.asc
```

The fingerprint gpg prints should be `31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE`. If gpg reports that the file can’t be opened or contains no valid OpenPGP data, the download failed or returned the wrong content: confirm your network can reach `downloads.claude.ai`, then rerun the download command.Register the repository on the `stable` channel and install:

```python
echo "deb [signed-by=/etc/apt/keyrings/claude-code.asc] https://downloads.claude.ai/claude-code/apt/stable stable main" \
  | sudo tee /etc/apt/sources.list.d/claude-code.list
sudo apt update
sudo apt install claude-code
```

To use the `latest` channel instead, both the URL path and the suite name change. Use this `deb` line:

```python
echo "deb [signed-by=/etc/apt/keyrings/claude-code.asc] https://downloads.claude.ai/claude-code/apt/latest latest main" \
  | sudo tee /etc/apt/sources.list.d/claude-code.list
```

To upgrade later, run `sudo apt update && sudo apt upgrade claude-code`.

For Fedora and RHEL. The following commands configure the `stable` channel:

```python
sudo tee /etc/yum.repos.d/claude-code.repo <<'EOF'
[claude-code]
name=Claude Code
baseurl=https://downloads.claude.ai/claude-code/rpm/stable
enabled=1
gpgcheck=1
gpgkey=https://downloads.claude.ai/keys/claude-code.asc
EOF
sudo dnf install claude-code
```

To use the `latest` channel instead, set `baseurl` to the `latest` repository:

```python
baseurl=https://downloads.claude.ai/claude-code/rpm/latest
```

dnf downloads the key on first install and prompts you to confirm the fingerprint. Verify it matches `31DD DE24 DDFA B679 F42D 7BD2 BAA9 29FF 1A7E CACE` before accepting.To upgrade later, run `sudo dnf upgrade claude-code`.

For Alpine Linux. The following commands configure the `stable` channel:

```python
wget -O /etc/apk/keys/claude-code.rsa.pub \
  https://downloads.claude.ai/keys/claude-code.rsa.pub
echo "https://downloads.claude.ai/claude-code/apk/stable" >> /etc/apk/repositories
apk add claude-code
```

To switch to the `latest` channel, remove the `stable` repository line and add the `latest` repository:

```python
sed -i '\|downloads.claude.ai/claude-code/apk/stable|d' /etc/apk/repositories
echo "https://downloads.claude.ai/claude-code/apk/latest" >> /etc/apk/repositories
```

Verify the downloaded key with `sha256sum /etc/apk/keys/claude-code.rsa.pub`, which should report `395759c1f7449ef4cdef305a42e820f3c766d6090d142634ebdb049f113168b6`.To upgrade later, run `apk update && apk upgrade claude-code`.


[​](#install-with-npm)

Install with npm

You can also install Claude Code as a global npm package. As of v2.1.198, the npm package requires [Node.js 22 or later](https://nodejs.org/en/download). On an older Node.js version, npm prints an `EBADENGINE` warning during install rather than failing; the install completes and `claude` still runs, since the package downloads a native binary that doesn’t use your Node.js at runtime.

```python
npm install -g @anthropic-ai/claude-code
```

The npm package installs the same native binary as the standalone installer. npm pulls the binary in through a per-platform optional dependency such as `@anthropic-ai/claude-code-darwin-arm64`, and a postinstall step links it into place. The installed `claude` binary does not itself invoke Node. Supported npm install platforms are `darwin-arm64`, `darwin-x64`, `linux-x64`, `linux-arm64`, `linux-x64-musl`, `linux-arm64-musl`, `win32-x64`, and `win32-arm64`. Your package manager must allow optional dependencies. See [troubleshooting](/docs/en/troubleshoot-install#native-binary-not-found-after-npm-install) if the binary is missing after install. To upgrade an npm installation, run `npm install -g @anthropic-ai/claude-code@latest`. Avoid `npm update -g`, which respects the semver range from the original install and may not move you to the newest release.

Do NOT use `sudo npm install -g` as this can lead to permission issues and security risks. If you encounter permission errors, see [troubleshooting permission errors](/docs/en/troubleshoot-install#permission-errors-during-installation).


[​](#binary-integrity-and-code-signing)

Binary integrity and code signing

Each release publishes a `manifest.json` containing SHA256 checksums for every platform binary. The manifest is signed with an Anthropic GPG key, so verifying the signature on the manifest transitively verifies every binary it lists.


[​](#verify-the-manifest-signature)

Verify the manifest signature

Steps 1-3 require a POSIX shell with `gpg` and `curl`. On Windows, run them in Git Bash or WSL. Step 4 includes a PowerShell option.

1

Download and import the public key

The release signing key is published at a fixed URL.

```python
curl -fsSL https://downloads.claude.ai/keys/claude-code.asc | gpg --import
```

Display the fingerprint of the imported key.

```python
gpg --fingerprint security@anthropic.com
```

Confirm the output includes this fingerprint:

```python
31DD DE24 DDFA B679 F42D  7BD2 BAA9 29FF 1A7E CACE
```

2

Download the manifest and signature

Set `VERSION` to the release you want to verify.

```python
REPO=https://downloads.claude.ai/claude-code-releases
VERSION=2.1.89
curl -fsSLO "$REPO/$VERSION/manifest.json"
curl -fsSLO "$REPO/$VERSION/manifest.json.sig"
```

3

Verify the signature

Verify the detached signature against the manifest.

```python
gpg --verify manifest.json.sig manifest.json
```

A valid result reports `Good signature from "Anthropic Claude Code Release Signing <security@anthropic.com>"`.`gpg` also prints `WARNING: This key is not certified with a trusted signature!` for any freshly imported key. This is expected. The `Good signature` line confirms the cryptographic check passed. The fingerprint comparison in Step 1 confirms the key itself is authentic.

4

Check the binary against the manifest

Compare the SHA256 checksum of the binary with the value listed under `platforms.<platform>.checksum` in `manifest.json`. The commands below assume a `claude` binary in the current directory. To verify an installed native binary instead, run the command against `~/.local/share/claude/versions/VERSION`, replacing VERSION with the release you set in Step 2.

- Linux

- macOS

- Windows PowerShell

```python
sha256sum claude
```

```python
shasum -a 256 claude
```

```python
(Get-FileHash claude.exe -Algorithm SHA256).Hash.ToLower()
```

Manifest signatures are available for releases from `2.1.89` onward. Earlier releases publish checksums in `manifest.json` without a detached signature.


[​](#platform-code-signatures)

Platform code signatures

In addition to the signed manifest, individual binaries carry platform-native code signatures where supported.

- **macOS**: signed by “Anthropic PBC” and notarized by Apple. Verify with `codesign --verify --verbose ./claude`.
- **Windows**: signed by “Anthropic, PBC”. Verify with `Get-AuthenticodeSignature .\claude.exe`.
- **Linux**: binaries are not individually code-signed. If you download directly from the `claude-code-releases` bucket or use the native installer, verify integrity with the manifest signature above. If you install with [apt, dnf, or apk](#install-with-linux-package-managers), your package manager verifies signatures automatically using the repository signing key.


[​](#uninstall-claude-code)

Uninstall Claude Code

To remove Claude Code, follow the instructions for your installation method. If `claude` still runs afterward, you likely have a second installation or a leftover shell alias from an older installer. See [Check for conflicting installations](/docs/en/troubleshoot-install#check-for-conflicting-installations) to find and remove it.


[​](#native-installation)

Native installation

Remove the Claude Code binary and version files:

- macOS, Linux, WSL

- Windows PowerShell

```python
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude
```

```python
Remove-Item -Path "$env:USERPROFILE\.local\bin\claude.exe" -Force
Remove-Item -Path "$env:USERPROFILE\.local\share\claude" -Recurse -Force
```


[​](#homebrew-installation)

Homebrew installation

Remove the Homebrew cask you installed. If you installed the stable cask:

```python
brew uninstall --cask claude-code
```

If you installed the latest cask:

```python
brew uninstall --cask claude-code@latest
```


[​](#winget-installation)

WinGet installation

Remove the WinGet package:

```python
winget uninstall Anthropic.ClaudeCode
```


[​](#apt-/-dnf-/-apk)

apt / dnf / apk

Remove the package and the repository configuration:

- apt

- dnf

- apk

```python
sudo apt remove claude-code
sudo rm /etc/apt/sources.list.d/claude-code.list /etc/apt/keyrings/claude-code.asc
```

```python
sudo dnf remove claude-code
sudo rm /etc/yum.repos.d/claude-code.repo
```

```python
apk del claude-code
sed -i '\|downloads.claude.ai/claude-code/apk|d' /etc/apk/repositories
rm /etc/apk/keys/claude-code.rsa.pub
```


[​](#npm)

npm

Remove the global npm package:

```python
npm uninstall -g @anthropic-ai/claude-code
```


[​](#remove-configuration-files)

Remove configuration files

Removing configuration files will delete all your settings, allowed tools, MCP server configurations, and session history.

The VS Code extension, the JetBrains plugin, and the Desktop app also write to `~/.claude/`. If any of them is still installed, the directory is recreated the next time it runs. To remove Claude Code completely, uninstall the [VS Code extension](/docs/en/vs-code#uninstall-the-extension), the JetBrains plugin, and the Desktop app before deleting these files. To remove Claude Code settings and cached data:

- macOS, Linux, WSL

- Windows PowerShell

```python
# Remove user settings and state
rm -rf ~/.claude
rm ~/.claude.json

# Remove project-specific settings (run from your project directory)
rm -rf .claude
rm -f .mcp.json
```

```python
# Remove user settings and state
Remove-Item -Path "$env:USERPROFILE\.claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude.json" -Force

# Remove project-specific settings (run from your project directory)
Remove-Item -Path ".claude" -Recurse -Force
Remove-Item -Path ".mcp.json" -Force
```


---
## amazon-bedrock-0f0d5f108c.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code on Amazon Bedrock

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

export const ContactSalesCard = ({surface}) => {
  const utm = content => `utm_source=claude_code&utm_medium=docs&utm_content=${surface}_${content}`;
  const iconArrowRight = (size = 13) => <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <line x1="5" y1="12" x2="19" y2="12" />
      <polyline points="12 5 19 12 12 19" />
    </svg>;
  const STYLES = `
.cc-cs {
  --cs-slate: #141413;
  --cs-clay: #d97757;
  --cs-clay-deep: #c6613f;
  --cs-gray-000: #ffffff;
  --cs-gray-700: #3d3d3a;
  --cs-border-default: rgba(31, 30, 29, 0.15);
  font-family: inherit;
}
.dark .cc-cs {
  --cs-slate: #f0eee6;
  --cs-gray-000: #262624;
  --cs-gray-700: #bfbdb4;
  --cs-border-default: rgba(240, 238, 230, 0.14);
}
.cc-cs-card {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 14px 16px; margin: 0;
  background: var(--cs-gray-000); border: 0.5px solid var(--cs-border-default);
  border-radius: 8px; flex-wrap: wrap;
}
.cc-cs-text { font-size: 13px; color: var(--cs-gray-700); line-height: 1.5; flex: 1; min-width: 240px; }
.cc-cs-text strong { font-weight: 550; color: var(--cs-slate); }
.cc-cs-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.cc-cs-btn-clay {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--cs-clay-deep); color: #fff; border: none;
  border-radius: 8px; padding: 8px 14px;
  font-size: 13px; font-weight: 500;
  transition: background-color 0.15s; white-space: nowrap;
}
.cc-cs-btn-clay:hover { background: var(--cs-clay); }
.cc-cs-btn-ghost {
  display: inline-flex; align-items: center; gap: 8px;
  background: transparent; color: var(--cs-gray-700);
  border: 0.5px solid var(--cs-border-default);
  border-radius: 8px; padding: 8px 14px;
  font-size: 13px; font-weight: 500;
}
.cc-cs-btn-ghost:hover { background: rgba(0, 0, 0, 0.04); }
.dark .cc-cs-btn-ghost:hover { background: rgba(255, 255, 255, 0.04); }
@media (max-width: 720px) {
  .cc-cs-actions { width: 100%; }
}
`;
  return <div className="cc-cs not-prose">
      <style>{STYLES}</style>
      <div className="cc-cs-card">
        <div className="cc-cs-text">
          <strong>Deploying Claude Code across your organization?</strong> Talk to sales about enterprise plans, SSO, and centralized billing.
        </div>
        <div className="cc-cs-actions">
          <a href={`https://claude.com/pricing?${utm('view_plans')}#plans-business`} className="cc-cs-btn-ghost">
            View plans
          </a>
          <a href={`https://claude.com/contact-sales?${utm('contact_sales')}`} className="cc-cs-btn-clay">
            Contact sales {iconArrowRight()}
          </a>
        </div>
      </div>
    </div>;
};

export const Experiment = ({flag, treatment, children}) => {
  const VID_KEY = 'exp_vid';
  const CONSENT_COUNTRIES = new Set(['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'RE', 'GP', 'MQ', 'GF', 'YT', 'BL', 'MF', 'PM', 'WF', 'PF', 'NC', 'AW', 'CW', 'SX', 'FO', 'GL', 'AX', 'GB', 'UK', 'AI', 'BM', 'IO', 'VG', 'KY', 'FK', 'GI', 'MS', 'PN', 'SH', 'TC', 'GG', 'JE', 'IM', 'CA', 'BR', 'IN']);
  const fnv1a = s => {
    let h = 0x811c9dc5;
    for (let i = 0; i < s.length; i++) {
      h ^= s.charCodeAt(i);
      h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
    }
    return h >>> 0;
  };
  const bucket = (seed, vid) => fnv1a(fnv1a(seed + vid) + '') % 10000 < 5000 ? 'control' : 'treatment';
  const [decision] = useState(() => {
    const params = new URLSearchParams(location.search);
    const preBucketed = document.documentElement.dataset['gb_' + flag.replace(/-/g, '_')];
    const force = params.get('gb-force');
    if (force) {
      for (const p of force.split(',')) {
        const [k, v] = p.split(':');
        if (k === flag) return {
          variant: v || 'treatment',
          track: false
        };
      }
    }
    if (navigator.globalPrivacyControl) {
      return {
        variant: 'control',
        track: false
      };
    }
    const prefsMatch = document.cookie.match(/(?:^|; )anthropic-consent-preferences=([^;]+)/);
    if (prefsMatch) {
      try {
        if (JSON.parse(decodeURIComponent(prefsMatch[1])).analytics !== true) {
          return {
            variant: 'control',
            track: false
          };
        }
      } catch {
        return {
          variant: 'control',
          track: false
        };
      }
    } else {
      const country = params.get('country')?.toUpperCase() || (document.cookie.match(/(?:^|; )cf_geo=([A-Z]{2})/) || [])[1];
      if (!country || CONSENT_COUNTRIES.has(country)) {
        return {
          variant: 'control',
          track: false
        };
      }
    }
    let vid;
    try {
      const ajsMatch = document.cookie.match(/(?:^|; )ajs_anonymous_id=([^;]+)/);
      if (ajsMatch) {
        vid = decodeURIComponent(ajsMatch[1]).replace(/^"|"$/g, '');
      } else {
        vid = localStorage.getItem(VID_KEY);
        if (!vid) {
          vid = crypto.randomUUID();
        }
        document.cookie = `ajs_anonymous_id=${vid}; domain=.claude.com; path=/; Secure; SameSite=Lax; max-age=31536000`;
      }
      try {
        localStorage.setItem(VID_KEY, vid);
      } catch {}
    } catch {
      return {
        variant: 'control',
        track: false
      };
    }
    const variant = preBucketed === '1' ? 'treatment' : preBucketed === '0' ? 'control' : bucket(flag, vid);
    return {
      variant,
      track: true,
      vid
    };
  });
  useEffect(() => {
    if (!decision.track) return;
    fetch('https://api.anthropic.com/api/event_logging/v2/batch', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-service-name': 'claude_code_docs'
      },
      body: JSON.stringify({
        events: [{
          event_type: 'GrowthbookExperimentEvent',
          event_data: {
            device_id: decision.vid,
            anonymous_id: decision.vid,
            timestamp: new Date().toISOString(),
            experiment_id: flag,
            variation_id: decision.variant === 'treatment' ? 1 : 0,
            environment: 'production'
          }
        }]
      }),
      keepalive: true
    }).catch(() => {});
  }, []);
  return decision.variant === 'treatment' ? treatment : children;
};

<Experiment flag="docs-contact-sales-cta" treatment={<ContactSalesCard surface="bedrock" />} />

## Prerequisites

Before configuring Claude Code with Bedrock, ensure you have:

* An AWS account with Bedrock access enabled
* Access to desired Claude models (for example, Claude Sonnet 4.6) in 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 Bedrock credentials, follow [Sign in with 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

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

<Steps>
  <Step title="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.
  </Step>

  <Step title="Start Claude Code and choose Bedrock">
    Run `claude`. At the login prompt, select **3rd-party platform**, then **Amazon Bedrock**.
  </Step>

  <Step title="Follow the wizard prompts">
    Choose how you authenticate to AWS: an AWS profile detected from your `~/.aws` directory, a Bedrock API key, an access key and secret, or credentials already in your environment. The wizard picks up 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](claude-code-settings-claude-code-docs-d4420b4b52.md), so you don't need to export environment variables yourself.
  </Step>
</Steps>

After you've signed in, run `/setup-bedrock` any time to reopen the wizard and change your credentials, region, or model pins.

## Set up manually

To configure 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

First-time users of Anthropic models are required to submit use case details before invoking a model. This is done once per AWS account.

1. Ensure you have the right IAM permissions described below
2. Navigate 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

Claude Code uses the default AWS SDK credential chain. Set up your credentials using one of these methods:

**Option A: AWS CLI configuration**

```bash theme={null}
aws configure
```

**Option B: Environment variables (access key)**

```bash theme={null}
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
```

**Option C: Environment variables (SSO profile)**

```bash theme={null}
aws sso login --profile=<your-profile-name>

export AWS_PROFILE=your-profile-name
```

**Option D: AWS Management Console credentials**

```bash theme={null}
aws login
```

[Learn more](https://docs.aws.amazon.com/signin/latest/userguide/command-line-sign-in.html) about `aws login`.

**Option E: Bedrock API keys**

```bash theme={null}
export AWS_BEARER_TOKEN_BEDROCK=your-bedrock-api-key
```

Bedrock API keys provide a simpler authentication method without needing full AWS credentials. [Learn more about Bedrock API keys](https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/).

#### 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](claude-code-settings-claude-code-docs-d4420b4b52.md) for file locations).

When Claude Code detects that your AWS credentials are expired (either locally based on their timestamp or when Bedrock returns a credential error), it will automatically run your configured `awsAuthRefresh` and/or `awsCredentialExport` commands to obtain new credentials before retrying the request.

##### Example configuration

```json theme={null}
{
  "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:

```json theme={null}
{
  "Credentials": {
    "AccessKeyId": "value",
    "SecretAccessKey": "value",
    "SessionToken": "value"
  }
}
```

### 3. Configure Claude Code

Set the following environment variables to enable Bedrock:

```bash theme={null}
# Enable Bedrock integration
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=us-east-1  # or your preferred region

# Optional: Override the region for the small/fast model (Haiku).
# Also applies to Bedrock Mantle.
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 Bedrock for Claude Code, keep the following in mind:

* `AWS_REGION` is a required environment variable. Claude Code does not read from the `.aws` config file for this setting.
* When using Bedrock, the `/login` and `/logout` commands are disabled since authentication is handled through AWS credentials.
* You can use settings files for environment variables like `AWS_PROFILE` that you don't want to leak to other processes. See [Settings](claude-code-settings-claude-code-docs-d4420b4b52.md) for more information.

### 4. Pin model versions

<Warning>
  Pin specific model versions when deploying to multiple users. Without pinning, model aliases such as `sonnet` and `opus` resolve to the latest version, which may not yet be available in your Bedrock account when Anthropic releases an update. Claude Code [falls back](#startup-model-checks) to the previous version at startup when the latest is unavailable, but pinning lets you control when your users move to a new model.
</Warning>

Set these environment variables to specific Bedrock model IDs.

Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias on Bedrock resolves to Opus 4.6. Set it to the Opus 4.7 ID to use the latest model:

```bash theme={null}
export ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-7'
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 variables use cross-region inference profile IDs (with the `us.` prefix). If you use a different region prefix or application inference profiles, adjust accordingly. For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview-2bbf09ff82.md). See [Model configuration](/en/model-config#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    | `us.anthropic.claude-sonnet-4-5-20250929-v1:0` |
| Small/fast model | `us.anthropic.claude-haiku-4-5-20251001-v1:0`  |

To customize models further, use one of these methods:

```bash theme={null}
# Using inference profile ID
export ANTHROPIC_MODEL='global.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
```

<Note>[Prompt caching](../10-Prompting-Guides/build-with-claude-prompt-caching-bf7c54aa4c.md) may not be available in all regions. Cache writes with a 1-hour TTL are billed at a higher rate than 5-minute writes.</Note>

#### 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](/en/settings#settings-files) instead.

This example maps four Opus versions to distinct ARNs so users can switch between them without bypassing your organization's inference profiles:

```json theme={null}
{
  "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 Bedrock with the mapped ARN. Versions without an override fall back to the built-in Bedrock model ID or any matching inference profile discovered at startup. See [Override model IDs per version](/en/model-config#override-model-ids-per-version) for details on how overrides interact with `availableModels` and other model settings.

## Startup model checks

When Claude Code starts with Bedrock configured, it verifies that the models it intends to use are accessible in your account. This check requires Claude Code v2.1.94 or later.

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](claude-code-settings-claude-code-docs-d4420b4b52.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 to the previous version for the current session and shows a notice. The fallback is not persisted. Enable the newer model in your Bedrock account or [pin a version](#4-pin-model-versions) to make the choice permanent.

## IAM configuration

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

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowModelAndInferenceProfileAccess",
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream",
        "bedrock:ListInferenceProfiles"
      ],
      "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.

For details, see [Bedrock IAM documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html).

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

## 1M token context window

Claude Opus 4.7, Opus 4.6, and Sonnet 4.6 support the [1M token context window](../04-API-Reference/Guides/build-with-claude-context-windows-13ca780d1d.md#1m-token-context-window) on Amazon Bedrock. Claude Code automatically enables the extended context window when you select a 1M model 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](/en/model-config#pin-models-for-third-party-deployments) for details.

## 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](claude-code-settings-claude-code-docs-d4420b4b52.md). Enable Cross-Region inference on your Guardrail if you're using cross-region inference profiles.

Example configuration:

```json theme={null}
{
  "env": {
    "ANTHROPIC_CUSTOM_HEADERS": "X-Amzn-Bedrock-GuardrailIdentifier: your-guardrail-id\nX-Amzn-Bedrock-GuardrailVersion: 1"
  }
}
```

## Use the Mantle endpoint

Mantle is an Amazon Bedrock endpoint that serves Claude models through the native Anthropic API shape rather than the Bedrock Invoke API. It uses the same AWS credentials, IAM permissions, and `awsAuthRefresh` configuration described earlier on this page.

<Note>
  Mantle requires Claude Code v2.1.94 or later. Run `claude --version` to check.
</Note>

### Enable Mantle

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

```bash theme={null}
export CLAUDE_CODE_USE_MANTLE=1
export AWS_REGION=us-east-1
```

Claude Code constructs the endpoint URL from `AWS_REGION`. To override it 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

Mantle uses model IDs prefixed with `anthropic.` and without a version suffix, for example `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:

```bash theme={null}
claude --model anthropic.claude-haiku-4-5
```

### 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 Bedrock Invoke API.

```bash theme={null}
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](claude-code-settings-claude-code-docs-d4420b4b52.md). This setting also restricts the picker to the listed entries, so include every alias you want to keep available:

```json theme={null}
{
  "availableModels": ["opus", "sonnet", "haiku", "anthropic.claude-haiku-4-5"]
}
```

Entries with the `anthropic.` prefix are added as custom picker options and routed to Mantle. Replace `anthropic.claude-haiku-4-5` with the model ID your account has been granted. See [Restrict model selection](/en/model-config#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

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

```bash theme={null}
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

These variables are specific to the Mantle endpoint. See [Environment variables](env-vars-5c624d392b.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 Bedrock) |

## Troubleshooting

### Authentication loop with SSO and corporate proxies

If browser tabs spawn repeatedly when using AWS SSO, remove the `awsAuthRefresh` setting from your [settings file](claude-code-settings-claude-code-docs-d4420b4b52.md). This can occur when corporate VPNs or TLS inspection proxies interrupt the SSO browser flow. Claude Code treats the interrupted connection as an authentication failure, re-runs `awsAuthRefresh`, and loops indefinitely.

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

### 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 Bedrock [Invoke API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html) and does not support the Converse API.

### 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](claude-code-settings-claude-code-docs-d4420b4b52.md).

A `403` from the Mantle endpoint with valid credentials means 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 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

* [Bedrock documentation](https://docs.aws.amazon.com/bedrock/)
* [Bedrock pricing](https://aws.amazon.com/bedrock/pricing/)
* [Bedrock inference profiles](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html)
* [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://community.aws/content/2tXkZKrZzlrlu0KfH8gST5Dkppq/claude-code-on-amazon-bedrock-quick-setup-guide)
* [Claude Code Monitoring Implementation (Bedrock)](https://github.com/aws-solutions-library-samples/guidance-for-claude-code-with-amazon-bedrock/blob/main/assets/docs/MONITORING.md)


---
## analytics-5356b88d0a.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Track team usage with analytics

> View Claude Code usage metrics, track adoption, and measure engineering velocity in the analytics dashboard.

Claude Code provides analytics dashboards to help organizations understand developer usage patterns, track contribution metrics, and measure how Claude Code impacts engineering velocity. Access the dashboard for your plan:

| Plan                          | Dashboard URL                                                              | Includes                                                                              | Read more                                            |
| ----------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| Claude for Teams / Enterprise | [claude.ai/analytics/claude-code](https://claude.ai/analytics/claude-code) | Usage metrics, contribution metrics with GitHub integration, leaderboard, data export | [Details](#access-analytics-for-team-and-enterprise) |
| API (Claude Console)          | [platform.claude.com/claude-code](https://platform.claude.com/claude-code) | Usage metrics, spend tracking, team insights                                          | [Details](#access-analytics-for-api-customers)       |

## Access analytics for Team and Enterprise

Navigate to [claude.ai/analytics/claude-code](https://claude.ai/analytics/claude-code). Admins and Owners can view the dashboard.

The Team and Enterprise dashboard includes:

* **Usage metrics**: lines of code accepted, suggestion accept rate, daily active users and sessions
* **Contribution metrics**: PRs and lines of code shipped with Claude Code assistance, with [GitHub integration](#enable-contribution-metrics)
* **Leaderboard**: top contributors ranked by Claude Code usage
* **Data export**: download contribution data as CSV for custom reporting

### Enable contribution metrics

<Note>
  Contribution metrics are in public beta and available on Claude for Teams and Claude for Enterprise plans. These metrics only cover users within your claude.ai organization. Usage through the Claude Console API or third-party integrations is not included.
</Note>

Usage and adoption data is available for all Claude for Teams and Claude for Enterprise accounts. Contribution metrics require additional setup to connect your GitHub organization.

You need the Owner role to configure analytics settings. A GitHub admin must install the GitHub app.

<Warning>
  Contribution metrics are not available for organizations with [Zero Data Retention](../22-Safety-Policy/zero-data-retention-claude-code-docs-6ec9ee63f1.md) enabled. The analytics dashboard will show usage metrics only.
</Warning>

<Steps>
  <Step title="Install the GitHub app">
    A GitHub admin installs the Claude GitHub app on your organization's GitHub account at [github.com/apps/claude](https://github.com/apps/claude).
  </Step>

  <Step title="Enable Claude Code analytics">
    A Claude Owner navigates to [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code) and enables the Claude Code analytics feature.
  </Step>

  <Step title="Enable GitHub analytics">
    On the same page, enable the "GitHub analytics" toggle.
  </Step>

  <Step title="Authenticate with GitHub">
    Complete the GitHub authentication flow and select which GitHub organizations to include in the analysis.
  </Step>
</Steps>

Data typically appears within 24 hours after enabling, with daily updates. If no data appears, you may see one of these messages:

* **"GitHub app required"**: install the GitHub app to view contribution metrics
* **"Data processing in progress"**: check back in a few days and confirm the GitHub app is installed if data doesn't appear

Contribution metrics support GitHub Cloud and GitHub Enterprise Server.

### Review summary metrics

<Note>
  These metrics are deliberately conservative and represent an underestimate of Claude Code's actual impact. Only lines and PRs where there is high confidence in Claude Code's involvement are counted.
</Note>

The dashboard displays these summary metrics at the top:

* **PRs with CC**: total count of merged pull requests that contain at least one line of code written with Claude Code
* **Lines of code with CC**: total lines of code across all merged PRs that were written with Claude Code assistance. Only "effective lines" are counted: lines with more than 3 characters after normalization, excluding empty lines and lines with only brackets or trivial punctuation.
* **PRs with Claude Code (%)**: percentage of all merged PRs that contain Claude Code-assisted code
* **Suggestion accept rate**: percentage of times users accept Claude Code's code editing suggestions, including Edit, Write, and NotebookEdit tool usage
* **Lines of code accepted**: total lines of code written by Claude Code that users have accepted in their sessions. This excludes rejected suggestions and does not track subsequent deletions.

### Explore the charts

The dashboard includes several charts to visualize trends over time.

#### Track adoption

The Adoption chart shows daily usage trends:

* **users**: daily active users
* **sessions**: number of active Claude Code sessions per day

#### Measure PRs per user

This chart displays individual developer activity over time:

* **PRs per user**: total number of PRs merged per day divided by daily active users
* **users**: daily active users

Use this to understand how individual productivity changes as Claude Code adoption increases.

#### View pull requests breakdown

The Pull requests chart shows a daily breakdown of merged PRs:

* **PRs with CC**: pull requests containing Claude Code-assisted code
* **PRs without CC**: pull requests without Claude Code-assisted code

Toggle to **Lines of code** view to see the same breakdown by lines of code rather than PR count.

#### Find top contributors

The Leaderboard shows the top 10 users ranked by contribution volume. Toggle between:

* **Pull requests**: shows PRs with Claude Code vs All PRs for each user
* **Lines of code**: shows lines with Claude Code vs All lines for each user

Click **Export all users** to download complete contribution data for all users as a CSV file. The export includes all users, not just the top 10 displayed.

### PR attribution

When contribution metrics are enabled, Claude Code analyzes merged pull requests to determine which code was written with Claude Code assistance. This is done by matching Claude Code session activity against the code in each PR.

#### Tagging criteria

PRs are tagged as "with Claude Code" if they contain at least one line of code written during a Claude Code session. The system uses conservative matching: only code where there is high confidence in Claude Code's involvement is counted as assisted.

#### Attribution process

When a pull request is merged:

1. Added lines are extracted from the PR diff
2. Claude Code sessions that edited matching files within a time window are identified
3. PR lines are matched against Claude Code output using multiple strategies
4. Metrics are calculated for AI-assisted lines and total lines

Before comparison, lines are normalized: whitespace is trimmed, multiple spaces are collapsed, quotes are standardized, and text is converted to lowercase.

Merged pull requests containing Claude Code-assisted lines are labeled as `claude-code-assisted` in GitHub.

#### Time window

Sessions from 21 days before to 2 days after the PR merge date are considered for attribution matching.

#### Excluded files

Certain files are automatically excluded from analysis because they are auto-generated:

* Lock files: package-lock.json, yarn.lock, Cargo.lock, and similar
* Generated code: Protobuf outputs, build artifacts, minified files
* Build directories: dist/, build/, node\_modules/, target/
* Test fixtures: snapshots, cassettes, mock data
* Lines over 1,000 characters, which are likely minified or generated

#### Attribution notes

Keep these additional details in mind when interpreting attribution data:

* Code substantially rewritten by developers, with more than 20% difference, is not attributed to Claude Code
* Sessions outside the 21-day window are not considered
* The algorithm does not consider the PR source or destination branch when performing attribution

### Get the most from analytics

Use contribution metrics to demonstrate ROI, identify adoption patterns, and find team members who can help others get started.

#### Monitor adoption

Track the Adoption chart and user counts to identify:

* Active users who can share best practices
* Overall adoption trends across your organization
* Dips in usage that may indicate friction or issues

#### Measure ROI

Contribution metrics help answer "Is this tool worth the investment?" with data from your own codebase:

* Track changes in PRs per user over time as adoption increases
* Compare PRs and lines of code shipped with vs. without Claude Code
* Use alongside [DORA metrics](https://dora.dev/), sprint velocity, or other engineering KPIs to understand changes from adopting Claude Code

#### Identify power users

The Leaderboard helps you find team members with high Claude Code adoption who can:

* Share prompting techniques and workflows with the team
* Provide feedback on what's working well
* Help onboard new users

#### Access data programmatically

To query this data through GitHub, search for PRs labeled with `claude-code-assisted`.

## Access analytics for API customers

API customers using the Claude Console can access analytics at [platform.claude.com/claude-code](https://platform.claude.com/claude-code). You need the UsageView permission to access the dashboard, which is granted to Developer, Billing, Admin, Owner, and Primary Owner roles.

<Note>
  Contribution metrics with GitHub integration are not currently available for API customers. The Console dashboard shows usage and spend metrics only.
</Note>

The Console dashboard displays:

* **Lines of code accepted**: total lines of code written by Claude Code that users have accepted in their sessions. This excludes rejected suggestions and does not track subsequent deletions.
* **Suggestion accept rate**: percentage of times users accept code editing tool usage, including Edit, Write, and NotebookEdit tools.
* **Activity**: daily active users and sessions shown on a chart.
* **Spend**: daily API costs in dollars alongside user count.

### View team insights

The team insights table shows per-user metrics:

* **Members**: all users who have authenticated to Claude Code. API key users display by key identifier, OAuth users display by email address.
* **Spend this month**: per-user total API costs for the current month.
* **Lines this month**: per-user total of accepted code lines for the current month.

<Note>
  Spend figures in the Console dashboard are estimates for analytics purposes. For actual costs, refer to your billing page.
</Note>

## Related resources

* [Monitoring with OpenTelemetry](../13-Enterprise-Admin/monitoring-claude-code-docs-72c46f3dc8.md): export real-time metrics and events to your observability stack
* [Manage costs effectively](../17-Billing-Plans/manage-costs-effectively-claude-code-docs-7c26178a4f.md): set spend limits and optimize token usage
* [Permissions](configure-permissions-claude-code-docs-7b0e64d485.md): configure roles and permissions


---
## authentication-ce6fdcb8aa.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

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

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 Vertex AI, or Microsoft Foundry.

## Log in to Claude Code

After [installing Claude Code](/en/setup#install-claude-code), run `claude` in your terminal. On first launch, Claude Code opens a browser window for you to log 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.

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](https://claude.com/pricing?utm_source=claude_code\&utm_medium=docs\&utm_content=authentication_pro_max).
* **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.
* **Cloud providers**: if your organization uses [Amazon Bedrock](../20-Models/claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.md), [Google Vertex AI](../20-Models/claude-code-on-google-vertex-ai-claude-code-docs-2acd050a7a.md), or [Microsoft Foundry](../20-Models/claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.md), set the required environment variables before running `claude`. No browser login is needed.

To log out and re-authenticate, type `/logout` at the Claude Code prompt.

If you're having trouble logging in, see [authentication troubleshooting](/en/troubleshooting#authentication-issues).

## 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)
* [Amazon Bedrock](../20-Models/claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.md)
* [Google Vertex AI](../20-Models/claude-code-on-google-vertex-ai-claude-code-docs-2acd050a7a.md)
* [Microsoft Foundry](../20-Models/claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.md)

### Claude for Teams or Enterprise

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

* **Claude for Teams**: self-service plan with collaboration features, admin tools, and billing management. Best for smaller teams.
* **Claude for Enterprise**: adds SSO, domain capture, role-based permissions, compliance API, and managed policy settings for organization-wide Claude Code configurations. Best for larger organizations with security and compliance requirements.

<Steps>
  <Step title="Subscribe">
    Subscribe to [Claude for Teams](https://claude.com/pricing?utm_source=claude_code\&utm_medium=docs\&utm_content=authentication_teams_step#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).
  </Step>

  <Step title="Invite team members">
    Invite team members from the admin dashboard.
  </Step>

  <Step title="Install and log in">
    Team members install Claude Code and log in with their Claude.ai accounts.
  </Step>
</Steps>

### Claude Console authentication

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

<Steps>
  <Step title="Create or use a Console account">
    Use your existing Claude Console account or create a new one.
  </Step>

  <Step title="Add users">
    You can add users through either method:

    * Bulk invite users from within the Console: Settings -> Members -> Invite
    * [Set up SSO](../21-Account-Support/setting-up-single-sign-on-sso.md)
  </Step>

  <Step title="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
  </Step>

  <Step title="Users complete setup">
    Each invited user needs to:

    * Accept the Console invite
    * [Check system requirements](/en/setup#system-requirements)
    * [Install Claude Code](/en/setup#install-claude-code)
    * Log in with Console account credentials
  </Step>
</Steps>

### Cloud provider authentication

For teams using Amazon Bedrock, Google Vertex AI, or Microsoft Foundry:

<Steps>
  <Step title="Follow provider setup">
    Follow the [Bedrock docs](../20-Models/claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.md), [Vertex docs](../20-Models/claude-code-on-google-vertex-ai-claude-code-docs-2acd050a7a.md), or [Microsoft Foundry docs](../20-Models/claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.md).
  </Step>

  <Step title="Distribute configuration">
    Distribute the environment variables and instructions for generating cloud credentials to your users. Read more about how to [manage configuration here](claude-code-settings-claude-code-docs-d4420b4b52.md).
  </Step>

  <Step title="Install Claude Code">
    Users can [install Claude Code](/en/setup#install-claude-code).
  </Step>
</Steps>

## Credential management

Claude Code securely manages your authentication credentials:

* **Storage location**: on macOS, credentials are stored in the encrypted macOS Keychain. On Linux and Windows, credentials are stored in `~/.claude/.credentials.json`, or under `$CLAUDE_CONFIG_DIR` if that variable is set. On Linux, the file is written with mode `0600`; on Windows, it inherits the access controls of your user profile directory.
* **Supported authentication types**: Claude.ai credentials, Claude API credentials, Azure Auth, Bedrock Auth, and Vertex Auth.
* **Custom credential scripts**: the [`apiKeyHelper`](/en/settings#available-settings) setting can be configured to run a shell script that returns an API key.
* **Refresh intervals**: by default, `apiKeyHelper` is called after 5 minutes or on HTTP 401 response. Set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` environment variable for custom refresh intervals.
* **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.

`apiKeyHelper`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` apply to terminal CLI sessions only. Claude Desktop and remote sessions use OAuth exclusively and do not call `apiKeyHelper` or read API key environment variables.

### 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](enterprise-deployment-overview-claude-code-docs-6eae0ecba2.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-configuration-claude-code-docs-7a1628ac88.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/platform-claude-com.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`. In non-interactive mode (`-p`), the key is always used when present.
4. [`apiKeyHelper`](/en/settings#available-settings) 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.
6. Subscription OAuth credentials from `/login`. This is the default for Claude Pro, Max, Team, and Enterprise users.

If you have an active Claude subscription but also have `ANTHROPIC_API_KEY` set in your environment, the API key takes precedence once approved. 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.

[Claude Code on the Web](claude-code-on-the-web-69d53821d4.md) always uses your subscription credentials. `ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN` in the sandbox environment do not override them.

### 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`:

```bash theme={null}
claude setup-token
```

The command walks you through OAuth authorization and prints a token to the terminal. 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:

```bash theme={null}
export CLAUDE_CODE_OAUTH_TOKEN=your-token
```

This token authenticates with your Claude subscription and requires a Pro, Max, Team, or Enterprise plan. It is scoped to inference only and cannot establish [Remote Control](continue-local-sessions-from-any-device-with-remote-control-claude-code-docs-c1c03fd914.md) sessions.

[Bare mode](/en/headless#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.


---
## authentication-claude-code-docs-2c6ada8385.md

## On this page

- [Log in to Claude Code](#log-in-to-claude-code)
- [Set up team authentication](#set-up-team-authentication)
  - [Claude for Teams or Enterprise](#claude-for-teams-or-enterprise)
  - [Claude Console authentication](#claude-console-authentication)
  - [Cloud provider authentication](#cloud-provider-authentication)
  - [Restrict login to your organization](#restrict-login-to-your-organization)
- [Credential management](#credential-management)
  - [Renew an expiring login](#renew-an-expiring-login)
  - [Authentication precedence](#authentication-precedence)
  - [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](/docs/en/setup#install-claude-code), run `claude` in your terminal. On first launch, Claude Code opens a browser window for you to log in. If you’ve set the `ANTHROPIC_API_KEY` environment variable, Claude Code skips the login prompt and asks you to approve the key instead. 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](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=authentication_pro_max).
- **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.
- **Cloud providers**: if your organization uses [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud’s Agent Platform](/docs/en/google-vertex-ai), or [Microsoft Foundry](/docs/en/microsoft-foundry), 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](/docs/en/claude-apps-gateway), sign in with corporate SSO through `/login`. The gateway-issued token is the session’s only credential.

Admins can restrict which login methods and organizations are accepted; 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](/docs/en/troubleshoot-install#login-and-authentication).


[​](#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](/docs/en/claude-apps-gateway), a self-hosted gateway that signs developers in with your IdP and routes inference to the cloud provider you configure
- [Amazon Bedrock](/docs/en/amazon-bedrock)
- [Google Cloud’s Agent Platform](/docs/en/google-vertex-ai)
- [Microsoft Foundry](/docs/en/microsoft-foundry)


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

Claude for Teams or Enterprise

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

- **Claude for Teams**: self-service plan with collaboration features, admin tools, and billing management. Best for smaller teams.
- **Claude for Enterprise**: adds SSO, domain capture, role-based permissions, compliance API, and managed policy settings for organization-wide Claude Code configurations. Best for larger organizations with security and compliance requirements.

1

Subscribe

Subscribe to [Claude for Teams](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=authentication_teams_step#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 within the Console: Settings -\> Members -\> Invite
- [Set up SSO](https://support.claude.com/en/articles/13132885-setting-up-single-sign-on-sso)

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](/docs/en/setup#system-requirements)
- [Install Claude Code](/docs/en/setup#install-claude-code)
- Log in with Console account 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](/docs/en/amazon-bedrock), [Google Cloud’s Agent Platform docs](/docs/en/google-vertex-ai), or [Microsoft Foundry docs](/docs/en/microsoft-foundry).

2

Distribute configuration

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

3

Install Claude Code

Users can [install Claude Code](/docs/en/setup#install-claude-code).


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

Restrict login to your organization

To require that developer sessions authenticate into a specific Anthropic organization, set [`forceLoginMethod` and `forceLoginOrgUUID`](/docs/en/settings#available-settings) in [managed settings](/docs/en/settings#settings-files). 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, or at [platform.claude.com/settings/organization](https://platform.claude.com/settings/organization) for Console organizations. With both keys set, Claude Code restricts login to the listed organization and exits at startup if the active credential belongs to a different one. Developers can log in from several paths: the terminal `/login` flow, the [VS Code extension](/docs/en/vs-code), the Agent SDK, `claude setup-token`, `/install-github-app`, and [gateway](/docs/en/claude-apps-gateway) sign-in for organizations that route through a cloud gateway. On Claude Code v2.1.212 or later, every path enforces `forceLoginMethod`; before v2.1.212, only terminal logins enforced either key. The paths differ on `forceLoginOrgUUID`:

- **Terminal, VS Code extension, and Agent SDK logins**: enforce both keys
- **`claude setup-token` and `/install-github-app`**: enforce only `forceLoginMethod`, so they can mint a token in a different organization
- **[Gateway](/docs/en/claude-apps-gateway) sign-in**: selected by `forceLoginMethod: "gateway"` rather than restricted by it, and doesn’t authenticate against an Anthropic organization, so `forceLoginOrgUUID` doesn’t apply; use your gateway identity provider to restrict access

Deploy the keys through your device management tooling. [Server-managed settings](/docs/en/server-managed-settings) reach only accounts that are already authenticated into your organization, so they can’t redirect a developer’s first login. If your organization distributes server-managed settings as well, set the keys in both places: managed-settings sources [don’t merge](/docs/en/server-managed-settings#settings-precedence), and cached server-managed settings replace the device-managed file entirely. The keys also block sessions authenticated by `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper`, since organization membership can’t be verified for an environment credential. Cloud provider sessions such as Amazon Bedrock authenticate against your cloud provider and aren’t blocked; restrict those through your cloud IAM policies. See [`forceLoginOrgUUID`](/docs/en/settings#available-settings) in the settings reference for the full behavior. Before v2.1.146, the pin applied only to the login flow and didn’t block API-key credentials.


[​](#credential-management)

Credential management

Claude Code securely manages your authentication credentials:

- **Storage location**:
  - On macOS, credentials are stored in the encrypted macOS Keychain.
  - 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 on Linux or Windows, the `.credentials.json` file lives under that directory instead.
  - Claude Code manages `.credentials.json` through `/login` and `/logout`. To route requests through a custom API endpoint, set the [`ANTHROPIC_BASE_URL`](/docs/en/env-vars) environment variable instead.
- **Supported authentication types**: Claude.ai credentials, Claude API credentials, Microsoft Foundry Auth, Bedrock Auth, Vertex Auth, and [Claude apps gateway](/docs/en/claude-apps-gateway) session tokens.
- **Custom credential scripts**: configure the [`apiKeyHelper`](/docs/en/settings#available-settings) setting to run a shell script that returns an API key.
- **Refresh intervals**: by default, `apiKeyHelper` is called after 5 minutes or on HTTP 401 response. Set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` environment variable for custom refresh intervals.
- **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`](/docs/en/errors#your-apikeyhelper-script-is-failing) within three attempts. Before v2.1.208, helper failures surfaced as a generic 401 after about ten silent retries.

`apiKeyHelper`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` apply to the CLI and the surfaces that wrap it, including the VS Code extension, the Agent SDK, and GitHub Actions. Claude Desktop and cloud sessions do not call `apiKeyHelper` or read these environment variables: they use OAuth, except desktop sessions running a [third-party inference configuration](/docs/en/llm-gateway-connect#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`. Requires Claude Code v2.1.203 or later. Before v2.1.217, the warning appeared five days out. Run `/login` to renew. The warning is informational and never blocks a request: authentication keeps working until the login actually expires. The login lifetime itself is unchanged; the advance warning is what v2.1.203 adds. Once the stored login expires and can’t be refreshed, each request fails with [`Login expired · Please run /login`](/docs/en/errors#login-expired) until you sign in again. Before v2.1.206, an expired login surfaced as a model error instead. You can check for this state before a request fails: [`/status`](/docs/en/commands) shows a `Login` row reading `Expired — log in again`, plus the organization and email it has saved for the expired login. The row appears only when the saved claude.ai or Claude Console login is the active credential. The row requires Claude Code v2.1.210 or later. The warning appears only when a claude.ai or Claude Console 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](/docs/en/agent-view) or a [Remote Control](/docs/en/remote-control) 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](/docs/en/third-party-integrations) for setup.
2.  `ANTHROPIC_AUTH_TOKEN` environment variable. Sent as the `Authorization: Bearer` header. Use this when routing through an [LLM gateway or proxy](/docs/en/llm-gateway) that authenticates with bearer tokens rather than Anthropic API keys.
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](https://platform.claude.com). In interactive mode, you are prompted once to approve or decline the key, and your choice is remembered. To change it later, use the “Use custom API key” toggle in `/config`. The toggle only appears while `ANTHROPIC_API_KEY` is set in your environment. In non-interactive mode (`-p`), the key is always used when present.
4.  [`apiKeyHelper`](/docs/en/settings#available-settings) 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.
6.  Subscription OAuth credentials from `/login`. This is the default for Claude Pro, Max, Team, and Enterprise users.

A signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) session sits outside this list: it is a provider selection like Amazon Bedrock or Google Cloud’s Agent Platform, and it outranks them. When a gateway session exists, the CLI authenticates with the gateway token even if `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, or `CLAUDE_CODE_USE_FOUNDRY` is set, and the bearer token, API key, and `apiKeyHelper` entries above are not used. If you have an active Claude subscription but also have `ANTHROPIC_API_KEY` set in your environment, the API key takes precedence once approved. 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. The `Login method` row shows your subscription account, and an `API key` row appears when an API key is in use. [Claude Code on the Web](/docs/en/claude-code-on-the-web) always uses your subscription credentials. If you set `ANTHROPIC_API_KEY` or `ANTHROPIC_AUTH_TOKEN` in the sandbox environment, it doesn’t override your subscription credentials.


[​](#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:

```python
export 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](/docs/en/remote-control) sessions or fetch [claude.ai connectors](/docs/en/mcp#use-mcp-servers-from-claude-ai). MCP servers you configure locally still work. [Bare mode](/docs/en/headless#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.


---
## authentication-claude-code-docs.md

# Authentication


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


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 Vertex AI, or Microsoft Foundry.

## 

Log in to Claude Code

After [installing Claude Code](/docs/en/setup#install-claude-code), run `claude` in your terminal. On first launch, Claude Code opens a browser window for you to log in. If the browser doesn’t open automatically, press `c` to copy the login URL to your clipboard, then paste it into your browser. 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](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=authentication_pro_max).
- **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.
- **Cloud providers**: if your organization uses [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Vertex AI](/docs/en/google-vertex-ai), or [Microsoft Foundry](/docs/en/microsoft-foundry), set the required environment variables before running `claude`. No browser login is needed.

To log out and re-authenticate, type `/logout` at the Claude Code prompt. If you’re having trouble logging in, see [authentication troubleshooting](/docs/en/troubleshooting#authentication-issues).

## 

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)
- [Amazon Bedrock](/docs/en/amazon-bedrock)
- [Google Vertex AI](/docs/en/google-vertex-ai)
- [Microsoft Foundry](/docs/en/microsoft-foundry)

### 

Claude for Teams or Enterprise

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

- **Claude for Teams**: self-service plan with collaboration features, admin tools, and billing management. Best for smaller teams.
- **Claude for Enterprise**: adds SSO, domain capture, role-based permissions, compliance API, and managed policy settings for organization-wide Claude Code configurations. Best for larger organizations with security and compliance requirements.

1

[](#)

Subscribe

Subscribe to [Claude for Teams](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=authentication_teams_step#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

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 within the Console: Settings -\> Members -\> 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](/docs/en/setup#system-requirements)
- [Install Claude Code](/docs/en/setup#install-claude-code)
- Log in with Console account credentials

### 

Cloud provider authentication

For teams using Amazon Bedrock, Google Vertex AI, or Microsoft Foundry:

1

[](#)

Follow provider setup

Follow the [Bedrock docs](/docs/en/amazon-bedrock), [Vertex docs](/docs/en/google-vertex-ai), or [Microsoft Foundry docs](/docs/en/microsoft-foundry).

2

[](#)

Distribute configuration

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

3

[](#)

Install Claude Code

Users can [install Claude Code](/docs/en/setup#install-claude-code).

## 

Credential management

Claude Code securely manages your authentication credentials:

- **Storage location**: on macOS, credentials are stored in the encrypted macOS Keychain.
- **Supported authentication types**: Claude.ai credentials, Claude API credentials, Azure Auth, Bedrock Auth, and Vertex Auth.
- **Custom credential scripts**: the [`apiKeyHelper`](/docs/en/settings#available-settings) setting can be configured to run a shell script that returns an API key.
- **Refresh intervals**: by default, `apiKeyHelper` is called after 5 minutes or on HTTP 401 response. Set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` environment variable for custom refresh intervals.


---
## auto-compact-deep-dive.md

# Auto-Compact Deep Dive — Window vs Percentage Override

**Topic**: `CLAUDE_CODE_AUTO_COMPACT_WINDOW` vs `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`
**Binary**: Claude Code 2.1.75
**Status**: Both active, fully implemented

---

## TL;DR

- **`CLAUDE_CODE_AUTO_COMPACT_WINDOW`** = "Pretend the context window is this size" (caps max window)
- **`CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`** = "Trigger compaction at X% of (possibly capped) window"
- They **compose**: window override runs first, percentage applies to the result
- **Order matters**: Window cap → percentage calculation → 13K safety headroom
- For **Opus 1M**, use both: `WINDOW=350000` + `PCT=85` to maintain 200K-like behavior

---

## The Calculation Pipeline

### Step 1: `BB(model)` — Calculate Effective Window

```javascript
function BB(H) {  // H = model
  let buffer = Math.min(PnH(H), 20000),        // Reserved buffer (~20K)
      baseWindow = LY(H, Qw()),                 // Model's native context window
      override = process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;

  if (override) {
    let parsed = parseInt(override, 10);
    if (!isNaN(parsed) && parsed > 0)
      baseWindow = Math.min(baseWindow, parsed);  // ← CAP DOWN (never extends)
  }

  return baseWindow - buffer;  // Effective window
}
```

**Key**: `Math.min(native, override)` — only applies if override is LOWER than native.

---

### Step 2: `bQH(model)` — Calculate Auto-Compact Threshold

```javascript
function bQH(H) {  // H = model
  let effectiveWindow = BB(H),                  // From step 1
      safeThreshold = effectiveWindow - 13000,  // Leave 13K headroom
      pctOverride = process.env.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE;

  if (pctOverride) {
    let pct = parseFloat(pctOverride);
    if (!isNaN(pct) && pct > 0 && pct <= 100) {
      let pctThreshold = Math.floor(effectiveWindow * (pct / 100));
      return Math.min(pctThreshold, safeThreshold);  // ← Never exceed safe headroom
    }
  }

  return safeThreshold;  // Default: effectiveWindow - 13K
}
```

**Key**: Percentage is calculated on the **capped window** (if window override is active).

---

### Step 3: `PKH(tokens, model)` — Check Thresholds

```javascript
function PKH(H, $) {  // H = current tokens, $ = model
  let autoCompactThreshold = bQH($),             // From step 2
      effectiveWindow = BB($),                   // From step 1
      percentLeft = Math.max(0, Math.round((effectiveWindow - H) / effectiveWindow * 100)),

      warningThreshold = effectiveWindow - 20000,
      errorThreshold = effectiveWindow - 20000,
      isAboveAutoCompactThreshold = oy() && H >= autoCompactThreshold,

      blockingLimit = effectiveWindow - 3000,
      blockingOverride = process.env.CLAUDE_CODE_BLOCKING_LIMIT_OVERRIDE,
      actualBlockingLimit = blockingOverride
                            ? parseInt(blockingOverride, 10)
                            : blockingLimit,
      isAtBlockingLimit = H >= actualBlockingLimit;

  return {
    percentLeft,
    isAboveWarningThreshold,
    isAboveErrorThreshold,
    isAboveAutoCompactThreshold,  // ← Triggers auto-compact
    isAtBlockingLimit
  };
}
```

---

## Default Behavior (No Overrides)

### Sonnet 4.6 (200K context)

```
Model native window:    200,000 tokens
Buffer:                 -20,000 tokens
─────────────────────────────────────
Effective window:       180,000 tokens
Safe headroom:          -13,000 tokens
─────────────────────────────────────
Threshold:              167,000 tokens  (~93%)
```

**Auto-compact triggers at 167K tokens** (~93% of effective window).

---

### Opus 1M (1M context)

```
Model native window:  1,000,000 tokens
Buffer:                 -20,000 tokens
─────────────────────────────────────
Effective window:       980,000 tokens
Safe headroom:          -13,000 tokens
─────────────────────────────────────
Threshold:              967,000 tokens  (~99%)
```

**Auto-compact triggers at 967K tokens** (~99% of effective window).

⚠️ **Problem**: Compacting at 99% means:
- Massive conversation history to summarize
- Slow compaction (takes minutes)
- Risk of memory exhaustion
- Poor compaction quality (too much context)

---

## Percentage Override Only

### Example: `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85`

#### Sonnet 4.6 (200K)

```
Effective window:       180,000 tokens
Percentage threshold:   floor(180,000 × 0.85) = 153,000
Safe headroom:          180,000 - 13,000      = 167,000
─────────────────────────────────────
Actual threshold:       min(153,000, 167,000) = 153,000 tokens  (~85%)
```

**Auto-compact at 153K** (~85% of effective window). ✅ Good.

---

#### Opus 1M (1M)

```
Effective window:       980,000 tokens
Percentage threshold:   floor(980,000 × 0.85) = 833,000
Safe headroom:          980,000 - 13,000      = 967,000
─────────────────────────────────────
Actual threshold:       min(833,000, 967,000) = 833,000 tokens  (~85%)
```

**Auto-compact at 833K** (~85% of effective window).

⚠️ **Still problematic**: 833K is **4.8x larger** than the 200K experience. Compaction will be slow and may fail.

---

## Window Override Only

### Example: `CLAUDE_CODE_AUTO_COMPACT_WINDOW=350000`

#### Sonnet 4.6 (200K)

```
Model native window:    200,000 tokens
Override:               350,000 tokens
Capped window:          min(200,000, 350,000) = 200,000  ← NO EFFECT
─────────────────────────────────────
(Same as default — 167K threshold)
```

**No change.** Window override is higher than native, so `Math.min()` picks native.

---

#### Opus 1M (1M)

```
Model native window:  1,000,000 tokens
Override:               350,000 tokens
Capped window:          min(1,000,000, 350,000) = 350,000  ← CAPPED
Buffer:                                           -20,000
─────────────────────────────────────
Effective window:                                 330,000 tokens
Safe headroom:                                    -13,000 tokens
─────────────────────────────────────
Threshold:                                        317,000 tokens  (~96% of capped)
```

**Auto-compact at 317K** (~96% of the capped window).

✅ **Better**, but still using fixed 13K headroom on a 330K window → 96% is late.

---

## Both Overrides (Recommended)

### Example: `CLAUDE_CODE_AUTO_COMPACT_WINDOW=350000` + `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85`

#### Sonnet 4.6 (200K)

```
Capped window:          min(200,000, 350,000) = 200,000  ← NO EFFECT
Effective window:       180,000
Threshold:              floor(180,000 × 0.85) = 153,000 tokens  (~85%)
```

Same as percentage-only case. Window override ignored.

---

#### Opus 1M (1M)

```
Model native window:  1,000,000 tokens
Override:               350,000 tokens
Capped window:          min(1,000,000, 350,000) = 350,000  ← CAPPED
Buffer:                                           -20,000
─────────────────────────────────────
Effective window:                                 330,000 tokens
Percentage threshold:   floor(330,000 × 0.85)   = 280,500
Safe headroom:          330,000 - 13,000        = 317,000
─────────────────────────────────────
Actual threshold:       min(280,500, 317,000)   = 280,500 tokens  (~85% of capped)
```

**Auto-compact at 280.5K** (~85% of the capped 350K window).

✅ **Excellent**: Similar to the 200K experience (153K @ 85%) but with room for larger individual inputs.

---

## Comparison Table

| Model | Window Override | PCT Override | Threshold | vs 200K Default |
|-------|----------------|--------------|-----------|-----------------|
| **Sonnet 4.6** (200K) | — | — | **167K** | Baseline (93%) |
| **Sonnet 4.6** (200K) | — | 85 | **153K** | -14K (-8%) |
| **Sonnet 4.6** (200K) | 350K | 85 | **153K** | No change (override ignored) |
| **Opus 1M** (1M) | — | — | **967K** | +800K (+579%) 🔴 |
| **Opus 1M** (1M) | — | 85 | **833K** | +666K (+480%) 🔴 |
| **Opus 1M** (1M) | 500K | — | **467K** | +300K (+280%) ⚠️ |
| **Opus 1M** (1M) | 500K | 85 | **408K** | +241K (+244%) ⚠️ |
| **Opus 1M** (1M) | **350K** | **85** | **280K** | **+113K (+168%)** ✅ |
| **Opus 1M** (1M) | **300K** | **85** | **238K** | **+71K (+142%)** ✅ |

---

## Why `Math.min()` Matters

### Common Mistake

"I'll set `CLAUDE_CODE_AUTO_COMPACT_WINDOW=1000000` to use the full 1M context!"

**Result**: No effect. `Math.min(1000000, 1000000) = 1000000` — same as native.

### Correct Use

The override is a **ceiling**, not a floor:
- Set it **lower** than native to cap the window
- Set it **higher** than native → ignored (no effect)

---

## Recommended Settings

### For 200K Models (Sonnet 4.6, Opus 4.6, Haiku 4.5)

```bash
# Percentage override only
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85

# Window override has no effect (200K < any reasonable override)
```

**Threshold**: 153K tokens (~85% of 180K effective window)

---

### For 1M Models (Sonnet 1M, Opus 1M)

```bash
# Recommended: Cap window + percentage
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=350000
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85
```

**Threshold**: 280.5K tokens (~85% of capped 350K window)

**Rationale**:
- Maintains similar compaction frequency as 200K models
- Allows larger individual inputs (files, tool results)
- Prevents runaway context accumulation
- Faster compaction (less history to summarize)

---

### Alternative: More Aggressive

```bash
# Tighter control
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=300000
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85
```

**Threshold**: 238K tokens (~85% of capped 300K window)

**Rationale**: Even closer to the 200K experience (153K → 238K is only +55%).

---

## Edge Cases

### What if I set window to 150K (below native 200K)?

```
Sonnet 4.6:
  Capped window:    min(200,000, 150,000) = 150,000  ← CAPPED
  Effective:        150,000 - 20,000     = 130,000
  Threshold (85%):  floor(130,000 × 0.85) = 110,500
```

**Result**: Auto-compact at 110.5K — more aggressive than default. Valid use case for CI/CD or short sessions.

---

### What if I set percentage to 99?

```
Opus 1M with WINDOW=350K:
  Effective:        330,000
  Threshold (99%):  floor(330,000 × 0.99) = 326,700
  Safe headroom:    330,000 - 13,000      = 317,000
  Actual:           min(326,700, 317,000) = 317,000  ← Headroom wins
```

**Result**: Safety headroom (13K) overrides the percentage. Max threshold is always `effectiveWindow - 13K`.

---

### What if I disable auto-compact entirely?

```bash
export DISABLE_AUTO_COMPACT=1
```

**Result**: Overrides are ignored. Manual compaction only (`/compact`). Risky — you can OOM.

---

## Debugging

### Check Current Settings

```bash
# Env vars
env | grep -i "COMPACT\|AUTOCOMPACT"

# Computed values (from logs)
# Run a session and look for:
v(`autocompact: tokens=${currentTokens} threshold=${threshold} effectiveWindow=${effectiveWindow}`)
```

### Example Log Output

```
autocompact: tokens=165000 threshold=153000 effectiveWindow=180000
```

Decode:
- `tokens=165000` — current conversation size
- `threshold=153000` — will compact at this level
- `effectiveWindow=180000` — 200K - 20K buffer

---

## Implementation Details

### Constants

```javascript
var lh6 = 20000,   // Buffer size
    KUA = 13000,   // Safe headroom
    nh6 = 20000,   // Warning threshold offset
    ih6 = 20000,   // Error threshold offset
    qUA = 3000;    // Blocking limit headroom
```

### Related Functions

- `BB(model)` — Effective window calculation
- `bQH(model)` — Auto-compact threshold
- `PKH(tokens, model)` — Threshold checks
- `rh6(messages, model, source, freed)` — Auto-compact decision
- `Inf(...)` — Auto-compact execution

---

## Testing

### Verify Window Override

```bash
# Set a low override
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=100000

# Start a session with a 200K model
# Expect auto-compact to trigger around 68K tokens
# (100K - 20K buffer = 80K effective, 80K - 13K = 67K threshold)
```

### Verify Percentage Override

```bash
# Set a high percentage
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=95

# Start a session with a 200K model
# Expect auto-compact to trigger around 167K tokens
# (95% of 180K effective = 171K, capped by 13K headroom → 167K)
```

---

## Related

- [analysis.md](./analysis.md) — Main 2.1.75 analysis
- [opus-1m-migration.md](./opus-1m-migration.md) — Opus 1M migration details
- [env-vars.md](./env-vars.md) — Environment variable reference


---
## auto-memory-internals.md

# Claude Code 2.1.76 — Auto-Memory Internals

How the post-sampling hook system and auto-memory extraction work under the hood.

---

## System Overview

```
Main Query Loop (3896.js)
│
│  user sends message
│  ↓
│  LLM sampling → response messages (e)
│  ↓
│  if (e.length > 0)
│      Zif([...existingMessages, ...newMessages], systemPrompt, userCtx, sysCtx, toolCtx, querySource)
│          │
│          ↓
│      Post-Sampling Hook Registry (Wif[])
│          │
│          └── g9_ (auto-memory extraction)
│                  │
│                  ├── gate checks (feature flag, thresholds)
│                  ├── reads current MEMORY.md
│                  ├── builds extraction prompt
│                  └── forks sub-query (AT) → writes updated MEMORY.md
```

---

## 1. Post-Sampling Hook Framework

**File**: `3887.js`

The hook system is a simple observer pattern — a push-only array of async callbacks.

```javascript
var Wif = [];   // hook registry

// Register a hook
function Tif(callback) {
    Wif.push(callback);
}

// Dispatch to all hooks (called after every LLM turn)
async function Zif(messages, systemPrompt, userContext, systemContext, toolUseContext, querySource) {
    let ctx = {
        messages,        // full conversation history (old + new)
        systemPrompt,    // current system prompt
        userContext,      // user-level context (CLAUDE.md, etc.)
        systemContext,    // system-level context
        toolUseContext,   // tool state (readFileState, etc.)
        querySource       // "repl_main_thread", "session_memory", "agent", etc.
    };
    for (let hook of Wif)
        try {
            await hook(ctx);
        } catch (err) {
            fH(err instanceof Error ? err : Error(`Post-sampling hook failed: ${err}`));
        }
}
```

### Key Properties

- **Sequential execution**: Hooks run one at a time (`for...of` + `await`), not in parallel
- **Error isolation**: Each hook is wrapped in try/catch — one failing hook doesn't block others
- **No return value**: Hooks are fire-and-forget; they can't modify the conversation flow
- **No priority/ordering**: Hooks execute in registration order (FIFO push)
- **Errors go to ring buffer**: Failed hooks report via `fH()` (error reporting system, 100-entry ring buffer)

### Call Site

In `3896.js`, inside the main query generator:

```javascript
// After LLM sampling produces assistant messages (e):
if (e.length > 0)
    Zif([...u, ...e], A, L, D, Y, M);
```

Where `u` = existing conversation messages, `e` = new assistant response messages.
Only fires when the model actually produced output (no-op on empty responses or errors).

---

## 2. Hook Registration

**File**: `4557.js`

Only one hook is currently registered: `g9_` (auto-memory extraction).

```javascript
function nX8() {
    if (L8()) return;     // skip if headless/simple mode (CLAUDE_CODE_SIMPLE)
    if (!$h()) return;    // skip if auto-compact disabled (DISABLE_COMPACT / DISABLE_AUTO_COMPACT)
    Tif(g9_);             // register the auto-memory hook
}
```

`nX8()` is called during session initialization. The hook is only registered when:
1. **Not in simple/headless mode** — `L8()` returns false
2. **Auto-compact enabled** — `$h()` returns true (respects `DISABLE_COMPACT` and `DISABLE_AUTO_COMPACT` env vars plus the `autoCompactEnabled` setting)

---

## 3. Auto-Memory Extraction Hook (g9_)

**File**: `4558.js`

This is the core logic. When the hook fires, it decides whether to extract memories from the conversation and write them to `summary.md`.

```javascript
g9_ = Tx(async function({ messages, toolUseContext, querySource }) {
    // ── Gate 1: Only run on main REPL thread ──
    if (querySource !== "repl_main_thread") return;

    // ── Gate 2: Feature flag must be on ──
    if (!b9_()) return;   // _A("tengu_session_memory", false)

    // ── Gate 3: Init config, check thresholds ──
    U9_();                // load config from tengu_sm_config
    if (!B9_(messages)) return;  // token + tool-call threshold check

    // ── Mark extraction in progress ──
    nnf();   // jR$ = Date.now()  (locks out concurrent extractions)

    // ── Read current memory file ──
    let toolCtx = gQH(toolUseContext);  // snapshot tool context
    let { memoryPath, currentMemory } = await p9_(toolCtx);

    // ── Build extraction prompt ──
    let prompt = await Kif(currentMemory, memoryPath);

    // ── Fork sub-query: extract and write memories ──
    await AT({
        promptMessages: [U$({ content: prompt })],
        cacheSafeParams: bu(hook_context),
        canUseTool: d9_(memoryPath),      // ONLY allow Write to the memory file
        querySource: "session_memory",
        forkLabel: "session_memory",
        overrides: { readFileState: toolCtx.readFileState }
    });

    // ── Log telemetry ──
    Q("tengu_session_memory_extraction", {
        input_tokens, output_tokens,
        cache_read_input_tokens, cache_creation_input_tokens,
        config_min_message_tokens_to_init,
        config_min_tokens_between_update,
        config_tool_calls_between_updates
    });

    // ── Update state ──
    tnf(jJ(messages));  // record token count at extraction time
    F9_(messages);      // update UUID bookmark
    inf();              // clear in-progress lock (jR$ = undefined)
});
```

---

## 4. Threshold System (B9_)

**File**: `4557.js` + `3879.js`

The hook doesn't fire every turn. `B9_()` enforces three thresholds:

```javascript
function B9_(messages) {
    let tokenCount = jJ(messages);  // total tokens in conversation

    // First-time init: have we hit minimum tokens?
    if (!snf()) {                             // snf() = Qnf (has init fired?)
        if (!Hif(tokenCount)) return false;   // tokenCount >= minimumMessageTokensToInit?
        enf();                                // mark init complete
    }

    // Recurring: enough tokens since last extraction?
    let tokenThresholdMet = $if(tokenCount);  // tokenCount - cnf >= minimumTokensBetweenUpdate?

    // Recurring: enough tool calls since last extraction?
    let toolCallThresholdMet = m9_(messages, lX8) >= Aif();  // count tool_use blocks since bookmark

    // Has assistant made tool calls in last message?
    let lastMsgHasToolUse = snH(messages);

    // Trigger if: (both thresholds met) OR (token threshold met AND no pending tool use)
    if (tokenThresholdMet && toolCallThresholdMet || tokenThresholdMet && !lastMsgHasToolUse) {
        lX8 = messages[messages.length - 1]?.uuid;  // bookmark current position
        return true;
    }
    return false;
}
```

### Default Thresholds

**File**: `3880.js`

```javascript
CnH = {
    minimumMessageTokensToInit:  10000,  // 10k tokens before first extraction
    minimumTokensBetweenUpdate:  5000,   // 5k tokens between extractions
    toolCallsBetweenUpdates:     3        // 3 tool calls between extractions
};
```

These can be overridden via the `tengu_sm_config` GrowthBook feature flag (object with same keys).

### State Variables

**File**: `3879.js`

```javascript
var cnf = 0;          // token count at last extraction
var Qnf = false;      // has first extraction fired?
var jR$ = undefined;   // timestamp when extraction started (concurrency lock)
var IWH = {...CnH};   // active config (defaults + overrides)
```

### Concurrency Protection

```javascript
function nnf() { jR$ = Date.now(); }   // mark extraction in-progress
function inf() { jR$ = undefined; }     // mark extraction complete

// rnf() — wait for in-progress extraction (with timeouts)
async function rnf() {
    let start = Date.now();
    while (jR$) {
        if (Date.now() - jR$ > 60000) return;   // extraction timeout: 60s
        if (Date.now() - start > 15000) return;  // wait timeout: 15s
        await new Promise(r => setTimeout(r, 1000));  // poll every 1s
    }
}
```

---

## 5. Memory File Location

**File**: `4468.js`

```javascript
function Um$() {
    return path.join(configDir(), sessionId(), "session-memory") + path.sep;
}

function XWH() {
    return path.join(Um$(), "summary.md");
}
```

Result: `~/.claude/projects/<project-hash>/<session-id>/session-memory/summary.md`

On first extraction, if the file doesn't exist, it's created with the default template via `flag: "wx"` (exclusive create — won't overwrite).

---

## 6. Extraction Prompt

**File**: `3880.js`

The extraction prompt (`fif()`) instructs the forked sub-query to update the memory file. Key rules:

1. **Scope**: Only analyze the user conversation — exclude system prompt, CLAUDE.md, and the note-taking instructions themselves
2. **Tool restriction**: Only use `Edit` tool on the memory file path (enforced by `d9_()`)
3. **Structure preservation**: Never modify section headers or italic description lines
4. **Per-section limit**: ~2,000 tokens per section (`JR$ = 2000`)
5. **Total file limit**: ~12,000 tokens (`Lif = 12000`)
6. **Parallel edits**: Make all Edit tool calls in a single parallel message, then stop
7. **Priority**: Always keep "Current State" up to date

### Customization

Users can override both the template and extraction prompt:

```
~/.claude/session-memory/config/template.md   → custom memory file template
~/.claude/session-memory/config/prompt.md      → custom extraction prompt
```

If these files exist, they're loaded instead of the defaults. If they fail to load (non-ENOENT error), the error is reported via `fH()` and defaults are used as fallback.

### Oversized File Handling

`sS6()` checks section sizes and total file size, appending condensation instructions:

- If any section exceeds 2,000 tokens: instructs the model to condense it
- If total file exceeds 12,000 tokens: **CRITICAL** instruction to aggressively shorten

### Default Template Sections

```markdown
# Session Title
# Current State
# Task specification
# Files and Functions
# Workflow
# Errors & Corrections
# Codebase and System Documentation
# Learnings
# Key results
# Worklog
```

---

## 7. Tool Restriction (d9_)

**File**: `4557.js`

The forked sub-query is sandboxed — it can only use one tool on one file:

```javascript
function d9_(memoryPath) {
    return async (tool, input) => {
        if (tool.name === Cf &&                // Cf = Edit tool name
            typeof input === "object" &&
            input !== null &&
            "file_path" in input) {
            let filePath = input.file_path;
            if (typeof filePath === "string" && filePath === memoryPath)
                return { behavior: "allow", updatedInput: input };
        }
        return {
            behavior: "deny",
            message: `only ${Cf} on ${memoryPath} is allowed`,
            decisionReason: { type: "other", reason: `only ${Cf} on ${memoryPath} is allowed` }
        };
    };
}
```

This ensures the memory extraction sub-query:
- Can ONLY use the Edit tool (not Read, Bash, Write, or any other tool)
- Can ONLY edit the specific memory file path
- Cannot read files, run commands, or modify anything else

---

## 8. Forked Sub-Query (AT)

**File**: `3900.js`

`AT()` creates an isolated LLM sub-query that shares the parent's conversation context but has its own tool permissions and query source:

```javascript
function AT({
    promptMessages,       // the extraction prompt
    cacheSafeParams,      // cache config from parent
    canUseTool,           // d9_(memoryPath) — restricted tool access
    querySource,          // "session_memory"
    forkLabel,            // "session_memory"
    overrides,            // { readFileState } from parent context
    maxOutputTokens,      // optional limit
    maxTurns,             // optional turn limit
    onMessage,            // optional message callback
    skipTranscript,       // don't save to transcript
    skipCacheWrite        // don't cache results
}) { ... }
```

The sub-query runs the same model as the main conversation, but:
- Uses a separate abort controller (doesn't affect main conversation if it fails)
- Has its own tool permission function (`canUseTool`)
- Is labeled `"session_memory"` for telemetry and to prevent recursive extraction
- Shares the parent's read file state so it knows what files have been read

---

## 9. Telemetry

### Event: `tengu_session_memory_extraction`
Fired after each successful extraction:
```javascript
{
    input_tokens: number,
    output_tokens: number,
    cache_read_input_tokens: number,
    cache_creation_input_tokens: number,
    config_min_message_tokens_to_init: number,    // active threshold
    config_min_tokens_between_update: number,     // active threshold
    config_tool_calls_between_updates: number     // active threshold
}
```

### Event: `tengu_session_memory_file_read`
Fired when the current memory file is read before extraction:
```javascript
{ content_length: number }
```

### Feature Flag: `tengu_session_memory`
- Type: boolean
- Default: `false`
- Controls: Whether auto-memory extraction is enabled at all

### Feature Flag: `tengu_sm_config`
- Type: object
- Default: `{}`
- Controls: Override threshold values (`minimumMessageTokensToInit`, `minimumTokensBetweenUpdate`, `toolCallsBetweenUpdates`)

---

## 10. Complete Data Flow

```
User sends message
    ↓
Main LLM sampling
    ↓
Response messages produced
    ↓
Zif() dispatches to all registered hooks
    ↓
g9_ (auto-memory) runs:
    │
    ├─ querySource === "repl_main_thread"?  (NO → skip, prevents recursion)
    ├─ tengu_session_memory flag on?         (NO → skip)
    ├─ Load config from tengu_sm_config
    ├─ B9_() threshold check:
    │   ├─ First time: tokenCount >= 10,000?
    │   ├─ Recurring: tokenCount - lastExtraction >= 5,000?
    │   └─ Recurring: toolCallsSinceLastExtraction >= 3?
    │   (NO → skip)
    │
    ├─ Lock (nnf: jR$ = Date.now())
    ├─ Read summary.md (create from template if missing)
    ├─ Build extraction prompt (fif + oversize warnings)
    │
    ├─ Fork sub-query via AT():
    │   ├─ Same model as main conversation
    │   ├─ Receives full conversation as context
    │   ├─ Tool access: ONLY Edit on summary.md
    │   ├─ querySource: "session_memory" (prevents recursive hook)
    │   └─ LLM extracts memories → Edit calls to update summary.md
    │
    ├─ Log tengu_session_memory_extraction
    ├─ Update token bookmark (cnf = current token count)
    ├─ Update UUID bookmark (lX8 = last message UUID)
    └─ Unlock (inf: jR$ = undefined)
```

---

## 11. Disabling Auto-Memory

Any of these will prevent the hook from running:

| Method | Effect |
|--------|--------|
| `tengu_session_memory = false` | Feature flag (server-side, default) |
| `DISABLE_COMPACT=true` | Prevents hook registration (`$h()` fails) |
| `DISABLE_AUTO_COMPACT=true` | Same effect |
| `CLAUDE_CODE_SIMPLE=true` | Headless mode, skips hook registration |
| Non-REPL querySource | Hook self-filters (only runs on `repl_main_thread`) |

---

## 12. Relationship to User-Facing "Auto Memory"

The auto-memory system visible to users (`/home/zack/.claude/projects/<hash>/memory/MEMORY.md`) is a **different system** from session memory. Session memory (`summary.md`) is:

- Per-session (lives in session directory, not project memory directory)
- Automatically extracted (no user control over content)
- Used for session continuity after compaction
- Gated by `tengu_session_memory` (currently off by default)

The user-facing auto-memory directory at `~/.claude/projects/<hash>/memory/` is managed by the model directly during conversation (via explicit Write/Edit tool calls in the main conversation), not by this post-sampling hook system.


---
## auto-mode-config-f0dacf5866.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure auto mode

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

[Auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) lets Claude Code run without permission prompts by routing each tool call through a classifier that blocks anything irreversible, destructive, or aimed outside your environment. Use the `autoMode` settings block to tell that classifier which repos, buckets, and domains your organization trusts, so it stops blocking routine internal operations.

Out of the box, 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`.

For how to enable auto mode and what it blocks by default, see [Permission modes](/en/permission-modes#eliminate-prompts-with-auto-mode). This page is the configuration reference.

This page covers how to:

* [Choose where to set rules](#where-the-classifier-reads-configuration) across CLAUDE.md, user settings, and managed settings
* [Define trusted infrastructure](#define-trusted-infrastructure) with `autoMode.environment`
* [Override the block and allow rules](#override-the-block-and-allow-rules) when the defaults don't fit your pipeline
* [Inspect your effective config](#inspect-the-defaults-and-your-effective-config) with the `claude auto-mode` subcommands
* [Review denials](#review-denials) so you know what to add next

## Where the classifier reads configuration

The classifier reads the same [CLAUDE.md](how-claude-remembers-your-project-claude-code-docs-f1c064262d.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                      |
| One project, one developer     | `.claude/settings.local.json`                   | Per-project trusted buckets or services, gitignored  |
| Organization-wide              | [Managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md) | Trusted infrastructure distributed to all developers |
| `--settings` flag or Agent SDK | Inline JSON                                     | Per-invocation overrides for automation              |

The classifier does not read `autoMode` from shared project settings in `.claude/settings.json`, so a checked-in repo cannot inject its own allow rules.

Entries from each scope are combined. A developer can extend `environment`, `allow`, and `soft_deny` with personal entries but cannot remove entries that managed settings provide. Because allow rules act as exceptions to 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.

<Note>
  The classifier is a second gate that runs after the [permissions system](configure-permissions-claude-code-docs-7b0e64d485.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 cannot be overridden.
</Note>

## 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.

The default environment list trusts the working repo and its configured remotes. To add your own entries alongside that default, 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.

```json theme={null}
{
  "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"
    ]
  }
}
```

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

```json theme={null}
{
  "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}"
    ]
  }
}
```

The more specific context you give, the better the classifier can distinguish routine internal operations from exfiltration attempts.

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.

## Override the block and allow rules

Two additional fields let you replace the classifier's built-in rule lists: `autoMode.soft_deny` controls what gets blocked, and `autoMode.allow` controls which exceptions apply. Each is an array of prose descriptions, read as natural-language rules. There is no `autoMode.deny` field; to hard-block an action regardless of intent, use [`permissions.deny`](configure-permissions-claude-code-docs-7b0e64d485.md), which runs before the classifier.

Inside the classifier, precedence works in three tiers:

* `soft_deny` rules block first
* `allow` rules then override matching blocks as exceptions
* Explicit user intent overrides both: 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" does not 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 risks specific to your environment that the defaults miss. 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.

```json theme={null}
{
  "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"
    ]
  }
}
```

<Danger>
  Setting any of `environment`, `allow`, or `soft_deny` without `"$defaults"` replaces the entire default list for that section. If you set `soft_deny` with a single entry and omit `"$defaults"`, every built-in block rule is discarded: force push, data exfiltration, `curl | bash`, production deploys, and all other default block rules become allowed. Only omit `"$defaults"` when you intend to take full ownership of the list. In that case, 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.
</Danger>

Each section is evaluated independently, so setting `environment` alone leaves the default `allow` and `soft_deny` lists intact.

## Inspect the defaults and your effective config

Three CLI subcommands help you inspect and validate your configuration.

Print the built-in `environment`, `allow`, and `soft_deny` rules as JSON:

```bash theme={null}
claude auto-mode defaults
```

Print what the classifier actually uses as JSON, with your settings applied where set and defaults otherwise:

```bash theme={null}
claude auto-mode config
```

Get AI feedback on your custom `allow` and `soft_deny` rules:

```bash theme={null}
claude auto-mode critique
```

Run `claude auto-mode config` after saving your settings to confirm the effective rules are what you expect, with `"$defaults"` expanded in place. 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. If you need to remove or rewrite a built-in rule rather than add alongside it, save the output of `claude auto-mode defaults` to a file, edit the lists, and paste the result into your settings file in place of `"$defaults"`.

## Review denials

When auto mode denies a tool call, the denial is recorded in `/permissions` under the Recently denied tab. 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.

Repeated denials for the same destination usually mean the classifier is missing context. Add that destination to `autoMode.environment`, then run `claude auto-mode config` to confirm it took effect.

To react to denials programmatically, use the [`PermissionDenied` hook](/en/hooks#permissiondenied).

## See also

* [Permission modes](/en/permission-modes#eliminate-prompts-with-auto-mode): what auto mode is, what it blocks by default, and how to enable it
* [Managed settings](../13-Enterprise-Admin/configure-server-managed-settings-claude-code-docs-d6a169b0bf.md): deploy `autoMode` configuration across your organization
* [Permissions](configure-permissions-claude-code-docs-7b0e64d485.md): allow, ask, and deny rules that apply before the classifier runs
* [Settings](claude-code-settings-claude-code-docs-d4420b4b52.md): the full settings reference, including the `autoMode` key


---
## automate-work-with-routines-claude-code-docs-1c8313d077.md

## On this page

- [Example use cases](#example-use-cases)
- [Create a routine](#create-a-routine)
  - [Create from the web](#create-from-the-web)
  - [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 routine](#trigger-a-routine)
  - [API reference](#api-reference)
  - [Add a GitHub trigger](#add-a-github-trigger)
  - [Supported events](#supported-events)
  - [Filter pull requests](#filter-pull-requests)
  - [How sessions map to events](#how-sessions-map-to-events)
- [Manage routines](#manage-routines)
  - [View and interact with runs](#view-and-interact-with-runs)
  - [Edit and control routines](#edit-and-control-routines)
  - [Repositories and branch permissions](#repositories-and-branch-permissions)
  - [Connectors](#connectors)
  - [Environments and network access](#environments-and-network-access)
- [Usage and limits](#usage-and-limits)
- [Troubleshooting](#troubleshooting)
  - [/schedule returns “Unknown command”](#%2Fschedule-returns-%E2%80%9Cunknown-command%E2%80%9D)
  - [/schedule asks you to authenticate](#%2Fschedule-asks-you-to-authenticate)
  - [”Routines are disabled by your organization’s policy”](#%E2%80%9Droutines-are-disabled-by-your-organization%E2%80%99s-policy%E2%80%9D)
- [Related resources](#related-resources)

Claude Code on the web

# Automate work with routines

Copy pageCopy page

Put Claude Code on autopilot. Define routines that run on a schedule, trigger on API calls, or react to GitHub events from Anthropic-managed cloud infrastructure.

Copy pageCopy page

Routines are in research preview. Behavior, limits, and the API surface may change.

A routine is a saved Claude Code configuration: a prompt, one or more repositories, and a set of [connectors](/docs/en/mcp), packaged once and run automatically. Routines execute on Anthropic-managed cloud infrastructure, so they keep working when your laptop is closed. Each routine can have one or more triggers attached to it:

- **Scheduled**: 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 a per-routine endpoint with a bearer token
- **GitHub**: run automatically in response to repository events such as pull requests or releases

A single routine can combine triggers. For example, a PR review routine can run nightly, trigger from a deploy script, and also react to every new PR. Routines are available on Pro, Max, Team, and Enterprise plans with [Claude Code on the web](/docs/en/claude-code-on-the-web) enabled. Create and manage them at [claude.ai/code/routines](https://claude.ai/code/routines), or from the CLI with `/schedule`. Team and Enterprise Owners can disable routines for all members with the Routines toggle at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code). When disabled, existing routines stop running and members cannot create new ones. This page covers creating a routine, configuring each trigger type, managing runs, and how usage limits apply.


[​](#example-use-cases)

Example use cases

Each example pairs a trigger type with the kind of work routines are suited to: unattended, repeatable, and tied to a clear outcome. **Backlog maintenance.** A schedule trigger runs every weeknight against your issue tracker via a connector. The routine reads issues opened since the last run, applies labels, assigns owners based on the area of code referenced, and posts a summary to Slack so the team starts the day with a groomed queue. **Alert triage.** Your monitoring tool calls the routine’s API endpoint when an error threshold is crossed, passing the alert body as `text`. The routine’s prompt tells Claude to investigate the alert in the fire payload, so it pulls the stack trace, correlates it with recent commits in the repository, and 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 routine applies your team’s own review checklist, leaves inline comments for security, performance, and style issues, and adds a summary comment so human reviewers can focus on design instead of mechanical checks. **Deploy verification.** Your CD pipeline calls the routine’s API endpoint after each production deploy. The routine 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 routine 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 routine 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. The sections below walk through creating a routine and configuring each of these trigger types.


[​](#create-a-routine)

Create a routine

Create a routine 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 routine you create in one shows up in the others immediately. In the Desktop app, click **Routines** in the sidebar, then **New routine**, and choose **Cloud**; choosing **Local** instead creates a [Desktop scheduled task](/docs/en/desktop-scheduled-tasks), which runs on your machine rather than in the cloud. The creation form sets up the routine’s prompt, repositories, environment, connectors, and triggers. Routines run autonomously as full Claude Code cloud sessions: execution stays within the repositories, environment, and connectors you preconfigure for the run. The session can run shell commands, use [skills](/docs/en/skills) committed to the cloned repository, and call any connectors you include. What a routine can reach is determined by the repositories you select, the [environment’s](/docs/en/cloud-environments) network access and variables, and the connectors you include. Scope each of those to what the routine actually needs. Routines belong to your individual claude.ai account. They are not shared with teammates, and they count against your account’s daily run allowance. Anything a routine does through your connected GitHub identity or connectors appears as you: commits and pull requests carry your GitHub user, and Slack messages, Linear tickets, or other connector actions use your linked accounts for those services.


[​](#create-from-the-web)

Create from the web

1

Open the creation form

Visit [claude.ai/code/routines](https://claude.ai/code/routines) and click **New routine**.

2

Name the routine and write the prompt

Give the routine a descriptive name and write the prompt Claude runs each time. The prompt is the most important part: the routine runs autonomously, so the prompt must be self-contained and explicit about what to do and what success looks like.When a trigger fires, the session receives the routine’s saved prompt as its assigned task 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, so the fired prompt is 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. Before v2.1.214, the session received the same prompt framed as an untrusted background notification and could refuse to act on it.The prompt input includes a model selector. Claude uses the selected model on every run.

3

Select repositories

Add one or more GitHub repositories for Claude to work in. Each repository is cloned at the start of a run, starting from the default branch. Claude creates `claude/`-prefixed branches for its changes.

4

Select an environment

Pick a [cloud environment](/docs/en/cloud-environments) for the routine. 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](/docs/en/cloud-environments#what-carries-over-from-your-setup), so add credentials with that in mind
- **Setup script**: install dependencies and tools the routine needs. The result is [cached](/docs/en/cloud-environments#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](/docs/en/cloud-environments#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 routine reach their services through Anthropic’s servers, so they don’t need allowlist changes. If your routine needs to reach your own services directly, or a domain outside that list, edit the environment’s [network access](/docs/en/cloud-environments#network-access) before running. To use a separate environment, [create one](/docs/en/cloud-environments#configure-your-environment) first.

5

Select a trigger

Under **Select a trigger**, choose how the routine starts. You can pick one trigger type or combine several.

- Schedule

- GitHub event

- API

Pick a preset frequency for a recurring run, or schedule a single one-off run at a specific timestamp. See [Add a schedule trigger](#add-a-schedule-trigger) for timezone handling, stagger, 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, then save the routine. The URL and token are generated after the routine is saved, since they depend on the routine ID. See [Add an API trigger](#add-an-api-trigger) to copy the URL and generate a token.

6

Review connectors

Under **Connectors** at the bottom of the form, all of your connected [MCP connectors](/docs/en/mcp) are included by default. Remove any the routine doesn’t need: Claude can use every tool from an included connector, including writes, without asking for permission during a run.

7

Create the routine

Click **Create**. The routine appears in the list and runs the next time one of its triggers matches. To start a run immediately, click **Run now** on the routine’s detail page.Each run creates a new session alongside your other sessions, where you can see what Claude did, review changes, and create a pull request.


[​](#create-from-the-cli)

Create from the CLI

Run `/schedule` in any session to create a scheduled routine conversationally. You can also pass a description directly, for a recurring routine 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 form collects, then saves the routine 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 routine was created; see [Troubleshooting](#troubleshooting). `/schedule` in the CLI creates scheduled routines only. To add an API or GitHub trigger, edit the routine on the web at [claude.ai/code/routines](https://claude.ai/code/routines). The CLI also supports managing existing routines. Run `/schedule list` to see all routines, `/schedule update` to change one, or `/schedule run` to trigger it immediately. A routine with no schedule trigger, such as one started only by API calls or GitHub events, has no next run time, and 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 routines.


[​](#configure-triggers)

Configure triggers

A routine starts when one of its triggers matches. You can attach any combination of schedule, API, and GitHub triggers to the same routine, and add or remove them at any time from the **Select a trigger** section of the routine’s edit form.


[​](#add-a-schedule-trigger)

Add a schedule trigger

A schedule trigger runs the routine on a recurring cadence, or once at a specific future time. Pick a preset frequency in the **Select a trigger** section: hourly, daily, weekdays, or weekly. Times are entered in your local zone and converted automatically, so the routine runs at that wall-clock time regardless of where the cloud infrastructure is located. Runs may start a few minutes after the scheduled time due to stagger. The offset is consistent for each routine. For a custom interval such as every two hours or the first of each month, pick the closest preset in the form, then run `/schedule update` in the CLI to set a specific cron expression. The minimum interval is one hour; expressions that run more frequently are rejected.


[​](#schedule-a-one-off-run)

Schedule a one-off run

A one-off schedule fires the routine a single time at a specific timestamp. Use it to remind yourself later in the week, to open a cleanup PR after a rollout finishes, or to kick off a follow-up task when an upstream change lands. After the routine fires, it auto-disables and the web UI marks it as **Ran**. To run it again, edit the routine and set a new one-off time.

One-off scheduling from the CLI is rolling out gradually and may not be available on your account yet. If `/schedule` only offers recurring schedules, create the one-off run from the web at [claude.ai/code/routines](https://claude.ai/code/routines) instead.

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

The same local-to-UTC conversion as recurring schedules applies to one-off timestamps. One-off runs do not count against the daily routine run cap. They consume your plan’s regular subscription usage like any other session. See [Usage and limits](#usage-and-limits) for details.


[​](#add-an-api-trigger)

Add an API trigger

An API trigger gives a routine a dedicated HTTP endpoint. POSTing to the endpoint with the routine’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. API triggers are added to an existing routine from the web. The CLI cannot currently create or revoke tokens.

1

Open the routine for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the routine you want to trigger via API, then click the pencil icon to open **Edit routine**.

2

Add an API trigger

Scroll to the **Select a trigger** section below the **Instructions** box, click **Add another trigger**, and choose **API**.

3

Copy the URL and generate a token

The modal shows the URL for this routine along with a sample curl command. Copy the URL, then click **Generate token** and copy the token immediately. The token is shown once and cannot be retrieved later, so store it somewhere secure such as your alerting tool’s secret store.

4

Call the endpoint

Send the token in the `Authorization: Bearer` header when you POST to the URL. The [Trigger a routine](#trigger-a-routine) section below shows a complete example.

Each routine has its own token, scoped to triggering that routine only. To rotate or revoke it, return to the same modal and click **Regenerate** or **Revoke**.


[​](#trigger-a-routine)

Trigger a routine

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 routine alongside its saved prompt. The value is freeform text and is not parsed: if you send JSON or another structured payload, the routine 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 routine from a shell. The routine 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 via API](https://platform.claude.com/docs/en/api/claude-code/routines-fire) 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. Each matching event starts its own session.

During the research preview, GitHub webhook events are subject to per-routine and per-account hourly caps. Events beyond the limit are dropped until the window resets. See your current limits at [claude.ai/code/routines](https://claude.ai/code/routines).


1

Open the routine for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the routine, then click the pencil icon to open **Edit routine**.

2

Add a GitHub event trigger

Scroll to the **Select a trigger** section, click **Add another trigger**, and choose **GitHub event**.

3

Install the Claude GitHub App

The Claude GitHub App must be installed on the repository you want to subscribe to. The trigger setup prompts you to install it if it isn’t already.

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. GitHub triggers require installing the Claude GitHub App, which the trigger setup prompts you to do.

4

Configure the trigger

Select the repository, choose an event from the [supported events](#supported-events) list, and optionally add filters. Save 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 routine 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 routine only runs when the PR is ready for review.
- **Label-gated backport**: labels include `needs-backport`. Triggers a port-to-another-branch routine only when a maintainer tags the PR.


[​](#how-sessions-map-to-events)

How sessions map to events

Each matching GitHub event starts a new session. Session reuse across events is not available for GitHub-triggered routines, so two PR updates produce two independent sessions.


[​](#manage-routines)

Manage routines

Click a routine in the list to open its detail page. The detail page shows the routine’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 task in your prompt succeeded. Open the run to read the transcript and confirm what Claude actually did. Blocked network requests, missing connector tools, and task-level failures all surface there rather than in the status indicator.


[​](#edit-and-control-routines)

Edit and control routines

From the routine detail page you can:

- Click **Run now** to start a run immediately without waiting for the next scheduled time. You can optionally supply run-specific text, which reaches the routine the same way as the API trigger’s `text` field.
- Use the toggle in the **Repeats** section to pause or resume the schedule. Paused routines keep their configuration but don’t run until you re-enable them.
- Click the pencil icon to open **Edit routine** and change the name, prompt, repositories, environment, connectors, or any of the routine’s triggers. The **Select a trigger** section is where you add or remove schedules, API tokens, and GitHub event triggers.
- Click the delete icon to remove the routine. Past sessions created by the routine remain in your session list.


[​](#repositories-and-branch-permissions)

Repositories and branch permissions

Routines need GitHub access to clone repositories. When you create a routine from the CLI with `/schedule`, Claude checks whether your account has GitHub connected and prompts you to run `/web-setup` if it doesn’t. See [GitHub authentication options](/docs/en/claude-code-on-the-web#github-authentication-options) for the two ways to grant access. Each repository you add is cloned on every run. Claude starts from the repository’s default branch unless your prompt specifies otherwise. Claude pushes its work to branches prefixed with `claude/`, which are always accepted. When your prompt directs Claude to push to another branch, Claude Code checks the push first and rejects it if any of the following is true:

- The branch is protected on GitHub
- Someone else has an open pull request from that branch
- The branch carries commits authored by someone other than you


[​](#connectors)

Connectors

Routines can use your connected MCP connectors to read from and write to external services during each run. For example, a routine that triages support requests might read from a Slack channel and create issues in Linear. Connectors are the [claude.ai integrations](/docs/en/mcp#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 routine, add it as a connector at [claude.ai/customize/connectors](https://claude.ai/customize/connectors), or declare it in a committed [`.mcp.json`](/docs/en/mcp#project-scope) so it is part of the cloned repository. When you create a routine, 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 routine form. To manage or add connectors outside of the routine form, visit [claude.ai/customize/connectors](https://claude.ai/customize/connectors) or use `/schedule update` in the CLI.


[​](#environments-and-network-access)

Environments and network access

Each routine uses a [cloud environment](/docs/en/cloud-environments) that controls network access, environment variables, and setup scripts. The routine inherits the environment’s network policy on every run. The **Default** environment uses **Trusted** network access, which allows only the [default allowlist](/docs/en/cloud-environments#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 routine work without adding their hosts to **Allowed domains**. Remove any connectors you don’t need under [Connectors](#connectors). To allow additional domains:

1

Open the routine for editing

On the routine’s detail page, click the pencil icon to open **Edit routine**.

2

Open the environment selector

Below the **Instructions** box, select 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 **Update 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](/docs/en/cloud-environments#default-allowed-domains) alongside your custom domains. Select **Full** instead for unrestricted access.

5

Save

Click **Save changes**. The new policy applies from the next run.

See [Network access](/docs/en/cloud-environments#network-access) for details on access levels and the default allowlist.


[​](#usage-and-limits)

Usage and limits

Routines draw down subscription usage the same way interactive sessions do. In addition to the standard subscription limits, routines have a daily cap on how many runs can start per account. See your current consumption and remaining daily routine runs at [claude.ai/code/routines](https://claude.ai/code/routines) or [claude.ai/settings/usage](https://claude.ai/settings/usage). When a routine hits the daily cap or your subscription usage limit, organizations with usage credits turned on can keep running routines on metered overage. Without usage credits, additional runs are rejected until the 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). One-off runs do not count against the daily routine cap. They draw down your regular subscription usage like any other session, but they are exempt from the per-account daily routine run allowance.


[​](#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, and submitting it returns `Unknown command: /schedule`. The cause is usually one of the following:

- You are authenticated with a Console API key or a cloud provider such as Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. `/schedule` requires a claude.ai subscription login. 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
- `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, or `DISABLE_GROWTHBOOK` is set in your shell environment or in the `env` block of a [`settings.json` file](/docs/en/settings#available-settings). These disable feature-flag fetching, which `/schedule` depends on
- You are inside a Claude Code on the web session. Manage routines from the [web UI](https://claude.ai/code/routines) instead

You can always create and manage routines at [claude.ai/code/routines](https://claude.ai/code/routines) regardless of how the CLI is configured.


[​](#/schedule-asks-you-to-authenticate)

`/schedule` asks you to authenticate

If `/schedule` runs but Claude responds that you need to authenticate with a claude.ai account first, the CLI has no stored claude.ai login. API accounts aren’t supported for routines. Run `/login`, sign in with your claude.ai account, then run `/schedule` again.


[​](#”routines-are-disabled-by-your-organization’s-policy”)

”Routines are disabled by your organization’s policy”

An Owner in your Team or Enterprise organization has likely turned off the **Routines** toggle at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code). This is a server-side organization setting, so it cannot be overridden from your local configuration. Ask an Owner to enable routines for your organization.


[​](#related-resources)

Related resources

- [`/loop` and in-session scheduling](/docs/en/scheduled-tasks): schedule local tasks within an open CLI session
- [Desktop scheduled tasks](/docs/en/desktop-scheduled-tasks): local scheduled tasks that run on your machine with access to local files
- [Cloud environments](/docs/en/cloud-environments): configure network access, environment variables, and setup scripts for cloud sessions
- [MCP connectors](/docs/en/mcp): connect external services like Slack, Linear, and Google Drive
- [GitHub Actions](/docs/en/github-actions): run Claude in your CI pipeline on repository events


---
## automate-work-with-routines-claude-code-docs-dbf1010e44.md

## On this page

- [Example use cases](#example-use-cases)
- [Create a routine](#create-a-routine)
  - [Create from the web](#create-from-the-web)
  - [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 routine](#trigger-a-routine)
  - [API reference](#api-reference)
  - [Add a GitHub trigger](#add-a-github-trigger)
  - [Supported events](#supported-events)
  - [Filter pull requests](#filter-pull-requests)
  - [How sessions map to events](#how-sessions-map-to-events)
- [Manage routines](#manage-routines)
  - [View and interact with runs](#view-and-interact-with-runs)
  - [Edit and control routines](#edit-and-control-routines)
  - [Repositories and branch permissions](#repositories-and-branch-permissions)
  - [Connectors](#connectors)
  - [Environments and network access](#environments-and-network-access)
- [Usage and limits](#usage-and-limits)
- [Troubleshooting](#troubleshooting)
  - [/schedule returns “Unknown command”](#%2Fschedule-returns-%E2%80%9Cunknown-command%E2%80%9D)
  - [/schedule asks you to authenticate](#%2Fschedule-asks-you-to-authenticate)
  - [”Routines are disabled by your organization’s policy”](#%E2%80%9Droutines-are-disabled-by-your-organization%E2%80%99s-policy%E2%80%9D)
- [Related resources](#related-resources)

Claude Code on the web

# Automate work with routines

Copy pageCopy page

Put Claude Code on autopilot. Define routines that run on a schedule, trigger on API calls, or react to GitHub events from Anthropic-managed cloud infrastructure.

Copy pageCopy page

Routines are in research preview. Behavior, limits, and the API surface may change.

A routine is a saved Claude Code configuration: a prompt, one or more repositories, and a set of [connectors](/docs/en/mcp), packaged once and run automatically. Routines execute on Anthropic-managed cloud infrastructure, so they keep working when your laptop is closed. Each routine can have one or more triggers attached to it:

- **Scheduled**: 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 a per-routine endpoint with a bearer token
- **GitHub**: run automatically in response to repository events such as pull requests or releases

A single routine can combine triggers. For example, a PR review routine can run nightly, trigger from a deploy script, and also react to every new PR. Routines are available on Pro, Max, Team, and Enterprise plans with [Claude Code on the web](/docs/en/claude-code-on-the-web) enabled. Create and manage them at [claude.ai/code/routines](https://claude.ai/code/routines), or from the CLI with `/schedule`. Team and Enterprise Owners can disable routines for all members with the Routines toggle at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code). When disabled, existing routines stop running and members cannot create new ones. This page covers creating a routine, configuring each trigger type, managing runs, and how usage limits apply.


[​](#example-use-cases)

Example use cases

Each example pairs a trigger type with the kind of work routines are suited to: unattended, repeatable, and tied to a clear outcome. **Backlog maintenance.** A schedule trigger runs every weeknight against your issue tracker via a connector. The routine reads issues opened since the last run, applies labels, assigns owners based on the area of code referenced, and posts a summary to Slack so the team starts the day with a groomed queue. **Alert triage.** Your monitoring tool calls the routine’s API endpoint when an error threshold is crossed, passing the alert body as `text`. The routine’s prompt tells Claude to investigate the alert in the fire payload, so it pulls the stack trace, correlates it with recent commits in the repository, and 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 routine applies your team’s own review checklist, leaves inline comments for security, performance, and style issues, and adds a summary comment so human reviewers can focus on design instead of mechanical checks. **Deploy verification.** Your CD pipeline calls the routine’s API endpoint after each production deploy. The routine 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 routine 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 routine 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. The sections below walk through creating a routine and configuring each of these trigger types.


[​](#create-a-routine)

Create a routine

Create a routine 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 routine you create in one shows up in the others immediately. In the Desktop app, click **Routines** in the sidebar, then **New routine**, and choose **Cloud**; choosing **Local** instead creates a [Desktop scheduled task](/docs/en/desktop-scheduled-tasks), which runs on your machine rather than in the cloud. The creation form sets up the routine’s prompt, repositories, environment, connectors, and triggers. Routines run autonomously as full Claude Code cloud sessions: execution stays within the repositories, environment, and connectors you preconfigure for the run. The session can run shell commands, use [skills](/docs/en/skills) committed to the cloned repository, and call any connectors you include. What a routine can reach is determined by the repositories you select, the [environment’s](/docs/en/cloud-environments) network access and variables, and the connectors you include. Scope each of those to what the routine actually needs. Routines belong to your individual claude.ai account. They are not shared with teammates, and they count against your account’s daily run allowance. Anything a routine does through your connected GitHub identity or connectors appears as you: commits and pull requests carry your GitHub user, and Slack messages, Linear tickets, or other connector actions use your linked accounts for those services.


[​](#create-from-the-web)

Create from the web

1

Open the creation form

Visit [claude.ai/code/routines](https://claude.ai/code/routines) and click **New routine**.

2

Name the routine and write the prompt

Give the routine a descriptive name and write the prompt Claude runs each time. The prompt is the most important part: the routine runs autonomously, so the prompt must be self-contained and explicit about what to do and what success looks like.When a trigger fires, the session receives the routine’s saved prompt as its assigned task 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, so the fired prompt is 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. Before v2.1.214, the session received the same prompt framed as an untrusted background notification and could refuse to act on it.The prompt input includes a model selector. Claude uses the selected model on every run.

3

Select repositories

Add one or more GitHub repositories for Claude to work in. Each repository is cloned at the start of a run, starting from the default branch. Claude creates `claude/`-prefixed branches for its changes.

4

Select an environment

Pick a [cloud environment](/docs/en/cloud-environments) for the routine. 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](/docs/en/cloud-environments#what-carries-over-from-your-setup), so add credentials with that in mind
- **Setup script**: install dependencies and tools the routine needs. The result is [cached](/docs/en/cloud-environments#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](/docs/en/cloud-environments#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 routine reach their services through Anthropic’s servers, so they don’t need allowlist changes. If your routine needs to reach your own services directly, or a domain outside that list, edit the environment’s [network access](/docs/en/cloud-environments#network-access) before running. To use a separate environment, [create one](/docs/en/cloud-environments#configure-your-environment) first.

5

Select a trigger

Under **Select a trigger**, choose how the routine starts. You can pick one trigger type or combine several.

- Schedule

- GitHub event

- API

Pick a preset frequency for a recurring run, or schedule a single one-off run at a specific timestamp. See [Add a schedule trigger](#add-a-schedule-trigger) for timezone handling, stagger, 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, then save the routine. The URL and token are generated after the routine is saved, since they depend on the routine ID. See [Add an API trigger](#add-an-api-trigger) to copy the URL and generate a token.

6

Review connectors

Under **Connectors** at the bottom of the form, all of your connected [MCP connectors](/docs/en/mcp) are included by default. Remove any the routine doesn’t need: Claude can use every tool from an included connector, including writes, without asking for permission during a run.

7

Create the routine

Click **Create**. The routine appears in the list and runs the next time one of its triggers matches. To start a run immediately, click **Run now** on the routine’s detail page.Each run creates a new session alongside your other sessions, where you can see what Claude did, review changes, and create a pull request.


[​](#create-from-the-cli)

Create from the CLI

Run `/schedule` in any session to create a scheduled routine conversationally. You can also pass a description directly, for a recurring routine 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 form collects, then saves the routine 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 routine was created; see [Troubleshooting](#troubleshooting). `/schedule` in the CLI creates scheduled routines only. To add an API or GitHub trigger, edit the routine on the web at [claude.ai/code/routines](https://claude.ai/code/routines). The CLI also supports managing existing routines. Run `/schedule list` to see all routines, `/schedule update` to change one, or `/schedule run` to trigger it immediately. A routine with no schedule trigger, such as one started only by API calls or GitHub events, has no next run time, and 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 routines.


[​](#configure-triggers)

Configure triggers

A routine starts when one of its triggers matches. You can attach any combination of schedule, API, and GitHub triggers to the same routine, and add or remove them at any time from the **Select a trigger** section of the routine’s edit form.


[​](#add-a-schedule-trigger)

Add a schedule trigger

A schedule trigger runs the routine on a recurring cadence, or once at a specific future time. Pick a preset frequency in the **Select a trigger** section: hourly, daily, weekdays, or weekly. Times are entered in your local zone and converted automatically, so the routine runs at that wall-clock time regardless of where the cloud infrastructure is located. Runs may start a few minutes after the scheduled time due to stagger. The offset is consistent for each routine. For a custom interval such as every two hours or the first of each month, pick the closest preset in the form, then run `/schedule update` in the CLI to set a specific cron expression. The minimum interval is one hour; expressions that run more frequently are rejected.


[​](#schedule-a-one-off-run)

Schedule a one-off run

A one-off schedule fires the routine a single time at a specific timestamp. Use it to remind yourself later in the week, to open a cleanup PR after a rollout finishes, or to kick off a follow-up task when an upstream change lands. After the routine fires, it auto-disables and the web UI marks it as **Ran**. To run it again, edit the routine and set a new one-off time.

One-off scheduling from the CLI is rolling out gradually and may not be available on your account yet. If `/schedule` only offers recurring schedules, create the one-off run from the web at [claude.ai/code/routines](https://claude.ai/code/routines) instead.

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

The same local-to-UTC conversion as recurring schedules applies to one-off timestamps. One-off runs do not count against the daily routine run cap. They consume your plan’s regular subscription usage like any other session. See [Usage and limits](#usage-and-limits) for details.


[​](#add-an-api-trigger)

Add an API trigger

An API trigger gives a routine a dedicated HTTP endpoint. POSTing to the endpoint with the routine’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. API triggers are added to an existing routine from the web. The CLI cannot currently create or revoke tokens.

1

Open the routine for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the routine you want to trigger via API, then click the pencil icon to open **Edit routine**.

2

Add an API trigger

Scroll to the **Select a trigger** section below the **Instructions** box, click **Add another trigger**, and choose **API**.

3

Copy the URL and generate a token

The modal shows the URL for this routine along with a sample curl command. Copy the URL, then click **Generate token** and copy the token immediately. The token is shown once and cannot be retrieved later, so store it somewhere secure such as your alerting tool’s secret store.

4

Call the endpoint

Send the token in the `Authorization: Bearer` header when you POST to the URL. The [Trigger a routine](#trigger-a-routine) section below shows a complete example.

Each routine has its own token, scoped to triggering that routine only. To rotate or revoke it, return to the same modal and click **Regenerate** or **Revoke**.


[​](#trigger-a-routine)

Trigger a routine

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 routine alongside its saved prompt. The value is freeform text and is not parsed: if you send JSON or another structured payload, the routine 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 routine from a shell. The routine 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 via API](https://platform.claude.com/docs/en/api/claude-code/routines-fire) 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. Each matching event starts its own session.

During the research preview, GitHub webhook events are subject to per-routine and per-account hourly caps. Events beyond the limit are dropped until the window resets. See your current limits at [claude.ai/code/routines](https://claude.ai/code/routines).


1

Open the routine for editing

Go to [claude.ai/code/routines](https://claude.ai/code/routines), click the routine, then click the pencil icon to open **Edit routine**.

2

Add a GitHub event trigger

Scroll to the **Select a trigger** section, click **Add another trigger**, and choose **GitHub event**.

3

Install the Claude GitHub App

The Claude GitHub App must be installed on the repository you want to subscribe to. The trigger setup prompts you to install it if it isn’t already.

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. GitHub triggers require installing the Claude GitHub App, which the trigger setup prompts you to do.

4

Configure the trigger

Select the repository, choose an event from the [supported events](#supported-events) list, and optionally add filters. Save 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 routine 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 routine only runs when the PR is ready for review.
- **Label-gated backport**: labels include `needs-backport`. Triggers a port-to-another-branch routine only when a maintainer tags the PR.


[​](#how-sessions-map-to-events)

How sessions map to events

Each matching GitHub event starts a new session. Session reuse across events is not available for GitHub-triggered routines, so two PR updates produce two independent sessions.


[​](#manage-routines)

Manage routines

Click a routine in the list to open its detail page. The detail page shows the routine’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 task in your prompt succeeded. Open the run to read the transcript and confirm what Claude actually did. Blocked network requests, missing connector tools, and task-level failures all surface there rather than in the status indicator.


[​](#edit-and-control-routines)

Edit and control routines

From the routine detail page you can:

- Click **Run now** to start a run immediately without waiting for the next scheduled time. You can optionally supply run-specific text, which reaches the routine the same way as the API trigger’s `text` field.
- Use the toggle in the **Repeats** section to pause or resume the schedule. Paused routines keep their configuration but don’t run until you re-enable them.
- Click the pencil icon to open **Edit routine** and change the name, prompt, repositories, environment, connectors, or any of the routine’s triggers. The **Select a trigger** section is where you add or remove schedules, API tokens, and GitHub event triggers.
- Click the delete icon to remove the routine. Past sessions created by the routine remain in your session list.


[​](#repositories-and-branch-permissions)

Repositories and branch permissions

Routines need GitHub access to clone repositories. When you create a routine from the CLI with `/schedule`, Claude checks whether your account has GitHub connected and prompts you to run `/web-setup` if it doesn’t. See [GitHub authentication options](/docs/en/claude-code-on-the-web#github-authentication-options) for the two ways to grant access. Each repository you add is cloned on every run. Claude starts from the repository’s default branch unless your prompt specifies otherwise. Claude pushes its work to branches prefixed with `claude/`, which are always accepted. When your prompt directs Claude to push to another branch, Claude Code checks the push first and rejects it if any of the following is true:

- The branch is protected on GitHub
- Someone else has an open pull request from that branch
- The branch carries commits authored by someone other than you


[​](#connectors)

Connectors

Routines can use your connected MCP connectors to read from and write to external services during each run. For example, a routine that triages support requests might read from a Slack channel and create issues in Linear. Connectors are the [claude.ai integrations](/docs/en/mcp#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 routine, add it as a connector at [claude.ai/customize/connectors](https://claude.ai/customize/connectors), or declare it in a committed [`.mcp.json`](/docs/en/mcp#project-scope) so it is part of the cloned repository. When you create a routine, 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 routine form. To manage or add connectors outside of the routine form, visit [claude.ai/customize/connectors](https://claude.ai/customize/connectors) or use `/schedule update` in the CLI.


[​](#environments-and-network-access)

Environments and network access

Each routine uses a [cloud environment](/docs/en/cloud-environments) that controls network access, environment variables, and setup scripts. The routine inherits the environment’s network policy on every run. The **Default** environment uses **Trusted** network access, which allows only the [default allowlist](/docs/en/cloud-environments#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 routine work without adding their hosts to **Allowed domains**. Remove any connectors you don’t need under [Connectors](#connectors). To allow additional domains:

1

Open the routine for editing

On the routine’s detail page, click the pencil icon to open **Edit routine**.

2

Open the environment selector

Below the **Instructions** box, select 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 **Update 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](/docs/en/cloud-environments#default-allowed-domains) alongside your custom domains. Select **Full** instead for unrestricted access.

5

Save

Click **Save changes**. The new policy applies from the next run.

See [Network access](/docs/en/cloud-environments#network-access) for details on access levels and the default allowlist.


[​](#usage-and-limits)

Usage and limits

Routines draw down subscription usage the same way interactive sessions do. In addition to the standard subscription limits, routines have a daily cap on how many runs can start per account. See your current consumption and remaining daily routine runs at [claude.ai/code/routines](https://claude.ai/code/routines) or [claude.ai/settings/usage](https://claude.ai/settings/usage). When a routine hits the daily cap or your subscription usage limit, organizations with usage credits turned on can keep running routines on metered overage. Without usage credits, additional runs are rejected until the 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). One-off runs do not count against the daily routine cap. They draw down your regular subscription usage like any other session, but they are exempt from the per-account daily routine run allowance.


[​](#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, and submitting it returns `Unknown command: /schedule`. The cause is usually one of the following:

- You are authenticated with a Console API key or a cloud provider such as Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry. `/schedule` requires a claude.ai subscription login. 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
- `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, or `DISABLE_GROWTHBOOK` is set in your shell environment or in the `env` block of a [`settings.json` file](/docs/en/settings#available-settings). These disable feature-flag fetching, which `/schedule` depends on
- You are inside a Claude Code on the web session. Manage routines from the [web UI](https://claude.ai/code/routines) instead

You can always create and manage routines at [claude.ai/code/routines](https://claude.ai/code/routines) regardless of how the CLI is configured.


[​](#/schedule-asks-you-to-authenticate)

`/schedule` asks you to authenticate

If `/schedule` runs but Claude responds that you need to authenticate with a claude.ai account first, the CLI has no stored claude.ai login. API accounts aren’t supported for routines. Run `/login`, sign in with your claude.ai account, then run `/schedule` again.


[​](#”routines-are-disabled-by-your-organization’s-policy”)

”Routines are disabled by your organization’s policy”

An Owner in your Team or Enterprise organization has likely turned off the **Routines** toggle at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code). This is a server-side organization setting, so it cannot be overridden from your local configuration. Ask an Owner to enable routines for your organization.


[​](#related-resources)

Related resources

- [`/loop` and in-session scheduling](/docs/en/scheduled-tasks): schedule local tasks within an open CLI session
- [Desktop scheduled tasks](/docs/en/desktop-scheduled-tasks): local scheduled tasks that run on your machine with access to local files
- [Cloud environments](/docs/en/cloud-environments): configure network access, environment variables, and setup scripts for cloud sessions
- [MCP connectors](/docs/en/mcp): connect external services like Slack, Linear, and Google Drive
- [GitHub Actions](/docs/en/github-actions): run Claude in your CI pipeline on repository events


---
## automated-security-reviews-in-claude-code-168fb0760e.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.


---
## 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](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).
:::


---
## best-practices-5fdbbed47a.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices for Claude Code

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

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 under the hood, see [How Claude Code works](how-claude-code-works-0871be411d.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-d266068204.md) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](customize-your-status-line-claude-code-docs-8a9fc80be1.md), and see [Reduce token usage](/en/costs#reduce-token-usage) for strategies on reducing token usage.

***

## Give Claude a way to verify its work

<Tip>
  Include tests, screenshots, or expected outputs so Claude can check itself. This is the single highest-leverage thing you can do.
</Tip>

Claude performs dramatically better when it can verify its own work, like run tests, compare screenshots, and validate outputs.

Without clear success criteria, it might produce something that looks right but actually doesn't work. You become the only feedback loop, and every mistake requires your attention.

| 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"*                                                             |

UI changes can be verified using the [Claude in Chrome extension](../03-IDE-Integrations/use-claude-code-with-chrome-beta-claude-code-docs-4f2f5a5a96.md). It opens new tabs in your browser, tests the UI, and iterates until the code works.

Your verification can also be a test suite, a linter, or a Bash command that checks output. Invest in making your verification rock-solid.

***

## Explore first, then plan, then code

<Tip>
  Separate research and planning from implementation to avoid solving the wrong problem.
</Tip>

Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [Plan Mode](/en/common-workflows#use-plan-mode-for-safe-code-analysis) to separate exploration from execution.

The recommended workflow has four phases:

<Steps>
  <Step title="Explore">
    Enter Plan Mode. Claude reads files and answers questions without making changes.

    ```txt claude (Plan Mode) theme={null}
    read /src/auth and understand how we handle sessions and login.
    also look at how we manage environment variables for secrets.
    ```
  </Step>

  <Step title="Plan">
    Ask Claude to create a detailed implementation plan.

    ```txt claude (Plan Mode) theme={null}
    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.
  </Step>

  <Step title="Implement">
    Switch back to Normal Mode and let Claude code, verifying against its plan.

    ```txt claude (Normal Mode) theme={null}
    implement the OAuth flow from your plan. write tests for the
    callback handler, run the test suite and fix any failures.
    ```
  </Step>

  <Step title="Commit">
    Ask Claude to commit with a descriptive message and create a PR.

    ```txt claude (Normal Mode) theme={null}
    commit with a descriptive message and open a PR
    ```
  </Step>
</Steps>

<Callout>
  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.
</Callout>

***

## Provide specific context in your prompts

<Tip>
  The more precise your instructions, the fewer corrections you'll need.
</Tip>

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

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

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

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](extend-claude-code-claude-code-docs-3b35aaf641.md).

### Write an effective CLAUDE.md

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

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.

The `/init` command analyzes your codebase to detect build systems, test frameworks, and code patterns, giving you a solid foundation to refine.

There's no required format for CLAUDE.md files, but keep it short and human-readable. For example:

```markdown CLAUDE.md theme={null}
# 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
```

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/extend-claude-with-skills-claude-code-docs.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 non-obvious behaviors              | 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.

You can tune instructions by adding emphasis (e.g., "IMPORTANT" or "YOU MUST") to improve adherence. 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:

```markdown CLAUDE.md theme={null}
See @README.md for project overview and @package.json for available npm commands.

# Additional Instructions
- Git workflow: @docs/git-instructions.md
- Personal overrides: @~/.claude/my-project-instructions.md
```

You can place CLAUDE.md files in several locations:

* **Home folder (`~/.claude/CLAUDE.md`)**: applies to all Claude sessions
* **Project root (`./CLAUDE.md`)**: check into git to share with your team
* **Project root (`./CLAUDE.local.md`)**: personal project-specific notes; add this file to your `.gitignore` so it isn't shared with your team
* **Parent directories**: useful for monorepos where both `root/CLAUDE.md` and `root/foo/CLAUDE.md` are pulled in automatically
* **Child directories**: Claude pulls in child CLAUDE.md files on demand when working with files in those directories

### Configure permissions

<Tip>
  Use [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) to let a classifier handle approvals, `/permissions` to allowlist specific commands, or `/sandbox` for OS-level isolation. Each reduces interruptions while keeping you in control.
</Tip>

By default, Claude Code requests permission for actions that might modify your system: file writes, Bash commands, MCP tools, etc. This is safe but tedious. After the tenth approval you're not really reviewing anymore, you're just clicking through. There are three ways to reduce these interruptions:

* **Auto mode**: a separate classifier model reviews commands and blocks only what looks risky: scope escalation, unknown infrastructure, or hostile-content-driven actions. Best when you trust the general direction of a task but don't want to click through every step
* **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-c83d6eff7e.md), [permission rules](configure-permissions-claude-code-docs-7b0e64d485.md), and [sandboxing](../22-Safety-Policy/sandboxing-claude-code-docs-5f97cd27c4.md).

### Use CLI tools

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

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

<Tip>
  Run `claude mcp add` to connect external tools like Notion, Figma, or your database.
</Tip>

With [MCP servers](../06-MCP-Tools/mcp-208e742686.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

<Tip>
  Use hooks for actions that must happen every time with zero exceptions.
</Tip>

[Hooks](../07-Hooks/automate-workflows-with-hooks-claude-code-docs-e843f93261.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

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

[Skills](../08-Plugins-Skills/extend-claude-with-skills-claude-code-docs.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/`:

```markdown .claude/skills/api-conventions/SKILL.md theme={null}
---
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:

```markdown .claude/skills/fix-issue/SKILL.md theme={null}
---
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

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

[Subagents](../09-Agents-Patterns/create-custom-subagents-claude-code-docs-7dc93e85c0.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.

```markdown .claude/agents/security-reviewer.md theme={null}
---
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

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

[Plugins](../08-Plugins-Skills/create-plugins-claude-code-docs.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](/en/discover-plugins#code-intelligence) 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](/en/features-overview#match-features-to-your-goal).

***

## Communicate effectively

The way you communicate with Claude Code significantly impacts the quality of results.

### Ask codebase questions

<Tip>
  Ask Claude questions you'd ask a senior engineer.
</Tip>

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

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

Claude asks about things you might not have considered yet, including technical implementation, UI/UX, edge cases, and tradeoffs.

```text theme={null}
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.

***

## Manage your session

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

### Course-correct early and often

<Tip>
  Correct Claude as soon as you notice it going off track.
</Tip>

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

<Tip>
  Run `/clear` between unrelated tasks to reset context.
</Tip>

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**. This condenses messages from that point forward while keeping earlier context intact.
* 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 quick questions that don't need to stay in context, use [`/btw`](/en/interactive-mode#side-questions-with-%2Fbtw). The answer appears in a dismissible overlay and never enters conversation history, so you can check a detail without growing context.

### Use subagents for investigation

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

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

```text theme={null}
Use subagents to investigate how our authentication system handles token
refresh, and whether we have any existing OAuth utilities I should reuse.
```

The subagent explores the codebase, reads relevant files, and reports back with findings, all without cluttering your main conversation.

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

```text theme={null}
use a subagent to review this code for edge cases
```

### Rewind with checkpoints

<Tip>
  Every action Claude makes creates a checkpoint. You can restore conversation, code, or both to any previous checkpoint.
</Tip>

Claude automatically checkpoints before changes. 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-94f7cd24eb.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 persist across sessions, so you can close your terminal and still rewind later.

<Warning>
  Checkpoints only track changes made *by Claude*, not external processes. This isn't a replacement for git.
</Warning>

### Resume conversations

<Tip>
  Run `claude --continue` to pick up where you left off, or `--resume` to choose from recent sessions.
</Tip>

Claude Code saves conversations locally. When a task spans multiple sessions, you don't have to re-explain the context:

```bash theme={null}
claude --continue    # Resume the most recent conversation
claude --resume      # Select from recent conversations
```

Use `/rename` to give sessions descriptive names like `"oauth-migration"` or `"debugging-memory-leak"` so you can find them later. Treat sessions like branches: different workstreams can have separate, persistent contexts.

***

## Automate and scale

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

Everything so far assumes one human, one Claude, and one conversation. But Claude Code scales horizontally. The techniques in this section show how you can get more done.

### Run non-interactive mode

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

With `claude -p "your prompt"`, you can run Claude non-interactively, without a session. Non-interactive mode 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.

```bash theme={null}
# 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
```

### Run multiple Claude sessions

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

There are three main ways to run parallel sessions:

* [Claude Code desktop app](/en/desktop#work-in-parallel-with-sessions): Manage multiple local sessions visually. Each session gets its own isolated worktree.
* [Claude Code on the web](claude-code-on-the-web-69d53821d4.md): Run on Anthropic's secure cloud infrastructure in isolated VMs.
* [Agent teams](../09-Agents-Patterns/agent-teams-e29da6ed1b.md): 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

<Tip>
  Loop through tasks calling `claude -p` for each. Use `--allowedTools` to scope permissions for batch operations.
</Tip>

For large migrations or analyses, you can distribute work across many parallel Claude invocations:

<Steps>
  <Step title="Generate a task list">
    Have Claude list all files that need migrating (e.g., `list all 2,000 Python files that need migrating`)
  </Step>

  <Step title="Write a script to loop through the list">
    ```bash theme={null}
    for file in $(cat files.txt); do
      claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
        --allowedTools "Edit,Bash(git commit *)"
    done
    ```
  </Step>

  <Step title="Test on a few files, then run at scale">
    Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag restricts what Claude can do, which matters when you're running unattended.
  </Step>
</Steps>

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

```bash theme={null}
claude -p "<your prompt>" --output-format json | your_command
```

Use `--verbose` for debugging during development, and turn it off in production.

### Run autonomously with auto mode

For uninterrupted execution with background safety checks, use [auto mode](/en/permission-modes#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.

```bash theme={null}
claude --permission-mode auto -p "fix all lint errors"
```

For non-interactive runs with the `-p` flag, auto mode aborts if the classifier repeatedly blocks actions, since there is no user to fall back to. See [when auto mode falls back](/en/permission-modes#when-auto-mode-falls-back) for thresholds.

***

## 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

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

* [How Claude Code works](how-claude-code-works-0871be411d.md): the agentic loop, tools, and context management
* [Extend Claude Code](extend-claude-code-claude-code-docs-3b35aaf641.md): skills, hooks, MCP, subagents, and plugins
* [Common workflows](common-workflows-c909406123.md): step-by-step recipes for debugging, testing, PRs, and more
* [CLAUDE.md](how-claude-remembers-your-project-claude-code-docs-f1c064262d.md): store project conventions and persistent context


---
## best-practices-for-claude-code-claude-code-docs-9686dc1633.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 under the hood, see [How Claude Code works](/docs/en/how-claude-code-works).

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

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](/docs/en/context-window) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](/docs/en/statusline), and see [Reduce token usage](/docs/en/costs#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](/docs/en/chrome) compared against a design.

| 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](/docs/en/goal). A separate evaluator re-checks it after every turn and Claude keeps working until it holds.
- **As a deterministic gate**: a [Stop hook](/docs/en/hooks#stop) runs your check as a script and blocks the turn from ending until it passes. Claude Code overrides the hook and ends the turn after 8 consecutive blocks.
- **By a second opinion**: a [verification subagent](/docs/en/sub-agents) or a [dynamic workflow](/docs/en/workflows) 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](/docs/en/permission-modes#analyze-before-you-edit-with-plan-mode) to separate exploration from execution. The recommended workflow has four phases:

1

Explore

Enter plan mode. 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 and let Claude code, verifying against its plan.

claude (default mode)

```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 (default mode)

```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` 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](/docs/en/features-overview).


[​](#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. The `/init` command analyzes your codebase to detect build systems, test frameworks, and code patterns, giving you a solid foundation to refine. 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](/docs/en/skills) 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 non-obvious behaviors              | 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. You can tune instructions by adding emphasis (e.g., “IMPORTANT” or “YOU MUST”) to improve adherence. 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:

CLAUDE.md

```python
See @README.md for project overview and @package.json for available npm commands.

# Additional Instructions
- Git workflow: @docs/git-instructions.md
- Personal overrides: @~/.claude/my-project-instructions.md
```

You can place CLAUDE.md files in several locations:

- **Home folder (`~/.claude/CLAUDE.md`)**: applies to all Claude sessions
- **Project root (`./CLAUDE.md`)**: check into git to share with your team
- **Project root (`./CLAUDE.local.md`)**: personal project-specific notes; add this file to your `.gitignore` so it isn’t shared with your team
- **Parent directories**: useful for monorepos where both `root/CLAUDE.md` and `root/foo/CLAUDE.md` are pulled in automatically
- **Child directories**: Claude pulls in child CLAUDE.md files on demand when it reads a file in those directories


[​](#configure-permissions)

Configure permissions

Use [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) to let a classifier handle approvals, `/permissions` to allowlist specific commands, or `/sandbox` for OS-level isolation. Each reduces interruptions while keeping you in control.

By default, Claude Code requests permission for actions that might modify your system: file writes, Bash commands, MCP tools, etc. This is safe but tedious. After the tenth approval you’re not really reviewing anymore, you’re just clicking through. There are three ways to reduce these interruptions:

- **Auto mode**: a separate classifier model reviews commands and blocks only what looks risky: scope escalation, unknown infrastructure, or hostile-content-driven actions. Best when you trust the general direction of a task but don’t want to click through every step
- **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](/docs/en/permission-modes), [permission rules](/docs/en/permissions), and [sandboxing](/docs/en/sandboxing).


[​](#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` to connect external tools like Notion, Figma, or your database.

With [MCP servers](/docs/en/mcp), 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](/docs/en/hooks-guide) 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](/docs/en/skills) 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](/docs/en/sub-agents) 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](/docs/en/plugins) bundle skills, hooks, subagents, and MCP servers into a single installable unit from the community and Anthropic. If you work with a typed language, install a [code intelligence plugin](/docs/en/discover-plugins#code-intelligence) 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](/docs/en/features-overview#match-features-to-your-goal).

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


[​](#communicate-effectively)

Communicate effectively

The way you communicate with Claude Code significantly impacts the quality of results.


[​](#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](/docs/en/checkpointing#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 quick questions that don’t need to stay in context, use [`/btw`](/docs/en/interactive-mode#side-questions-with-%2Fbtw). The answer appears in a dismissible overlay and 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, subagents are one of the most powerful tools available. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries:

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

The subagent explores the codebase, reads relevant files, and reports back with findings, all without cluttering your main conversation. You can also use subagents for verification after Claude implements something:

```python
use a subagent to review this code for edge cases
```


[​](#rewind-with-checkpoints)

Rewind with checkpoints

Every prompt you send 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](/docs/en/checkpointing) 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` to pick up the most recent session, or `claude --resume` to choose from a list. Give sessions descriptive names like `oauth-migration` so you can find them later. See [Manage sessions](/docs/en/sessions) 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. Everything so far assumes one human, one Claude, and one conversation. But Claude Code scales horizontally. The techniques in this section show how you can get more done.


[​](#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](/docs/en/headless) 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:

- [Worktrees](/docs/en/worktrees): run separate CLI sessions in isolated git checkouts so edits don’t collide
- [Desktop app](/docs/en/desktop#work-in-parallel-with-sessions): manage multiple local sessions visually, each in its own worktree
- [Claude Code on the web](/docs/en/claude-code-on-the-web): run sessions on Anthropic-managed cloud infrastructure in isolated VMs
- [Agent teams](/docs/en/agent-teams): 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 scope permissions for batch operations.

For large migrations or analyses, you can distribute work across many parallel Claude invocations:

1

Generate a task list

Have Claude list all files that need migrating (e.g., `list all 2,000 Python files that need migrating`)

2

Write a script to loop through the list

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

3

Test on a few files, then run at scale

Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag restricts what Claude can do, which matters when you’re running unattended.

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

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

Use `--verbose` for debugging during development, and turn it off in production.


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

Run autonomously with auto mode

For uninterrupted execution with background safety checks, use [auto mode](/docs/en/permission-modes#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"
```

For non-interactive runs with the `-p` flag, auto mode aborts if the classifier repeatedly blocks actions, since there is no user to fall back to. See [when auto mode falls back](/docs/en/permission-modes#when-auto-mode-falls-back) for 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](/docs/en/sub-agents) 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](/docs/en/commands), which reviews the current diff for bugs in a fresh subagent and returns findings to the session. To check the diff against your plan instead, write the review prompt yourself. Name the work to check, the plan to check it against, and what counts as a finding:

```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. For longer autonomous runs, an [agent team](/docs/en/agent-teams) can keep this loop going across many tasks while you spot-check the recorded findings.

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


---
## best-practices.md

> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices for Claude Code

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

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 under the hood, see [How Claude Code works](how-claude-code-works-0871be411d.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. For detailed strategies on reducing token usage, see [Reduce token usage](/en/costs#reduce-token-usage).

***

## Give Claude a way to verify its work

<Tip>
  Include tests, screenshots, or expected outputs so Claude can check itself. This is the single highest-leverage thing you can do.
</Tip>

Claude performs dramatically better when it can verify its own work, like run tests, compare screenshots, and validate outputs.

Without clear success criteria, it might produce something that looks right but actually doesn't work. You become the only feedback loop, and every mistake requires your attention.

| 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"*                                                             |

UI changes can be verified using the [Claude in Chrome extension](chrome.md). It opens a browser, tests the UI, and iterates until the code works.

Your verification can also be a test suite, a linter, or a Bash command that checks output. Invest in making your verification rock-solid.

***

## Explore first, then plan, then code

<Tip>
  Separate research and planning from implementation to avoid solving the wrong problem.
</Tip>

Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [Plan Mode](/en/common-workflows#use-plan-mode-for-safe-code-analysis) to separate exploration from execution.

The recommended workflow has four phases:

<Steps>
  <Step title="Explore">
    Enter Plan Mode. Claude reads files and answers questions without making changes.

    ```txt claude (Plan Mode) theme={null}
    read /src/auth and understand how we handle sessions and login.
    also look at how we manage environment variables for secrets.
    ```
  </Step>

  <Step title="Plan">
    Ask Claude to create a detailed implementation plan.

    ```txt claude (Plan Mode) theme={null}
    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.
  </Step>

  <Step title="Implement">
    Switch back to Normal Mode and let Claude code, verifying against its plan.

    ```txt claude (Normal Mode) theme={null}
    implement the OAuth flow from your plan. write tests for the
    callback handler, run the test suite and fix any failures.
    ```
  </Step>

  <Step title="Commit">
    Ask Claude to commit with a descriptive message and create a PR.

    ```txt claude (Normal Mode) theme={null}
    commit with a descriptive message and open a PR
    ```
  </Step>
</Steps>

<Callout>
  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.
</Callout>

***

## Provide specific context in your prompts

<Tip>
  The more precise your instructions, the fewer corrections you'll need.
</Tip>

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

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

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

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](extend-claude-code-claude-code-docs-3b35aaf641.md).

### Write an effective CLAUDE.md

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

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

The `/init` command analyzes your codebase to detect build systems, test frameworks, and code patterns, giving you a solid foundation to refine.

There's no required format for CLAUDE.md files, but keep it short and human-readable. For example:

```markdown CLAUDE.md theme={null}
# 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
```

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/extend-claude-with-skills-claude-code-docs.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 non-obvious behaviors              | 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.

You can tune instructions by adding emphasis (e.g., "IMPORTANT" or "YOU MUST") to improve adherence. 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:

```markdown CLAUDE.md theme={null}
See @README.md for project overview and @package.json for available npm commands.

# Additional Instructions
- Git workflow: @docs/git-instructions.md
- Personal overrides: @~/.claude/my-project-instructions.md
```

You can place CLAUDE.md files in several locations:

* **Home folder (`~/.claude/CLAUDE.md`)**: Applies to all Claude sessions
* **Project root (`./CLAUDE.md`)**: Check into git to share with your team, or name it `CLAUDE.local.md` and `.gitignore` it
* **Parent directories**: Useful for monorepos where both `root/CLAUDE.md` and `root/foo/CLAUDE.md` are pulled in automatically
* **Child directories**: Claude pulls in child CLAUDE.md files on demand when working with files in those directories

### Configure permissions

<Tip>
  Use `/permissions` to allowlist safe commands or `/sandbox` for OS-level isolation. This reduces interruptions while keeping you in control.
</Tip>

By default, Claude Code requests permission for actions that might modify your system: file writes, Bash commands, MCP tools, etc. This is safe but tedious. After the tenth approval you're not really reviewing anymore, you're just clicking through. There are two ways to reduce these interruptions:

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

Alternatively, use `--dangerously-skip-permissions` to bypass all permission checks for contained workflows like fixing lint errors or generating boilerplate.

<Warning>
  Letting Claude run arbitrary commands can result in data loss, system corruption, or data exfiltration via prompt injection. Only use `--dangerously-skip-permissions` in a sandbox without internet access.
</Warning>

Read more about [configuring permissions](claude-code-settings-claude-code-docs-d4420b4b52.md) and [enabling sandboxing](/en/sandboxing#sandboxing).

### Use CLI tools

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

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

<Tip>
  Run `claude mcp add` to connect external tools like Notion, Figma, or your database.
</Tip>

With [MCP servers](../06-MCP-Tools/General/connect-claude-code-to-tools-via-mcp-claude-code-docs.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

<Tip>
  Use hooks for actions that must happen every time with zero exceptions.
</Tip>

[Hooks](../07-Hooks/automate-workflows-with-hooks-claude-code-docs-e843f93261.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."* Run `/hooks` for interactive configuration, or edit `.claude/settings.json` directly.

### Create skills

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

[Skills](../08-Plugins-Skills/extend-claude-with-skills-claude-code-docs.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/`:

```markdown .claude/skills/api-conventions/SKILL.md theme={null}
---
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:

```markdown .claude/skills/fix-issue/SKILL.md theme={null}
---
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

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

[Subagents](../09-Agents-Patterns/create-custom-subagents-claude-code-docs-7dc93e85c0.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.

```markdown .claude/agents/security-reviewer.md theme={null}
---
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

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

[Plugins](../08-Plugins-Skills/create-plugins-claude-code-docs.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](/en/discover-plugins#code-intelligence) 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](/en/features-overview#match-features-to-your-goal).

***

## Communicate effectively

The way you communicate with Claude Code significantly impacts the quality of results.

### Ask codebase questions

<Tip>
  Ask Claude questions you'd ask a senior engineer.
</Tip>

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

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

Claude asks about things you might not have considered yet, including technical implementation, UI/UX, edge cases, and tradeoffs.

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

***

## Manage your session

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

### Course-correct early and often

<Tip>
  Correct Claude as soon as you notice it going off track.
</Tip>

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.
* **`"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

<Tip>
  Run `/clear` between unrelated tasks to reset context.
</Tip>

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

### Use subagents for investigation

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

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

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

The subagent explores the codebase, reads relevant files, and reports back with findings, all without cluttering your main conversation.

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

```
use a subagent to review this code for edge cases
```

### Rewind with checkpoints

<Tip>
  Every action Claude makes creates a checkpoint. You can restore conversation, code, or both to any previous checkpoint.
</Tip>

Claude automatically checkpoints before changes. Double-tap `Escape` or run `/rewind` to open the checkpoint menu. You can restore conversation only (keep code changes), restore code only (keep conversation), or restore both.

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 persist across sessions, so you can close your terminal and still rewind later.

<Warning>
  Checkpoints only track changes made *by Claude*, not external processes. This isn't a replacement for git.
</Warning>

### Resume conversations

<Tip>
  Run `claude --continue` to pick up where you left off, or `--resume` to choose from recent sessions.
</Tip>

Claude Code saves conversations locally. When a task spans multiple sessions (you start a feature, get interrupted, come back the next day) you don't have to re-explain the context:

```bash  theme={null}
claude --continue    # Resume the most recent conversation
claude --resume      # Select from recent conversations
```

Use `/rename` to give sessions descriptive names (`"oauth-migration"`, `"debugging-memory-leak"`) so you can find them later. Treat sessions like branches. Different workstreams can have separate, persistent contexts.

***

## Automate and scale

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

Everything so far assumes one human, one Claude, and one conversation. But Claude Code scales horizontally. The techniques in this section show how you can get more done.

### Run headless mode

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

With `claude -p "your prompt"`, you can run Claude headlessly, without an interactive session. Headless mode is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats (plain text, JSON, streaming JSON) let you parse results programmatically.

```bash  theme={null}
# 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
```

### Run multiple Claude sessions

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

There are two main ways to run parallel sessions:

* [Claude Desktop](../16-Mobile-Desktop/desktop.md): Manage multiple local sessions visually. Each session gets its own isolated worktree.
* [Claude Code on the web](claude-code-on-the-web-69d53821d4.md): Run on Anthropic's secure cloud infrastructure in isolated VMs.

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

<Tip>
  Loop through tasks calling `claude -p` for each. Use `--allowedTools` to scope permissions for batch operations.
</Tip>

For large migrations or analyses, you can distribute work across many parallel Claude invocations:

<Steps>
  <Step title="Generate a task list">
    Have Claude list all files that need migrating (e.g., `list all 2,000 Python files that need migrating`)
  </Step>

  <Step title="Write a script to loop through the list">
    ```bash  theme={null}
    for file in $(cat files.txt); do
      claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
        --allowedTools "Edit,Bash(git commit *)"
    done
    ```
  </Step>

  <Step title="Test on a few files, then run at scale">
    Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag restricts what Claude can do, which matters when you're running unattended.
  </Step>
</Steps>

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

```bash  theme={null}
claude -p "<your prompt>" --output-format json | your_command
```

Use `--verbose` for debugging during development, and turn it off in production.

### Safe Autonomous Mode

Use `claude --dangerously-skip-permissions` to bypass all permission checks and let Claude work uninterrupted. This works well for workflows like fixing lint errors or generating boilerplate code.

<Warning>
  Letting Claude run arbitrary commands is risky and can result in data loss, system corruption, or data exfiltration (e.g., via prompt injection attacks). To minimize these risks, use `--dangerously-skip-permissions` in a container without internet access.

  With sandboxing enabled (`/sandbox`), you get similar autonomy with better security. Sandbox defines upfront boundaries rather than bypassing all checks.
</Warning>

***

## 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

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

<CardGroup cols={2}>
  <Card title="How Claude Code works" icon="gear" href="/en/how-claude-code-works">
    Understand the agentic loop, tools, and context management
  </Card>

  <Card title="Extend Claude Code" icon="puzzle-piece" href="/en/features-overview">
    Choose between skills, hooks, MCP, subagents, and plugins
  </Card>

  <Card title="Common workflows" icon="list-check" href="/en/common-workflows">
    Step-by-step recipes for debugging, testing, PRs, and more
  </Card>

  <Card title="CLAUDE.md" icon="file-lines" href="/en/memory">
    Store project conventions and persistent context
  </Card>
</CardGroup>


---
## built-in-commands-claude-code-docs.md

# Built-in commands


Complete reference for built-in commands available in Claude Code.


Type `/` in Claude Code to see all available commands, or type `/` followed by any letters to filter. Not all commands are visible to every user. Some depend on your platform, plan, or environment. For example, `/desktop` only appears on macOS and Windows, `/upgrade` and `/privacy-settings` are only available on Pro and Max plans, and `/terminal-setup` is hidden when your terminal natively supports its keybindings. Claude Code also includes [bundled skills](/docs/en/skills#bundled-skills) like `/simplify`, `/batch`, and `/debug` that appear alongside built-in commands when you type `/`. To create your own commands, see [skills](/docs/en/skills). In the table below, `<arg>` indicates a required argument and `[arg]` indicates an optional one.

| Command | Purpose |
|:---|:---|
| `/add-dir <path>` | Add a new working directory to the current session |
| `/agents` | Manage [agent](/docs/en/sub-agents) configurations |
| `/btw <question>` | Ask a quick [side question](/docs/en/interactive-mode#side-questions-with-btw) without adding to the conversation |
| `/chrome` | Configure [Claude in Chrome](/docs/en/chrome) settings |
| `/clear` | Clear conversation history and free up context. Aliases: `/reset`, `/new` |
| `/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 |
| `/compact [instructions]` | Compact conversation with optional focus instructions |
| `/config` | Open the [Settings](/docs/en/settings) interface to adjust theme, model, [output style](/docs/en/output-styles), and other preferences. Alias: `/settings` |
| `/context` | Visualize current context usage as a colored grid. Shows optimization suggestions for context-heavy tools, memory bloat, and capacity warnings |
| `/copy` | Copy the last assistant response to clipboard. When code blocks are present, shows an interactive picker to select individual blocks or the full response |
| `/cost` | Show token usage statistics. See [cost tracking guide](/docs/en/costs#using-the-cost-command) for subscription-specific details |
| `/desktop` | Continue the current session in the Claude Code Desktop app. macOS and Windows only. Alias: `/app` |
| `/diff` | Open an interactive diff viewer showing uncommitted changes and per-turn diffs. Use left/right arrows to switch between the current git diff and individual Claude turns, and up/down to browse files |
| `/doctor` | Diagnose and verify your Claude Code installation and settings |
| `/effort [low|medium|high|max|auto]` | Set the model [effort level](/docs/en/model-config#adjust-effort-level). `low`, `medium`, and `high` persist across sessions. `max` applies to the current session only and requires Opus 4.6. `auto` resets to the model default. Without an argument, shows the current level. Takes effect immediately without waiting for the current response to finish |
| `/exit` | Exit the CLI. 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 |
| `/extra-usage` | Configure extra usage to keep working when rate limits are hit |
| `/fast [on|off]` | Toggle [fast mode](/docs/en/fast-mode) on or off |
| `/feedback [report]` | Submit feedback about Claude Code. Alias: `/bug` |
| `/fork [name]` | Create a fork of the current conversation at this point |
| `/help` | Show help and available commands |
| `/hooks` | View [hook](/docs/en/hooks) configurations for tool events |
| `/ide` | Manage IDE integrations and show status |
| `/init` | Initialize project with `CLAUDE.md` guide |
| `/insights` | Generate a report analyzing your Claude Code sessions, including project areas, interaction patterns, and friction points |
| `/install-github-app` | Set up the [Claude GitHub Actions](/docs/en/github-actions) app for a repository. Walks you through selecting a repo and configuring the integration |
| `/install-slack-app` | Install the Claude Slack app. Opens a browser to complete the OAuth flow |
| `/keybindings` | Open or create your keybindings configuration file |
| `/login` | Sign in to your Anthropic account |
| `/logout` | Sign out from your Anthropic account |
| `/mcp` | Manage MCP server connections and OAuth authentication |
| `/memory` | Edit `CLAUDE.md` memory files, enable or disable [auto-memory](/docs/en/memory#auto-memory), and view auto-memory entries |
| `/mobile` | Show QR code to download the Claude mobile app. Aliases: `/ios`, `/android` |
| `/model [model]` | Select or change the AI model. For models that support it, use left/right arrows to [adjust effort level](/docs/en/model-config#adjust-effort-level). The change takes effect immediately without waiting for the current response to finish |
| `/passes` | Share a free week of Claude Code with friends. Only visible if your account is eligible |
| `/permissions` | View or update [permissions](/docs/en/permissions#manage-permissions). Alias: `/allowed-tools` |
| `/plan` | Enter plan mode directly from the prompt |
| `/plugin` | Manage Claude Code [plugins](/docs/en/plugins) |
| `/pr-comments [PR]` | Fetch and display 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 |
| `/release-notes` | View the full changelog, with the most recent version closest to your prompt |
| `/reload-plugins` | Reload all active [plugins](/docs/en/plugins) to apply pending changes without restarting. Reports what was loaded and notes any changes that require a restart |
| `/remote-control` | Make this session available for [remote control](/docs/en/remote-control) from claude.ai. Alias: `/rc` |
| `/remote-env` | Configure the default remote environment for [web sessions started with `--remote`](/docs/en/claude-code-on-the-web#environment-configuration) |
| `/rename [name]` | Rename the current session and show the name on the prompt bar. Without a name, auto-generates one from conversation history |
| `/resume [session]` | Resume a conversation by ID or name, or open the session picker. Alias: `/continue` |
| `/review` | Deprecated. Install the [`code-review` plugin](https://github.com/anthropics/claude-code-marketplace/blob/main/code-review/README.md) instead: `claude plugin install code-review@claude-code-marketplace` |
| `/rewind` | Rewind the conversation and/or code to a previous point, or summarize from a selected message. See [checkpointing](/docs/en/checkpointing). Alias: `/checkpoint` |
| `/sandbox` | Toggle [sandbox mode](/docs/en/sandboxing). Available on supported platforms only |
| `/security-review` | Analyze pending changes on the current branch for security vulnerabilities. Reviews the git diff and identifies risks like injection, auth issues, and data exposure |
| `/skills` | List available [skills](/docs/en/skills) |
| `/stats` | Visualize daily usage, session history, streaks, and model preferences |
| `/status` | Open the Settings interface (Status tab) showing version, model, account, and connectivity |
| `/statusline` | Configure Claude Code’s [status line](/docs/en/statusline). Describe what you want, or run without arguments to auto-configure from your shell prompt |
| `/stickers` | Order Claude Code stickers |
| `/tasks` | List and manage background tasks |
| `/terminal-setup` | Configure terminal keybindings for Shift+Enter and other shortcuts. Only visible in terminals that need it, like VS Code, Alacritty, or Warp |
| `/theme` | Change the color theme. Includes light and dark variants, colorblind-accessible (daltonized) themes, and ANSI themes that use your terminal’s color palette |
| `/upgrade` | Open the upgrade page to switch to a higher plan tier |
| `/usage` | Show plan usage limits and rate limit status |
| `/vim` | Toggle between Vim and Normal editing modes |

## 

MCP prompts

MCP servers can expose prompts that appear as commands. These use the format `/mcp__<server>__<prompt>` and are dynamically discovered from connected servers. See [MCP prompts](/docs/en/mcp#use-mcp-prompts-as-commands) for details.

## 

See also

- [Skills](/docs/en/skills): create your own commands
- [Interactive mode](/docs/en/interactive-mode): keyboard shortcuts, Vim mode, and command history
- [CLI reference](/docs/en/cli-reference): launch-time flags


---
## catch-security-issues-as-claude-writes-code-claude-code-docs-6f144bf1df.md

## On this page

- [Prerequisites](#prerequisites)
- [Install the plugin](#install-the-plugin)
  - [Enable in cloud sessions and shared repositories](#enable-in-cloud-sessions-and-shared-repositories)
- [What the plugin checks](#what-the-plugin-checks)
  - [On each file edit](#on-each-file-edit)
  - [At the end of each turn](#at-the-end-of-each-turn)
  - [On each commit or push Claude makes](#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)

Code review & CI/CD

# 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](/docs/en/code-review), 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

- Claude Code CLI version 2.1.144 or later
- 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](/docs/en/discover-plugins#official-anthropic-marketplace):

```python
/plugin install security-guidance@claude-plugins-official
```

`/plugin` opens an interactive panel and is available only 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**: open the [plugin browser](/docs/en/desktop#install-plugins) by clicking the **+** button next to the prompt, then **Plugins**, then **Add plugin**
- **Claude Code on the web or a desktop cloud session**: declare the plugin in `.claude/settings.json` as shown under [Enable in cloud sessions](#enable-in-cloud-sessions-and-shared-repositories)

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 Claude Code reports `Marketplace "claude-plugins-official" not found`, add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`. If it reports that the plugin is not found in the marketplace, your local copy is outdated: refresh it with `/plugin marketplace update claude-plugins-official`. Then retry the install. Then activate it in the current session with `/reload-plugins`, which applies pending plugin changes without a restart:

```python
/reload-plugins
```


[​](#enable-in-cloud-sessions-and-shared-repositories)

Enable in cloud sessions and shared repositories

User-scoped plugins do not carry into [Claude Code on the web](/docs/en/claude-code-on-the-web), because those sessions run on Anthropic infrastructure rather than your machine. To enable the plugin there, or to turn it on for everyone who clones a 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`](/docs/en/settings#plugin-settings) in [managed settings](/docs/en/admin-setup).


[​](#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.


[​](#on-each-file-edit)

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.


[​](#at-the-end-of-each-turn)

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.


[​](#on-each-commit-or-push-claude-makes)

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](/docs/en/hooks-guide#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](/docs/en/costs) like any other Claude request. The commit review is agentic and may take several model turns per commit, capped at 20 reviews per rolling hour. 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`, disabling 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`; that option requires Claude Code v2.1.203 or later. If it was enabled through [managed settings](/docs/en/admin-setup), 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](/docs/en/hooks), 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`](/docs/en/commands#all-commands)           | One-time security pass on the current branch, run when you ask                                           |
| On demand, deep scan   | [Claude Security plugin](/docs/en/claude-security)             | Multi-agent vulnerability scan of a repository or diff, with independently reviewed findings and patches |
| On pull request        | [Code Review](/docs/en/code-review), 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         |

Each later stage catches what earlier ones miss. The plugin’s value is reducing the volume that reaches them, not eliminating the need for them. 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](/docs/en/claude-security) for a deeper multi-agent scan of the whole repository; [`/security-review`](/docs/en/commands#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](/docs/en/code-review): set up the PR-time multi-agent review
- [Automate actions with hooks](/docs/en/hooks-guide): build your own checks at the same lifecycle points
- [Discover and install plugins](/docs/en/discover-plugins#official-anthropic-marketplace): browse other official plugins


---
## champion-kit-claude-code-docs-a490488ead.md

## On this page

- [The champion role](#the-champion-role)
  - [What this should cost you](#what-this-should-cost-you)
- [Share what you discover](#share-what-you-discover)
  - [What is worth sharing](#what-is-worth-sharing)
  - [Where to share it](#where-to-share-it)
  - [The format that works](#the-format-that-works)
- [Be the person people ask](#be-the-person-people-ask)
  - [Answer with a prompt rather than an explanation](#answer-with-a-prompt-rather-than-an-explanation)
  - [Point at the feature rather than the documentation](#point-at-the-feature-rather-than-the-documentation)
  - [Questions you are likely to hear](#questions-you-are-likely-to-hear)
- [Grow the circle](#grow-the-circle)
  - [Patterns that tend to work](#patterns-that-tend-to-work)
  - [Thirty-day playbook](#thirty-day-playbook)
  - [When someone wants to go deeper](#when-someone-wants-to-go-deeper)
- [Respond to common concerns](#respond-to-common-concerns)
- [Quick-reference sheet](#quick-reference-sheet)

Adoption

# Champion kit

Copy pageCopy page

A playbook for engineers advocating Claude Code internally: what to share, how to answer questions, and how to grow adoption on your team.

Copy pageCopy page

This page is for individual engineers who are already using Claude Code and want to help their team adopt it. It covers what to share, how to answer the questions you will get, a thirty-day playbook, and responses to common concerns. Adoption of a developer tool rarely happens 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. 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 a help desk, and this guide is structured to keep the role sustainable on those terms.


[​](#the-champion-role)

The champion role

The role consists of three behaviors that reinforce one another.

| Behavior                 | What it looks like in practice                                                                                                                                                           | Why it matters                                                                                                                                                                          |
|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Share what you discover  | Post the prompts, screenshots, and small wins from your own work in the places your team already reads, such as an engineering channel, a standup thread, or a pull-request description. | Examples drawn from your own codebase are more persuasive than any external documentation, because colleagues can see exactly how the tool applies to the problems they share with you. |
| Be the person people ask | When a colleague asks how you accomplished something, respond with the actual prompt you used so they can apply it directly to their own task.                                           | A concrete, runnable example removes the gap between curiosity and a first successful use, which is where most adoption efforts stall.                                                  |
| Grow the circle          | Establish a small number of lightweight, recurring habits, such as a dedicated channel or a weekly thread, so that momentum continues even when your attention is elsewhere.             | Adoption that depends on a single person is fragile. Adoption that is carried by shared habits continues to compound on its own.                                                        |

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.


[​](#what-this-should-cost-you)

What this should cost you

Set 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.

| Activity                                | Time per week    | Guidance                                                                                                                            |
|-----------------------------------------|------------------|-------------------------------------------------------------------------------------------------------------------------------------|
| Posting wins and prompts                | About 15 minutes | Capture these in the moment with a screenshot and one or two sentences; avoid turning them into formal write-ups.                   |
| Answering questions in a shared channel | About 20 minutes | Answer publicly once, then link back to that answer when the question recurs.                                                       |
| Hosting a weekly show-and-tell thread   | About 5 minutes  | You post the opening prompt; the team supplies the content.                                                                         |
| Optional pairing or walkthroughs        | 0 to 30 minutes  | Reserve this for colleagues who are genuinely blocked, and offer the [Quickstart](/docs/en/quickstart) link before scheduling time. |


[​](#share-what-you-discover)

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)

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. Examples of reusable techniques:

- “I learned that @-mentioning a directory works. Pointing it at `@src/components/` and asking which were missing tests surfaced two I had overlooked.”
- “Plan mode (`Shift+Tab`) shows exactly which files will be touched before any edit is made, which is why I am comfortable using it on shared code.”
- “I configured a Stop hook so I receive a desktop notification when a long task completes. Configuration is in the thread.”
- “Running `/init` generates a `CLAUDE.md` from the repository so the assistant stops re-asking about our conventions.”


[​](#where-to-share-it)

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 destination.

| Location                                        | Best suited for                                                            | Recommended format                                                                          |
|-------------------------------------------------|----------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
| A `#claude-code` or general engineering channel | Discoveries, prompts, and “today I learned” moments                        | A screenshot accompanied by one or two sentences of context                                 |
| Pull-request descriptions                       | Demonstrating the approach on real code that reviewers are already reading | A single line such as “Claude and I did this refactor; happy to walk through the approach.” |
| Standups or weekly written updates              | Normalizing usage with leads and skip-level managers                       | One sentence describing one concrete outcome                                                |
| Team wiki or internal documentation             | Durable patterns, custom skills, and `CLAUDE.md` examples                  | A short page, linked from the channel topic so it remains discoverable                      |


[​](#the-format-that-works)

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. The example posts below illustrate tone and length; adapt them rather than copying verbatim.

```python
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.
```

```python
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.
```

```python
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.
```


[​](#be-the-person-people-ask)

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)

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.

```python
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)

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)

Questions you are likely to hear

| Question                                           | Suggested response                                                                                                                                                                                                           | Follow-up resource                                                |
|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|
| ”What should I try it on first?”                   | Recommend a real but contained task, ideally a bug or chore the person has been postponing because it is tedious rather than difficult.                                                                                      | [Common workflows](/docs/en/common-workflows)                     |
| ”How do I trust it with my code?”                  | Introduce plan mode: pressing `Shift+Tab` cycles into it, Claude proposes exactly what it intends to change, and nothing is modified until the user approves.                                                                | [Permissions](/docs/en/permissions)                               |
| ”Is the setup worth the effort?”                   | Installation takes roughly two minutes, runs in the terminal, and requires no IDE extension. Running `/init` once is sufficient to begin working.                                                                            | [Quickstart](/docs/en/quickstart)                                 |
| ”It produced an incorrect result.”                 | Encourage them to provide the failure back to Claude. Pasting the error message or failing test is far more effective than rephrasing the original request.                                                                  | [Common workflows](/docs/en/common-workflows)                     |
| ”It does not understand our codebase conventions.” | Suggest running `/init` to generate a `CLAUDE.md` file, then adding the team’s conventions, test commands, and any directories that should be avoided.                                                                       | [Memory](/docs/en/memory)                                         |
| ”Is this just autocomplete?”                       | Offer a brief demonstration in which Claude explains an unfamiliar file, traces a bug across services, or drafts a migration plan. These tasks require reasoning across the repository rather than completing a single line. | A two-minute live demonstration                                   |
| ”What about security and data handling?”           | Refer this question to your administrator. Your organization’s deployment and data-handling policy is already configured, and champions should not improvise this answer.                                                    | [Security](/docs/en/security) · [Data usage](/docs/en/data-usage) |


[​](#grow-the-circle)

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)

Patterns that tend to work

| Pattern                                    | How to run it                                                                                                                                                                                                                                     | Effort required                            |
|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------|
| A dedicated channel                        | Create a `#claude-code` channel (or a recurring thread in an existing one), pin the [Quickstart](/docs/en/quickstart) link and one strong example, and answer questions publicly so each answer benefits everyone watching.                       | About five minutes to set up, then ambient |
| A weekly show-and-tell thread              | Each Friday, post “What did Claude help you with this week?” No preparation, slides, or meeting are required; screenshots and short descriptions are sufficient.                                                                                  | About two minutes per week                 |
| Share a custom skill                       | Post your most useful `.claude/skills/<name>/SKILL.md` file, for example a `/ship` skill that runs tests and lint before committing, with a one-line description. Because skills are plain Markdown, colleagues can adopt them immediately.       | About five minutes per skill               |
| Generate a setup guide from your own usage | Run `/team-onboarding` in a project you have spent real time in. Claude scans your recent sessions, commands, and MCP servers, then produces a guide a new teammate can paste as their first message to replay your setup. Pin it in the channel. | About two minutes                          |
| Pair on a first task                       | Offer a single fifteen-minute pairing session to anyone getting started. One successful outcome on their own code is more persuasive than any presentation.                                                                                       | About fifteen minutes per person           |
| Identify the next champion                 | The colleague who asks you the most questions is usually ready to take on this role. Forward them this page and divide the channel responsibilities between you.                                                                                  | Negligible                                 |


[​](#thirty-day-playbook)

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.

1

Week 1: Seed the channel

Create the channel, pin the [Quickstart](/docs/en/quickstart), and post two or three of your own examples with the prompts included.**Signal that it is working:** a few colleagues react or reply, and at least one question is asked in the channel.

2

Week 2: Start the rhythm

Start the weekly show-and-tell thread, answer every question publicly, and share one custom skill or `CLAUDE.md` snippet.**Signal that it is working:** someone other than you posts an example of their own.

3

Week 3: Pair and consolidate

Offer two or three short pairing sessions and consolidate the most common questions and answers into a pinned FAQ message.**Signal that it is working:** you see repeat usage, with the same colleagues returning rather than trying once and stopping.

4

Week 4: Hand off

Identify a second champion and share a brief summary of what is working and what is not with your lead or administrator.**Signal that it is working:** questions in the channel are being answered by people other than you.


[​](#when-someone-wants-to-go-deeper)

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 [Quickstart](/docs/en/quickstart) and [Common workflows](/docs/en/common-workflows) pages. They contain short sections covering the features that are genuinely useful but difficult to discover on your own.


[​](#respond-to-common-concerns)

Respond to common concerns

Healthy skepticism is expected; engineers should be cautious about tools that touch their code. 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.

| Concern                                       | Suggested response                                                                                                                                                                                 | Evidence to offer                                         |
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|
| ”I am faster without it.”                     | That is likely true for code the person writes routinely. Suggest trying it on the work they tend to avoid: legacy files, unfamiliar services, or test scaffolding, where the leverage is highest. | Time one tedious task both ways and compare.              |
| ”I do not trust AI to touch production code.” | Agree that no change should land unread. Plan mode combined with normal diff review means nothing is applied that the engineer has not inspected, the same standard as any pull request.           | Demonstrate plan mode on a real file.                     |
| ”It will make junior engineers weaker.”       | Used well, it is an effective explainer. Encourage junior engineers to ask Claude to explain a file and its call sites before asking it to change anything.                                        | Run “Explain @file and where it is called from” together. |
| ”I tried it once and it hallucinated.”        | This is usually a context problem rather than a model problem. @-mentioning the relevant files, running `/init`, and providing the actual error output typically resolves it.                      | Re-run their original prompt with proper `@`-context.     |
| ”We do not have time to learn another tool.”  | Claude Code is a terminal command rather than a platform. If it does not return value within the first session, it is reasonable to set it aside.                                                  | A two-minute install followed by one real bug.            |


[​](#quick-reference-sheet)

Quick-reference sheet

The techniques below are the ones that most reliably move someone from a first trial to daily use. Pin this table in a channel or share it on its own.

| Technique                        | How to apply it                                                                                                                                                       |
|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Provide the right context        | Use `@file` or `@directory/` references, or paste the error or log output directly. Supplying relevant context is more effective than elaborate prompting.            |
| Review the plan before the edit  | Press `Shift+Tab` to enter plan mode. Claude will describe the intended changes for your approval before executing them.                                              |
| Teach it your repository         | Run `/init` to generate a `CLAUDE.md` file, then add your conventions, test commands, and any directories that should not be modified. See [Memory](/docs/en/memory). |
| Reuse a workflow                 | Save a `SKILL.md` file in `.claude/skills/<name>/` to create a `/name` skill that the entire team can use. See [Skills](/docs/en/skills).                             |
| Stay informed during long tasks  | Configure a Stop hook to receive a desktop notification when a long-running task completes. See [Hooks](/docs/en/hooks-guide).                                        |
| Recover from an incorrect result | Rather than rephrasing the request, paste the failing test or stack trace back to Claude and ask it to address that specific failure.                                 |
| Keep edits surgical              | Ask for a diff, or specify “only change X.” Claude respects scope when scope is stated.                                                                               |

Claude Code is updated frequently. Verify version-specific details against the [documentation home page](/docs/en/overview) before distributing this material internally.


---
## changelog-67fadc96e4.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

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

This page is generated from the [CHANGELOG.md on GitHub](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md).

Run `claude --version` to check your installed version.

<Update label="2.1.119" description="April 23, 2026">
  * `/config` settings (theme, editor mode, verbose, etc.) now persist to `~/.claude/settings.json` and participate in project/local/policy override precedence
  * 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
  * `--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`
  * 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
  * Tool search is now disabled by default on Vertex AI to avoid an unsupported beta header error (opt in with `ENABLE_TOOL_SEARCH`)
  * 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
  * Windows: removed false-positive "Windows requires 'cmd /c' wrapper" MCP config warning
  * \[VSCode] Fixed voice dictation's first recording producing nothing on macOS while the microphone permission prompt is showing
</Update>

<Update label="2.1.118" description="April 23, 2026">
  * Added vim visual mode (`v`) and visual-line mode (`V`) with selection, operators, and visual feedback
  * 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"`
  * Added `DISABLE_UPDATES` env var to completely block all update paths including manual `claude update` — stricter than `DISABLE_AUTOUPDATER`
  * 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
  * 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
  * `--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
  * 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
</Update>

<Update label="2.1.117" description="April 22, 2026">
  * 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`
  * 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
  * 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`)
  * 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
</Update>

<Update label="2.1.116" description="April 20, 2026">
  * `/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`
  * 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
</Update>

<Update label="2.1.114" description="April 18, 2026">
  * Fixed a crash in the permission dialog when an agent teams teammate requested tool permission
</Update>

<Update label="2.1.113" description="April 17, 2026">
  * Changed the CLI to spawn a native Claude Code binary (via a per-platform optional dependency) instead of bundled JavaScript
  * Added `sandbox.network.deniedDomains` setting to block specific domains even when a broader `allowedDomains` wildcard would otherwise permit them
  * 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)
  * Improved `/loop`: pressing Esc now cancels pending wakeups, and wakeups display as "Claude resuming /loop wakeup" for clarity
  * `/extra-usage` now works from Remote Control (mobile/web) clients
  * Remote Control clients can now query `@`-file autocomplete suggestions
  * Improved `/ultrareview`: faster launch with parallelized checks, diffstat in the launch dialog, and animated launching state
  * 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`
  * 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
</Update>

<Update label="2.1.112" description="April 16, 2026">
  * Fixed "claude-opus-4-7 is temporarily unavailable" for auto mode
</Update>

<Update label="2.1.111" description="April 16, 2026">
  * 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
  * 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`
  * `/effort` now opens an interactive slider when called without arguments, with arrow-key navigation between levels and Enter to confirm
  * 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
  * 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
  * 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
  * `/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
  * Added `OTEL_LOG_RAW_API_BODIES` environment variable to emit full API request and response bodies as OpenTelemetry log events for debugging
  * 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
  * 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`
  * 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
  * 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
  * 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
</Update>

<Update label="2.1.110" description="April 15, 2026">
  * 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
  * Changed `Ctrl+O` to toggle between normal and verbose transcript only; focus view is now toggled separately with the new `/focus` command
  * 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`)
  * 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
  * `--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`.
  * 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
  * Hardened "Open in editor" actions against command injection from untrusted filenames
  * 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
</Update>

<Update label="2.1.109" description="April 15, 2026">
  * Improved the extended-thinking indicator with a rotating progress hint
</Update>

<Update label="2.1.108" description="April 14, 2026">
  * 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.
  * 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`
  * 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
  * Reduced memory footprint for file reads, edits, and syntax highlighting by loading language grammars on demand
  * 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
  * 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
</Update>

<Update label="2.1.107" description="April 14, 2026">
  * Show thinking hints sooner during long operations
</Update>

<Update label="2.1.105" description="April 13, 2026">
  * 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
  * `/proactive` is now an alias for `/loop`
  * 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)
  * 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
</Update>

<Update label="2.1.101" description="April 10, 2026">
  * 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)
  * `/ultraplan` and other remote-session features now auto-create a default cloud environment instead of requiring web setup first
  * 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`
  * 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
</Update>

<Update label="2.1.98" description="April 9, 2026">
  * 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
  * LSP: Claude Code now identifies itself to language servers via `clientInfo` in the initialize request
  * 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
  * 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
  * Updated the `/claude-api` skill to cover Managed Agents alongside Claude API
  * \[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.
  * Dropped `/compact` hints when `DISABLE_COMPACT` is set.
</Update>

<Update label="2.1.97" description="April 8, 2026">
  * 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`)
  * 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)
  * 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
  * Updated `/claude-api` skill to cover Managed Agents alongside the Claude API
</Update>

<Update label="2.1.96" description="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)
</Update>

<Update label="2.1.94" description="April 7, 2026">
  * Added support for Amazon Bedrock powered by Mantle, set `CLAUDE_CODE_USE_MANTLE=1`
  * Changed default effort level from medium to high for API-key, Bedrock/Vertex/Foundry, Team, and Enterprise users (control this with `/effort`)
  * 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
  * 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
  * 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
  * Improved `--resume` to resume sessions from other worktrees of the same repo directly instead of printing a `cd` command
  * 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] Reduced cold-open subprocess work on starting a session
  * \[VSCode] Fixed dropdown menus selecting the wrong item when the mouse was over the list while typing or using arrow keys
  * \[VSCode] Added a warning banner when `settings.json` files fail to parse, so users know their permission rules are not being applied
</Update>

<Update label="2.1.92" description="April 4, 2026">
  * 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
  * `/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
  * 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
  * Improved Write tool diff computation speed for large files (60% faster on files with tabs/`&`/`$`)
  * 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
</Update>

<Update label="2.1.91" description="April 2, 2026">
  * 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)
  * Plugins can now ship executables under `bin/` and invoke them as bare commands from the Bash tool
  * 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
  * `/feedback` now explains why it's unavailable instead of disappearing from the slash menu
  * 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`
  * Edit tool now uses shorter `old_string` anchors, reducing output tokens
</Update>

<Update label="2.1.90" description="April 1, 2026">
  * 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)
  * 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
  * Hardened PowerShell tool permission checks: fixed trailing `&` background job bypass, `-ErrorAction Break` debugger hang, archive-extraction TOCTOU, and parse-fail fallback deny-rule degradation
  * 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
  * 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)
</Update>

<Update label="2.1.89" description="April 1, 2026">
  * 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
  * Auto mode: denied commands now show a notification and appear in `/permissions` → Recent tab where you can retry with `r`
  * 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)
  * 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+)
  * 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 50K characters to be saved to disk with a file path + 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
</Update>

<Update label="2.1.87" description="March 29, 2026">
  * Fixed messages in Cowork Dispatch not getting delivered
</Update>

<Update label="2.1.86" description="March 27, 2026">
  * 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
  * 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
  * 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
  * Improved prompt cache hit rate for Bedrock, Vertex, and Foundry users by removing dynamic content from tool descriptions
  * 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")
  * \[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)
  * Read tool now uses compact line-number format and deduplicates unchanged re-reads, reducing token usage
</Update>

<Update label="2.1.85" description="March 26, 2026">
  * 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
  * 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`
  * 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
  * 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
  * Reduced UI stutter when compaction triggers on large sessions
</Update>

<Update label="2.1.84" description="March 26, 2026">
  * Added PowerShell tool for Windows as an opt-in preview. Learn more at [https://code.claude.com/docs/en/tools-reference#powershell-tool](../04-API-Reference/tools-reference-claude-code-docs-d21fdcb4c5.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
  * 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
  * 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
  * 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
  * 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
  * \[VSCode] Added rate limit warning banner with usage percentage and reset time
  * Stats screenshot (Ctrl+S in /stats) now works in all builds and is 16× faster
</Update>

<Update label="2.1.83" description="March 25, 2026">
  * 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)
  * 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`
  * 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
  * 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`
  * 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
  * Added `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK` env var to disable the non-streaming fallback when streaming fails
  * 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
  * 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] Spinner now turns red with "Not responding" when the backend hasn't responded for 60 seconds
  * \[VSCode] Fixed session history not loading correctly when reopening a session via URL or after restart
  * \[VSCode] Added Esc-twice (or `/rewind`) to open a keyboard-navigable rewind picker
  * \[VSCode] Fixed "Fork conversation from here" and rewind actions failing silently after the session cache goes stale
</Update>

<Update label="2.1.81" description="March 20, 2026">
  * 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
  * 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
  * Resuming a session that was in a worktree now switches back to that worktree
  * 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
  * 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
  * 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
  * \[VSCode] Fixed Windows PATH inheritance for Bash tool when using Git Bash (regression in v2.1.78)
</Update>

<Update label="2.1.80" description="March 19, 2026">
  * 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
  * 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
  * 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
  * 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)
  * 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
</Update>

<Update label="2.1.79" description="March 18, 2026">
  * Added `--console` flag to `claude auth login` for Anthropic Console (API billing) authentication
  * Added "Show turn duration" toggle to the `/config` menu
  * 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
  * 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
  * `CLAUDE_CODE_PLUGIN_SEED_DIR` now supports multiple seed directories separated by the platform path delimiter (`:` on Unix, `;` on Windows)
  * \[VSCode] Added `/remote-control` — bridge your session to claude.ai/code to continue from a browser or phone
  * \[VSCode] Session tabs now get AI-generated titles based on your first message
  * \[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
</Update>

<Update label="2.1.78" description="March 17, 2026">
  * 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
  * 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
  * 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
  * 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
  * Fixed `ANTHROPIC_BETAS` environment variable being silently ignored when using Haiku models
  * Fixed queued prompts being concatenated without a newline separator
  * Improved memory usage and startup time when resuming large sessions
  * \[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
</Update>

<Update label="2.1.77" description="March 17, 2026">
  * 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
  * Added `allowRead` sandbox filesystem setting to re-allow read access within `denyRead` regions
  * `/copy` now accepts an optional index: `/copy N` copies the Nth-latest assistant response
  * 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
  * 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
  * 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
  * 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
  * Improved headless mode plugin installation to compose correctly with `CLAUDE_CODE_PLUGIN_SEED_DIR`
  * 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] Improved plan preview tab titles to use the plan's heading instead of "Claude's Plan"
  * \[VSCode] When option+click doesn't trigger native selection on macOS, the footer now points to the `macOptionClickForcesSelection` setting
</Update>

<Update label="2.1.76" description="March 14, 2026">
  * 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
  * 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
  * 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
  * Updated `--plugin-dir` to only accept one path to support subcommands — use repeated `--plugin-dir` for multiple directories
  * \[VSCode] Fixed gitignore patterns containing commas silently excluding entire filetypes from the @-mention file picker
</Update>

<Update label="2.1.75" description="March 13, 2026">
  * 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
  * 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"
  * Improved startup performance on macOS non-MDM machines by skipping unnecessary subprocess spawns
  * 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`
</Update>

<Update label="2.1.74" description="March 12, 2026">
  * 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
  * 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
  * 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)
  * \[VSCode] Fixed delete button not working for Untitled sessions
  * \[VSCode] Improved scroll wheel responsiveness in the integrated terminal with terminal-aware acceleration
</Update>

<Update label="2.1.73" description="March 11, 2026">
  * 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`)
  * 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
  * 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
  * 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
  * VSCode: Fixed HTTP 400 errors for users behind proxies or on Bedrock/Vertex with Claude 4.5 models
</Update>

<Update label="2.1.72" description="March 10, 2026">
  * Fixed tool search to activate even with `ANTHROPIC_BASE_URL` as long as `ENABLE_TOOL_SEARCH` is set.
  * 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
  * 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
  * 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
  * 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
  * 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
  * Added support for marketplace git URLs without `.git` suffix (Azure DevOps, AWS CodeCommit)
  * Improved marketplace clone failure messages to show diagnostic info even when git produces no stderr
  * 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
  * Improved CPU utilization in long sessions
  * 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
  * 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
</Update>

<Update label="2.1.71" description="March 7, 2026">
  * 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
  * 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
  * 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.
  * 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
</Update>

<Update label="2.1.70" description="March 6, 2026">
  * 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
  * 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
  * 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.
  * \[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
</Update>

<Update label="2.1.69" description="March 5, 2026">
  * 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
  * 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)
  * 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)
  * 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] Added compaction display as a collapsible "Compacted chat" card with the summary inside
  * \[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
  * \[VSCode] Fixed RTL text (Arabic, Hebrew, Persian) rendering reversed in the chat panel (regression in v2.1.63)
</Update>

<Update label="2.1.68" description="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
</Update>

<Update label="2.1.66" description="March 4, 2026">
  * Reduced spurious error logging
</Update>

<Update label="2.1.63" description="February 28, 2026">
  * Added `/simplify` and `/batch` bundled slash commands
  * Fixed local slash command output like /cost appearing as user-sent messages instead of system messages in the UI
  * Project configs & auto memory now shared across git worktrees of the same repository
  * Added `ENABLE_CLAUDEAI_MCP_SERVERS=false` env var to opt out from making claude.ai MCP servers available
  * Improved `/model` command to show the currently active model in the slash command menu
  * Added HTTP hooks, which can POST JSON to a URL and receive JSON instead of running a shell command
  * Fixed listener leak in bridge polling loop
  * Fixed listener leak in MCP OAuth flow cleanup
  * 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.
  * 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
  * Improved memory usage in long sessions with subagents by stripping heavy progress message payloads during context compaction
  * 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
  * Fixed `/clear` not resetting cached skills, which could cause stale skill content to persist in the new conversation
</Update>

<Update label="2.1.62" description="February 27, 2026">
  * Fixed prompt suggestion cache regression that reduced cache hit rates
</Update>

<Update label="2.1.61" description="February 26, 2026">
  * Fixed concurrent writes corrupting config file on Windows
</Update>

<Update label="2.1.59" description="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
</Update>

<Update label="2.1.58" description="February 25, 2026">
  * Expand Remote Control to more users
</Update>

<Update label="2.1.56" description="February 25, 2026">
  * VS Code: Fixed another cause of "command 'claude-vscode.editor.openLast' not found" crashes
</Update>

<Update label="2.1.55" description="February 25, 2026">
  * Fixed BashTool failing on Windows with EINVAL error
</Update>

<Update label="2.1.53" description="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
</Update>

<Update label="2.1.52" description="February 24, 2026">
  * VS Code: Fixed extension crash on Windows ("command 'claude-vscode.editor.openLast' not found")
</Update>

<Update label="2.1.51" description="February 24, 2026">
  * Added `claude remote-control` subcommand for external builds, enabling local environment serving for all users.
  * Updated plugin marketplace default git timeout from 30s to 120s and added `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` to configure.
  * Added support for custom npm registries and specific version pinning when installing plugins from npm sources
  * 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`.
  * Fixed a security issue where `statusLine` and `fileSuggestion` hook commands could execute without workspace trust acceptance in interactive mode.
  * Tool results larger than 50K characters are now persisted to disk (previously 100K). This reduces context window usage and improves conversation longevity.
  * 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.
  * 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.
  * Fixed slash command autocomplete crashing when a plugin's SKILL.md description is a YAML array or other non-string type
  * 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](claude-code-settings-claude-code-docs-d4420b4b52.md#settings-files)
</Update>

<Update label="2.1.50" description="February 20, 2026">
  * 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.
  * 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
  * Added support for `isolation: worktree` in agent definitions, allowing agents to declaratively run in isolated git worktrees.
  * `CLAUDE_CODE_SIMPLE` mode now also disables MCP tools, attachments, hooks, and CLAUDE.md file loading for a fully minimal experience.
  * Fixed bug where MCP tools were not discovered when tool search is enabled and a prompt is passed in as a launch argument
  * Improved memory usage during long sessions by clearing internal caches after compaction
  * Added `claude agents` CLI command to list all configured agents
  * Improved memory usage during long sessions by clearing large tool results after they have been processed
  * 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
  * Improved startup performance for headless mode (`-p` flag) by deferring Yoga WASM and UI component imports
  * Fixed prompt suggestion cache regression that reduced cache hit rates
  * Fixed unbounded memory growth in long sessions by capping file history snapshots
  * Added `CLAUDE_CODE_DISABLE_1M_CONTEXT` environment variable to disable 1M context window support
  * Opus 4.6 (fast mode) now includes the full 1M context window
  * VSCode: Added `/extra-usage` command support in VS Code sessions
  * 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
</Update>

<Update label="2.1.49" description="February 19, 2026">
  * Improved MCP OAuth authentication with step-up auth support and discovery caching, reducing redundant network requests during server connections
  * Added `--worktree` (`-w`) flag to start Claude in an isolated git worktree
  * Subagents support `isolation: "worktree"` for working in a temporary git worktree
  * Added Ctrl+F keybinding to kill background agents (two-press confirmation)
  * Agent definitions support `background: true` to always run as a background task
  * Plugins can ship `settings.json` for default configuration
  * 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
  * 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.
  * 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
  * 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
  * Fixed unbounded memory growth during long-running sessions caused by Yoga WASM linear memory never shrinking
  * SDK model info now includes `supportsEffort`, `supportedEffortLevels`, and `supportsAdaptiveThinking` fields so consumers can discover model capabilities.
  * Added `ConfigChange` hook event that fires when configuration files change during a session, enabling enterprise security auditing and optional blocking of settings changes.
  * 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
  * 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.
  * 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
</Update>

<Update label="2.1.47" description="February 18, 2026">
  * 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.
  * 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.
  * 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)
  * 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.
  * Fixed an issue where bash tool output was silently discarded on Windows when using MSYS2 or Cygwin shells.
  * 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
  * 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)
  * Search patterns in collapsed tool results are now displayed in quotes for clarity
  * Windows: Fixed CWD tracking temp files never being cleaned up, causing them to accumulate indefinitely (anthropics/claude-code#17600)
  * 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.
  * 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.
  * Simplified teammate navigation to use only Shift+Down (with wrapping) instead of both Shift+Up and Shift+Down.
  * 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.
  * 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.
  * 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)
  * 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)
  * 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)
  * Increased initial session count in resume picker from 10 to 50 for faster session discovery (anthropics/claude-code#26123)
  * 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)
  * Moved config backup files from home directory root to `~/.claude/backups/` to reduce home directory clutter (anthropics/claude-code#26130)
  * 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)
  * The `/rename` command now updates the terminal tab title by default (anthropics/claude-code#25789)
  * 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.
</Update>

<Update label="2.1.46" description="February 18, 2026">
  * Fixed orphaned CC processes after terminal disconnect on macOS
  * Added support for using claude.ai MCP connectors in Claude Code
</Update>

<Update label="2.1.45" description="February 17, 2026">
  * 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
  * 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
  * 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
</Update>

<Update label="2.1.44" description="February 16, 2026">
  * Fixed ENAMETOOLONG errors for deeply-nested directory paths
  * Fixed auth refresh errors
</Update>

<Update label="2.1.43" description="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
</Update>

<Update label="2.1.42" description="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
</Update>

<Update label="2.1.41" description="February 13, 2026">
  * Added guard against launching Claude Code inside another Claude Code session
  * 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
  * Improved model error messages for Bedrock/Vertex/Foundry users with fallback suggestions
  * 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
  * 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 `/rename` to auto-generate session name from conversation context when called without arguments
  * Improved narrow terminal layout for prompt footer
  * 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
</Update>

<Update label="2.1.39" description="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
</Update>

<Update label="2.1.38" description="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
</Update>

<Update label="2.1.37" description="February 7, 2026">
  * Fixed an issue where /fast was not immediately available after enabling /extra-usage
</Update>

<Update label="2.1.36" description="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-847ef2d690.md)
</Update>

<Update label="2.1.34" description="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
</Update>

<Update label="2.1.33" description="February 6, 2026">
  * Fixed agent teammate sessions in tmux to send and receive messages
  * Fixed warnings about agent teams not being available on your current plan
  * 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
  * 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
  * Improved error messages for API connection failures — now shows specific cause (e.g., ECONNREFUSED, SSL errors) instead of generic "Connection error"
  * Errors from invalid managed settings are now surfaced
  * 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
  * VSCode: Fixed scroll-to-bottom under-scrolling on initial session load and session switch
</Update>

<Update label="2.1.32" description="February 5, 2026">
  * Claude Opus 4.6 is now available!
  * Added research preview agent teams feature for multi-agent collaboration (token-intensive feature, requires setting CLAUDE\_CODE\_EXPERIMENTAL\_AGENT\_TEAMS=1)
  * Claude now automatically records and recalls memories as it works
  * Added "Summarize from here" to the message selector, allowing partial conversation summarization.
  * Skills defined in `.claude/skills/` within additional directories (`--add-dir`) are now loaded automatically.
  * Fixed `@` file completion showing incorrect relative paths when running from a subdirectory
  * Updated --resume to re-use --agent value specified in previous conversation by default.
  * Fixed: Bash tool no longer throws "Bad substitution" errors when heredocs contain JavaScript template literals like `${index + 1}`, which previously interrupted tool execution
  * 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 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
  * VSCode: Added spinner when loading past conversations list
</Update>

<Update label="2.1.31" description="February 4, 2026">
  * 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
  * 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
  * 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)
  * 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
</Update>

<Update label="2.1.30" description="February 3, 2026">
  * 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
  * 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
  * 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
  * Changed `/model` to execute immediately instead of being queued
  * \[VSCode] Added multiline input support to the "Other" text input in question dialogs (use Shift+Enter for new lines)
  * \[VSCode] Fixed duplicate sessions appearing in the session list when starting a new conversation
</Update>

<Update label="2.1.29" description="January 31, 2026">
  * Fixed startup performance issues when resuming sessions that have `saved_hook_context`
</Update>

<Update label="2.1.27" description="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
</Update>

<Update label="2.1.25" description="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
</Update>

<Update label="2.1.23" description="January 29, 2026">
  * Added customizable spinner verbs setting (`spinnerVerbs`)
  * 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
  * Improved terminal rendering performance with optimized screen data layout
  * Changed Bash commands to show timeout duration alongside elapsed time
  * Changed merged pull requests to show a purple status indicator in the prompt footer
  * \[IDE] Fixed model options displaying incorrect region strings for Bedrock users in headless mode
</Update>

<Update label="2.1.22" description="January 28, 2026">
  * Fixed structured outputs for non-interactive (-p) mode
</Update>

<Update label="2.1.21" description="January 28, 2026">
  * Added support for full-width (zenkaku) number input from Japanese IME in option selection prompts
  * 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
  * 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)
  * \[VSCode] Added automatic Python virtual environment activation, ensuring `python` and `pip` commands use the correct interpreter (configurable via `claudeCode.usePythonEnvironment` setting)
  * \[VSCode] Fixed message action buttons having incorrect background colors
</Update>

<Update label="2.1.20" description="January 27, 2026">
  * 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
  * 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
  * 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
  * 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
</Update>

<Update label="2.1.19" description="January 23, 2026">
  * 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
  * 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
  * 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)
  * \[SDK] Added replay of `queued_command` attachment messages as `SDKUserMessageReplay` events when `replayUserMessages` is enabled
  * \[VSCode] Enabled session forking and rewind functionality for all users
</Update>

<Update label="2.1.18" description="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](customize-keyboard-shortcuts-claude-code-docs-f23eb8cfd3.md)
</Update>

<Update label="2.1.17" description="January 22, 2026">
  * Fixed crashes on processors without AVX instruction support
</Update>

<Update label="2.1.16" description="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
</Update>

<Update label="2.1.15" description="January 21, 2026">
  * Added deprecation notification for npm installations - run `claude install` or see [https://docs.anthropic.com/en/docs/claude-code/getting-started](https://docs.anthropic.com/en/docs/claude-code/getting-started) 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
</Update>

<Update label="2.1.14" description="January 20, 2026">
  * 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
  * 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
  * Improved backspace to delete pasted text as a single token instead of one character at a time
  * \[VSCode] Added `/usage` command to display current plan usage
</Update>

<Update label="2.1.12" description="January 17, 2026">
  * Fixed message rendering bug
</Update>

<Update label="2.1.11" description="January 17, 2026">
  * Fixed excessive MCP connection requests for HTTP/SSE transports
</Update>

<Update label="2.1.10" description="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
</Update>

<Update label="2.1.9" description="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)
</Update>

<Update label="2.1.7" description="January 14, 2026">
  * 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
  * 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
  * Improved typing responsiveness by reducing memory allocation overhead in terminal rendering
  * 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
  * \[VSCode] Fixed `claudeProcessWrapper` setting passing the wrapper path instead of the Claude binary path
</Update>

<Update label="2.1.6" description="January 13, 2026">
  * 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
  * 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`
  * 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
  * 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
  * \[VSCode] Fixed usage indicator not updating after manual compact
</Update>

<Update label="2.1.5" description="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
</Update>

<Update label="2.1.4" description="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
</Update>

<Update label="2.1.3" description="January 9, 2026">
  * Merged slash commands and skills, simplifying the mental model with no change in behavior
  * 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
  * 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
  * Improved terminal rendering stability by preventing uncontrolled writes from corrupting cursor state
  * Improved slash command suggestion readability by truncating long descriptions to 2 lines
  * Changed tool hook execution timeout from 60 seconds to 10 minutes
  * \[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)
</Update>

<Update label="2.1.2" description="January 9, 2026">
  * 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
  * 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
  * 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
  * 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
  * \[VSCode] Fixed usage display not updating after manual compact
</Update>

<Update label="2.1.0" description="January 7, 2026">
  * 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")
  * Changed Shift+Enter to work out of the box in iTerm2, WezTerm, Ghostty, and Kitty without modifying terminal configs
  * 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
  * 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
  * Reduced permission prompts for complex bash commands
  * 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
  * Improved CLI help output to display options and subcommands in alphabetical order for easier navigation
  * 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
  * 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
  * Multiple optimizations to improve startup performance
  * 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
  * 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
  * \[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")
  * \[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
</Update>

<Update label="2.0.76" description="January 7, 2026">
  * Fixed issue with macOS code-sign warning when using Claude in Chrome integration
</Update>

<Update label="2.0.75" description="January 7, 2026">
  * Minor bugfixes
</Update>

<Update label="2.0.74" description="December 19, 2025">
  * 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
  * 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'
  * Improved `/context` command visualization with grouped skills and agents by source, slash commands, and sorted token count
  * \[Windows] Fixed issue with improper rendering
  * \[VSCode] Added gift tag pictogram for year-end promotion message
</Update>

<Update label="2.0.73" description="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)
</Update>

<Update label="2.0.72" description="December 17, 2025">
  * 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
  * Reduced terminal flickering
  * Added scannable QR code to mobile app tip for quick app downloads
  * Added loading indicator when resuming conversations for better feedback
  * Fixed `/context` command not respecting custom system prompts in non-interactive mode
  * Fixed order of consecutive Ctrl+K lines when pasting with Ctrl+Y
  * 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
  * Changed thinking toggle from Tab to Alt+T to avoid accidental triggers
</Update>

<Update label="2.0.71" description="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
</Update>

<Update label="2.0.70" description="December 15, 2025">
  * 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
  * 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
  * Improved memory usage by 3x for large conversations
  * Improved resolution of stats screenshots copied to clipboard (Ctrl+S) for crisper images
  * Removed # shortcut for quick memory entry (tell Claude to edit your CLAUDE.md instead)
  * Fix thinking mode toggle in /config not persisting correctly
  * Improve UI for file creation permission dialog
</Update>

<Update label="2.0.69" description="December 13, 2025">
  * Minor bugfixes
</Update>

<Update label="2.0.68" description="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.
</Update>

<Update label="2.0.67" description="December 12, 2025">
  * Thinking mode is now enabled by default for Opus 4.5
  * Thinking mode configuration has moved to /config
  * Added search functionality to `/permissions` command with `/` keyboard shortcut for filtering rules by tool name
  * Show reason why autoupdater is disabled in `/doctor`
  * 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
</Update>

<Update label="2.0.65" description="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
</Update>

<Update label="2.0.64" description="December 10, 2025">
  * 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
  * 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](how-claude-remembers-your-project-claude-code-docs-f1c064262d.md) for details.
  * Added image dimension metadata when images are resized, enabling accurate coordinate mappings for large images
  * Fixed auto-loading .env when using native installer
  * Fixed `--system-prompt` being ignored when using `--continue` or `--resume` flags
  * Improved `/resume` screen with grouped forked sessions and keyboard shortcuts for preview (P) and rename (R)
  * VSCode: Added copy-to-clipboard button on code blocks and bash tool inputs
  * VSCode: Fixed extension not working on Windows ARM64 by falling back to x64 binary via emulation
  * Bedrock: Improve efficiency of token counting
  * Bedrock: Add support for `aws login` AWS Management Console credentials
  * Unshipped AgentOutputTool and BashOutputTool, in favor of a new unified TaskOutputTool
</Update>

<Update label="2.0.62" description="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
</Update>

<Update label="2.0.61" description="December 7, 2025">
  * Reverted VSCode support for multiple terminal clients due to responsiveness issues.
</Update>

<Update label="2.0.60" description="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
</Update>

<Update label="2.0.59" description="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
</Update>

<Update label="2.0.58" description="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.
</Update>

<Update label="2.0.57" description="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
</Update>

<Update label="2.0.56" description="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.
</Update>

<Update label="2.0.55" description="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
</Update>

<Update label="2.0.54" description="November 26, 2025">
  * Hooks: Enable PermissionRequest hooks to process 'always allow' suggestions and apply permission updates
  * Fix issue with excessive iTerm notifications
</Update>

<Update label="2.0.52" description="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
</Update>

<Update label="2.0.51" description="November 24, 2025">
  * Added Opus 4.5! [https://www.anthropic.com/news/claude-opus-4-5](https://www.anthropic.com/news/claude-opus-4-5)
  * 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
</Update>

<Update label="2.0.50" description="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
</Update>

<Update label="2.0.49" description="November 21, 2025">
  * Added readline-style ctrl-y for pasting deleted text
  * Improved clarity of usage limit warning message
  * Fixed handling of subagent permissions
</Update>

<Update label="2.0.47" description="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`
</Update>

<Update label="2.0.46" description="November 19, 2025">
  * Fixed image files being reported with incorrect media type when format cannot be detected from metadata
</Update>

<Update label="2.0.45" description="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 `&`
</Update>

<Update label="2.0.43" description="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`
</Update>

<Update label="2.0.42" description="November 15, 2025">
  * Added `agent_id` and `agent_transcript_path` fields to `SubagentStop` hooks.
</Update>

<Update label="2.0.41" description="November 14, 2025">
  * Added `model` parameter to prompt-based stop hooks, allowing users to specify a custom model for hook evaluation
  * 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
  * 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
  * Plugins: Added support for sharing and installing output styles
  * Teleporting a session from web will automatically set the upstream branch
</Update>

<Update label="2.0.37" description="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
</Update>

<Update label="2.0.36" description="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
</Update>

<Update label="2.0.35" description="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)
</Update>

<Update label="2.0.34" description="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)
</Update>

<Update label="2.0.33" description="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
</Update>

<Update label="2.0.32" description="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
</Update>

<Update label="2.0.31" description="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
</Update>

<Update label="2.0.30" description="October 30, 2025">
  * 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)
  * 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
  * 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
  * VSCode: Restored selection indicator in input footer showing current file or code selection status
</Update>

<Update label="2.0.28" description="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
</Update>

<Update label="2.0.27" description="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
</Update>

<Update label="2.0.25" description="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)
</Update>

<Update label="2.0.24" description="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
</Update>

<Update label="2.0.22" description="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
</Update>

<Update label="2.0.21" description="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
</Update>

<Update label="2.0.20" description="October 16, 2025">
  * Added support for Claude Skills
</Update>

<Update label="2.0.19" description="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
</Update>

<Update label="2.0.17" description="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
</Update>

<Update label="2.0.15" description="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
</Update>

<Update label="2.0.14" description="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
</Update>

<Update label="2.0.13" description="October 9, 2025">
  * Fixed `/plugin` not working on native build
</Update>

<Update label="2.0.12" description="October 9, 2025">
  * **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/create-plugins-claude-code-docs.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
</Update>

<Update label="2.0.11" description="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
</Update>

<Update label="2.0.10" description="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
</Update>

<Update label="2.0.9" description="October 6, 2025">
  * Fix regression where bash backgrounding stopped working
</Update>

<Update label="2.0.8" description="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)
</Update>

<Update label="2.0.5" description="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
</Update>

<Update label="2.0.1" description="September 30, 2025">
  * Skip Sonnet 4.5 default model setting change for Bedrock and Vertex
  * Various bug fixes and presentation improvements
</Update>

<Update label="2.0.0" description="September 29, 2025">
  * New native VS Code extension
  * 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
  * Add subagents dynamically with `--agents` flag
</Update>

<Update label="1.0.126" description="September 26, 2025">
  * Enable /context command for Bedrock and Vertex
  * Add mTLS support for HTTP-based OpenTelemetry exporters
</Update>

<Update label="1.0.124" description="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
</Update>

<Update label="1.0.123" description="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
</Update>

<Update label="1.0.120" description="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
</Update>

<Update label="1.0.119" description="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
</Update>

<Update label="1.0.117" description="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
</Update>

<Update label="1.0.115" description="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
</Update>

<Update label="1.0.113" description="September 13, 2025">
  * Deprecated piped input in interactive mode
  * Move Ctrl+R keybinding for toggling transcript to Ctrl+O
</Update>

<Update label="1.0.112" description="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
</Update>

<Update label="1.0.111" description="September 10, 2025">
  * /model now validates provided model names
  * Fixed Bash tool crashes caused by malformed shell syntax parsing
</Update>

<Update label="1.0.110" description="September 10, 2025">
  * /terminal-setup command now supports WezTerm
  * MCP: OAuth tokens now proactively refresh before expiration
  * Fixed reliability issues with background Bash processes
</Update>

<Update label="1.0.109" description="September 9, 2025">
  * SDK: Added partial message streaming support via `--include-partial-messages` CLI flag
</Update>

<Update label="1.0.106" description="September 5, 2025">
  * Windows: Fixed path permission matching to consistently use POSIX format (e.g., `Read(//c/Users/...)`)
</Update>

<Update label="1.0.97" description="August 29, 2025">
  * Settings: /doctor now validates permission rule syntax and suggests corrections
</Update>

<Update label="1.0.94" description="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
</Update>

<Update label="1.0.93" description="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
</Update>

<Update label="1.0.90" description="August 25, 2025">
  * Settings file changes take effect immediately - no restart required
</Update>

<Update label="1.0.88" description="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
</Update>

<Update label="1.0.86" description="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
</Update>

<Update label="1.0.85" description="August 19, 2025">
  * Status line input now includes session cost info
  * Hooks: Introduced SessionEnd hook
</Update>

<Update label="1.0.84" description="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
</Update>

<Update label="1.0.83" description="August 18, 2025">
  * @-mention: Support files with spaces in path
  * New shimmering spinner
</Update>

<Update label="1.0.82" description="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
</Update>

<Update label="1.0.81" description="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-claude-code-docs-c315eeed32.md)
  * Agents: Fix custom agent loading when agent files are unparsable
</Update>

<Update label="1.0.80" description="August 14, 2025">
  * UI improvements: Fix text contrast for custom subagent colors and spinner rendering issues
</Update>

<Update label="1.0.77" description="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
</Update>

<Update label="1.0.73" description="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)
</Update>

<Update label="1.0.72" description="August 11, 2025">
  * Ask permissions: have Claude Code always ask for confirmation to use specific tools with /permissions
</Update>

<Update label="1.0.71" description="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
</Update>

<Update label="1.0.70" description="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
</Update>

<Update label="1.0.69" description="August 5, 2025">
  * Upgraded Opus to version 4.1
</Update>

<Update label="1.0.68" description="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
</Update>

<Update label="1.0.65" description="July 31, 2025">
  * IDE: Fixed connection stability issues and error handling for diagnostics
  * Windows: Fixed shell environment setup for users without .bashrc files
</Update>

<Update label="1.0.64" description="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
</Update>

<Update label="1.0.63" description="July 29, 2025">
  * Windows: Fixed file search, @agent mentions, and custom slash commands functionality
</Update>

<Update label="1.0.62" description="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
</Update>

<Update label="1.0.61" description="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
</Update>

<Update label="1.0.60" description="July 24, 2025">
  * You can now create custom subagents for specialized tasks! Run /agents to get started
</Update>

<Update label="1.0.59" description="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
</Update>

<Update label="1.0.58" description="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
</Update>

<Update label="1.0.57" description="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
</Update>

<Update label="1.0.56" description="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
</Update>

<Update label="1.0.55" description="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
</Update>

<Update label="1.0.54" description="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
</Update>

<Update label="1.0.53" description="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).
</Update>

<Update label="1.0.52" description="July 18, 2025">
  * Added support for MCP server instructions
</Update>

<Update label="1.0.51" description="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
</Update>

<Update label="1.0.48" description="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
</Update>

<Update label="1.0.45" description="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.
</Update>

<Update label="1.0.44" description="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.
</Update>

<Update label="1.0.43" description="July 3, 2025">
  * Fixed a bug where the theme selector was saving excessively
  * Hooks: Added EPIPE system error handling
</Update>

<Update label="1.0.42" description="July 3, 2025">
  * Added tilde (`~`) expansion support to `/add-dir` command
</Update>

<Update label="1.0.41" description="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
</Update>

<Update label="1.0.40" description="July 3, 2025">
  * Fixed a bug causing API connection errors with UNABLE\_TO\_GET\_ISSUER\_CERT\_LOCALLY if `NODE_EXTRA_CA_CERTS` was set
</Update>

<Update label="1.0.39" description="July 3, 2025">
  * New Active Time metric in OpenTelemetry logging
</Update>

<Update label="1.0.38" description="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-9168ed62a4.md)
</Update>

<Update label="1.0.37" description="June 30, 2025">
  * Remove ability to set `Proxy-Authorization` header via ANTHROPIC\_AUTH\_TOKEN or apiKeyHelper
</Update>

<Update label="1.0.36" description="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
</Update>

<Update label="1.0.35" description="June 25, 2025">
  * Added support for MCP OAuth Authorization Server discovery
</Update>

<Update label="1.0.34" description="June 24, 2025">
  * Fixed a memory leak causing a MaxListenersExceededWarning message to appear
</Update>

<Update label="1.0.33" description="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
</Update>

<Update label="1.0.32" description="June 24, 2025">
  * Updated loopback config for litellm
  * Added forceLoginMethod setting to bypass login selection screen
</Update>

<Update label="1.0.31" description="June 24, 2025">
  * Fixed a bug where \~/.claude.json would get reset when file contained invalid JSON
</Update>

<Update label="1.0.30" description="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
</Update>

<Update label="1.0.29" description="June 24, 2025">
  * Improved CJK character support in cursor navigation and rendering
</Update>

<Update label="1.0.28" description="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
</Update>

<Update label="1.0.27" description="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
</Update>

<Update label="1.0.25" description="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
</Update>

<Update label="1.0.24" description="June 16, 2025">
  * Improved /mcp output
  * Fixed a bug where settings arrays got overwritten instead of merged
</Update>

<Update label="1.0.23" description="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
</Update>

<Update label="1.0.22" description="June 12, 2025">
  * SDK: Renamed `total_cost` to `total_cost_usd`
</Update>

<Update label="1.0.21" description="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
</Update>

<Update label="1.0.18" description="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
</Update>

<Update label="1.0.17" description="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"
</Update>

<Update label="1.0.11" description="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
</Update>

<Update label="1.0.10" description="June 4, 2025">
  * Added markdown table support
  * Improved streaming performance
</Update>

<Update label="1.0.8" description="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
</Update>

<Update label="1.0.7" description="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
</Update>

<Update label="1.0.6" description="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
</Update>

<Update label="1.0.4" description="May 28, 2025">
  * Fixed a bug where MCP tool errors weren't being parsed correctly
</Update>

<Update label="1.0.1" description="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
</Update>

<Update label="1.0.0" description="May 22, 2025">
  * Claude Code is now generally available
  * Introducing Sonnet 4 and Opus 4 models
</Update>

<Update label="0.2.125" description="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
</Update>

<Update label="0.2.117" description="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
</Update>

<Update label="0.2.108" description="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
</Update>

<Update label="0.2.107" description="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
</Update>

<Update label="0.2.106" description="May 9, 2025">
  * MCP SSE server configs can now specify custom headers
  * Fixed a bug where MCP permission prompt didn't always show correctly
</Update>

<Update label="0.2.105" description="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
</Update>

<Update label="0.2.102" description="May 5, 2025">
  * Improved thinking triggering reliability
  * Improved @mention reliability for images and folders
  * You can now paste multiple large chunks into one prompt
</Update>

<Update label="0.2.100" description="May 2, 2025">
  * Fixed a crash caused by a stack overflow error
  * Made db storage optional; missing db support disables --continue and --resume
</Update>

<Update label="0.2.98" description="May 1, 2025">
  * Fixed an issue where auto-compact was running twice
</Update>

<Update label="0.2.96" description="May 1, 2025">
  * Claude Code can now also be used with a Claude Max subscription ([https://claude.ai/upgrade](https://claude.ai/upgrade))
</Update>

<Update label="0.2.93" description="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
</Update>

<Update label="0.2.82" description="April 25, 2025">
  * Added support for --disallowedTools
  * Renamed tools for consistency: LSTool -> LS, View -> Read, etc.
</Update>

<Update label="0.2.75" description="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
</Update>

<Update label="0.2.74" description="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
</Update>

<Update label="0.2.72" description="April 18, 2025">
  * Updated spinner to indicate tokens loaded and tool usage
</Update>

<Update label="0.2.70" description="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
</Update>

<Update label="0.2.69" description="April 17, 2025">
  * Fixed UI glitches with improved Select component behavior
  * Enhanced terminal output display with better text truncation logic
</Update>

<Update label="0.2.67" description="April 17, 2025">
  * Shared project permission rules can be saved in .claude/settings.json
</Update>

<Update label="0.2.66" description="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
</Update>

<Update label="0.2.63" description="April 17, 2025">
  * Fixed an issue where MCP tools were loaded twice, which caused tool call errors
</Update>

<Update label="0.2.61" description="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
</Update>

<Update label="0.2.59" description="April 2, 2025">
  * Copy+paste images directly into your prompt
  * Improved progress indicators for bash and fetch tools
  * Bugfixes for non-interactive mode (-p)
</Update>

<Update label="0.2.54" description="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
</Update>

<Update label="0.2.53" description="April 2, 2025">
  * New web fetch tool lets Claude view URLs that you paste in
  * Fixed a bug with JPEG detection
</Update>

<Update label="0.2.50" description="April 2, 2025">
  * New MCP "project" scope now allows you to add MCP servers to .mcp.json files and commit them to your repository
</Update>

<Update label="0.2.49" description="April 2, 2025">
  * Previous MCP server scopes have been renamed: previous "project" scope is now "local" and "global" scope is now "user"
</Update>

<Update label="0.2.47" description="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)
</Update>

<Update label="0.2.44" description="April 2, 2025">
  * Ask Claude to make a plan with thinking mode: just say 'think' or 'think harder' or even 'ultrathink'
</Update>

<Update label="0.2.41" description="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
</Update>

<Update label="0.2.37" description="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
</Update>

<Update label="0.2.36" description="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>`
</Update>

<Update label="0.2.34" description="April 2, 2025">
  * Vim bindings for text input - enable with /vim or /config
</Update>

<Update label="0.2.32" description="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
</Update>

<Update label="0.2.31" description="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
</Update>

<Update label="0.2.30" description="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
</Update>

<Update label="0.2.26" description="April 2, 2025">
  * New /approved-tools command for managing tool permissions
  * Word-level diff display for improved code readability
  * Fuzzy matching for slash commands
</Update>

<Update label="0.2.21" description="April 2, 2025">
  * Fuzzy matching for /commands
</Update>


---
## channels-00374ea787.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Push events into a running session with channels

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

<Note>
  Channels are in [research preview](#research-preview) and require Claude Code v2.1.80 or later. They require claude.ai login. Console and API key authentication is not supported. Team and Enterprise organizations must [explicitly enable them](#enterprise-controls).
</Note>

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.

This page covers:

* [Supported channels](#supported-channels): Telegram, Discord, and iMessage setup
* [Install and run a channel](#quickstart) with fakechat, a localhost demo
* [Who can push messages](#security): sender allowlists and how you pair
* [Enable channels for your organization](#enterprise-controls) on Team and Enterprise
* [How channels compare](#how-channels-compare) to web sessions, Slack, MCP, and Remote Control

To build your own channel, see the [Channels reference](channels-reference-claude-code-docs-67a0bbe41f.md).

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

<Tabs>
  <Tab title="Telegram">
    View the full [Telegram plugin source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/telegram).

    <Steps>
      <Step title="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.
      </Step>

      <Step title="Install the plugin">
        In Claude Code, run:

        ```
        /plugin install telegram@claude-plugins-official
        ```

        If Claude Code reports that the plugin is not found in any marketplace, your marketplace is either missing or outdated. Run `/plugin marketplace update claude-plugins-official` to refresh it, or `/plugin marketplace add anthropics/claude-plugins-official` if you haven't added it before. Then retry the install.

        After installing, run `/reload-plugins` to activate the plugin's configure command.
      </Step>

      <Step title="Configure your token">
        Run the configure command with the token from BotFather:

        ```
        /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.
      </Step>

      <Step title="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:

        ```bash theme={null}
        claude --channels plugin:telegram@claude-plugins-official
        ```
      </Step>

      <Step title="Pair your account">
        Open Telegram and send any message to your bot. The bot replies with a pairing code.

        <Note>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.</Note>

        Back in Claude Code, run:

        ```
        /telegram:access pair <code>
        ```

        Then lock down access so only your account can send messages:

        ```
        /telegram:access policy allowlist
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Discord">
    View the full [Discord plugin source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/discord).

    <Steps>
      <Step title="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.
      </Step>

      <Step title="Enable Message Content Intent">
        In your bot's settings, scroll to **Privileged Gateway Intents** and enable **Message Content Intent**.
      </Step>

      <Step title="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.
      </Step>

      <Step title="Install the plugin">
        In Claude Code, run:

        ```
        /plugin install discord@claude-plugins-official
        ```

        If Claude Code reports that the plugin is not found in any marketplace, your marketplace is either missing or outdated. Run `/plugin marketplace update claude-plugins-official` to refresh it, or `/plugin marketplace add anthropics/claude-plugins-official` if you haven't added it before. Then retry the install.

        After installing, run `/reload-plugins` to activate the plugin's configure command.
      </Step>

      <Step title="Configure your token">
        Run the configure command with the bot token you copied:

        ```
        /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.
      </Step>

      <Step title="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:

        ```bash theme={null}
        claude --channels plugin:discord@claude-plugins-official
        ```
      </Step>

      <Step title="Pair your account">
        DM your bot on Discord. The bot replies with a pairing code.

        <Note>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.</Note>

        Back in Claude Code, run:

        ```
        /discord:access pair <code>
        ```

        Then lock down access so only your account can send messages:

        ```
        /discord:access policy allowlist
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="iMessage">
    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.

    <Steps>
      <Step title="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`.
      </Step>

      <Step title="Install the plugin">
        In Claude Code, run:

        ```
        /plugin install imessage@claude-plugins-official
        ```

        If Claude Code reports that the plugin is not found in any marketplace, your marketplace is either missing or outdated. Run `/plugin marketplace update claude-plugins-official` to refresh it, or `/plugin marketplace add anthropics/claude-plugins-official` if you haven't added it before. Then retry the install.
      </Step>

      <Step title="Restart with channels enabled">
        Exit Claude Code and restart with the channel flag:

        ```bash theme={null}
        claude --channels plugin:imessage@claude-plugins-official
        ```
      </Step>

      <Step title="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.

        <Note>The first reply Claude sends triggers a macOS Automation prompt asking if your terminal can control Messages. Click **OK**.</Note>
      </Step>

      <Step title="Allow other senders">
        By default, only your own messages pass through. To let another contact reach Claude, add their handle:

        ```
        /imessage:access allow +15551234567
        ```

        Handles are phone numbers in `+country` format or Apple ID emails like `user@example.com`.
      </Step>
    </Steps>
  </Tab>
</Tabs>

You can also [build your own channel](channels-reference-claude-code-docs-67a0bbe41f.md) for systems that don't have a plugin yet.

## 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](/en/quickstart#step-1-install-claude-code) with a claude.ai account
* [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 users**: your organization admin must [enable channels](#enterprise-controls) in managed settings

<Steps>
  <Step title="Install the fakechat channel plugin">
    Start a Claude Code session and run the install command:

    ```text theme={null}
    /plugin install fakechat@claude-plugins-official
    ```

    If Claude Code reports that the plugin is not found in any marketplace, your marketplace is either missing or outdated. Run `/plugin marketplace update claude-plugins-official` to refresh it, or `/plugin marketplace add anthropics/claude-plugins-official` if you haven't added it before. Then retry the install.
  </Step>

  <Step title="Restart with the channel enabled">
    Exit Claude Code, then restart with `--channels` and pass the fakechat plugin you installed:

    ```bash theme={null}
    claude --channels plugin:fakechat@claude-plugins-official
    ```

    The fakechat server starts automatically.

    <Tip>
      You can pass several plugins to `--channels`, space-separated.
    </Tip>
  </Step>

  <Step title="Push a message in">
    Open the fakechat UI at [http://localhost:8787](http://localhost:8787) and type a message:

    ```text theme={null}
    hey, what's in my working directory?
    ```

    The message arrives in your Claude Code session as a `<channel source="fakechat">` event. Claude reads it, does the work, and calls fakechat's `reply` tool. The answer shows up in the chat UI.
  </Step>
</Steps>

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](/en/channels-reference#relay-permission-prompts) can forward these prompts to you so you can approve or deny remotely. For unattended use, the admin-gated unattended-mode option bypasses prompts entirely; only enable it in environments you trust.

## 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 on Team and Enterprise plans your organization controls availability with [`channelsEnabled`](#enterprise-controls).

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](/en/channels-reference#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

On Team and Enterprise plans, channels are off by default. Admins control availability through two [managed settings](claude-code-settings-claude-code-docs-d4420b4b52.md) that users cannot override:

| Setting                 | Purpose                                                                                                                                                                                                                                                     | When not configured            |
| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- |
| `channelsEnabled`       | Master switch. Must be `true` for any channel to deliver messages. Set via the [claude.ai Admin console](https://claude.ai/admin-settings/claude-code) toggle or directly in managed settings. Blocks all channels including the development flag when off. | Channels blocked               |
| `allowedChannelPlugins` | Which plugins can register once channels are enabled. Replaces the Anthropic-maintained list when set. Only applies when `channelsEnabled` is `true`.                                                                                                       | 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

Admins can enable channels from [**claude.ai → Admin settings → Claude Code → Channels**](https://claude.ai/admin-settings/claude-code), 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

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:

```json theme={null}
{
  "channelsEnabled": true,
  "allowedChannelPlugins": [
    { "marketplace": "claude-plugins-official", "plugin": "telegram" },
    { "marketplace": "claude-plugins-official", "plugin": "discord" },
    { "marketplace": "acme-corp-plugins", "plugin": "internal-alerts" }
  ]
}
```

When `allowedChannelPlugins` is set, it replaces the Anthropic allowlist entirely: only the listed plugins can register. Leave it unset to fall back to the default Anthropic allowlist. An empty array blocks all channel plugins from the allowlist, but `--dangerously-load-development-channels` can still bypass it 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.

## 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.

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, use `--dangerously-load-development-channels`. See [Test during the research preview](/en/channels-reference#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

Several Claude Code features connect to systems outside the terminal, each suited to a different kind of work:

| Feature                                              | What it does                                                          | Good for                                                  |
| ---------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------- |
| [Claude Code on the web](claude-code-on-the-web-69d53821d4.md) | Runs tasks in a fresh cloud sandbox, cloned from GitHub               | Delegating self-contained async work you check on later   |
| [Claude in Slack](../14-Connectors/claude-code-in-slack-claude-code-docs-c62a093e92.md)                         | Spawns a web session from an `@Claude` mention in a channel or thread | Starting tasks directly from team conversation context    |
| Standard [MCP server](../06-MCP-Tools/mcp-208e742686.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](continue-local-sessions-from-any-device-with-remote-control-claude-code-docs-c1c03fd914.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](/en/channels-reference#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

Once you have a channel running, explore these related features:

* [Build your own channel](channels-reference-claude-code-docs-67a0bbe41f.md) for systems that don't have plugins yet
* [Remote Control](continue-local-sessions-from-any-device-with-remote-control-claude-code-docs-c1c03fd914.md) to drive a local session from your phone instead of forwarding events into it
* [Scheduled tasks](run-prompts-on-a-schedule-claude-code-docs.md) to poll on a timer instead of reacting to pushed events


---
## channels-reference-claude-code-docs-67a0bbe41f.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](/docs/en/channels#research-preview). Team and Enterprise organizations must [explicitly enable them](/docs/en/channels#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](/docs/en/channels). 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) (Claude Code spawns your server as a subprocess)

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](/docs/en/channels#supported-channels). Use `--dangerously-load-development-channels` to test locally. See [Test during the research preview](#test-during-the-research-preview) for details.


[​](#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 examples later on this page 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': {} } },
    // added to Claude's system prompt 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 does three things in order:

- **Server configuration**: creates the MCP server with `claude/channel` in its capabilities, which is what tells Claude Code this is a channel. The [`instructions`](#server-options) string goes into Claude’s system prompt: 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): Claude Code spawns it as a subprocess.
- **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](/docs/en/channels#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. “Failed to connect” usually means a dependency or import error in your server file; check the debug log at `~/.claude/debug/<session-id>.txt` for the stderr trace.
- **`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](/docs/en/channels#research-preview) to register. The development flag bypasses the allowlist for specific entries after a confirmation prompt. This example shows both entry types:

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

The bypass is per-entry. Combining this flag with `--channels` doesn’t extend the bypass to the `--channels` entries. During the research preview, the approved allowlist is Anthropic-curated, so your channel 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`](https://modelcontextprotocol.io/docs/learn/server-concepts) constructor. The `instructions` and `capabilities.tools` fields are [standard MCP](https://modelcontextprotocol.io/docs/learn/server-concepts); `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` | Optional. Always `{}`. Declares 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. 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. Added to Claude’s system prompt. 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
    },
    // added to Claude's system prompt so it knows how to handle your events
    instructions: 'Messages arrive as <channel source="your-channel" ...>. Reply with the reply tool.',
  },
)
```

To push an event, call `mcp.notification()` with method `notifications/claude/channel`. The params are in the next section.


[​](#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: the user DMs the bot, the bot replies with a pairing code, the user approves it in their Claude Code session, and their platform ID is added. 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.


[​](#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 both fields before relaying them: they neutralize direction-override and invisible characters and quote and angle-bracket lookalikes, fold whitespace runs to a single space, and relay text whole up to 3,500 code points, applied per top-level field for `input_preview`, which also keeps the JSON’s own structural quotes. A longer value keeps its start and end visible around a counted `⋯ N code points elided ⋯` marker, so the end of a long command still reaches the approver. Earlier clients relay `description` raw and cut `input_preview` to 200 UTF-16 units with a trailing ellipsis. 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, the same as answering No in the local dialog. 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) } },
  })
}
```

Claude Code also keeps the local terminal dialog open, so you can answer in either place, and the first answer to arrive is applied. A remote reply that doesn’t exactly match the expected format fails in one of two ways, and in both cases the 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
```

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 lands 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](/docs/en/plugins) and publish it to a [marketplace](/docs/en/plugin-marketplaces). Users install it with `/plugin install`, then enable it per session with `--channels plugin:<name>@<marketplace>`. A channel published to your own marketplace still needs `--dangerously-load-development-channels` to run, since it isn’t on the [approved allowlist](/docs/en/channels#supported-channels). The default allowlist is the channel plugins in `claude-plugins-official`, which Anthropic curates at its discretion. The [in-app submission forms](/docs/en/plugins#submit-your-plugin-to-the-community-marketplace) add plugins to the community marketplace, which is not on the channel allowlist. 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`](/docs/en/channels#restrict-which-channel-plugins-can-run) list, which replaces the default Anthropic allowlist.


[​](#see-also)

See also

- [Channels](/docs/en/channels) to install and use Telegram, Discord, iMessage, or the fakechat demo, and to enable channels for a Team or Enterprise org
- [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](/docs/en/mcp) for the underlying protocol that channel servers implement
- [Plugins](/docs/en/plugins) to package your channel so users can install it with `/plugin install`


---
## channels-reference.md

# Channels reference

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.

> Channels are in research preview and require Claude Code v2.1.80 or later. They require claude.ai login. Console and API key authentication is not supported. Team and Enterprise organizations must explicitly enable them.

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 also 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 so you can approve or deny tool use remotely.

## Overview

A channel is an MCP server that runs on the same machine as Claude Code. Claude Code spawns it as a subprocess and communicates over stdio.

- **Chat platforms** (Telegram, Discord): your plugin runs locally and polls the platform's API for new messages
- **Webhooks** (CI, monitoring): your server listens on a local HTTP port. External systems POST to that port

## What you need

The only hard requirement is the `@modelcontextprotocol/sdk` package and a Node.js-compatible runtime (Bun, Node, or Deno).

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

## Example: build a webhook receiver

```ts
#!/usr/bin/env bun
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'

const mcp = new Server(
  { name: 'webhook', version: '0.0.1' },
  {
    capabilities: { experimental: { 'claude/channel': {} } },
    instructions: 'Events from the webhook channel arrive as <channel source="webhook" ...>. Read them and act, no reply expected.',
  },
)

await mcp.connect(new StdioServerTransport())

Bun.serve({
  port: 8788,
  hostname: '127.0.0.1',
  async fetch(req) {
    const body = await req.text()
    await mcp.notification({
      method: 'notifications/claude/channel',
      params: {
        content: body,
        meta: { path: new URL(req.url).pathname, method: req.method },
      },
    })
    return new Response('ok')
  },
})
```

Register in `.mcp.json`:

```json
{
  "mcpServers": {
    "webhook": { "command": "bun", "args": ["./webhook.ts"] }
  }
}
```

Test with the development flag:

```bash
claude --dangerously-load-development-channels server:webhook
```

Then from another terminal:

```bash
curl -X POST localhost:8788 -d "build failed on main: https://ci.example.com/run/1234"
```

## Server options

| Field                                                    | Type     | Description                                                     |
| :------------------------------------------------------- | :------- | :-------------------------------------------------------------- |
| `capabilities.experimental['claude/channel']`            | `object` | Required. Always `{}`. Registers the notification listener.     |
| `capabilities.experimental['claude/channel/permission']` | `object` | Optional. Declares channel can receive permission relay requests.|
| `capabilities.tools`                                     | `object` | Two-way only. Standard MCP tool capability.                     |
| `instructions`                                           | `string` | Added to Claude's system prompt.                                |

## Notification format

| Field     | Type                     | Description                                            |
| :-------- | :----------------------- | :----------------------------------------------------- |
| `content` | `string`                 | The event body, delivered as body of `<channel>` tag.  |
| `meta`    | `Record<string, string>` | Optional. Each entry becomes a tag attribute.          |

## Expose a reply tool

For two-way channels, expose a standard MCP tool:

1. Add `tools: {}` to capabilities
2. Register `ListToolsRequestSchema` and `CallToolRequestSchema` handlers
3. Update `instructions` to tell Claude when to call the tool

## Gate inbound messages

Check the sender against an allowlist before calling `mcp.notification()`:

```ts
const allowed = new Set(loadAllowlist())
if (!allowed.has(message.from.id)) {
  return  // drop silently
}
await mcp.notification({ ... })
```

Gate on the **sender's identity**, not the chat or room identity.

## Relay permission prompts

> Permission relay requires Claude Code v2.1.81 or later.

When Claude calls a tool that needs approval, a two-way channel can receive the same prompt and relay it remotely.

### Permission request fields

| Field           | Description                                              |
| --------------- | -------------------------------------------------------- |
| `request_id`    | Five lowercase letters (a-z without l)                   |
| `tool_name`     | Name of the tool Claude wants to use                     |
| `description`   | Human-readable summary of what the tool call does        |
| `input_preview` | Tool arguments as JSON, truncated to 200 characters      |

The verdict sends `notifications/claude/channel/permission` with `request_id` and `behavior` set to `'allow'` or `'deny'`.

### Add relay to a chat bridge

1. Declare `claude/channel/permission: {}` capability
2. Handle `notifications/claude/channel/permission_request` notifications
3. Check inbound for `yes <id>` / `no <id>` verdict pattern

## Package as a plugin

Wrap in a plugin and publish to a marketplace. Users install with `/plugin install`, then enable per session with `--channels plugin:<name>@<marketplace>`.

## See Also

- [Channels](channels.md) — Install and use Telegram, Discord, iMessage, or fakechat
- [Working channel implementations](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins)
- [MCP](../06-MCP-Tools/General/connect-claude-code-to-tools-via-mcp-claude-code-docs.md) — The underlying protocol
- [Plugins](../08-Plugins-Skills/create-plugins-claude-code-docs.md) — Package your channel for installation


---
## channels.md

# Push events into a running session with channels

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.

> Channels are in research preview and require Claude Code v2.1.80 or later. They require claude.ai login. Console and API key authentication is not supported. Team and Enterprise organizations must explicitly enable them.

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.

You install a channel as a plugin and configure it with your own credentials. Telegram, Discord, and iMessage are included in the research preview.

## Supported channels

Each supported channel is a plugin that requires [Bun](https://bun.sh).

### Telegram

1. **Create a Telegram bot**: Open BotFather in Telegram and send `/newbot`. Copy the token.
2. **Install the plugin**: `/plugin install telegram@claude-plugins-official`
3. **Configure your token**: `/telegram:configure <token>`
4. **Restart with channels enabled**: `claude --channels plugin:telegram@claude-plugins-official`
5. **Pair your account**: Send any message to your bot, get the pairing code, run `/telegram:access pair <code>`, then `/telegram:access policy allowlist`

### Discord

1. **Create a Discord bot**: Go to Discord Developer Portal, create application, enable Message Content Intent
2. **Invite the bot**: OAuth2 > URL Generator, select `bot` scope with View Channels, Send Messages, Read Message History permissions
3. **Install the plugin**: `/plugin install discord@claude-plugins-official`
4. **Configure your token**: `/discord:configure <token>`
5. **Restart with channels enabled**: `claude --channels plugin:discord@claude-plugins-official`
6. **Pair your account**: DM your bot, get pairing code, run `/discord:access pair <code>`

### iMessage

The iMessage channel reads your Messages database directly and sends replies through AppleScript. Requires macOS.

1. **Grant Full Disk Access** for your terminal
2. **Install the plugin**: `/plugin install imessage@claude-plugins-official`
3. **Restart with channels enabled**: `claude --channels plugin:imessage@claude-plugins-official`
4. **Text yourself**: Self-chat bypasses access control
5. **Allow other senders**: `/imessage:access allow +15551234567`

You can also build your own channel — see the Channels reference.

## Quickstart with fakechat

Fakechat is a demo channel that runs a chat UI on localhost:

1. Install: `/plugin install fakechat@claude-plugins-official`
2. Restart: `claude --channels plugin:fakechat@claude-plugins-official`
3. Open http://localhost:8787 and type a message

## 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. iMessage detects the user's own addresses automatically.

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 if the channel declares it. Anyone who can reply through the channel can approve or deny tool use in your session.

## Enterprise controls

On Team and Enterprise plans, channels are off by default. Admins control availability through two managed settings:

| Setting                 | Purpose                                                    | When not configured            |
| :---------------------- | :--------------------------------------------------------- | :----------------------------- |
| `channelsEnabled`       | Master switch. Must be `true` for any channel to deliver.  | Channels blocked               |
| `allowedChannelPlugins` | Which plugins can register once channels are enabled.      | Anthropic default list applies |

Pro and Max users without an organization skip these checks entirely.

### Enable channels for your organization

Admins can enable channels from **claude.ai → Admin settings → Claude Code → Channels**, or by setting `channelsEnabled` to `true` in managed settings.

### Restrict which channel plugins can run

```json
{
  "channelsEnabled": true,
  "allowedChannelPlugins": [
    { "marketplace": "claude-plugins-official", "plugin": "telegram" },
    { "marketplace": "claude-plugins-official", "plugin": "discord" },
    { "marketplace": "acme-corp-plugins", "plugin": "internal-alerts" }
  ]
}
```

## How channels compare

| Feature                | What it does                                                    | Good for                                              |
| :--------------------- | :-------------------------------------------------------------- | :---------------------------------------------------- |
| Claude Code on the web | Runs tasks in a fresh cloud sandbox                             | Delegating self-contained async work                  |
| Claude in Slack        | Spawns a web session from an `@Claude` mention                  | Starting tasks from team conversation                 |
| Standard MCP server    | Claude queries it during a task; nothing is pushed              | Giving Claude on-demand access to a system            |
| Remote Control         | You drive your local session from claude.ai or mobile           | Steering in-progress work from another device         |
| **Channels**           | Push events from non-Claude sources into your running session   | Reacting to CI failures, chat messages, webhooks      |

## See Also

- [Channels reference](channels-reference.md) — Build your own channel
- [Remote Control](remote-control.md)
- [Scheduled tasks](run-prompts-on-a-schedule-claude-code-docs.md)


---
## checkpointing-94f7cd24eb.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkpointing

> Track, rewind, and summarize Claude's edits and conversation to manage session state.

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

As you work with Claude, checkpointing automatically captures the state of your code before each edit. This safety net lets you pursue ambitious, wide-scale tasks knowing you can always return to a prior code state.

### Automatic tracking

Claude Code tracks all changes made by its file editing tools:

* Every user prompt creates a new checkpoint
* Checkpoints persist across sessions, so you can access them in resumed conversations
* Automatically cleaned up along with sessions after 30 days (configurable)

### Rewind and summarize

Press `Esc` twice (`Esc` + `Esc`) or use the `/rewind` command to open the rewind menu. A scrollable list shows each of your prompts from 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
* **Never mind**: return to the message list without making changes

After restoring the conversation or summarizing, the original prompt from the selected message is restored into the input field so you can re-send or edit it.

#### Restore vs. summarize

The three restore options revert state: they undo code changes, conversation history, or both. "Summarize from here" works differently:

* Messages before the selected message stay intact
* The selected message and all subsequent messages get replaced with a compact AI-generated summary
* No files on disk are changed
* The original messages are preserved in the session transcript, so Claude can reference the details if needed

This is similar to `/compact`, but targeted: instead of summarizing the entire conversation, you keep early context in full detail and only compress the parts that are using up space. You can type optional instructions to guide what the summary focuses on.

<Note>
  Summarize keeps you in the same session and compresses context. If you want to branch off and try a different approach while preserving the original session intact, use [fork](/en/how-claude-code-works#resume-or-fork-sessions) instead (`claude --continue --fork-session`).
</Note>

## 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

### Bash command changes not tracked

Checkpointing does not track files modified by bash commands. For example, if Claude Code runs:

```bash theme={null}
rm file.txt
mv old.txt new.txt
cp source.txt dest.txt
```

These file modifications cannot be undone through rewind. Only direct file edits made through Claude's file editing tools are 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.

### Not a replacement for version control

Checkpoints are designed for quick, session-level recovery. For permanent version history and collaboration:

* Continue using version control (ex. Git) for commits, branches, and long-term history
* Checkpoints complement but don't replace proper version control
* Think of checkpoints as "local undo" and Git as "permanent history"

## See also

* [Interactive mode](interactive-mode-c5c4efb32c.md) - Keyboard shortcuts and session controls
* [Commands](built-in-commands-claude-code-docs.md) - Accessing checkpoints using `/rewind`
* [CLI reference](cli-reference-7bb98e3312.md) - Command-line options


---
## checkpointing-claude-code-docs-49f31e05d8.md

## On this page

- [How checkpoints work](#how-checkpoints-work)
  - [Automatic tracking](#automatic-tracking)
  - [Rewind and summarize](#rewind-and-summarize)
  - [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)
  - [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 user prompt. This safety net lets you pursue ambitious, wide-scale tasks knowing you can always return to a prior code state.


[​](#automatic-tracking)

Automatic tracking

Claude Code tracks all changes made by its file editing tools:

- Every user prompt 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. Before v2.1.208, those superseded snapshot files stayed on disk until the session was cleaned up.
- Claude Code saves checkpoints with the conversation, so you can still run `/rewind` after you resume a session
- Claude Code deletes checkpoints along with sessions after 30 days; change the period with [`cleanupPeriodDays`](/docs/en/settings#available-settings)


[​](#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 each prompt 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.


[​](#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, and requires Claude Code v2.1.191 or later. On earlier versions, run `/resume` and pick the previous session from the list instead.


[​](#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`](/docs/en/sessions#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

Checkpointing does not track files modified by bash commands. For example, if Claude Code runs:

```python
rm file.txt
mv old.txt new.txt
cp source.txt dest.txt
```

These file modifications cannot be undone through rewind. Only direct file edits made through Claude’s file editing tools are tracked.


[​](#subagent-edits-not-restored)

Subagent edits not restored

Except for a [skill with `context: fork`](/docs/en/skills#run-skills-in-a-subagent) that runs in the foreground, edits a [subagent](/docs/en/sub-agents) applies land outside your session’s checkpoints, so rewinding doesn’t restore them, even though the subagent makes them with Claude’s file editing tools. This includes a background [`/code-review --fix`](/docs/en/code-review) run and any forked skill that runs in the background. Use git to revert those edits. The foreground fork edits your working tree during your own turn, so rewinding restores its edits as usual. A forked skill runs in the background by default; set `background: false` in its frontmatter to run it in the foreground, where the invoking turn waits for the result. Before v2.1.218, forked skills always ran in the foreground.


[​](#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.


[​](#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](/docs/en/errors#restored-the-code-but-skipped-files).

Before v2.1.216, `/rewind` wrote and deleted through links at tracked paths without a warning.


[​](#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 (ex. Git) for commits, branches, and long-term history
- Checkpoints complement but don’t replace proper version control
- Think of checkpoints as “local undo” and Git as “permanent history”


[​](#see-also)

See also

- [Interactive mode](/docs/en/interactive-mode) - Keyboard shortcuts and session controls
- [Commands](/docs/en/commands) - Accessing checkpoints using `/rewind`
- [CLI reference](/docs/en/cli-reference) - Command-line options


---
## checkpointing-claude-code-docs.md

# Checkpointing


Track, rewind, and summarize Claude’s edits and conversation to manage session state.


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

As you work with Claude, checkpointing automatically captures the state of your code before each edit. This safety net lets you pursue ambitious, wide-scale tasks knowing you can always return to a prior code state.


Automatic tracking

Claude Code tracks all changes made by its file editing tools:

- Every user prompt creates a new checkpoint
- Checkpoints persist across sessions, so you can access them in resumed conversations
- Automatically cleaned up along with sessions after 30 days (configurable)


Rewind and summarize

Press `Esc` twice (`Esc` + `Esc`) or use the `/rewind` command to open the rewind menu. A scrollable list shows each of your prompts from 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
- **Never mind**: return to the message list without making changes

After restoring the conversation or summarizing, the original prompt from the selected message is restored into the input field so you can re-send or edit it.


Restore vs. summarize

The three restore options revert state: they undo code changes, conversation history, or both. “Summarize from here” works differently:

- Messages before the selected message stay intact
- The selected message and all subsequent messages get replaced with a compact AI-generated summary
- No files on disk are changed
- The original messages are preserved in the session transcript, so Claude can reference the details if needed

This is similar to `/compact`, but targeted: instead of summarizing the entire conversation, you keep early context in full detail and only compress the parts that are using up space. You can type optional instructions to guide what the summary focuses on.

Summarize keeps you in the same session and compresses context. If you want to branch off and try a different approach while preserving the original session intact, use [fork](/docs/en/how-claude-code-works#resume-or-fork-sessions) instead (`claude --continue --fork-session`).


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


Bash command changes not tracked

Checkpointing does not track files modified by bash commands. For example, if Claude Code runs:

```python
rm file.txt
mv old.txt new.txt
cp source.txt dest.txt
```

These file modifications cannot be undone through rewind. Only direct file edits made through Claude’s file editing tools are 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.


Not a replacement for version control

Checkpoints are designed for quick, session-level recovery. For permanent version history and collaboration:

- Continue using version control (ex. Git) for commits, branches, and long-term history
- Checkpoints complement but don’t replace proper version control
- Think of checkpoints as “local undo” and Git as “permanent history”


See also

- [Interactive mode](/docs/en/interactive-mode) - Keyboard shortcuts and session controls
- [Commands](/docs/en/commands) - Accessing checkpoints using `/rewind`
- [CLI reference](/docs/en/cli-reference) - Command-line options


---
## checkpointing.md

> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkpointing

> Automatically track and rewind Claude's edits to quickly recover from unwanted changes.

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

As you work with Claude, checkpointing automatically captures the state of your code before each edit. This safety net lets you pursue ambitious, wide-scale tasks knowing you can always return to a prior code state.

### Automatic tracking

Claude Code tracks all changes made by its file editing tools:

* Every user prompt creates a new checkpoint
* Checkpoints persist across sessions, so you can access them in resumed conversations
* Automatically cleaned up along with sessions after 30 days (configurable)

### Rewinding changes

Press `Esc` twice (`Esc` + `Esc`) or use the `/rewind` command to open up the rewind menu. You can choose to restore:

* **Conversation only**: Rewind to a user message while keeping code changes
* **Code only**: Revert file changes while keeping the conversation
* **Both code and conversation**: Restore both to a prior point in the session

## 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

## Limitations

### Bash command changes not tracked

Checkpointing does not track files modified by bash commands. For example, if Claude Code runs:

```bash  theme={null}
rm file.txt
mv old.txt new.txt
cp source.txt dest.txt
```

These file modifications cannot be undone through rewind. Only direct file edits made through Claude's file editing tools are 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.

### Not a replacement for version control

Checkpoints are designed for quick, session-level recovery. For permanent version history and collaboration:

* Continue using version control (ex. Git) for commits, branches, and long-term history
* Checkpoints complement but don't replace proper version control
* Think of checkpoints as "local undo" and Git as "permanent history"

## See also

* [Interactive mode](interactive-mode-claude-code-docs.md) - Keyboard shortcuts and session controls
* [Built-in commands](/en/interactive-mode#built-in-commands) - Accessing checkpoints using `/rewind`
* [CLI reference](cli-reference-7bb98e3312.md) - Command-line options


---
## choose-a-permission-mode-claude-code-docs-c8a9703cc1.md

## On this page

- [Available modes](#available-modes)
- [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)
  - [What the classifier blocks by default](#what-the-classifier-blocks-by-default)
  - [Boundaries you state in conversation](#boundaries-you-state-in-conversation)
  - [When auto mode falls back](#when-auto-mode-falls-back)
- [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)
- [Protected paths](#protected-paths)
- [See also](#see-also)

Use Claude Code

# Choose a permission mode

Copy pageCopy page

Control whether Claude asks before editing files or running commands. Cycle modes with Shift+Tab in the CLI or use the mode selector in VS Code, Desktop, and claude.ai.

Copy pageCopy page

When Claude wants to edit a file, run a shell command, or make a network request, it pauses and asks you to approve the action. Permission modes control how often that pause happens. The mode you pick shapes the flow of a session: Manual mode has you review each action as it comes, while looser modes let Claude work in longer uninterrupted stretches and report back when done. Pick more oversight for sensitive work, or fewer interruptions when you trust the direction.


[​](#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.

| Mode                                                                | What runs without asking                                                                                  | Best for                                |
|:--------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------|:----------------------------------------|
| `default`                                                           | Reads only                                                                                                | Getting started, 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)       | Only pre-approved tools                                                                                   | 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"`. The Manual label and the `manual` alias require Claude Code v2.1.200 or later. The desktop app’s label doesn’t depend on your CLI version. Writes to [protected paths](#protected-paths) are never auto-approved except in `bypassPermissions` mode and in planning sessions with bypass permissions available, guarding repository state and Claude’s own configuration against accidental corruption. Modes set the baseline. Layer [permission rules](/docs/en/permissions#manage-permissions) on top to pre-approve or block specific tools. These controls apply in every mode, including `bypassPermissions`:

- deny rules and explicit ask rules, which apply to every tool but can’t block [`EndConversation`](/docs/en/tools-reference#endconversation-tool-behavior) while any other tool remains
- the [org `ask` setting on connector tools](/docs/en/mcp#organization-controls-on-connector-tools)
- the [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool) marker

Allow rules have no effect in `bypassPermissions` because everything else is already approved.


[​](#switch-permission-modes)

Switch permission modes

You can switch modes mid-session, at startup, or as a persistent default. The mode is set through these controls, not by asking Claude in chat. Select your interface below to see how to change it.

- CLI

- VS Code

- JetBrains

- Desktop

- Web and mobile

**During a session**: press `Shift+Tab` to cycle `default` → `acceptEdits` → `plan`. The status bar shows the active mode as `⏸ plan mode on`, `⏵⏵ accept edits on`, `⏵⏵ auto mode on`, `⏵⏵ don't ask on`, or `⏵⏵ bypass permissions on`. Manual mode, `default` in that cycle, shows a gray `⏸ manual mode on` badge. Before v2.1.203, the status bar showed no badge in Manual mode.Not every mode is in the default cycle:

- `auto`: appears when your account meets the [auto mode requirements](#eliminate-prompts-with-auto-mode); cycling to it switches 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 [settings](/docs/en/settings#permission-settings); the `--allow-` variant adds the 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`.**At startup**: pass the mode as a flag.

```python
claude --permission-mode plan
```

**As a default**: set `defaultMode` in a [settings file](/docs/en/settings#settings-files) such as `~/.claude/settings.json`:

```python
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}
```

The same `--permission-mode` flag works with `-p` for [non-interactive runs](/docs/en/headless).

**During a session**: click the mode indicator at the bottom of the prompt box.**As a default**: set `claudeCode.initialPermissionMode` in VS Code settings, or use the Claude Code extension settings panel.The mode indicator shows these labels, mapped to the mode each one applies:

| UI label           | Mode                |
|:-------------------|:--------------------|
| Manual             | `default`           |
| Edit automatically | `acceptEdits`       |
| Plan               | `plan`              |
| Auto               | `auto`              |
| Bypass permissions | `bypassPermissions` |

Before v2.1.205, the extension labeled `plan` as Plan mode and `auto` as Auto mode.Auto mode appears in the mode indicator when your account meets every requirement listed in the [auto mode section](#eliminate-prompts-with-auto-mode). The `claudeCode.initialPermissionMode` setting does not accept `auto`. To start in auto mode by default, set `defaultMode` in your [user settings](/docs/en/settings#settings-files) instead. Claude Code ignores `defaultMode: "auto"` in project and local settings.Bypass permissions requires the **Allow dangerously skip permissions** toggle in the extension settings before it appears in the mode indicator.See the [VS Code guide](/docs/en/vs-code) for extension-specific details.

The JetBrains plugin runs Claude Code in the IDE terminal, so switching modes works the same as in the CLI: press `Shift+Tab` to cycle, or pass `--permission-mode` when launching.

**During a session**: use the mode selector next to the send button. Not every mode appears in the selector:

- **Auto**: appears when your account meets the [auto mode requirements](#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

For desktop-specific details, see [Choose a permission mode](/docs/en/desktop#choose-a-permission-mode) in the Desktop guide.**As a default**: set `defaultMode` in [settings](/docs/en/settings#settings-files). The desktop app reads the same settings files as the CLI and applies the 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.This example sets Plan mode as the default for new local sessions:

```python
{
  "permissions": {
    "defaultMode": "plan"
  }
}
```

Use the mode dropdown next to the prompt box on [claude.ai/code](https://claude.ai/code) or in the mobile app. Permission prompts appear in claude.ai for approval. Which modes appear depends on where the session runs:

- **Cloud sessions** on [Claude Code on the web](/docs/en/claude-code-on-the-web): 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](/docs/en/remote-control) sessions** on your local machine: Manual, Accept edits, and Plan. You can’t select Auto or Bypass permissions from the app. The dropdown shows the mode the local session is in, including a mode set from the terminal, and updates when the mode changes in the app or in the terminal. The one exception is Bypass permissions: the session never reports that mode to claude.ai, so switching into it from the terminal doesn’t change what the dropdown shows. Before v2.1.202, sessions connected with `/remote-control` or `claude --remote-control` didn’t report their mode at all, so claude.ai and the mobile app could show a mode the session wasn’t in. The mismatch affected only the label: Claude Code generated permission prompts from the session’s actual mode, and they still appeared in the app for approval.

For Remote Control, the host must be signed in with your claude.ai account; API keys are not supported. You can also set the starting mode when launching the host:

```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`. Paths outside that scope, writes to [protected paths](#protected-paths), and all other Bash commands except the [built-in read-only set](/docs/en/permissions#read-only-commands) still prompt. When the [PowerShell tool](/docs/en/tools-reference#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. 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 sessions with [bypass permissions available](#skip-all-checks-with-bypasspermissions-mode), edits stay blocked until you approve the plan. When [auto mode](/docs/en/auto-mode-config) is available and the `useAutoModeDuringPlan` setting is on, which it is by default, the classifier reviews shell commands during planning instead of prompting you. Approved commands run, and rejected ones are blocked. Otherwise, commands outside the [built-in read-only set](/docs/en/permissions#read-only-commands) prompt for approval, including when the sandbox’s [auto-allow mode](/docs/en/sandboxing#sandbox-modes) is enabled. Sessions with [bypass permissions available](#skip-all-checks-with-bypasspermissions-mode) skip both paths; that section covers what still prompts there. In sessions without them, commands outside the read-only set prompted either way in v2.1.212 through v2.1.217. 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). When auto mode is unavailable, this option reads **Yes, auto-accept edits**. Sessions started with bypass permissions enabled show **Yes, and bypass permissions** instead.
- **Yes, manually approve edits**: approve and review each edit individually.
- **No, refine with Ultraplan on Claude Code on the web**: send the plan to [Ultraplan](/docs/en/ultraplan) for browser-based review.
- **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`](/docs/en/settings#available-settings) is enabled, the list gains a first option that approves the plan and clears the planning context. Accepting a plan also names the session from the plan content automatically, unless you’ve already set a name with `--name` or `/rename`.


[​](#set-plan-mode-as-the-default)

Set plan mode as the default

To make plan mode the default for a project, set `defaultMode` in `.claude/settings.json`:

```python
{
  "permissions": {
    "defaultMode": "plan"
  }
}
```


[​](#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](/docs/en/permissions#manage-permissions) still force a prompt. The classifier also decides removals targeting the filesystem root or home directory, such as `rm -rf /` and `rm -rf ~`, including when the removal sits inside command or process substitution. Before v2.1.218, the plain forms prompted for approval instead, and the substitution forms prompted in v2.1.208 through v2.1.217. 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 while keeping permission prompts, set the [Proactive output style](/docs/en/output-styles) 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](/docs/en/permissions#managed-settings).
- **Model**: on the Anthropic API and [Claude Platform on AWS](/docs/en/claude-platform-on-aws), Claude Opus 4.6 or later, Sonnet 4.6 or later, or [Fable 5](/docs/en/model-config#work-with-fable-5). On Amazon Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, and signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) sessions, only Claude Sonnet 5, Opus 4.7 or later, and Fable 5. Older models, including Sonnet 4.5, Opus 4.5, Haiku, and claude-3 models, are not supported on any provider.
- **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. In v2.1.158 through v2.1.206, auto mode was off on all of these providers except the Anthropic API and Claude Platform on AWS until you set `CLAUDE_CODE_ENABLE_AUTO_MODE=1`; v2.1.207 removed the requirement.

If Claude Code reports auto mode as unavailable, one of these requirements is unmet; this is not a transient outage. 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](/docs/en/errors#auto-mode-cannot-determine-the-safety-of-an-action) for the causes and what to do. If you set `defaultMode: "auto"` in [settings](/docs/en/settings#available-settings) and the session starts in `default` mode with no error, the setting is likely in `.claude/settings.json` or `.claude/settings.local.json`. Claude Code v2.1.142 and later ignore `auto` from those files so a repository cannot grant itself auto mode. Move it to `~/.claude/settings.json`.


[​](#enable-auto-mode-on-bedrock-agent-platform-or-foundry)

Auto mode on Bedrock, Agent Platform, or Foundry

On [Amazon Bedrock](/docs/en/amazon-bedrock), [Google Cloud’s Agent Platform](/docs/en/google-vertex-ai), [Microsoft Foundry](/docs/en/microsoft-foundry), and signed-in [Claude apps gateway](/docs/en/claude-apps-gateway) sessions, auto mode appears in the `Shift+Tab` cycle by default. Appearing in the cycle doesn’t change the mode a session starts in: sessions still start in your [`defaultMode`](/docs/en/settings#available-settings), which is Manual unless you change it. Only Claude Sonnet 5, Opus 4.7 or later, and Fable 5 are supported on these providers. To make auto mode the default starting mode, set `"permissions": {"defaultMode": "auto"}` in user or managed settings. The [`/doctor`](/docs/en/commands#all-commands) checkup proposes this user-settings default on these providers the same way it does on the Anthropic API. To prevent developers from using auto mode, set `disableAutoMode` to `"disable"` in [managed settings](/docs/en/permissions#managed-settings). This removes `auto` from the `Shift+Tab` cycle and rejects `--permission-mode auto` at startup. In v2.1.158 through v2.1.206, auto mode was off on these providers until you set `CLAUDE_CODE_ENABLE_AUTO_MODE=1`, and Claude Code ignored `defaultMode: "auto"` on these providers unless the variable was also set. The variable is still accepted for compatibility and has no effect from v2.1.207 onward.


[​](#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](/docs/en/auto-mode-config). Before v2.1.200, remotes added mid-session were also trusted. **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 hands 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 lands, whether or not that landing triggers the pipeline; clearing it requires naming the execution effect, not only the commit or push. Before v2.1.211, this check was scoped to the default branch instead: a push there was blocked when it carried sensitive content, changes concealed or misdescribed relative to what you asked for, content ported in from outside the repository, or routed around a review you asked for, and before v2.1.203 any direct push to the default branch was blocked
- `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

Claude Code v2.1.195 and later block more categories by default. Several depend on [environment](/docs/en/auto-mode-config#define-trusted-infrastructure) entries, such as sensitive remote targets and protected IaC scopes, that you can narrow to concrete names.

- 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](/docs/en/auto-mode-config#define-trusted-infrastructure), or copying data out of one. As of v2.1.198 this also blocks sending data from one to an audience the entry excludes
- Routing a package install around your internal package registry to a public registry. As of v2.1.198, this also applies when you’ve told Claude an internal registry or mirror exists in the conversation, not only when one is listed in your environment
- 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`. As of v2.1.198 this also covers 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](/docs/en/chrome) browser actions that could send page content, cookies, or credentials off-origin

Claude Code v2.1.198 and later also block these by default:

- 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. The PR, issue, and commit-message scoping requires Claude Code v2.1.200 or later. 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. That check requires Claude Code v2.1.203 or later
- 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

Claude Code v2.1.200 and later also block these by default:

- 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; both refinements require Claude Code v2.1.203 or later. Before v2.1.203, personal data was grouped with confidential material and blocked only when it wasn’t part of that repository’s own work. 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

Claude Code v2.1.203 and later also block these by default:

- 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

Claude Code v2.1.205 and later also block these by default:

- 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. A transcript is session state that Claude Code writes, not a working file, and a tampered entry reaches every later check once you resume the session, so auto mode blocks these writes as defense in depth. 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, or a glob rooted at one, that isn’t assigned anywhere in the conversation the classifier sees. 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 classifier reads the conversation rather than command output by design, so it blocks the call instead of guessing at the target. 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

**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. The push’s content is still checked against the other rules, [`permissions.deny` rules](/docs/en/permissions#manage-permissions) can still block pushes to specific branches outright in every mode, and the remote’s own branch protection still applies. Before v2.1.211, only pushes to the branch you started on, branches Claude created, and routine pushes to the default branch were allowed by default, and before v2.1.203 any direct push to the default branch was blocked

Claude Code v2.1.195 and later also allow these 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`](/docs/en/auto-mode-config#define-trusted-infrastructure). This covers data flow only, not destructive or credential operations on the same infrastructure
- [Claude in Chrome](/docs/en/chrome) navigation to a trusted internal domain, localhost, or a URL you named

Sandbox network access requests are routed through the classifier rather than allowed by default. As of v2.1.198, the classifier reuses its verdict for a network host and port instead of re-running on every connection:

- An allow is reused until new content enters the conversation, at which point that host is checked again
- In the interactive CLI, a deny is dropped when the turn ends
- In [non-interactive mode](/docs/en/headless) and Agent SDK sessions there is no turn boundary, so a deny is reused for the rest of the run
- Changing your permission mode or rules drops all cached verdicts

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](/docs/en/auto-mode-config). Pushing to any branch of the repository you’re working in and creating a pull request that matches your request run without a prompt, with the two exceptions the lists above cover: the classifier judges a push to a deploy-named branch such as `production` or `gh-pages` on its own terms, and still blocks a push whose content carries risk. To require a human checkpoint before these actions while staying in auto mode, add `permissions.ask` rules: see [Common boundaries](/docs/en/auto-mode-config#common-boundaries).


[​](#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](/docs/en/costs#reduce-token-usage) removes the message that stated it. For a hard guarantee, add a [deny rule](/docs/en/permissions#permission-rule-syntax) instead.


[​](#when-auto-mode-falls-back)

When auto mode falls back

Each denied action shows a notification and appears in `/permissions` under the Recently denied tab, where you can press `r` to retry it with a manual approval. 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. These thresholds are not configurable. Any allowed action resets the consecutive counter, while the total counter persists for the session and resets only when its own limit triggers a fallback. In [non-interactive mode](/docs/en/headless) with the `-p` flag, repeated blocks abort the session since there is no user to prompt. 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](/docs/en/auto-mode-config).

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](/docs/en/permissions#manage-permissions) resolve immediately. Writes to [protected paths](#protected-paths) route to the classifier even when an allow rule matches. Connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) and MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool) prompt you directly even when an allow rule matches. Content-scoped ask rules fall back to a permission prompt
2.  Read-only actions and file edits in your working directory are auto-approved, except writes to [protected paths](#protected-paths)
3.  Everything else goes to the classifier. A connector tool [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) skips the classifier and prompts you directly, so an org-required approval is never auto-approved. As of v2.1.199, an MCP tool marked with [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool) also skips the classifier and prompts you directly, so a consent step is never auto-approved on the tool author’s behalf
4.  If the classifier blocks, Claude receives the reason and tries an alternative. In most sessions the reason is the fixed text `Blocked by classifier` rather than a written explanation, in Claude Code v2.1.208 and later; see [Review denials](/docs/en/auto-mode-config#review-denials)

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

Narrow rules like `Bash(npm test)` carry over. Dropped rules are restored when you leave auto mode.The classifier sees user messages, tool calls, and your CLAUDE.md content. Tool results are stripped, so hostile content in a file or web page cannot manipulate it directly. 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](/docs/en/sub-agents) 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 classifier with the same rules as the parent session, and any `permissionMode` in the subagent’s frontmatter is ignored.
3.  When the subagent finishes, the classifier reviews its full action history; if that return check flags a concern, a security warning is prepended to the subagent’s results.

Step 1 requires Claude Code v2.1.178 or later. Earlier versions applied the classifier at steps 2 and 3, but did not evaluate the task description before the subagent started.

Cost and latency

The classifier runs on Claude Sonnet 5 by default rather than on your `/model` selection. A classifier model that Anthropic configures server-side takes precedence over that default. When your session’s model is Claude Sonnet 4.6, or when [`availableModels`](/docs/en/model-config#restrict-model-selection) excludes Sonnet 5, the classifier runs on the session’s model instead, or on an Opus model when the session runs on [Fable 5](/docs/en/model-config#work-with-fable-5); on providers other than the Anthropic API, that Opus fallback is the provider’s default Opus model.The session’s first auto-mode request validates the Sonnet 5 default: if the request succeeds, Sonnet 5 stays the session’s classifier model, and if it fails because the model isn’t available, the session uses the fallback instead. After that validation settles, the classifier’s model doesn’t change for the session.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.The classifier reuses a sandbox network verdict for a host and port, so repeated connections to the same host don’t each add a check. [What the classifier blocks by default](#what-the-classifier-blocks-by-default) describes how long an allow and a deny last.


[​](#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. Claude runs only actions matching your `permissions.allow` rules, [read-only Bash commands](/docs/en/permissions#read-only-commands), and calls approved by a [PreToolUse hook](/docs/en/permissions#extend-permissions-with-hooks). Use this mode for CI pipelines or restricted environments where you pre-define exactly what Claude may do; the session never waits for input. The status bar shows `⏵⏵ don't ask on` while this mode is active. Claude Code denies calls matching your explicit [`ask` rules](/docs/en/permissions#manage-permissions) rather than prompting. It also denies the built-in `AskUserQuestion` tool and connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), even if your allow rules match them. It denies MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool) the same way, because their approval card needs an answer this mode never collects; this requires Claude Code v2.1.199 or later. Cloud sessions on [Claude Code on the web](/docs/en/claude-code-on-the-web) 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). Before v2.1.126, protected-path writes still prompted in this mode. Explicit [ask rules](/docs/en/permissions#manage-permissions) and connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools) still force a prompt in this mode. MCP tools marked with [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool) also still prompt; this requires Claude Code v2.1.199 or later. Removals targeting the filesystem root or home directory, such as `rm -rf /` and `rm -rf ~`, still prompt as a circuit breaker against model error. The circuit breaker also fires when the command contains command substitution with `$(...)` or backticks, or process substitution with `<(...)`, whether the removal sits inside the substitution, as in `echo "$(rm -rf ~)"`, or elsewhere in the same command. The plain form, typed as its own command, has prompted in this mode since the circuit breaker was introduced; before v2.1.208, commands containing those forms didn’t prompt. In 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](/docs/en/permissions#manage-permissions) and the removal circuit breaker above still prompt.

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 that was started without it enabled. Enable it at launch with `permissions.defaultMode: "bypassPermissions"` in [settings](/docs/en/settings#permission-settings) or with an enabling flag:

```python
claude --permission-mode bypassPermissions
```

The `--dangerously-skip-permissions` flag is equivalent. 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. Claude Code saves your acceptance to user settings, so the dialog appears only once. If you decline, Claude Code exits. In [non-interactive mode](/docs/en/headless) no dialog is shown, and a [background session](/docs/en/agent-view) started with `--bg` is refused until you’ve accepted the dialog in an interactive session. On Linux and macOS, Claude Code refuses to start in this 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](/docs/en/devcontainer) configuration, which runs Claude Code as a non-root user. [Claude Code on the web](/docs/en/claude-code-on-the-web) does not honor `defaultMode: "bypassPermissions"` or `"dontAsk"` from your settings files, so a repository’s checked-in settings cannot start a cloud session in bypass-permissions mode. The setting is ignored silently and the session starts in the 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](/docs/en/permissions#managed-settings).


[​](#protected-paths)

Protected paths

Writes to a small set of paths are never auto-approved, except in `bypassPermissions` mode and in planning sessions 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`                   | Prompted. In sessions with [bypass permissions](#skip-all-checks-with-bypasspermissions-mode) available, allowed. Otherwise, with [auto mode](#eliminate-prompts-with-auto-mode) available during planning, routed to the classifier |
| `auto`                   | Routed to the classifier                                                                                                                                                                                                             |
| `dontAsk`                | Denied                                                                                                                                                                                                                               |
| `bypassPermissions`      | Allowed                                                                                                                                                                                                                              |

[`permissions.allow`](/docs/en/permissions#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 modes that prompt, the prompt for a `.claude/` write offers **Yes, and allow Claude to edit its own settings for this session**, which approves later `.claude/` writes in that session without prompting again. Protected directories:

- `.git`
- `.config/git`
- `.vscode`
- `.idea`
- `.husky`
- `.cargo`
- `.devcontainer`
- `.yarn`
- `.mvn`
- `.claude`, except for `.claude/worktrees` where Claude stores its own git worktrees

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`


[​](#see-also)

See also

- [Permissions](/docs/en/permissions): allow, ask, and deny rules; managed policies
- [Configure auto mode](/docs/en/auto-mode-config): tell the classifier which infrastructure your organization trusts
- [Hooks](/docs/en/hooks): custom permission logic via `PreToolUse` and `PermissionRequest` hooks
- [Ultraplan](/docs/en/ultraplan): run plan mode in a Claude Code on the web session with browser-based review
- [Security](/docs/en/security): safeguards and best practices
- [Sandboxing](/docs/en/sandboxing): filesystem and network isolation for Bash commands
- [Non-interactive mode](/docs/en/headless): run Claude Code with the `-p` flag


---
## choose-a-sandbox-environment-claude-code-docs-3f4c15772e.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)
- [Dev containers](#dev-containers)
- [Custom container](#custom-container)
- [Virtual machine](#virtual-machine)
- [Claude Code on the web](#claude-code-on-the-web)
- [Enforce isolation across an organization](#enforce-isolation-across-an-organization)
- [See also](#see-also)

Settings and permissions

# 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](/docs/en/security). For Agent SDK deployments, see [Secure deployment](/docs/en/agent-sdk/secure-deployment).


[​](#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 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                                                                                    |
| [Claude Code on the web](#claude-code-on-the-web) | Full operating system, hosted by Anthropic                                  | No              | None; requires a Claude subscription, and GitHub when you launch from the web interface |

The [sandboxed Bash tool](/docs/en/sandboxing) is built into Claude Code and restricts only 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](/docs/en/sandboxing#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](/docs/en/data-usage) 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](/docs/en/sandboxing), enabled with `/sandbox`                                                                                                                     |
| Let Claude work unattended with `--dangerously-skip-permissions` or auto mode | The preconfigured [dev container](/docs/en/devcontainer), 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 [Claude Code on the web](/docs/en/claude-code-on-the-web) if you have a Claude subscription; GitHub is only required when you launch from the web interface |
| Standardize a sandboxed environment across a team                             | The preconfigured [dev container](/docs/en/devcontainer), copied into your repository                                                                                                       |
| Use Claude Code from a device with no local setup                             | [Claude Code on the web](/docs/en/claude-code-on-the-web), 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](/docs/en/permission-modes) 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; you’re only prompted for explicit [ask rules](/docs/en/permissions#manage-permissions), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), MCP tools marked [`requiresUserInteraction`](/docs/en/mcp#require-approval-for-a-specific-tool), and removals targeting `/` or your home directory. 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. [Auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) replaces the prompt with a classifier that reviews actions and blocks ones that escalate beyond the request, target unrecognized infrastructure, or appear driven by hostile content Claude read. 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 Bash, 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](/docs/en/sandboxing#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 every Bash command Claude runs: Seatbelt, the built-in macOS sandbox, and [bubblewrap](https://github.com/containers/bubblewrap) on Linux and WSL2. By default it allows writes to the working directory and prompts the first time a command needs a new network domain. Enable it with the `/sandbox` command. The [Sandboxing](/docs/en/sandboxing) 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](/docs/en/tools-reference) such as Read, Edit, and WebFetch run inside the Claude Code process and do not spawn arbitrary code. [Permission rules](/docs/en/permissions) for path or domain gate them instead.
- [MCP](/docs/en/mcp) servers and hooks are separate processes that run unconstrained on the host.

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/anthropic-experimental/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 it constrains every tool, hook, and MCP server in the session, not only Bash. The runtime is a beta research preview, and its configuration format may change as the package evolves. The runtime denies all write and network access by default, so configure it before launching Claude Code through it. In `~/.srt-settings.json`, or a file you pass with `--settings`, allow write access to at least your project directory, Claude Code’s configuration paths `~/.claude` and `~/.claude.json`, and `/tmp`, where Claude Code writes runtime files. Allow the network domains your session needs, including `api.anthropic.com` or your configured provider’s endpoint. See the package [README](https://github.com/anthropic-experimental/sandbox-runtime) for the full configuration schema. Once the settings file is in place, launch Claude Code with `npx` and pass `claude` as the command to wrap:

```python
npx @anthropic-ai/sandbox-runtime claude
```

Claude Code starts inside the sandbox with the filesystem and network boundaries you configured. The same command works for sandboxing standalone MCP servers or other helper processes.


[​](#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](/docs/en/devcontainer) 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 the nested-sandbox setting described in [Sandboxing troubleshooting](/docs/en/sandboxing#troubleshooting).


[​](#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 Desktop’s [sandboxes feature](https://docs.docker.com/ai/sandboxes/) provides a microVM with its own Docker daemon and workspace sync, which can run Claude Code on hosts that already have Docker Desktop.


[​](#claude-code-on-the-web)

Claude Code on the web

[Claude Code on the web](/docs/en/claude-code-on-the-web) runs each session 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. 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. When you launch a session from the web interface, 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](/docs/en/claude-code-on-the-web#send-local-repositories-without-github) instead if GitHub isn’t connected. See [Claude Code on the web](/docs/en/claude-code-on-the-web) for plan availability and GitHub authentication options.


[​](#enforce-isolation-across-an-organization)

Enforce isolation across an organization

Individual developers can opt into any approach above. 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](/docs/en/settings#settings-files), either as a file managed by your MDM or through [server-managed settings](/docs/en/server-managed-settings) on Claude.ai. See [Enforce sandboxing with managed settings](/docs/en/sandboxing#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](/docs/en/devcontainer) 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 approaches above.

- [Sandboxing](/docs/en/sandboxing): configure the built-in sandboxed Bash tool
- [Dev container](/docs/en/devcontainer): the preconfigured Docker development container
- [Security](/docs/en/security): the full Claude Code security model
- [Secure deployment](/docs/en/agent-sdk/secure-deployment): isolation guidance for Agent SDK applications
- [Settings](/docs/en/settings#sandbox-settings): all sandbox configuration keys, including managed settings delivery


---
## chrome-8f9d762cc1.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Claude Code with Chrome (beta)

> Connect Claude Code to your Chrome browser to test web apps, debug with console logs, automate form filling, and extract data from web pages.

Claude Code integrates with the [Claude in Chrome browser extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) to give you browser automation capabilities from the CLI or the [VS Code extension](/en/vs-code#automate-browser-tasks-with-chrome). Build your code, then test and debug in the browser without switching contexts.

Claude opens new tabs for browser tasks and shares your browser's login state, so it can access any site you're already signed into. Browser actions run in a visible Chrome window in real time. When Claude encounters a login page or CAPTCHA, it pauses and asks you to handle it manually.

<Note>
  Chrome integration is in beta and currently works with Google Chrome and Microsoft Edge. It is not yet supported on Brave, Arc, or other Chromium-based browsers. WSL (Windows Subsystem for Linux) is also not supported.
</Note>

## Capabilities

With Chrome connected, you can chain browser actions with coding tasks in a single workflow:

* **Live debugging**: read console errors and DOM state directly, then fix the code that caused them
* **Design verification**: build a UI from a Figma mock, then open it in the browser to verify it matches
* **Web app testing**: test form validation, check for visual regressions, or verify user flows
* **Authenticated web apps**: interact with Google Docs, Gmail, Notion, or any app you're logged into without API connectors
* **Data extraction**: pull structured information from web pages and save it locally
* **Task automation**: automate repetitive browser tasks like data entry, form filling, or multi-site workflows
* **Session recording**: record browser interactions as GIFs to document or share what happened

## Prerequisites

Before using Claude Code with Chrome, you need:

* [Google Chrome](https://www.google.com/chrome/) or [Microsoft Edge](https://www.microsoft.com/edge) browser
* [Claude in Chrome extension](https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn) version 1.0.36 or higher, available in the Chrome Web Store for both browsers
* [Claude Code](/en/quickstart#step-1-install-claude-code) version 2.0.73 or higher
* A direct Anthropic plan (Pro, Max, Team, or Enterprise)

<Note>
  Chrome integration is not available through third-party providers like Amazon Bedrock, Google Cloud Vertex AI, or Microsoft Foundry. If you access Claude exclusively through a third-party provider, you need a separate claude.ai account to use this feature.
</Note>

## Get started in the CLI

<Steps>
  <Step title="Launch Claude Code with Chrome">
    Start Claude Code with the `--chrome` flag:

    ```bash theme={null}
    claude --chrome
    ```

    You can also enable Chrome from within an existing session by running `/chrome`.
  </Step>

  <Step title="Ask Claude to use the browser">
    This example navigates to a page, interacts with it, and reports what it finds, all from your terminal or editor:

    ```text theme={null}
    Go to code.claude.com/docs, click on the search box,
    type "hooks", and tell me what results appear
    ```
  </Step>
</Steps>

Run `/chrome` at any time to check the connection status, manage permissions, or reconnect the extension.

For VS Code, see [browser automation in VS Code](/en/vs-code#automate-browser-tasks-with-chrome).

### Enable Chrome by default

To avoid passing `--chrome` each session, run `/chrome` and select "Enabled by default".

In the [VS Code extension](/en/vs-code#automate-browser-tasks-with-chrome), Chrome is available whenever the Chrome extension is installed. No additional flag is needed.

<Note>
  Enabling Chrome by default in the CLI increases context usage since browser tools are always loaded. If you notice increased context consumption, disable this setting and use `--chrome` only when needed.
</Note>

### Manage site permissions

Site-level permissions are inherited from the Chrome extension. Manage permissions in the Chrome extension settings to control which sites Claude can browse, click, and type on.

## Example workflows

These examples show common ways to combine browser actions with coding tasks. Run `/mcp` and select `claude-in-chrome` to see the full list of available browser tools.

### Test a local web application

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

```text theme={null}
I just updated the login form validation. Can you open localhost:3000,
try submitting the form with invalid data, and check if the error
messages appear correctly?
```

Claude navigates to your local server, interacts with the form, and reports what it observes.

### Debug with console logs

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

```text theme={null}
Open the dashboard page and check the console for any errors when
the page loads.
```

Claude reads the console messages and can filter for specific patterns or error types.

### Automate form filling

Speed up repetitive data entry tasks:

```text theme={null}
I have a spreadsheet of customer contacts in contacts.csv. For each row,
go to the CRM at crm.example.com, click "Add Contact", and fill in the
name, email, and phone fields.
```

Claude reads your local file, navigates the web interface, and enters the data for each record.

### Draft content in Google Docs

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

```text theme={null}
Draft a project update based on the recent commits and add it to my
Google Doc at docs.google.com/document/d/abc123
```

Claude opens the document, clicks into the editor, and types the content. This works with any web app you're logged into: Gmail, Notion, Sheets, and more.

### Extract data from web pages

Pull structured information from websites:

```text theme={null}
Go to the product listings page and extract the name, price, and
availability for each item. Save the results as a CSV file.
```

Claude navigates to the page, reads the content, and compiles the data into a structured format.

### Run multi-site workflows

Coordinate tasks across multiple websites:

```text theme={null}
Check my calendar for meetings tomorrow, then for each meeting with
an external attendee, look up their company website and add a note
about what they do.
```

Claude works across tabs to gather information and complete the workflow.

### Record a demo GIF

Create shareable recordings of browser interactions:

```text theme={null}
Record a GIF showing how to complete the checkout flow, from adding
an item to the cart through to the confirmation page.
```

Claude records the interaction sequence and saves it as a GIF file.

## Troubleshooting

### Extension not detected

If Claude Code shows "Chrome extension not detected":

1. Verify the Chrome extension is installed and enabled in `chrome://extensions`
2. Verify Claude Code is up to date by running `claude --version`
3. Check that Chrome is running
4. Run `/chrome` and select "Reconnect extension" to re-establish the connection
5. If the issue persists, restart both Claude Code and Chrome

The first time you enable Chrome integration, Claude Code installs a native messaging host configuration file. Chrome reads this file on startup, so if the extension isn't detected on your first attempt, restart Chrome to pick up the new configuration.

If the connection still fails, verify the host configuration file exists at:

For Chrome:

* **macOS**: `~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json`
* **Linux**: `~/.config/google-chrome/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json`
* **Windows**: check `HKCU\Software\Google\Chrome\NativeMessagingHosts\` in the Windows Registry

For Edge:

* **macOS**: `~/Library/Application Support/Microsoft Edge/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json`
* **Linux**: `~/.config/microsoft-edge/NativeMessagingHosts/com.anthropic.claude_code_browser_extension.json`
* **Windows**: check `HKCU\Software\Microsoft\Edge\NativeMessagingHosts\` in the Windows Registry

### Browser not responding

If Claude's browser commands stop working:

1. Check if a modal dialog (alert, confirm, prompt) is blocking the page. JavaScript dialogs block browser events and prevent Claude from receiving commands. Dismiss the dialog manually, then tell Claude to continue.
2. Ask Claude to create a new tab and try again
3. Restart the Chrome extension by disabling and re-enabling it in `chrome://extensions`

### Connection drops during long sessions

The Chrome extension's service worker can go idle during extended sessions, which breaks the connection. If browser tools stop working after a period of inactivity, run `/chrome` and select "Reconnect extension".

### Windows-specific issues

On Windows, you may encounter:

* **Named pipe conflicts (EADDRINUSE)**: if another process is using the same named pipe, restart Claude Code. Close any other Claude Code sessions that might be using Chrome.
* **Native messaging host errors**: if the native messaging host crashes on startup, try reinstalling Claude Code to regenerate the host configuration.

### Common error messages

These are the most frequently encountered errors and how to resolve them:

| Error                                | Cause                                            | Fix                                                             |
| ------------------------------------ | ------------------------------------------------ | --------------------------------------------------------------- |
| "Browser extension is not connected" | Native messaging host cannot reach the extension | Restart Chrome and Claude Code, then run `/chrome` to reconnect |
| "Extension not detected"             | Chrome extension is not installed or is disabled | Install or enable the extension in `chrome://extensions`        |
| "No tab available"                   | Claude tried to act before a tab was ready       | Ask Claude to create a new tab and retry                        |
| "Receiving end does not exist"       | Extension service worker went idle               | Run `/chrome` and select "Reconnect extension"                  |

## See also

* [Computer use](computer-use-427032da98.md): control native macOS apps when a task can't be done in a browser
* [Use Claude Code in VS Code](/en/vs-code#automate-browser-tasks-with-chrome): browser automation in the VS Code extension
* [CLI reference](cli-reference-7bb98e3312.md): command-line flags including `--chrome`
* [Common workflows](common-workflows-c909406123.md): more ways to use Claude Code
* [Data and privacy](../22-Safety-Policy/data-usage-claude-code-docs-06b2864aaa.md): how Claude Code handles your data
* [Getting started with Claude in Chrome](../15-Claude-AI-Features/getting-started-with-claude-in-chrome.md): full documentation for the Chrome extension, including shortcuts, scheduling, and permissions


---
## chrome.md

# Use Claude Code with Chrome (beta)

Connect Claude Code to your Chrome browser to test web apps, debug with console logs, automate form filling, and extract data from web pages.

Claude Code integrates with the Claude in Chrome browser extension to give you browser automation capabilities from the CLI or the VS Code extension. Build your code, then test and debug in the browser without switching contexts.

Claude opens new tabs for browser tasks and shares your browser's login state, so it can access any site you're already signed into. Browser actions run in a visible Chrome window in real time.

> Chrome integration is in beta and currently works with Google Chrome and Microsoft Edge. WSL is not supported.

## Capabilities

- **Live debugging**: read console errors and DOM state, then fix the code
- **Design verification**: build a UI from a Figma mock, open it in browser to verify
- **Web app testing**: test form validation, check for visual regressions, verify user flows
- **Authenticated web apps**: interact with Google Docs, Gmail, Notion, or any app you're logged into
- **Data extraction**: pull structured information from web pages and save locally
- **Task automation**: automate repetitive browser tasks like data entry, form filling
- **Session recording**: record browser interactions as GIFs

## Prerequisites

- Google Chrome or Microsoft Edge
- Claude in Chrome extension v1.0.36+
- Claude Code v2.0.73+
- Direct Anthropic plan (Pro, Max, Team, or Enterprise)

> Not available through third-party providers (Bedrock, Vertex, Foundry).

## Get started

```bash
claude --chrome
```

Or enable from within a session with `/chrome`.

### Enable Chrome by default

Run `/chrome` and select "Enabled by default".

### Manage site permissions

Site-level permissions are inherited from the Chrome extension settings.

## Example workflows

### Test a local web application

```
I just updated the login form validation. Can you open localhost:3000,
try submitting the form with invalid data, and check if the error
messages appear correctly?
```

### Debug with console logs

```
Open the dashboard page and check the console for any errors when
the page loads.
```

### Automate form filling

```
I have a spreadsheet of customer contacts in contacts.csv. For each row,
go to the CRM at crm.example.com, click "Add Contact", and fill in the
name, email, and phone fields.
```

### Draft content in Google Docs

```
Draft a project update based on the recent commits and add it to my
Google Doc at docs.google.com/document/d/abc123
```

### Record a demo GIF

```
Record a GIF showing how to complete the checkout flow, from adding
an item to the cart through to the confirmation page.
```

## Troubleshooting

| Error                                | Cause                                            | Fix                                                             |
| ------------------------------------ | ------------------------------------------------ | --------------------------------------------------------------- |
| "Browser extension is not connected" | Native messaging host cannot reach the extension | Restart Chrome and Claude Code, then run `/chrome` to reconnect |
| "Extension not detected"             | Chrome extension not installed or disabled        | Install or enable in `chrome://extensions`                      |
| "No tab available"                   | Claude tried to act before a tab was ready       | Ask Claude to create a new tab and retry                        |
| "Receiving end does not exist"       | Extension service worker went idle               | Run `/chrome` and select "Reconnect extension"                  |

## See Also

- [Computer use](computer-use.md)
- [VS Code browser automation](/en/vs-code#automate-browser-tasks-with-chrome)
- [CLI reference](cli-reference-7bb98e3312.md)


---
## claude-apps-gateway-configuration-claude-code-docs-8fd92cde14.md

## On this page

- [File structure](#file-structure)
- [Secret expansion](#secret-expansion)
- [Required sections](#required-sections)
  - [listen](#listen)
  - [oidc](#oidc)
  - [session](#session)
  - [store](#store)
  - [upstreams](#upstreams)
  - [Anthropic API](#anthropic-api)
  - [Amazon Bedrock](#amazon-bedrock)
  - [Claude Platform on AWS](#claude-platform-on-aws)
  - [Google Cloud Agent Platform](#google-cloud-agent-platform)
  - [Microsoft Foundry](#microsoft-foundry)
  - [Multiple upstreams](#multiple-upstreams)
- [Optional sections](#optional-sections)
  - [admin](#admin)
  - [enforcement](#enforcement)
  - [models](#models)
  - [managed](#managed)
  - [What goes in cli](#what-goes-in-cli)
  - [Claude Desktop overlay](#claude-desktop-overlay)
  - [Precedence with other managed sources](#precedence-with-other-managed-sources)
  - [telemetry](#telemetry)
  - [HTTP tuning](#http-tuning)
- [Complete example](#complete-example)
- [Client-side managed settings](#client-side-managed-settings)
- [Related](#related)

Claude apps gateway

# Claude apps gateway configuration

Copy pageCopy page

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.

Copy pageCopy page

A Claude apps gateway deployment is configured by one YAML file, conventionally `gateway.yaml`. The file defines everything the gateway does: where it listens, how developers sign in, where inference goes, and which policies and telemetry apply. This page is the reference for every option in that file. To write your first one, start from the [quickstart](/docs/en/claude-apps-gateway#quickstart), which builds a minimal working config and runs it. Once you have a config you’re happy with, the [deployment guide](/docs/en/claude-apps-gateway-deploy) covers containerizing and hosting it on Kubernetes, Cloud Run, or your own platform. The gateway reads the file once, at startup, with `claude gateway --config /path/to/gateway.yaml`. Every option is validated against a schema at boot, so a malformed config fails at start with a field-level error rather than at first use. The [complete example](#complete-example) at the end of this page exercises every section.


[​](#file-structure)

File structure

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

- [`listen`](#listen): bind address, public URL, TLS termination
- [`oidc`](#oidc): your identity provider (IdP), including issuer, client, claim mapping, and who may sign in
- [`session`](#session): the bearer tokens the gateway mints, with secret and lifetime
- [`store`](#store): PostgreSQL, for device grants and rate-limit counters
- [`upstreams`](#upstreams): where inference goes, whether Anthropic, Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, or Microsoft Foundry

**Optional sections:**

- [`admin`](#admin): Admin API auth and retention for spend limits
- [`enforcement`](#enforcement): spend-limit fail-open or fail-closed behavior
- [`models`](#models) and `auto_include_builtin_models`: admin-curated model list and per-upstream IDs
- [`managed`](#managed): managed settings policies by IdP group
- [`telemetry`](#telemetry): OTLP forwarding to your observability stack
- [`access_control`, `limits`, `timeouts`, `rate_limits`](#http-tuning): IP allow/deny, request size caps, upstream time-to-first-byte, and per-IP sign-in limits


[​](#secret-expansion)

Secret expansion

Don’t write secrets such as `client_secret`, `jwt_secret`, or `postgres_url` directly in `gateway.yaml`. Reference them with one of the forms below, and the gateway resolves the value at boot from an environment variable or a file:

| Form            | Resolves to                                              | Use for                                                                |
|-----------------|----------------------------------------------------------|------------------------------------------------------------------------|
| `${VAR}`        | The environment variable `VAR`. Boot fails if undefined. | Container environment variables, AWS Secrets Manager via env injection |
| `${file:/path}` | File contents, trimmed                                   | Kubernetes Secret volume mounts, Vault Agent, SOPS                     |


[​](#required-sections)

Required sections


[​](#listen)

`listen`

The `listen` block controls where the gateway serves: the bind address and port, the externally visible origin, and optional TLS termination.

| Field                  | Required       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `host`                 | No             | Bind address. Default `0.0.0.0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `port`                 | No             | Bind port. Default `8080`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `public_url`           | Behind a proxy | The externally visible `https://` origin, used to build the IdP `redirect_uri` and discovery metadata. Required behind any TLS-terminating proxy such as an ALB, Ingress, or Cloud Run, because the gateway doesn’t trust `X-Forwarded-*` headers when constructing its own origin; they are client-spoofable. `trusted_proxies` below governs client-IP resolution only. Also required to enable [telemetry](#telemetry), because the gateway builds the OTLP endpoint it pushes to clients from this URL. |
| `tls.cert` / `tls.key` | No             | PEM paths if the gateway terminates TLS itself                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `trusted_proxies`      | No             | CIDRs or IPs of load balancers in front of the gateway. When set, the gateway trusts `X-Forwarded-For` only from these peers and records the real client IP for per-IP rate limiting and audit. Equivalent to nginx `set_real_ip_from`.                                                                                                                                                                                                                                                                     |


[​](#oidc)

`oidc`

The `oidc` block connects the gateway to your identity provider and decides who can sign in. It names the issuer and OAuth client, maps the claims that carry email and groups, and restricts sign-in by email domain or group. OpenID Connect (OIDC) is the SSO protocol the gateway uses with your identity provider; see [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup) for what to register on the IdP side.

| Field                           | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|---------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `issuer`                        | Yes      | OIDC discovery base. Must serve discovery at `/.well-known/openid-configuration`. Use HTTPS in production; the gateway accepts an `http://` issuer. A loopback issuer such as `http://localhost:8081` is rejected by the [SSRF guard](/docs/en/claude-apps-gateway-deploy#threat-model-summary) unless `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` is set in the gateway’s environment.                                                                                                                                                                                                                       |
| `client_id` / `client_secret`   | Yes      | From your OAuth client registration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `allowed_email_domains`         | No       | Reject id_tokens whose `email` claim isn’t in one of these domains, case-insensitive. Defense-in-depth against multi-tenant IdP misconfiguration. Independent of this setting, an id_token whose `email_verified` claim is explicitly `false` is always rejected.                                                                                                                                                                                                                                                                                                                                   |
| `allowed_groups`                | No       | Restrict sign-in to members of these IdP groups, matched against `groups_claim`. A user in an allowed email domain but in none of these groups is rejected. Requires the IdP to emit the groups claim.                                                                                                                                                                                                                                                                                                                                                                                              |
| `groups_claim`                  | No       | Which id_token claim carries group membership. Default `groups`. Microsoft Entra emits app roles under `roles`. Accepts a flat key or an RFC 6901 JSON Pointer such as `/resource_access/gateway/roles` for nested claims.                                                                                                                                                                                                                                                                                                                                                                          |
| `google_groups`                 | No       | Look up the signed-in user’s groups through the Google Workspace Admin SDK Directory API, because Google’s id_token carries no groups claim. Set `service_account_json_path` to a service-account key file with domain-wide delegation on the `https://www.googleapis.com/auth/admin.directory.group.readonly` scope, and `admin_email` to a Workspace administrator the service account impersonates; the Directory API requires a real admin subject. Each user’s group email addresses become their groups claim, so `allowed_groups` and `managed.policies.match.groups` match on group emails. |
| `email_claim`                   | No       | Which id_token claim carries the user’s email. Default `email`. Some IdPs, such as ADFS and Entra B2C, emit `upn` or `preferred_username` instead. Accepts a flat key, a JSON Pointer, or a list of fallback keys where the first present key is used.                                                                                                                                                                                                                                                                                                                                              |
| `scopes`                        | No       | Full override of the OIDC scopes the gateway requests. Default `[openid, profile, email, offline_access]`. Set when your IdP rejects scopes it doesn’t recognize, or requires a custom scope to emit groups or email. Must include `openid`. Dropping `offline_access` disables refresh tokens, so developers re-run the browser login every `session.ttl_hours`. See [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup) for per-IdP scope recipes such as Google’s refresh-token flow.                                                                         |
| `extra_auth_params`             | No       | Extra query parameters appended to the IdP authorization request, verbatim. This is the override mechanism for IdP-specific behavior, such as `access_type: offline` for Google refresh tokens, `domain_hint` for some Entra tenants, or `acr_values` for step-up flows. Cannot override the gateway-managed protocol params: `state`, `nonce`, `redirect_uri`, PKCE, `scope`, `response_type`, `response_mode`, and `client_id`.                                                                                                                                                                   |
| `userinfo_fallback`             | No       | When the id_token omits email or groups, fetch them from `/userinfo`. Needed for Keycloak lightweight access tokens, the Okta org server, and ADFS minimal tokens. The id_token stays authoritative; userinfo only fills gaps. Default `false`.                                                                                                                                                                                                                                                                                                                                                     |
| `use_pkce`                      | No       | Send a PKCE (S256) challenge on the authorization request. Default `true`. Set `false` only if your IdP rejects PKCE for this confidential client.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `clock_skew_seconds`            | No       | Tolerate clock drift when validating id_token time claims. Default `0`, which is strict. Raise if you see “token expired / not yet valid” errors right after sign-in due to host/IdP clock skew.                                                                                                                                                                                                                                                                                                                                                                                                    |
| `token_endpoint_auth_method`    | No       | Override the token-endpoint auth method. Accepts `client_secret_basic` or `client_secret_post`. Auto-negotiated by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `id_token_signed_response_alg`  | No       | Expected id_token signing algorithm. Default `RS256`. Set for IdPs that sign with ES256, PS256, or EdDSA.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `additional_authorized_parties` | No       | Extra `azp` values to accept beyond `client_id`, for Keycloak broker and token-exchange flows                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `discovery_url`                 | No       | Fetch the discovery document from this URL instead of deriving it from `issuer`, for IdPs behind a proxy that rewrites the issuer host. The path must contain `/.well-known/`.                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `form_action_origins`           | No       | Additional origins for the `/device` page’s `Content-Security-Policy: form-action` directive. The gateway already allows `'self'` and the discovered `authorization_endpoint` origin, but Chrome enforces `form-action` against the entire redirect chain. If your IdP redirects through a second host, such as Azure AD federated to ADFS, hub-spoke Okta, or a corporate SSO interceptor, list every origin the authorization request may redirect through.                                                                                                                                       |
| `ca_cert_pem`                   | No       | PEM CA cert that replaces the system trust store for IdP requests only. Use for Keycloak or Dex behind corporate PKI.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |


[​](#session)

`session`

The `session` block shapes the bearer tokens the gateway mints after sign-in: the secret that signs them and how long they live.

| Field        | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                           |
|--------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `jwt_secret` | Yes      | At least 32 bytes of entropy, for example from `openssl rand -base64 32`. Signs the gateway’s HS256 bearer tokens. Accepts a single string or an array for rotation: index 0 signs and all entries verify. To rotate, prepend a new secret, wait `ttl_hours`, then drop the old one.                                                                                                                                  |
| `ttl_hours`  | No       | Gateway bearer token lifetime. Default `1`. The CLI silently refreshes before expiry when the IdP issues refresh tokens. A shorter lifetime deprovisions faster; a longer one makes fewer IdP round-trips. If your IdP can’t issue refresh tokens because `offline_access` is unavailable, there is no silent refresh, so raise this to `8` or `12` to avoid sending developers back to the browser login every hour. |


[​](#store)

`store`

The `store` block points the gateway at its PostgreSQL database, which holds device grants and rate-limit counters.

| Field             | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|-------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `postgres_url`    | Yes      | `postgres://` or `postgresql://` URL. Required: the device-grant rendezvous, where the browser callback writes and the polling CLI reads, needs cross-replica state. The gateway runs its own schema migrations at boot, so the role needs `CREATE TABLE` on the target schema. If your security policy prohibits DDL from the application role, run the migrations with an admin role, initially and again whenever a new release ships migrations, and grant the app role `SELECT, INSERT, UPDATE, DELETE` on the gateway’s tables. See [Upgrades](/docs/en/claude-apps-gateway-deploy#upgrades) and [Postgres](/docs/en/claude-apps-gateway-deploy#postgres). |
| `username`        | No       | Overrides the user in `postgres_url`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `password`        | No       | Database credential. Set it here rather than in `postgres_url` so the credential stays out of the URL. Accepts any characters and takes precedence over URL credentials.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `max_connections` | No       | Postgres connection-pool size per replica. Default `5`, which is conservative and friendly to shared databases. With [spend limits](#admin) enabled, the hot path does a few operations per inference request, so raise it for a dedicated database under load, and keep replicas × this below the database’s `max_connections`.                                                                                                                                                                                                                                                                                                                                 |

For local development, point `postgres_url` at a throwaway Postgres container, for example `docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres`.


[​](#upstreams)

`upstreams`

`upstreams` is an ordered list. The gateway forwards inference to the first upstream that resolves the requested model. On `5xx`, `429`, `401`, `403`, `404`, or timeout it fails over to the next; other `4xx` doesn’t, because those errors are attributable to the request rather than the upstream. A `401` or `403` means the gateway’s own credential failed against that upstream, and a `404` means that upstream doesn’t serve the requested model, so a later upstream in the list still can. Failover on `404` requires gateway v2.1.198 or later. Earlier releases returned the first `404` to the client even when a later upstream in the list served the model. Multiple upstreams of the same provider must set a distinct `name:`. Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, and Microsoft Foundry clients are built once at startup, and their SDKs refresh credentials internally, so rotating cloud credentials doesn’t require a restart. Static Anthropic API keys and bearers are read at startup; see [Anthropic API](#anthropic-api).


[​](#anthropic-api)

Anthropic API

The minimal Anthropic upstream is an API key from the [Claude Console](https://platform.claude.com):

```python
upstreams:
  - provider: anthropic
    auth:
      api_key: ${ANTHROPIC_API_KEY}
    # OR an OAuth bearer (e.g. a Workload-Identity-Federation-exchanged token):
    #   oauth_token: ${file:/var/run/secrets/anthropic-oauth-token}
    # base_url: https://api.anthropic.com   # default; override for a forward proxy
```

The two credential forms differ in the header they send:

- **`api_key`**: sends `x-api-key`. Rotate it in the Claude Console and update the env var.
- **`oauth_token`**: sends `Authorization: Bearer`. Use the bearer form when your org issues short-lived tokens instead of long-lived API keys. The bearer is read once at startup, so refresh by remounting the secret and restarting.

Instead of a static key or bearer, you can use Workload Identity Federation. Create a federation rule by following the [Workload Identity Federation guide](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation), then mount your workload’s OIDC JWT as a file, such as a Kubernetes projected service-account token or a CI platform’s id-token. The gateway exchanges the JWT for a short-lived bearer and refreshes it automatically. The token file is re-read on every exchange, so rotated projected tokens are picked up without a restart.

```python
upstreams:
  - provider: anthropic
    auth:
      federation_rule_id: ${ANTHROPIC_FEDERATION_RULE_ID}
      organization_id: ${ANTHROPIC_ORGANIZATION_ID}
      identity_token_file: /var/run/secrets/anthropic/id-token
      # workspace_id: wrkspc_...       # required if the rule covers >1 workspace
      # service_account_id: svac_...   # optional expected-target check
```


[​](#amazon-bedrock)

Amazon Bedrock

For the client-side Amazon Bedrock deployment that the gateway replaces or fronts, see [Claude Code on Amazon Bedrock](/docs/en/amazon-bedrock). The gateway-side upstream:

```python
upstreams:
  - provider: bedrock
    region: us-east-1
    auth: {}                           # preferred: AWS default credential chain
    # OR explicit credentials:
    # auth:
    #   aws_access_key_id: ${AWS_AKID}
    #   aws_secret_access_key: ${AWS_SK}
    #   aws_session_token: ${AWS_ST}
    # OR a Bedrock API bearer token:
    # auth:
    #   aws_bearer_token: ${AWS_BEARER_TOKEN}
    # Override the bedrock-runtime endpoint for FIPS or VPC-endpoint deployments:
    # base_url: https://bedrock-runtime-fips.us-east-1.amazonaws.com
```

An empty `auth` block uses the AWS SDK’s default credential chain: env vars, `~/.aws/credentials`, ECS task role, EC2 instance metadata, or IRSA on EKS. In production, give the gateway pod an IAM role instead of embedding static keys in a container image. Explicit credentials must be complete: the gateway fails at boot when `aws_access_key_id` and `aws_secret_access_key` aren’t set together, or when `aws_session_token` is set without them. Before v2.1.207, a partial `auth:` block passed validation.

| Setup           | How                                                                                                                                                                                                                                                                                                                                               |
|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| IAM permissions | Grant the gateway’s principal `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` on both the inference-profile ARNs and the underlying foundation-model ARNs. For the built-in catalog in US regions: `arn:aws:bedrock:<region>:<account>:inference-profile/us.anthropic.*` and `arn:aws:bedrock:*::foundation-model/anthropic.*`. |
| Model access    | In the Amazon Bedrock console, per region, request and enable model access for the Claude models you want. Cross-region inference profiles (`us.anthropic.*`) require model access in each region the profile spans.                                                                                                                              |
| EKS (IRSA)      | Create an IAM role with the policy above and a trust policy for your cluster’s OIDC provider scoped to the gateway’s service account. Annotate the service account with `eks.amazonaws.com/role-arn: arn:aws:iam::<acct>:role/claude-gateway`. `auth: {}` picks it up.                                                                            |
| ECS / EC2       | Attach the IAM role to the task definition or instance profile. `auth: {}` picks it up.                                                                                                                                                                                                                                                           |
| Anywhere else   | Pass credentials via the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN` env vars, or set them explicitly in `auth:` with `${VAR}` expansion                                                                                                                                                                                |
| Region          | `region:` is the API endpoint region. Cross-region inference profiles route across the geo (US, EU, APAC) regardless of which one you pick. For non-US regions or provisioned-throughput ARNs, add a [`models:`](#models) block with the right per-upstream IDs.                                                                                  |


[​](#claude-platform-on-aws)

Claude Platform on AWS

Claude Platform on AWS serves the first-party Anthropic API on AWS infrastructure at `aws-external-anthropic.<region>.api.aws`. It uses first-party model IDs, honors `anthropic-beta` headers as sent, and serves `count_tokens`, so none of the Bedrock-specific translation applies. The `anthropicAws` provider requires Claude Code v2.1.198 or later; earlier gateway releases reject it at boot. For the client-side deployment of the same platform, see [Claude Code on Claude Platform on AWS](/docs/en/claude-platform-on-aws). The gateway-side upstream:

```python
upstreams:
  - provider: anthropicAws
    region: us-east-1
    workspace_id: wrkspc_...
    auth:
      api_key: ${ANTHROPIC_AWS_API_KEY}   # sent as x-api-key
    # OR SigV4 via the AWS default credential chain:
    # auth: {}
    # OR explicit SigV4 credentials:
    # auth:
    #   aws_access_key_id: ${AWS_ACCESS_KEY_ID}
    #   aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
    # Override the derived endpoint:
    # base_url: https://aws-external-anthropic.us-east-1.api.aws
```

The platform runs in a separate AWS account from Amazon Bedrock and signs SigV4 requests for its own service name, `aws-external-anthropic`, so a Bedrock-scoped IAM role doesn’t authorize it. An API key in `auth.api_key` takes precedence when SigV4 credentials are also set. An empty `auth` block uses the AWS SDK’s default credential chain, the same chain the [Amazon Bedrock](#amazon-bedrock) upstream uses.

| Field                                                   | Required | Description                                                                                                                                        |
|---------------------------------------------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `region`                                                | Yes      | AWS region, lowercase letters, digits, and hyphens. The gateway derives the endpoint from it as `https://aws-external-anthropic.<region>.api.aws`. |
| `workspace_id`                                          | Yes      | Sent as a header on every request; the platform requires it                                                                                        |
| `auth.api_key`                                          | No       | API key for the platform, sent as `x-api-key`. Not a bearer token: the two auth modes are an API key or SigV4.                                     |
| `auth.aws_access_key_id` / `auth.aws_secret_access_key` | No       | Explicit SigV4 credentials. Setting one without the other fails at boot. `auth.aws_session_token` is accepted alongside them.                      |
| `base_url`                                              | No       | Override the derived endpoint                                                                                                                      |

Because the platform resolves first-party model IDs, the built-in catalog routes to it with no [`models:`](#models) block. When you curate a `models:` list, key the entry `anthropicAws:` with the first-party ID.


[​](#google-cloud-agent-platform)

Google Cloud Agent Platform

For the equivalent client-side setup, see [Claude Code on Google Cloud](/docs/en/google-vertex-ai). The gateway-side upstream:

```python
upstreams:
  - provider: vertex
    region: us-east5
    project_id: example-prod
    auth: {}                           # preferred: Application Default Credentials
    # OR a service account key file:
    # auth: { service_account_json: /secrets/sa.json }
    # Override the aiplatform endpoint for Private Service Connect:
    # base_url: https://us-east5-aiplatform.p.googleapis.com
```

An empty `auth` block uses Application Default Credentials: `GOOGLE_APPLICATION_CREDENTIALS`, GCE metadata, or GKE Workload Identity. Service-account JSON key files are supported but discouraged; use Workload Identity or attach a service account to the GCE or Cloud Run instance. Set `region: global` to use the [global endpoint for Google Cloud’s Agent Platform](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations) instead of a regional one. Google then routes each request to an available region, so you don’t track per-region model availability. Setting a specific region pins every request to it.

| Setup                   | How                                                                                                                                                                                                       |
|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| IAM permissions         | Grant the gateway’s service account `roles/aiplatform.user` on the project, or a custom role with `aiplatform.endpoints.predict`. Enable Google Cloud’s Agent Platform API (`aiplatform.googleapis.com`). |
| Model access            | In Model Garden, enable the Claude models for your project. They publish to specific regions; check the model card for supported regions.                                                                 |
| GKE (Workload Identity) | Bind a GCP service account to the gateway’s Kubernetes service account and annotate the KSA with `iam.gke.io/gcp-service-account: claude-gateway@<proj>.iam.gserviceaccount.com`. `auth: {}` picks it up. |
| Cloud Run / GCE         | Set the service’s service account to one with `roles/aiplatform.user`. `auth: {}` picks it up.                                                                                                            |
| Anywhere else           | `auth: { service_account_json: /secrets/sa.json }`, the path to a JSON key file mounted as a secret. The field takes a file path, not the key contents, so no `${file:…}` expansion is involved.          |


[​](#microsoft-foundry)

Microsoft Foundry

For the client-side Microsoft Foundry deployment, see [Claude Code on Microsoft Foundry](/docs/en/microsoft-foundry). The gateway-side upstream:

```python
upstreams:
  - provider: foundry
    resource: example-foundry              # https://example-foundry.services.ai.azure.com
    auth: { use_azure_ad: true }        # preferred: DefaultAzureCredential / Managed Identity
    # OR an API key:
    # auth:
    #   api_key: ${FOUNDRY_API_KEY}
```

`use_azure_ad: true` resolves through `DefaultAzureCredential`: Managed Identity on AKS, ACI, or App Service; the Azure CLI; or environment credentials. API keys work but are project-wide and don’t rotate automatically. Microsoft Foundry’s endpoint is derived from `resource:`; set the optional `base_url` to override it for sovereign clouds such as Azure Government.

| Setup                   | How                                                                                                                                                                                       |
|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| RBAC                    | Grant the gateway’s identity `Azure AI User` or `Cognitive Services User` on the Microsoft Foundry resource                                                                               |
| Deployments             | Microsoft Foundry uses admin-chosen deployment names, not canonical model IDs. Add a [`models:`](#models) block mapping each canonical ID to your deployment name.                        |
| AKS (workload identity) | Federate a User-Assigned Managed Identity with the cluster’s OIDC issuer and bind it to the gateway’s service account. `use_azure_ad: true` picks it up via `WorkloadIdentityCredential`. |
| ACI / App Service       | Enable system-assigned or user-assigned managed identity on the resource. `use_azure_ad: true` picks it up.                                                                               |
| Anywhere else           | `auth: { api_key: "${FOUNDRY_API_KEY}" }`. Quote `${…}` inside `{ }`.                                                                                                                     |


[​](#multiple-upstreams)

Multiple upstreams

The same provider can appear more than once with a distinct `name:`. This covers different regions, different accounts via different credential chains, provisioned throughput versus on-demand, and cross-provider fallback. The gateway tries upstreams in order. `5xx`, `429`, `401`, `403`, `404`, timeouts, and missing-endpoint (`501`) fail over; other `4xx` doesn’t. `429` is per-upstream capacity, so provisioned-throughput (PT) exhaustion fails over to on-demand. `404` is per-upstream model availability, so an upstream that hasn’t enabled a model doesn’t block a later upstream that serves it. An upstream that can’t resolve the requested model is skipped without a network round-trip. This example routes a provisioned-throughput Amazon Bedrock allotment first, overflows to on-demand and a second account, and falls back to the Anthropic API last:

```python
upstreams:
  # Primary: provisioned throughput in your home region.
  - name: bedrock-pt
    provider: bedrock
    region: us-east-1
    auth: {}
  # Overflow: on-demand cross-region.
  - name: bedrock-od
    provider: bedrock
    region: us-west-2
    auth: {}
  # Different account: a separate Bedrock allotment via assumed-role creds.
  - name: bedrock-acct2
    provider: bedrock
    region: us-east-1
    auth:
      aws_access_key_id: ${ACCT2_AKID}
      aws_secret_access_key: ${ACCT2_SK}
  # Last resort: direct Anthropic API.
  - name: anthropic-fallback
    provider: anthropic
    auth:
      api_key: ${ANTHROPIC_API_KEY}

# Per-upstream model IDs are keyed on the upstream's `name:`; an upstream
# without a `name:` defaults to its provider string (e.g. `bedrock`). Any
# upstream not listed for a model is skipped, which is how you route a model
# to provisioned throughput while everything else stays on-demand.
models:
  - id: claude-opus-4-8
    label: Claude Opus 4.8
    upstream_model:
      bedrock-pt: arn:aws:bedrock:us-east-1:111111111111:provisioned-model/abcdef
      bedrock-od: us.anthropic.claude-opus-4-8
      bedrock-acct2: us.anthropic.claude-opus-4-8
      anthropic-fallback: claude-opus-4-8
```

| Lever                  | How                                                                                                                                                                                                                                    |
|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Different regions      | One Amazon Bedrock upstream per region, each with its own `region:`. With [`auto_include_builtin_models: true`](#models) the cross-region inference profiles route automatically; for region-pinned deployments use a `models:` block. |
| Different accounts     | One Amazon Bedrock upstream per account, each with its own credentials in `auth:`. The default chain (`auth: {}`) uses the pod’s identity; for a second account, set explicit credentials or a bearer token.                           |
| Provisioned throughput | Map the model to the provisioned-throughput ARN in `models:` for that upstream’s name. Other upstreams keep the on-demand ID, so PT capacity is exhausted before failing over.                                                         |
| VPC / FIPS endpoints   | Set `base_url:` on the upstream to your VPC endpoint or FIPS endpoint URL                                                                                                                                                              |
| Model-scoped routing   | Omit an upstream from a model’s `upstream_model:` map and that upstream is skipped for that model. For example, route Opus to provisioned throughput and Sonnet and Haiku to on-demand.                                                |

Failing over between cloud providers, or to the direct Anthropic API, changes which agreement, geography, and other terms govern the request. The CLI applies the same feature gating to gateways regardless of which upstream serves a given request, so failover doesn’t send a body field an upstream would reject.


[​](#optional-sections)

Optional sections


[​](#admin)

`admin`

Optional. Enables `/v1/organizations/spend_limits`, which mirrors Anthropic’s public Admin API, and per-developer spend enforcement on `/v1/messages`. See [Spend limits](/docs/en/claude-apps-gateway-spend-limits) for how caps are set and enforced; this section covers the `gateway.yaml` keys that turn the feature on and tune it.

```python
admin:
  # Named static API keys for the admin endpoints, sent as x-api-key.
  # The id appears in the audit log as admin-key:<id> so each key is
  # attributable. Array for rotation: add the new key, roll clients,
  # remove the old.
  write_keys:
    - { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
    - { id: ci,        key: "${GATEWAY_ADMIN_WRITE_KEY_CI}" }
  read_keys:
    - { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
  # IdP groups granted full admin via the normal gateway JWT (no API key).
  admin_groups: [platform-finops]
  blocked_message: request an increase at https://go.example.com/claude-limits
```

| Field                     | Required | Description                                                                                                                                                                                                                                               |
|---------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `write_keys`              | No       | Array of `{id, key}`. An `x-api-key` matching one of these can list, set, and delete spend limits. Key values must be at least 32 characters; `id`s must be unique across `read_keys` and `write_keys`.                                                   |
| `read_keys`               | No       | Array of `{id, key}`. Read-only: every `GET` endpoint, including listing caps, fetching one by ID, and reading [`/effective`](/docs/en/claude-apps-gateway-spend-limits#%2Feffective) and [`/audit`](/docs/en/claude-apps-gateway-spend-limits#%2Faudit). |
| `admin_groups`            | No       | IdP group names. A gateway JWT whose `groups` claim includes one of these has full admin access, read and write, and audits as `oidc:<sub>`. Use this for human admins; use API keys for machines.                                                        |
| `blocked_message`         | No       | Appended verbatim to the `429 billing_error` a blocked developer sees. Write the whole instruction, such as a URL or a Slack channel. Unset, the error is `spend limit reached`.                                                                          |
| `audit_retention_days`    | No       | Default `365`. Older `admin_audit` rows are swept.                                                                                                                                                                                                        |
| `spend_retention_months`  | No       | Default `13`. `spend` counter rows older than this are swept. The default keeps a full year plus the current partial month for year-over-year reporting.                                                                                                  |
| `identity_retention_days` | No       | Default `90`. Last-seen TTL for `principal_emails` rows, which hold each developer’s email, display name, and groups (PII). Deliberately shorter than spend retention so a deprovisioned identity ages out while its anonymous spend counters remain.     |
| `group_limit_mode`        | No       | `min` (default) or `max`. When a developer is in several groups with caps, `min` enforces the most restrictive and `max` the least. Used by both enforcement and `/effective`.                                                                            |


[​](#enforcement)

`enforcement`

The `enforcement` block controls how spend-limit checks behave when the store is unavailable.

| Field                  | Required | Description                                                                                                                                                                                                                                                    |
|------------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `fail_closed_on_error` | No       | Default `false`. Spend enforcement fails open on a Postgres outage, so inference stays up. Set `true` to fail closed: over-cap developers are blocked, but so is everyone else if the store is unreachable. Has no effect without an [`admin:`](#admin) block. |


[​](#models)

`models`

The `models` block is an optional admin-curated model list, served at `/v1/models` and used to translate model IDs per upstream. It is required for non-US Amazon Bedrock regions, Amazon Bedrock provisioned-throughput ARNs, and Microsoft Foundry deployment names.

```python
auto_include_builtin_models: true   # false: expose only the list below
models:
  - id: claude-opus-4-8
    label: Claude Opus 4.8
    # description: optional text shown in clients that surface it
    upstream_model:
      anthropic: claude-opus-4-8
      bedrock: us.anthropic.claude-opus-4-8   # or an inference-profile ARN
      foundry: your-opus-deployment-name
```


[​](#managed)

`managed`

The `managed` block defines role-based access policies keyed on IdP groups or email domain. Policies are evaluated in order; the first match is selected, then merged onto the `match: {}` catch-all base described below. They are served per-user at `GET /managed/settings` with ETag/304 caching.

```python
managed:
  policies:
    # Specific groups first.
    - match: { groups: [eng-contractors] }
      cli:
        availableModels: [claude-sonnet-4-6]
        permissions: { deny: ["WebFetch", "WebSearch"] }
    # Default catch-all last: matches everyone who authenticated.
    - match: {}
      cli:
        availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
```

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

- **Allow-lists**: `availableModels` and `permissions.allow`. A specific policy’s list fully replaces the base’s.
- **Deny-lists and hook arrays**: `permissions.deny`, `permissions.ask`, `disabledMcpjsonServers`, `deniedMcpServers`, `blockedMarketplaces`, and every `hooks` event-type array. These take the union of base and policy, so an org-wide deny or audit hook can’t be accidentally dropped by a per-role override.
- **Record-typed keys**: `env`, `modelOverrides`, and `skillOverrides`. These shallow-merge, so a per-role `env` block overrides keys it sets and inherits the rest from the base.

`availableModels` is also enforced server-side at `/v1/messages`, so a denied model returns `400` regardless of what the client sends.

| Matcher                                             | Behavior                                                                                                                         |
|-----------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|
| `match: {}`                                         | Matches every authenticated user. Start with one of these and add group-scoped policies above it later.                          |
| `match: { groups: [a, b] }`                         | Matches if the JWT’s `groups` claim contains any of the listed groups. Case-sensitive: groups must match the IdP’s exact casing. |
| `match: { email_domain: example.com }`              | Matches the part after the last `@` in the JWT’s `email` claim, case-insensitive. Accepts one domain per policy.                 |
| `match: { groups: [a], email_domain: example.com }` | Both conditions must match                                                                                                       |

An authenticated user who matches no policy gets the gateway’s defaults, which means every model in the catalog and no managed settings. Add a `match: {}` catch-all last if you want a guaranteed default policy.

The gateway keeps no user directory of its own. It authorizes each request from the user’s IdP token, reading group membership from the token’s `groups` claim and evaluating policies against it. There is no roster to enumerate and no accounts to pre-create, and therefore no SCIM endpoint, because there is nothing for SCIM to sync into.Run user and group lifecycle management at the source of truth, which is your IdP’s native SCIM provisioning or a dedicated identity-governance platform. Membership and deprovisioning governed there flow into the gateway automatically through the token. If you want SCIM provisioning of Claude accounts themselves, that is a [Claude for Enterprise](/docs/en/admin-setup) capability.Two propagation clocks apply:

- **Policy contents**: editing a policy and redeploying reaches connected clients on their next managed-settings poll, within an hour
- **Group membership**: changing a user’s group membership changes which policy matches them. This takes effect on the next session re-mint, meaning the next silent refresh, bounded by `session.ttl_hours`.


[​](#what-goes-in-cli)

What goes in `cli`

Each `cli` value is a complete Claude Code `managed-settings.json` document, the same schema you would deploy via MDM or `/etc/claude-code/managed-settings.json`, expressed here as YAML. The CLI applies the delivered document at the managed tier, above user and project settings. The gateway validates each document against the CLI’s settings schema at boot, so an unrecognized top-level key or a recognized key with a malformed value fails boot with an error naming every offending key. Deliberately open parts of the schema still accept arbitrary values, because newer clients may recognize entries the gateway’s schema doesn’t. These open keys are `env`, `pluginConfigs`, and keys nested under `permissions`. Because validation uses the schema bundled with the gateway’s installed version, putting a top-level settings key introduced by a newer Claude Code release into managed config requires upgrading the gateway first. Smoke-test a new policy on one client before rolling it out. The full key reference is in [Claude Code settings](/docs/en/settings#available-settings). The keys most operators reach for first:

```python
managed:
  policies:
    - match: {}
      cli:
        # Model access (also enforced server-side at /v1/messages)
        availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]

        # Permission policy
        permissions:
          deny:
            - "WebFetch"
            - "Read(./.env)"
            - "Read(./secrets/**)"
          disableBypassPermissionsMode: disable   # blocks --dangerously-skip-permissions
        allowManagedPermissionRulesOnly: true     # ignore user/project permission rules

        # Environment pushed into the CLI process. DISABLE_UPDATES blocks
        # background and manual updates; DISABLE_AUTOUPDATER stops only
        # background updates.
        env:
          DISABLE_UPDATES: "1"                    # pin versions via your own distribution

        # Org-wide hooks. Hook commands run on developer machines, not the
        # gateway, so the path must exist on every client OS in the policy.
        hooks:
          PostToolUse:
            - matcher: "Edit|Write"
              hooks:
                - { type: command, command: /usr/local/bin/audit-edit.sh }
```

| Key                                        | Enforced by   | Effect                                                                                                                                                                                                        |
|--------------------------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `availableModels`                          | Gateway + CLI | Model allowlist. Also checked at `/v1/messages`, so a patched client can’t bypass it.                                                                                                                         |
| `permissions.allow` / `.deny`              | CLI           | Tool and command rules. See [Permissions](/docs/en/permissions).                                                                                                                                              |
| `permissions.disableBypassPermissionsMode` | CLI           | Set to `disable` to block [`bypassPermissions`](/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode), the mode that skips permission prompts, and the `--dangerously-skip-permissions` flag |
| `allowManagedPermissionRulesOnly`          | CLI           | When `true`, user and project permission rules are ignored; only rules from this document apply                                                                                                               |
| `env`                                      | CLI           | Environment variables merged into the CLI process. Use for telemetry, auto-update, and model-name overrides.                                                                                                  |
| `hooks`                                    | CLI           | Org-wide [hooks](/docs/en/hooks)                                                                                                                                                                              |

Because these settings arrive over the network, the CLI shows each developer a one-time security approval dialog before applying the settings listed below:

- `hooks`
- `env` variables that require the developer’s approval, such as proxy and base-URL variables
- shell-execution settings such as `apiKeyHelper` and `statusLine`
- managed CLAUDE.md content

Claude Code applies some delivered `env` variables without showing the developer the approval dialog, such as model selection settings and numeric limits. Other delivered variables can require the developer’s approval before they take effect; a non-empty proxy, base-URL, or `OTEL_EXPORTER_OTLP_ENDPOINT` value always does. When a delivered variable needs approval, the dialog names it. [Environment variables and the approval dialog](/docs/en/server-managed-settings#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval. Before v2.1.218, Claude Code applied fewer variables without asking the developer, so more delivered variables triggered the dialog. The gateway’s [telemetry](#telemetry) configuration pushes `OTEL_EXPORTER_OTLP_ENDPOINT`, so setting `telemetry.forward_to` triggers the dialog on each interactive client. The dialog protects the developer’s machine from a compromised or hostile gateway, not the organization from the developer. A non-interactive run with the `-p` flag can’t show the dialog. It applies the pushed settings for that run only and doesn’t record them as approved, so the developer’s next interactive session still shows the dialog. Before v2.1.207, a non-interactive run saved the settings as approved and no later interactive session showed the dialog for them. If a developer declines, Claude Code exits rather than applying the policy. Pushing a new hook, or any env var that triggers the dialog, to a broad policy therefore means an approval prompt on every matching developer’s next startup. The `cli` key was named `settings` in earlier releases. That spelling is still accepted as an alias, but new deployments should use `cli`.


[​](#claude-desktop-overlay)

Claude Desktop overlay

If your organization also deploys [Claude Desktop](/docs/en/desktop), the same gateway serves both clients. Point `bootstrapUrl`, in Claude Desktop’s [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration), at `<listen.public_url>/user/bootstrap`. Claude Desktop derives the OAuth issuer from that URL, runs the same device-code sign-in against this gateway, and fetches its configuration from the response.

Requires Claude Code v2.1.203 or later on the gateway server, and an explicit opt-in: `/user/bootstrap` returns 404 unless the policy matching the user carries a `desktop` key. An empty `desktop: {}` opts a policy in, and a `desktop` key on the `match: {}` base layer opts in every policy that inherits it. The audit log records each request as `desktop_bootstrap.serve` or `desktop_bootstrap.denied`.

The gateway derives much of the response from the matched policy’s `cli` block and from top-level gateway config:

- The model list, from `availableModels`
- Disabled tools, from bare tool-name `permissions.deny` entries
- The egress allowlist, from `sandbox.network.allowedDomains`
- An OTLP endpoint that points at the gateway itself, which fans out to your destinations, included when [`telemetry`](#telemetry) forwarding is configured

The gateway omits keys with no Claude Desktop equivalent, such as `hooks` and scoped permission rules like `Bash(npm *)`, from the bootstrap response. The optional `desktop` block alongside `cli` holds the Claude Desktop feature gates that have no CLI equivalent:

```python
managed:
  policies:
    - match: { groups: [eng-contractors] }
      cli:
        availableModels: [claude-sonnet-4-6]
      desktop:
        isLocalDevMcpEnabled: false
        disableAutoUpdates: true
        banner: { text: "Contractor build: internal use only" }
```

| Key                                                                | Effect                                                                                                             |
|--------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| `modelDiscoveryEnabled`                                            | Whether Claude Desktop fetches `/v1/models` for its picker. Set `false` to rely solely on the policy’s model list. |
| `coworkTabEnabled`, `isClaudeCodeForDesktopEnabled`                | Show or hide individual tabs                                                                                       |
| `isDesktopExtensionEnabled`, `isDesktopExtensionSignatureRequired` | Desktop extension loading and signature checks                                                                     |
| `isLocalDevMcpEnabled`                                             | Allow locally defined MCP servers                                                                                  |
| `disableAutoUpdates`, `autoUpdaterEnforcementHours`                | Auto-update policy                                                                                                 |
| `banner`                                                           | Persistent banner at the top of the app: `enabled`, `text`, `backgroundColor`, `textColor`, `linkUrl`              |

Every key is optional; Claude Desktop applies its own default for any key you omit. The gateway rejects unknown keys at boot. If you don’t deploy Claude Desktop, leave `desktop` out of your policies entirely; `/user/bootstrap` then returns 404 for every user.


[​](#precedence-with-other-managed-sources)

Precedence with other managed sources

If a device also has a local `managed-settings.json` or MDM-delivered policy, the managed sources don’t merge. The highest-priority source provides all policy settings, ranked in this order with highest priority first:

1.  The [policy helper](/docs/en/settings#compute-managed-settings-with-a-policy-helper)
2.  Gateway-delivered settings
3.  MDM, via the HKLM registry on Windows or a plist on macOS
4.  The `managed-settings.json` file
5.  The HKCU registry, on Windows only

Embedding hosts such as [Claude Desktop](/docs/en/desktop) can supply policy through the SDK `managedSettings` option. Whether it applies depends on the machine’s managed configuration:

- On machines with an admin-deployed managed source, it is ignored unless the highest-priority source opts in with [`parentSettingsBehavior: "merge"`](/docs/en/settings#available-settings).
- It is never merged while a [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) is configured.
- When merged, it passes through a restrictive-only allowlist. [Restrict parent settings](/docs/en/claude-apps-gateway#restrict-parent-settings) lists which allow-direction settings still apply without the `allowManaged*Only` locks.

The following keys are honored when any admin source above the user-writable HKCU tier sets them, regardless of which source provides the rest of the policy. When a [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) is configured, its output is the only source these checks read:

- `sandbox.network.allowManagedDomainsOnly` and `sandbox.filesystem.allowManagedReadPathsOnly`: when locked, the corresponding allowlists are unioned across sources
- [`allowAllClaudeAiMcps`](/docs/en/settings#available-settings): allow-only override for the claude.ai MCP server allowlist
- `sandbox.bwrapPath` and `sandbox.socatPath`: filesystem paths to the [sandbox](/docs/en/sandboxing) helper binaries
- [`forceRemoteSettingsRefresh`](/docs/en/server-managed-settings): blocks startup until remote managed settings are freshly fetched, so an MDM or file policy that sets it is honored even when a cached remote payload that lacks the key is the highest-priority source

Every other key, including `disableBypassPermissionsMode`, comes from the highest-priority source only. Two [parent-settings](/docs/en/claude-apps-gateway#restrict-parent-settings) checks read every admin source:

- When any admin source sets `allowManagedPermissionRulesOnly`, Claude Code drops parent-supplied permission allow rules and `additionalDirectories`. The key’s effect on the developer’s own rules still follows the highest-priority source.
- A `forceLoginOrgUUID` or `allowedMcpServers` value in any admin source blocks a parent-supplied one. The value that applies still comes from the highest-priority source.

See [Settings precedence](/docs/en/settings#settings-precedence) for the same rules on the settings page. Gateway policies apply to every Claude Code invocation on the machine, including non-interactive `claude -p` runs and sessions spawned by the Agent SDK. If the gateway is unreachable at startup, signed-in sessions exit with an error rather than running without their policy.

`mcpServers` inside a policy’s `cli` block is rejected at gateway boot. Per-group MCP distribution is not available; deploy MCP servers via the file-based `managed-mcp.json` on each device or let developers add them locally.


[​](#telemetry)

`telemetry`

The CLI sends OpenTelemetry Protocol (OTLP) over HTTP metrics, logs, and, when enabled, traces to the gateway, which relays them verbatim to each configured destination. See [Monitoring usage](/docs/en/monitoring-usage) for the metrics and events the CLI emits. The CLI stamps each export with the authenticated user’s identity, read from the gateway-issued JWT: the `user.id`, `user.email`, and `user.groups` attributes. Per-developer cost and usage attribution therefore works with no developer-side configuration.

```python
telemetry:
  forward_to:
    - url: https://otel-collector.internal.example.com
      headers:
        Authorization: ${OTLP_TOKEN}
      # Per-signal opt-in. Default: metrics only.
      metrics: true
      logs: false
      traces: false
    - url: https://api.datadoghq.com/api/v2/otlp
      headers:
        DD-API-KEY: ${DD_API_KEY}
```

Each destination opts into `metrics`, `logs`, and `traces` independently, and the default is metrics only. The signals differ in sensitivity:

- **Metrics**: aggregate counters such as token counts, request counts, and latency
- **Logs and traces**: can carry full bash commands, tool inputs, and file paths, covering anything Claude Code does on a developer’s machine

Enable logs and traces only on destinations with the access controls and retention policy that data warrants.

Telemetry is off in the CLI by default. Configuring `telemetry.forward_to` together with `listen.public_url` turns it on. The gateway pushes six env vars to every connected client through `/managed/settings`:

- `CLAUDE_CODE_ENABLE_TELEMETRY=1`
- `OTEL_METRICS_EXPORTER=otlp`
- `OTEL_LOGS_EXPORTER=otlp`
- `OTEL_TRACES_EXPORTER=otlp`
- `OTEL_EXPORTER_OTLP_ENDPOINT=<public_url>`
- `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`

The pushed endpoint is built from the public URL, so metrics and logs need no OTEL configuration from developers or policies. The pushed configuration is applied at the managed tier, overriding `OTEL_*` variables a developer sets locally. [Traces](/docs/en/monitoring-usage#traces-beta) additionally require `CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1` on each client. The gateway doesn’t push that variable, so set it through a managed policy’s `env` block. It isn’t among the variables Claude Code applies without the developer’s approval, so delivering it through a policy is covered by the same [security approval dialog](#managed) that the pushed OTLP endpoint already triggers. Both protobuf and JSON OTLP encodings are relayed, and any OpenTelemetry-compatible backend works as a destination.


[​](#http-tuning)

HTTP tuning

Four optional top-level blocks, `access_control`, `limits`, `timeouts`, and `rate_limits`, tune the HTTP surface. The defaults suit most deployments.

| Block            | Key                                            | Default  | Description                                                                                                                                                                                                                                                                                                                              |
|------------------|------------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `access_control` | `allow_cidrs` / `deny_cidrs`                   | empty    | Inbound IP allow/deny by client address, after `trusted_proxies` resolution. `deny_cidrs` is checked first; a client it matches is rejected even if `allow_cidrs` also matches. If `allow_cidrs` is non-empty the gateway is default-deny. `/healthz` and `/readyz` are exempt from `allow_cidrs`.                                       |
| `limits`         | `max_request_bytes`                            | 32 MiB   | Max inbound request body; oversize requests get `413` before the body is buffered. Raise for large file or image requests.                                                                                                                                                                                                               |
| `limits`         | `max_request_header_bytes`                     | unset    | When set, oversize headers return `431`                                                                                                                                                                                                                                                                                                  |
| `limits`         | `max_url_length`                               | unset    | When set, an over-long URL returns `414`                                                                                                                                                                                                                                                                                                 |
| `timeouts`       | `upstream_ttfb_ms`                             | 120000   | Max wait for the upstream’s response headers (time to first byte). The response body then streams with no wall-clock cap. Applies to the direct Anthropic upstream path; every other provider is bounded by its provider SDK’s own timeout.                                                                                              |
| `rate_limits`    | `device_authorization.max` / `.window_seconds` | 30 / 600 | Per-IP rate limit on the unauthenticated device-authorization endpoint. Raise for a large org behind a shared egress IP or NAT. These limits apply only to the device-grant sign-in flow, not to `/v1/messages` inference. See [User-code brute-force resistance](/docs/en/claude-apps-gateway-deploy#user-code-brute-force-resistance). |
| `rate_limits`    | `device_verify.max` / `.window_seconds`        | 10 / 600 | Per-IP rate limit on `user_code` submissions at `/device`                                                                                                                                                                                                                                                                                |


[​](#complete-example)

Complete example

This full reference config exercises every core section; the [HTTP tuning blocks](#http-tuning) keep their defaults. Copy it, delete what you don’t need, and fill in your values. The config in the [Quickstart](/docs/en/claude-apps-gateway#quickstart) is a minimal version of this.

gateway.yaml

```python
# Run with:
#   claude gateway --config gateway.yaml
# Operational log verbosity is controlled by the CLAUDE_GATEWAY_LOG_LEVEL
# environment variable (info | warn | error; default info). It does not
# affect audit events, which are always emitted.

listen:
  host: 0.0.0.0
  port: 8080
  public_url: https://claude-gateway.internal.example.com
  # Omit the tls block when running behind a TLS-terminating ingress.
  # tls:
  #   cert: /certs/gateway.crt
  #   key: /certs/gateway.key
  # trusted_proxies:
  #   - 10.0.0.0/8

oidc:
  issuer: https://example.okta.com
  client_id: 0oa1example2
  client_secret: ${OIDC_CLIENT_SECRET}
  allowed_email_domains:
    - example.com
  # Required when the issuer is the Okta org server, whose id_tokens
  # can omit email and groups; the gateway fills them from /userinfo.
  userinfo_fallback: true
  # allowed_groups: [claude-code-users]
  # Okta emits groups only when the `groups` scope is requested and the
  # app's groups claim filter allows them. The contractors policy below
  # matches on groups, so the scope is requested here.
  scopes: [openid, profile, email, offline_access, groups]
  # extra_auth_params: { access_type: offline, prompt: consent }  # Google
  # groups_claim: groups          # Entra app roles: use `roles`
  # email_claim: email

session:
  jwt_secret: ${GATEWAY_JWT_SECRET}   # openssl rand -base64 32
  # ttl_hours: 1

store:
  postgres_url: ${GATEWAY_POSTGRES_URL}
  # max_connections: 5

# Enables /v1/organizations/spend_limits (mirrors the Anthropic Admin API)
# and per-developer spend enforcement on /v1/messages. Omit to disable.
# Caps themselves are set via the admin API, not here.
# admin:
#   write_keys:
#     - { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
#   read_keys:
#     - { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
#   admin_groups: [platform-finops]
#   blocked_message: request an increase at https://go.example.com/claude-limits
#   # audit_retention_days: 365
#   # spend_retention_months: 13
#   # identity_retention_days: 90
#   # group_limit_mode: min

# enforcement:
#   fail_closed_on_error: false

upstreams:
  - provider: anthropic
    auth:
      api_key: ${ANTHROPIC_API_KEY}

  # - provider: bedrock
  #   region: us-east-1
  #   auth: {}

  # - provider: anthropicAws
  #   region: us-east-1
  #   workspace_id: wrkspc_...
  #   auth:
  #     api_key: ${ANTHROPIC_AWS_API_KEY}

  # - provider: vertex
  #   region: us-east5
  #   project_id: example-prod
  #   auth: {}

  # - provider: foundry
  #   resource: example-foundry
  #   auth: { use_azure_ad: true }

auto_include_builtin_models: true
models:
  - id: claude-opus-4-8
    label: Claude Opus 4.8
    upstream_model:
      anthropic: claude-opus-4-8
      # bedrock: us.anthropic.claude-opus-4-8
      # anthropicAws: claude-opus-4-8
      # vertex: claude-opus-4-8
      # foundry: <your-opus-deployment-name>
  - id: claude-sonnet-4-6
    label: Claude Sonnet 4.6
    upstream_model:
      anthropic: claude-sonnet-4-6
  - id: claude-haiku-4-5
    label: Claude Haiku 4.5
    upstream_model:
      anthropic: claude-haiku-4-5

managed:
  policies:
    - match: { groups: [contractors] }
      cli:
        availableModels: [claude-haiku-4-5]
        # Constrain the Default picker option to availableModels instead of
        # the tier default, so contractors don't get a 400 on the default.
        enforceAvailableModels: true
        # allow auto-approves these tools; it does not block the rest.
        # Add deny rules to restrict tools.
        permissions: { allow: [Read, Grep] }
    - match: {}
      cli:
        availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
        permissions:
          allow: [Read, Grep, Bash, Edit]
          deny: ["WebFetch"]
        env: { HTTP_PROXY: http://proxy.example.com:8080 }

telemetry:
  forward_to:
    - url: https://otel.internal.example.com:4318
      headers:
        Authorization: Bearer ${OTEL_TOKEN}
```


[​](#client-side-managed-settings)

Client-side managed settings

Everything above configures the gateway server. You point developer machines at the gateway separately, on each device, through Claude Code’s [managed settings](/docs/en/settings#settings-files). The gateway can’t push the login keys itself, because they’re what tell the client where the gateway is. For the CLI, set these keys in the per-OS `managed-settings.json`. The two login keys route each developer’s `/login` to your gateway:

```python
{
  "forceLoginMethod": "gateway",
  "forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
  "parentSettingsBehavior": "merge"
}
```

`parentSettingsBehavior: "merge"` keeps Claude Desktop’s policy delivery to its embedded Claude Code sessions working; [Deliver policy to Claude Desktop sessions](/docs/en/claude-apps-gateway#deliver-policy-to-claude-desktop-sessions) explains the mechanism and where the opt-in must sit. Deploy the `managed-settings.json` file to each device, typically via your MDM platform. The file path differs by platform:

| Platform      | Path                                                                                                                          |
|---------------|-------------------------------------------------------------------------------------------------------------------------------|
| macOS         | `/Library/Application Support/ClaudeCode/managed-settings.json`, or the `com.anthropic.claudecode` managed preferences domain |
| Linux and WSL | `/etc/claude-code/managed-settings.json`                                                                                      |
| Windows       | `C:\Program Files\ClaudeCode\managed-settings.json`, or Group Policy via the HKLM registry                                    |

A registry policy on Windows or a managed-preferences plist on macOS replaces the `managed-settings.json` file rather than merging with it, apart from the [exception keys and cross-source checks above](#precedence-with-other-managed-sources). All three keys in this snippet follow the highest-priority-source rule, so fleets that deliver policy through Group Policy or configuration profiles must put all three in that mechanism instead. For Claude Desktop, set the `bootstrapUrl` key in Claude Desktop’s own [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration) to `<listen.public_url>/user/bootstrap`. The sign-in flow and per-group policy then match the CLI’s once a policy opts in server-side with a `desktop` key; without the opt-in, `/user/bootstrap` returns 404. See [Claude Desktop overlay](#claude-desktop-overlay) for the server-side half. `forceLoginGatewayUrl`, and the `"gateway"` value of `forceLoginMethod`, are honored only from the admin-controlled managed tier. A developer setting them in their own `~/.claude/settings.json` has no effect.


[​](#related)

Related

- [Claude apps gateway overview](/docs/en/claude-apps-gateway): quickstart and developer connection
- [Deployment guide](/docs/en/claude-apps-gateway-deploy): IdP setup, container image, Kubernetes and Cloud Run, and operations
- [Spend limits](/docs/en/claude-apps-gateway-spend-limits): per-developer caps and the Admin API


---
## claude-apps-gateway-deployment-and-operations-claude-code-docs-8daea5e8ae.md

## On this page

- [Identity provider setup](#identity-provider-setup)
- [Deployment](#deployment)
  - [Container image](#container-image)
  - [Kubernetes](#kubernetes)
  - [Cloud Run](#cloud-run)
  - [Push the gateway URL to developer machines](#push-the-gateway-url-to-developer-machines)
- [Operations](#operations)
  - [Logs](#logs)
  - [Health](#health)
  - [Outage behavior](#outage-behavior)
  - [JWT secret rotation](#jwt-secret-rotation)
  - [Postgres](#postgres)
  - [Upgrades](#upgrades)
- [Security](#security)
  - [Data flow](#data-flow)
  - [Threat model summary](#threat-model-summary)
  - [User-code brute-force resistance](#user-code-brute-force-resistance)
  - [Compliance posture](#compliance-posture)
- [Troubleshooting](#troubleshooting)
- [Related](#related)

Claude apps gateway

# Claude apps gateway deployment and operations

Copy pageCopy page

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.

Copy pageCopy page

This page covers the operational side of running [Claude apps gateway](/docs/en/claude-apps-gateway): registering an OAuth client in your identity provider (IdP), deploying the gateway as a container, and running it day-to-day. For every option in the `gateway.yaml` file the gateway reads at boot, see the [Configuration reference](/docs/en/claude-apps-gateway-config). A production deployment follows four steps in order, and the sections below match them. The first two are where you make choices; the second two are reference material to consult once it’s running.

1.  [Set up your identity provider](#identity-provider-setup): register the OAuth client and check the per-IdP notes for Okta, Entra, and Google
2.  [Deploy the gateway](#deployment): build a pinned container image and run it on Kubernetes, Cloud Run, or your own platform. This section also covers cost, bypass, multiple-gateway, and serverless decisions
3.  [Set up operations](#operations): logs, health probes, outage behavior, secret rotation, and upgrades. Reference for when you’re setting up monitoring and runbooks
4.  [Review the security posture](#security): what data flows where, the threat model, and compliance answers. Reference for a security review

If a sign-in or boot fails along the way, go straight to [Troubleshooting](#troubleshooting), which is keyed on the error you see.

**Deploy on your private network.** Claude Code only connects to a gateway whose address is private. This is a security guard, because a trusted gateway can push settings that run commands on developer machines. Put the gateway you deploy behind an internal load balancer or VPN and give it a hostname that resolves to private IPs only.Anthropic-operated public gateway endpoints are the exception: `/login` accepts them over `https://`. These are a small fixed set of gateways that Anthropic itself operates; they aren’t a deployment option you can select or configure. The list is compiled into Claude Code, so no configuration can add a hostname to it and no gateway you host qualifies for the exemption. Before v2.1.206, `/login` rejected those endpoints like any other public address.


[​](#identity-provider-setup)

Identity provider setup

Register a confidential OAuth/OpenID Connect (OIDC) web application with a single redirect URI, `https://<gateway>/oauth/callback`, and assign it to the users or groups who should have gateway access. Any OIDC-compliant IdP works: Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate, and others. The IdP must meet three requirements:

- Serves `/.well-known/openid-configuration`, over HTTPS in production; the gateway accepts an [`http://` issuer](/docs/en/claude-apps-gateway-config#oidc), and a loopback issuer additionally requires `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1`
- Supports the authorization-code flow. PKCE (Proof Key for Code Exchange) is on by default; disable it with `oidc.use_pkce: false` for IdPs that don’t support it
- Returns `email` and optionally `groups` in the id_token, or serves them from the userinfo endpoint with `oidc.userinfo_fallback: true`

For private PKI, set `oidc.ca_cert_pem`. A few providers handle email and group claims differently:

- **Okta**: the org authorization server at `https://example.okta.com` returns a thin id_token that omits `email` and `groups`, so set `oidc.userinfo_fallback: true` whenever you use it as `issuer`. A custom authorization server such as `https://example.okta.com/oauth2/default` that includes `email` and optionally `groups` in the id_token emits them directly and needs no fallback. Okta emits `groups` only when the `groups` scope is requested in `oidc.scopes` and the app’s groups claim filter allows it; `userinfo_fallback` can’t fill a claim the IdP wasn’t asked for.
- **Microsoft Entra ID**: `issuer` = `https://login.microsoftonline.com/<tenant-id>/v2.0`. Entra emits group Object IDs rather than names, so use the GUIDs in `managed.policies.match.groups`, or use App Roles for human-readable names. If your tenant emits roles under `roles` instead of `groups`, set `oidc.groups_claim: roles`.
- **Google Workspace**: `issuer` = `https://accounts.google.com`. Google’s id_token doesn’t carry groups. To use group-based `allowed_groups` or `managed.policies` with Google as the IdP, configure [`oidc.google_groups`](/docs/en/claude-apps-gateway-config#oidc), which looks up each user’s groups through the Admin SDK Directory API using a service account with domain-wide delegation. Without it, use `oidc.allowed_email_domains` for membership gating and `managed.policies.match.email_domain` for policy assignment. Google also ignores the standard `offline_access` scope. For refresh tokens, set `oidc.scopes: [openid, profile, email]` and `oidc.extra_auth_params: { access_type: offline, prompt: consent }`.

For support with an identity provider not covered above, see [Troubleshooting](#troubleshooting).

Refresh tokens let the gateway renew a developer’s session silently, without sending the developer back to the browser. They also drive deprovisioning, because when the IdP disables a user, the next refresh fails and the session ends within `ttl_hours`. The gateway requests `offline_access` by default to get a refresh token. If your IdP requires explicit consent for offline access, configure the OAuth client to allow it.If your IdP can’t issue refresh tokens at all, the gateway still works, but there is no silent renewal, so developers re-run the browser login when their session expires. To keep that from happening every hour, raise [`session.ttl_hours`](/docs/en/claude-apps-gateway-config#session) to `8` or `12`. The tradeoff is deprovisioning latency, because without refresh tokens a disabled user keeps access until the longer TTL elapses.


[​](#deployment)

Deployment

The gateway is a single Linux binary. It scales horizontally because replicas are stateless and Postgres is the shared coordination layer. Run it however you run stateless services in your environment. The rest of this section states what the image needs, with short notes for Kubernetes and Cloud Run. The gateway is designed to run inside your network, because it holds your upstream credential and acts as the single egress point for inference. It can run anywhere your developers and your IdP can reach over HTTPS; treat it like any other service holding a production credential. A few decisions shape the deployment beyond where it runs:

- **Cost**: there is no separate license or per-seat fee for the gateway; it’s part of the `claude` binary. You pay for inference through your existing cloud or Anthropic commitment, plus the compute for the container and your telemetry collector.
- **Bypass**: the gateway doesn’t enforce that the only route to a model goes through it. A developer with their own credential can still call the provider directly, so closing that path is a network policy decision, for example blocking egress to `api.anthropic.com` except from the gateway. Blocking that egress also breaks the [WebFetch domain safety check](/docs/en/data-usage#webfetch-domain-safety-check), which calls `api.anthropic.com` from each developer’s machine; set `skipWebFetchPreflight: true` in the managed policy to disable it.
- **Multiple gateways**: each gateway is a separate deployment with its own config. The CLI stores its trust fingerprint and credentials per gateway hostname, so different teams can connect to different gateways without conflict. To serve multiple OIDC issuers, run separate instances.
- **Serverless**: Cloud Run works; set `min-instances: 1` to avoid cold OIDC discovery. Lambda and Cloud Functions don’t, because the gateway is a long-running HTTP server.

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


[​](#container-image)

Container image

Build your own image around the native `claude` binary from the standard Claude Code release:

1.  Download the Linux build for your image architecture from a pinned release; see [Install a specific version](/docs/en/setup#install-a-specific-version) for the download URL.
2.  Verify it against the release’s GPG-signed `manifest.json` as described in [Binary integrity and code signing](/docs/en/setup#binary-integrity-and-code-signing).
3.  Copy it into the build context.

Mirror the release into your internal registry if your builds can’t reach the release host, and pin the version your fleet runs. Beyond the binary, the image needs:

- **A glibc-based image**: the glibc build’s only dynamic dependencies are glibc libraries. Musl-based images need the `linux-x64-musl` or `linux-arm64-musl` build plus additional packages; see [Alpine Linux setup](/docs/en/setup#alpine-linux-and-musl-based-distributions).
- **A writable state directory**: the gateway runs as any user, but minimal images have no writable home. Set `CLAUDE_CONFIG_DIR` to a writable path such as `/tmp/.claude`.
- **The container command**: `claude gateway --config /etc/claude/gateway.yaml`, with the config file mounted read-only and secrets supplied as environment variables; the gateway listens on `listen.port`, default `8080`.


[​](#kubernetes)

Kubernetes

Run the gateway as a Deployment, like any stateless service:

- Mount the config from a ConfigMap and secrets from a Secret; reference secrets in the YAML via `${file:/path/to/secret}` or as environment variables
- Terminate TLS at the Ingress and set `listen.public_url` to the Ingress hostname
- Point the readiness probe at `GET /readyz` and the liveness probe at `GET /healthz`

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

**Workload identity**Prefer the platform’s workload identity over static keys: IRSA on EKS for Amazon Bedrock and for Claude Platform on AWS, Workload Identity on GKE for Google Cloud’s Agent Platform, and workload identity on AKS for Microsoft Foundry. Set `auth: {}` in the upstream block, or `use_azure_ad: true` for Microsoft Foundry, and the gateway picks up the pod’s identity through that provider’s default credential chain. For a cross-cloud pairing, such as an Amazon Bedrock upstream on GKE, set explicit credentials in the upstream’s `auth` block instead. The [`upstreams` reference](/docs/en/claude-apps-gateway-config#upstreams) has per-platform setup details.


[​](#cloud-run)

Cloud Run

Configure the service as follows:

- Leave `listen.port` at its default of `8080`, which matches Cloud Run’s default `PORT`, or set `port: ${PORT}`
- Set `public_url` to the externally reachable origin. For production this is normally an internal load balancer’s hostname, because `/login` [rejects public addresses](/docs/en/claude-apps-gateway#prerequisites) and the `*.run.app` URL resolves to one, so the Cloud Run URL alone works only for a `curl` or browser smoke test. The exception is a network where `*.run.app` resolves privately through Private Service Connect and a Cloud DNS private zone; in that topology the Cloud Run URL is a valid `public_url`. The [Google Cloud worked example](/docs/en/claude-apps-gateway-on-gcp#deploy-the-gateway) covers both.
- Mount the config as a secret volume
- Set `min-instances: 1` to avoid a cold OIDC discovery on first request

For a complete worked example on Google Cloud, covering Cloud Run or GKE, Cloud SQL, and Secret Manager, see [Deploy on Google Cloud](/docs/en/claude-apps-gateway-on-gcp).


[​](#push-the-gateway-url-to-developer-machines)

Push the gateway URL to developer machines

Once the gateway is serving, push `forceLoginMethod`, `forceLoginGatewayUrl`, and `parentSettingsBehavior: "merge"` to each developer’s machine through managed settings, via MDM or by writing the per-OS `managed-settings.json` directly. Without this, `/login` shows the standard account picker with no gateway option. See [Client-side managed settings](/docs/en/claude-apps-gateway-config#client-side-managed-settings) for the file paths and the Claude Desktop `bootstrapUrl` equivalent.


[​](#operations)

Operations

Once the gateway is serving traffic, day-to-day operation is reading its logs, probing its health, and rotating its secrets on your schedule. The subsections cover each, plus what Postgres holds and how upgrades and rollbacks behave.


[​](#logs)

Logs

The gateway writes two streams to stderr, both JSON-friendly:

- **Audit events**: single-line JSON per security-relevant event. Pipe stderr to your log aggregator. The events emitted include `config.load`, `session.mint`, `session.refresh`, `device.authorize`, `device.verify`, `auth.denied`, `access.denied`, `inference`, `managed.serve`, `desktop_bootstrap.serve`, `desktop_bootstrap.denied`, `spend.blocked`, and `admin.denied`. Fields vary by event:
  - Successful mint and refresh events carry `sub`, `email`, `client_ip`, and the result
  - `auth.denied` and `access.denied` carry the reason and client IP, plus the request path for `auth.denied`, since no user identity exists at those denials
  - `inference` records which upstream served the request and the response status
  - `desktop_bootstrap.denied` records a rejected Claude Desktop bootstrap fetch with the reason (`not_configured`, `policy_not_opted_in`, or `no_policy_matched`) and the user’s identity
  - `admin.denied` records a rejected admin-API auth attempt with the reason (`invalid_key` or `no_credentials`), client IP, method, and path, without the presented key material
- **Operational logs**: human-readable `[gateway]`-prefixed lines for boot, warnings, and upstream errors. The `CLAUDE_GATEWAY_LOG_LEVEL` environment variable controls verbosity and accepts `info`, `warn`, or `error`, with `info` as the default. It doesn’t affect audit events, which are always emitted.


[​](#health)

Health

The gateway serves `GET /healthz` as a liveness probe and `GET /readyz` as a readiness probe; `/readyz` verifies the store is reachable. Both are exempt from `access_control.allow_cidrs`, so probes keep working on a locked-down listener. The OAuth discovery document at `/.well-known/oauth-authorization-server` also returns `200` only after config load, OIDC discovery, upstream client construction, and Postgres migration all succeed, so it doubles as an end-to-end boot check. A running gateway also serves a description of the paths and request shapes it accepts at `<public_url>/protocol`, matched to the version you’re running. The contents aren’t stable across releases.


[​](#outage-behavior)

Outage behavior

If Postgres goes down, the gateway itself keeps serving signed-in developers and new sign-ins fail. Whether developers actually keep working depends on how your orchestrator handles readiness:

- **Existing sessions**: bearer tokens validate locally with the JWT secret, session refreshes don’t touch the store, and the gateway process can still serve inference
- **New sign-ins**: fail until Postgres recovers, because the device flow and its rate-limit counters live in Postgres
- **[Spend-limit enforcement](/docs/en/claude-apps-gateway-spend-limits#postgres-availability)**: fails open by default during the outage, so inference still flows; flip it to fail closed if you’d rather block than run unmetered
- **Readiness**: `/readyz` reports not-ready during the outage, so orchestrators that gate traffic on readiness remove every replica from rotation at once. In that topology all traffic, including inference the gateway could still serve, fails at the load balancer until Postgres recovers. The liveness probe on `/healthz` keeps passing, so replicas aren’t restarted. Point the readiness probe at `/healthz` instead if you’d rather signed-in developers keep working through a store outage; the cost is that new sign-ins fail against a replica that still reports ready.

If your IdP goes down, existing sessions work until `ttl_hours`, and new logins and refreshes fail. Set a longer `ttl_hours` if your IdP has frequent maintenance windows.


[​](#jwt-secret-rotation)

JWT secret rotation

Rotate the signing secret in three steps so existing sessions stay valid:

1.  Generate a new secret. Prepend it to the `session.jwt_secret` array.
2.  Roll the deployment. New tokens sign with the new secret; old tokens still verify.
3.  After `ttl_hours` plus a margin, remove the old secret and roll again.

Rotation is also the only way to force sessions out before they expire: bearer tokens validate locally against the JWT secret, so there is no per-session revocation. Replacing the secret outright, without keeping the old one in the array, invalidates every outstanding session at once. For individual offboarding, deprovision the user in your IdP; their session ends within `ttl_hours`.


[​](#postgres)

Postgres

The gateway holds five tables, all created by its boot-time migrations:

| Table              | Contents                                                                      | Retention                                                       |
|--------------------|-------------------------------------------------------------------------------|-----------------------------------------------------------------|
| `kv`               | Device grants (10-minute TTL) and rate-limit counters                         | TTL per row                                                     |
| `spend`            | Per-principal period-to-date spend counters, in cents                         | `admin.spend_retention_months`, default 13                      |
| `spend_limits`     | Configured spend caps                                                         | Until deleted via the API                                       |
| `admin_audit`      | Admin API mutation trail                                                      | `admin.audit_retention_days`, default 365                       |
| `principal_emails` | Each principal’s last-seen email, display name, and IdP groups. Contains PII. | `admin.identity_retention_days` since last activity, default 90 |

A 30-second loop expires `kv` rows past their TTL, and an hourly sweep enforces the retention windows on the spend tables, so nothing grows without bound. Without [spend limits](/docs/en/claude-apps-gateway-spend-limits) configured, only `kv` is written. If your security policy prohibits DDL from the application role, pre-create these tables and `_migrations` with an admin role and grant the app role `SELECT, INSERT, UPDATE, DELETE` on each. With spend limits in use, a lost database means lost spend tracking and caps, not only developer re-logins, so run regular backups. To erase one departed developer immediately rather than waiting on retention, run `DELETE FROM principal_emails WHERE principal = '<sub>'` directly; that removes the only table holding their email, name, and groups. `spend` and `admin_audit` rows reference the pseudonymous OIDC `sub` only.


[​](#upgrades)

Upgrades

Replicas are stateless, so a rolling restart is safe at any time. The gateway runs schema migrations at boot, which means deploying the new binary self-migrates the database. If the database role can’t run DDL, pre-create the schema, including the `_migrations` table seeded to the current version; otherwise boot fails attempting `CREATE TABLE`. Migrations are append-only, so rolling back to a prior binary that knows fewer migrations is safe; it ignores the extra rows. Rollback also re-validates the YAML against the older binary’s schema, so a config that adopted a key introduced by the newer release fails boot on the older one. Remove the new key before rolling back. Because you pin the gateway’s version in your own image, fixes in new Claude Code releases, including security fixes, reach your deployment only when you update the pin and redeploy. Include the gateway in the same patching cadence you use for other services that hold production credentials.


[​](#security)

Security

This section answers the questions a security review asks: what data flows through the gateway and where it goes, which attacks the design defends against, and which answers belong in a compliance questionnaire.


[​](#data-flow)

Data flow

| Data                                                                                                   | Path                                                         | Sent to Anthropic by the gateway                   |
|--------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|----------------------------------------------------|
| Inference (prompts, completions)                                                                       | CLI → gateway → your upstream                                | Only if the Anthropic API is a configured upstream |
| Telemetry (OTLP metrics, plus [opt-in logs and traces](/docs/en/claude-apps-gateway-config#telemetry)) | CLI → gateway → your collector                               | Never                                              |
| Identity (email, groups, sub)                                                                          | IdP → gateway → JWT → CLI; the CLI stamps it on OTLP exports | Never                                              |
| Managed settings                                                                                       | Your gateway YAML → CLI                                      | Never                                              |
| Audit log                                                                                              | Gateway stderr → your aggregator                             | Never                                              |


[​](#threat-model-summary)

Threat model summary

The gateway sits inside your network perimeter, but individual developer laptops aren’t treated as trusted. The design accounts for this in three ways:

- Developers hold short-lived JWTs instead of raw upstream keys. The CLI-to-gateway leg uses the RFC 8628 device grant, and the gateway’s authorization-code exchange with the IdP runs PKCE in the default configuration, so an intercepted IdP authorization code is useless.
- The device-verification page enforces same-origin POST and a per-IP rate limit per RFC 8628 §5.1. See [User-code brute-force resistance](#user-code-brute-force-resistance).
- Outbound requests go through a server-side request forgery (SSRF) guard that resolves DNS, blocks link-local and cloud-metadata addresses plus loopback by default, and pins the connection to the resolved IP, so operator-influenced URLs such as the IdP and OTLP destinations can’t be redirected to cloud metadata endpoints. RFC 1918 private ranges are deliberately allowed, because IdPs and OTLP collectors commonly live on private IPs. For local development against a loopback IdP or collector, set `CLAUDE_GATEWAY_ALLOW_LOOPBACK=1` in the gateway’s environment; leave it unset in production.

If you add your own egress controls, the gateway must reach the metadata server whenever it uses instance-metadata credentials such as workload identity. Two threats are out of scope because they are your infrastructure to secure:

- **A compromised gateway host**: the host both holds the upstream credential and distributes [managed settings](/docs/en/claude-apps-gateway-config#managed) to every connected developer, so control over the gateway’s configuration is comparable to control over your MDM. The CLI’s one-time approval dialog for shell-capable settings limits silent changes but doesn’t replace host security.
- **A malicious OIDC provider**: the provider signs the id_tokens the gateway trusts, so it can assert any identity. Vetting and securing your IdP is your responsibility.


[​](#user-code-brute-force-resistance)

User-code brute-force resistance

The `user_code` a developer types into the `/device` verification page is 8 characters drawn from a 20-character alphabet, which yields 20⁸ or about 2.56×10¹⁰ combinations, and it expires after 10 minutes. The gateway applies per-IP rate limits on the device-grant endpoints, configurable via [`rate_limits`](/docs/en/claude-apps-gateway-config#http-tuning). Raise the limits if many developers sign in from a single shared corporate NAT address. The limits apply only to the sign-in flow, not to inference.


[​](#compliance-posture)

Compliance posture

- **Data residency**: the gateway’s own data plane sends nothing to Anthropic unless the Anthropic API is a configured upstream; when it is, your existing data-handling agreement applies to the inference path. Telemetry, audit, identity, and settings go only to the destinations you configure.
- **Host-process traffic**: the host process is the Claude Code CLI, which can send startup analytics and update checks to Anthropic. For strict-egress deployments, set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` in the gateway’s container environment.
- **Client analytics**: the CLI disables its own usage analytics while signed in to a gateway, and error reporting is off by default on third-party API surfaces.
- **Client machines**: developers’ CLIs still send WebFetch hostname checks and version checks to Anthropic unless `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` and `skipWebFetchPreflight: true` are set. See [data usage](/docs/en/data-usage).
- **Survey ratings**: the gateway credential disables the Anthropic-bound rating sink, so ratings aren’t sent to Anthropic.
- **Transcript sharing**: choosing Yes on a survey’s transcript-share prompt writes a local file under `~/.claude/feedback-bundles/` instead of uploading to Anthropic.
- **Client updates**: update checks are separate from gateway traffic. Pin versions through your own distribution and set `DISABLE_UPDATES` if laptops must not fetch releases. `DISABLE_AUTOUPDATER` stops only background updates while `claude update` still works.
- **TLS**: serve `public_url` over HTTPS in production, either from the gateway’s own listener via `listen.tls` or from a TLS-terminating ingress in front of plain-HTTP replicas with `listen.public_url` set. The gateway doesn’t refuse plain HTTP. The IdP must serve HTTPS in production, and Postgres supports `?sslmode=require`. Set `Strict-Transport-Security` at your ingress.
- **Vulnerability disclosure**: follow [Reporting security issues](/docs/en/security#reporting-security-issues)


[​](#troubleshooting)

Troubleshooting

For questions and feedback, use [Claude Code support](https://support.claude.com/en/collections/14445694-claude-code), or open an issue on the [Claude Code GitHub repository](https://github.com/anthropics/claude-code/issues). When reporting a problem, include:

- **Gateway issue**: the gateway’s stderr for the relevant window, your `gateway.yaml` with secrets redacted, the gateway version, shown on the landing page at `/` and in the `x-cc-gateway-version` response header on `/managed/settings`, and what changed recently
- **Login issue**: the developer runs `claude --debug-file ./claude-debug.txt`, reproduces, and sends that file plus the gateway’s audit log for the same window
- **Inference issue**: the model requested, the upstreams configured, and the gateway’s audit log for the request, which records which upstream served it and the response status

The gateway’s stderr includes the audit event stream, the audit log records developer identities, and the debug file records hook and MCP server output from the developer’s machine. Review and redact these before posting to a public issue.

| Symptom                                                                                                                                                                     | Cause                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Fix                                                                                                                                                                                                                                                                                                                                                                                                                                   |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| A developer’s `/login` shows the standard account picker instead of the **Cloud gateway** screen                                                                            | `forceLoginMethod` or `forceLoginGatewayUrl` isn’t set in managed settings on that machine                                                                                                                                                                                                                                                                                                                                                                                                                             | Deploy the [managed settings file](/docs/en/claude-apps-gateway#set-the-gateway-url) to the device; `/login` reads the gateway URL from there                                                                                                                                                                                                                                                                                         |
| Claude Desktop reports that its bootstrap configuration couldn’t be fetched                                                                                                 | `/user/bootstrap` returned 404: the policy matching the user doesn’t carry a `desktop` key, or no policy matched. The gateway’s audit log records each rejection as `desktop_bootstrap.denied` with the reason.                                                                                                                                                                                                                                                                                                        | Add a `desktop` block to the policy that matches the user, or to the `match: {}` base layer; an empty `desktop: {}` suffices. See [Claude Desktop overlay](/docs/en/claude-apps-gateway-config#claude-desktop-overlay).                                                                                                                                                                                                               |
| Startup shows `Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support.`                                         | The installed Claude Code build predates gateway support                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Have the developer update Claude Code to a release that includes Cloud gateway support                                                                                                                                                                                                                                                                                                                                                |
| CLI `/login`: `Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip>`                                  | The gateway hostname resolves to at least one public IP address. Claude Code checks each resolved address and requires every one to be private. A common cause is a dual-stack name where one family resolves to a public address, including AWS internal dual-stack load balancers, which return public-range AAAA addresses. Anthropic-operated public gateway endpoints are exempt from the check, and `/login` accepts them over `https://`. Before v2.1.206, `/login` rejected them like any other public address | Have the gateway name resolve only to private addresses on developer machines. For a dual-stack name, drop the public-range record or serve a separate internal-only DNS name. See the [private-network prerequisite](/docs/en/claude-apps-gateway#prerequisites).                                                                                                                                                                    |
| CLI `/login`: `Gateway login requires a direct connection and does not support connecting through an HTTP proxy`                                                            | An `HTTPS_PROXY` or `HTTP_PROXY` applies to the gateway host and the proxy’s hostname resolves to a public address. A proxy whose host resolves only to private addresses is allowed and doesn’t trigger this error                                                                                                                                                                                                                                                                                                    | Add the gateway host to `NO_PROXY` on the developer’s machine so the connection is direct, or use a proxy whose hostname resolves to private addresses                                                                                                                                                                                                                                                                                |
| CLI `/login`: `Could not resolve gateway host <host>`                                                                                                                       | The machine can’t resolve the gateway’s internal DNS name, typically because it isn’t on the corporate network                                                                                                                                                                                                                                                                                                                                                                                                         | Have the developer connect to your network or VPN, then retry `/login`                                                                                                                                                                                                                                                                                                                                                                |
| Boot exits with a config validation error naming `store.postgres_url`                                                                                                       | No Postgres configured; the gateway requires Postgres                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Set `store.postgres_url`. For local development, use a throwaway container: `docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres`.                                                                                                                                                                                                                                                                               |
| Boot exits: `requires the native binary`                                                                                                                                    | Running under Node instead of the native binary                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Install Claude Code with one of the [standalone install methods](/docs/en/setup)                                                                                                                                                                                                                                                                                                                                                      |
| Boot exits with an OIDC discovery error after `config.load`                                                                                                                 | `oidc.issuer` unreachable, or TLS chain not trusted                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Check the issuer is reachable from the pod and serves `/.well-known/openid-configuration`. Set `ca_cert_pem` for private PKI.                                                                                                                                                                                                                                                                                                         |
| Boot exits with a Postgres permission error                                                                                                                                 | App role lacks `CREATE TABLE`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | Pre-create the schema with an admin role and grant DML to the app role, or grant DDL temporarily for boots that apply new migrations                                                                                                                                                                                                                                                                                                  |
| `/oauth/callback` shows “Sign-in could not be completed”                                                                                                                    | Email domain rejected, id_token validation failed, or `email_verified` is explicitly `false`, which the gateway always rejects with no override                                                                                                                                                                                                                                                                                                                                                                        | Check `allowed_email_domains` and that the IdP returns a verified `email` claim. For `email_verified: false`, fix the IdP-side verification. If your IdP emits email under a different claim name, set `oidc.email_claim`.                                                                                                                                                                                                            |
| Log: `token exchange failed: id_token missing email claim`                                                                                                                  | The IdP isn’t including `email` in the id_token by default. This rejection fires only when `allowed_email_domains` is set; without it, a missing email mints a session with no email                                                                                                                                                                                                                                                                                                                                   | Configure the IdP to emit `email` in the id_token. Okta: add `email` to a custom authorization server’s ID-token claims. Entra: add `email` as an optional claim on the app registration. PingFederate: enable an OpenID Connect Policy that emits `email`. If the IdP serves `email` from the userinfo endpoint but won’t include it in the id_token, such as the Okta org authorization server, set `oidc.userinfo_fallback: true`. |
| Every Amazon Bedrock request returns 502; log shows `Could not load credentials from any providers`                                                                         | On EC2, IMDSv2’s default hop limit of 1 blocks the instance-metadata request from inside the container. Boot and `/readyz` pass anyway because the AWS SDK resolves instance credentials on the first request, not at client construction                                                                                                                                                                                                                                                                              | Raise the hop limit with `aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2`, or set it in the launch template. The change applies to every container on the instance. Prefer ECS task roles where available, which read credentials from the ECS container-credentials endpoint and avoid the change entirely, or apply the change on a dedicated gateway instance to limit the exposure.  |
| IdP error: unknown or unsupported scope                                                                                                                                     | The IdP rejects scopes it doesn’t recognize                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Set `oidc.scopes` to exactly the list your IdP accepts; it must include `openid`. The default is `openid profile email offline_access`.                                                                                                                                                                                                                                                                                               |
| Sessions don’t silently renew after setting `oidc.scopes`                                                                                                                   | `offline_access` was dropped from the override                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Add `offline_access` back if your IdP supports it. Without a refresh token, developers re-run the browser login every `session.ttl_hours`.                                                                                                                                                                                                                                                                                            |
| Browser shows “This request came from another site and was blocked”                                                                                                         | Cross-site form POST, blocked as CSRF protection. Expected for embedded or proxied pages                                                                                                                                                                                                                                                                                                                                                                                                                               | Open the verification link directly                                                                                                                                                                                                                                                                                                                                                                                                   |
| Chrome blocks the Approve button with “Refused to send form data … violates … Content Security Policy directive: form-action”, but the same page works in Safari or Firefox | Chrome enforces `form-action` against the entire redirect chain. Your IdP redirects onward to a second host that isn’t allowlisted.                                                                                                                                                                                                                                                                                                                                                                                    | Add each additional origin in the redirect chain to `oidc.form_action_origins`. Open Chrome DevTools → Console on the Approve page to see which origin was blocked.                                                                                                                                                                                                                                                                   |
| Sign-in completes at the IdP but the callback fails, with a CSP error in Chrome or “this sign-in link has expired” in Safari                                                | The IdP returned the code via `response_mode=form_post`, which auto-submits it cross-origin via POST to `/oauth/callback`. Chrome blocks that under a strict CSP; Safari allows the submit but the callback reads only the query string.                                                                                                                                                                                                                                                                               | Make sure your IdP honors `response_mode=query`, which the gateway requests explicitly so the callback is a plain redirect                                                                                                                                                                                                                                                                                                            |
| Login works locally but fails behind an ALB                                                                                                                                 | `public_url` not set, so the IdP gets the inner `http://` origin as `redirect_uri`                                                                                                                                                                                                                                                                                                                                                                                                                                     | Set `listen.public_url` to the external `https://` origin                                                                                                                                                                                                                                                                                                                                                                             |
| Developer sees the trust prompt repeatedly                                                                                                                                  | TLS cert is rotating per replica or per request                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Use a stable cert at the ingress, or terminate TLS once and run replicas over plain HTTP internally                                                                                                                                                                                                                                                                                                                                   |
| CLI `/login`: “Could not verify the gateway’s TLS certificate” or `SELF_SIGNED_CERT_IN_CHAIN`                                                                               | Gateway’s TLS chain is signed by a private CA not in the CLI host’s trust store                                                                                                                                                                                                                                                                                                                                                                                                                                        | Claude Code reads the OS trust store by default on the native binary and on Node 22.15 or later; [`CLAUDE_CODE_CERT_STORE`](/docs/en/network-config#ca-certificate-store) controls this behavior. If the CA is installed in the OS trust store, ensure developers are on a current runtime. Otherwise set `NODE_EXTRA_CA_CERTS` to the CA certificate PEM before launching. The first-connect fingerprint prompt still applies.       |


[​](#related)

Related

- [Claude apps gateway overview](/docs/en/claude-apps-gateway): quickstart and developer connection
- [Configuration reference](/docs/en/claude-apps-gateway-config): every `gateway.yaml` option


---
## claude-apps-gateway-for-amazon-bedrock-claude-platform-on-aws-google-cloud-and-m-092e6df913.md

## On this page

- [Why Claude apps gateway](#why-claude-apps-gateway)
  - [Other gateway implementations](#other-gateway-implementations)
- [Quickstart](#quickstart)
  - [Prerequisites](#prerequisites)
  - [Steps](#steps)
- [Connect developers](#connect-developers)
  - [Set the gateway URL](#set-the-gateway-url)
  - [Deliver policy to Claude Desktop sessions](#deliver-policy-to-claude-desktop-sessions)
  - [Which machines need the opt-in](#which-machines-need-the-opt-in)
  - [Set the opt-in](#set-the-opt-in)
  - [Restrict parent settings](#restrict-parent-settings)
  - [Deploy the locks](#deploy-the-locks)
  - [Lock behavior across sources](#lock-behavior-across-sources)
  - [Settings the locks don’t cover](#settings-the-locks-don%E2%80%99t-cover)
  - [Connect Claude Desktop](#connect-claude-desktop)
  - [CI pipelines and remote machines](#ci-pipelines-and-remote-machines)
  - [What’s enforced on developers](#what%E2%80%99s-enforced-on-developers)
  - [What the organization can see](#what-the-organization-can-see)
- [Availability and limitations](#availability-and-limitations)
- [Next steps](#next-steps)

Claude apps gateway

# Claude apps gateway for Amazon Bedrock, Claude Platform on AWS, Google Cloud, and Microsoft Foundry

Copy pageCopy page

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.

Copy pageCopy page

The Claude apps gateway is designed for organizations that must, or prefer to, route inference through their own cloud provider, for example to meet [data residency](/docs/en/claude-apps-gateway-deploy#compliance-posture) requirements. If you don’t have this requirement, and want access to other features such as SCIM provisioning or Claude Code on web and mobile, Claude Enterprise may be a better fit. See the [feature availability](/docs/en/feature-availability) page for a full comparison of all deployment methods.

Claude apps gateway is a self-hosted service that sits between your developers’ Claude Code clients and your model provider. Developers sign in with your corporate identity provider (IdP) instead of holding API keys or cloud credentials. The gateway holds the upstream credential, enforces model access and [managed settings](/docs/en/permissions#managed-settings) by IdP group, and relays usage telemetry to your own observability stack. It is included in the `claude` binary, so the same executable that runs Claude Code on a laptop runs the gateway server with `claude gateway --config gateway.yaml`. This page covers:

- [Why Claude apps gateway](#why-claude-apps-gateway), what it adds over running your own, and when something else fits better
- A [quickstart](#quickstart) with [prerequisites](#prerequisites) that takes a gateway from zero to a signed-in developer
- [Connecting developers](#connect-developers), including setting the gateway URL through managed settings
- [Availability and limitations](#availability-and-limitations) covering which Claude Code features work through the gateway and what the server supports

Companion pages go deeper. The [configuration reference](/docs/en/claude-apps-gateway-config) covers every option in the YAML file the quickstart writes, and the [deployment guide](/docs/en/claude-apps-gateway-deploy) covers per-IdP setup, Kubernetes and Cloud Run deployment, and operations.


[​](#why-claude-apps-gateway)

Why Claude apps gateway

The [gateway overview](/docs/en/gateways) covers what a gateway does and why you’d run one. Claude apps gateway is Anthropic’s own gateway, built into the `claude` binary and tested alongside each Claude Code release, so it forwards the headers and request fields Claude Code sends without operators maintaining a separate allowlist. Once deployed it gives you:

- **Credentials**: the upstream API key or cloud credential lives only in your infrastructure. Developers authenticate with corporate SSO and receive short-lived bearer tokens, so offboarding happens in your IdP. Deprovision a user and their gateway access expires within the session lifetime, one hour by default.
- **Access control**: your IdP groups map to model allowlists and [managed settings](/docs/en/permissions#managed-settings) policies. The gateway enforces model access server-side, rejecting requests for non-granted models, and selects each group’s managed settings policy, which the CLI applies at the [managed settings tier](/docs/en/settings#settings-precedence). Different teams get different models, tools, and permissions, and a developer can’t override what their policy locks.
- **Settings delivery**: the gateway delivers managed settings to signed-in clients itself, taking the place of [server-managed settings](/docs/en/server-managed-settings) from the claude.ai admin console.
- **Telemetry**: each configured destination, such as Datadog, Splunk, or ClickHouse, receives [OpenTelemetry Protocol (OTLP) metrics](/docs/en/monitoring-usage) with token counts, model, user identity, and latency by default, with logs and traces as per-destination opt-ins.
- **Upstream routing**: clients speak the Anthropic Messages API to the gateway, and the gateway translates for each upstream, whether Amazon Bedrock, [Claude Platform on AWS](/docs/en/claude-platform-on-aws), Google Cloud’s Agent Platform, Microsoft Foundry, or the Anthropic API, with failover between them. You can change regions, providers, or failover order without developers noticing or reconfiguring.

The gateway’s own data plane sends nothing to Anthropic infrastructure unless the Anthropic API is a configured upstream. You control where telemetry, audit logs, managed settings, and your developers’ IdP identity go, and the gateway sends none of them to Anthropic. For the remaining traffic the CLI process can send and how to close it, see [Compliance posture](/docs/en/claude-apps-gateway-deploy#compliance-posture).

For which Claude Code features work through the gateway and what the server itself supports, see [Availability and limitations](#availability-and-limitations) below. For decisions such as cost, bypass, running multiple gateways, and serverless platforms, see the [deployment guide](/docs/en/claude-apps-gateway-deploy#deployment).


[​](#other-gateway-implementations)

Other gateway implementations

If you already run an LLM gateway or API gateway that meets your needs, keep using it; [Other LLM gateways](/docs/en/llm-gateway) covers configuring Claude Code against it. The [gateway protocol reference](/docs/en/llm-gateway-protocol) documents the contract Claude Code expects from any gateway: the endpoints it calls, the headers and body fields to forward, and what stops working when they’re stripped. A running Claude apps gateway serves a superset of that contract at `GET /protocol`, adding the Claude apps gateway-specific endpoints for SSO sign-in, managed settings delivery, and telemetry. Fetch it with `curl https://claude-gateway.internal.example.com/protocol` from any deployed gateway, such as the one the [quickstart](#quickstart) below produces. Breaking changes to the protocol are announced in advance, but indefinite backwards compatibility isn’t guaranteed.


[​](#quickstart)

Quickstart

This quickstart walks the minimal path: register an OAuth client in your IdP, write a `gateway.yaml`, run the gateway alongside Postgres with Docker Compose, and verify sign-in end to end. It uses an Amazon Bedrock upstream; Claude Platform on AWS, Google Cloud’s Agent Platform, Microsoft Foundry, and the Anthropic API are equally supported by swapping the `upstreams` block as shown in the [configuration reference](/docs/en/claude-apps-gateway-config#upstreams). At the end you have a gateway a developer can `/login` to.

**Deploy on your private network.** Claude Code only connects to a gateway whose address is private. This is a security guard, because a trusted gateway can push settings that run commands on developer machines. Put the gateway behind an internal load balancer or VPN and give it a hostname that resolves to private IPs only.Anthropic-operated public gateway endpoints are the exception: `/login` accepts them over `https://`. These are a small fixed set of gateways that Anthropic itself operates; they aren’t a deployment option you can select or configure. The list is compiled into Claude Code, so no configuration can add a hostname to it and no gateway you host qualifies for the exemption. Before v2.1.206, `/login` rejected those endpoints like any other public address.


[​](#prerequisites)

Prerequisites

Have these in place before you start:

| You need                                | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Claude Code v2.1.195 or later           | The `claude gateway` subcommand and the gateway sign-in flow ship in v2.1.195. Earlier public builds don’t include them. Both the machine running the gateway server and each developer’s machine must be on v2.1.195 or later; run `claude update` to get the latest release. The [Claude Platform on AWS upstream](/docs/en/claude-apps-gateway-config#claude-platform-on-aws) requires Claude Code v2.1.198 or later on the gateway server.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| OpenID Connect (OIDC) identity provider | Okta, Microsoft Entra ID, Google Workspace, Keycloak, or Dex, or any other OIDC-compliant IdP such as PingFederate. The gateway runs standard OIDC discovery and the authorization-code flow against it. SAML and LDAP aren’t supported.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| PostgreSQL 14 or later                  | Backs the device sign-in flow, where the browser callback writes and the polling CLI reads, plus rate-limit counters. Any managed Postgres works, including the smallest tier. Without spend limits configured, the gateway stores a few KB of short-lived auth state; with [spend limits](/docs/en/claude-apps-gateway-spend-limits), it also holds durable spend, audit, and identity tables that should be backed up. TLS via `?sslmode=require` is recommended.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Model upstream                          | Amazon Bedrock credentials, Claude Platform on AWS credentials, Google Cloud credentials, a Microsoft Foundry resource, or an Anthropic API key. Multiple upstreams are supported with failover.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| HTTPS                                   | The gateway must be reachable over `https://` from developer laptops and from any browser used for sign-in; the gateway serves the device-verification page on the same listener. Either provide a TLS cert via `listen.tls`, or run behind a TLS-terminating ingress and set `listen.public_url`. A plain `http://` origin is accepted only on loopback, for local development.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Private-network address                 | At `/login`, Claude Code requires the gateway’s hostname or IP address to resolve only to private addresses: RFC 1918, link-local, CGNAT `100.64.0.0/10`, IPv6 ULA `fc00::/7`, or loopback for local development. For a gateway you host, any public address is rejected; see the [threat model](/docs/en/claude-apps-gateway-deploy#threat-model-summary) in the deployment guide. The check runs on each resolved IP, so if any address the name resolves to is public, `/login` rejects the URL. If developer machines route HTTPS through a corporate proxy, sign-in also requires the proxy host to resolve to private addresses; if it doesn’t, add the gateway host to `NO_PROXY` so the CLI connects directly. Anthropic-operated public gateway endpoints are exempt from the private-address and proxy checks: `/login` accepts them over `https://` by exact hostname match, so the private-network requirement applies only to a gateway you host yourself. Before v2.1.206, `/login` rejected an Anthropic-operated endpoint like any other public address. |
| Linux runtime                           | The gateway server runs only on the native Linux binary. macOS works for local development. Windows isn’t supported as a server platform.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

The gateway server requires the native `claude` binary; download a pinned release as described in [Install Claude Code](/docs/en/setup). The server uses runtime features that aren’t available when Claude Code runs under Node. If you see `requires the native binary` at boot, switch to one of the standalone install methods.


[​](#steps)

Steps

1

Register an OAuth client in your IdP

Decide the gateway’s hostname first, because the redirect URI must match it. Create a new OIDC web application and set the redirect URI to `https://claude-gateway.<your-domain>/oauth/callback`, where the host is the same value you set as [`listen.public_url`](/docs/en/claude-apps-gateway-config#listen) in step 3. Note the `client_id` and `client_secret`. Per-IdP instructions are in [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup).

2

Provision a PostgreSQL database

Any Postgres 14 or later works, including the smallest managed tier. The gateway runs its own schema migrations at boot, so the database user needs `CREATE TABLE` permission. If your security policy prohibits DDL from application roles, pre-create the schema instead; see [`store`](/docs/en/claude-apps-gateway-config#store).

3

Write gateway.yaml

Secrets are read via `${ENV_VAR}` expansion so the file itself can live in version control. Use a `public_url` hostname that resolves to a private IP on your network, because `/login` rejects public addresses. The minimal config has five sections, and every other field has a default:

gateway.yaml

```python
listen:
  host: 0.0.0.0
  port: 8080
  # Required behind any TLS-terminating proxy. Used for the IdP
  # redirect_uri and the discovery document.
  public_url: https://claude-gateway.internal.example.com

oidc:
  issuer: https://login.example.com        # must serve /.well-known/openid-configuration
  client_id: 0oa1example2
  client_secret: ${OIDC_CLIENT_SECRET}
  allowed_email_domains: [example.com]        # reject id_tokens outside your org
  userinfo_fallback: true                  # for IdPs whose id_token omits email/groups; harmless otherwise

session:
  jwt_secret: ${GATEWAY_JWT_SECRET}        # openssl rand -base64 32
  ttl_hours: 1                             # also bounds revocation latency on IdP deprovision

store:
  postgres_url: ${GATEWAY_POSTGRES_URL}    # add ?sslmode=require for managed Postgres

upstreams:
  - provider: bedrock
    region: us-east-1
    auth: {}                               # empty: AWS default credential chain
                                           # (IRSA, EC2/ECS task role, env vars, ~/.aws)

# Models are translated per upstream automatically. The built-in catalog
# maps claude-opus-4-8 to us.anthropic.claude-opus-4-8 and so on for every
# Bedrock-supported Claude model. Set false and add a `models:` list to
# expose only specific models.
auto_include_builtin_models: true
```

This config is enough for a working sign-in loop with the default Amazon Bedrock model catalog. Once it’s running, add per-group RBAC and managed settings via [`managed.policies`](/docs/en/claude-apps-gateway-config#managed), telemetry fan-out via [`telemetry`](/docs/en/claude-apps-gateway-config#telemetry), and multi-upstream failover, provisioned-throughput ARNs, or non-US regions via [`models`](/docs/en/claude-apps-gateway-config#models).

The Amazon Bedrock upstream needs an AWS principal with `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` on both the `inference-profile/us.anthropic.*` ARNs and the underlying `foundation-model/anthropic.*` ARNs, and Anthropic’s one-time use case form submitted for the account from the Bedrock console’s Model catalog. Supply the credential with IRSA on EKS, an ECS task role, or an EC2 instance profile rather than static keys. The [`upstreams` reference](/docs/en/claude-apps-gateway-config#upstreams) has the full IAM details, the cross-cloud credential matrix, and the `auth` blocks for the other providers.

4

Run it

Build a container image around the `claude` binary that meets the [image requirements](/docs/en/claude-apps-gateway-deploy#container-image), then run it alongside Postgres. The Compose file references the image as `registry.example.com/claude-gateway:2.1.198`; substitute your own registry and image tag:

docker-compose.yaml

```python
services:
  gateway:
    image: registry.example.com/claude-gateway:2.1.198
    ports: ["8080:8080"]
    volumes: ["./gateway.yaml:/etc/claude/gateway.yaml:ro"]
    environment:
      OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
      GATEWAY_JWT_SECRET: ${GATEWAY_JWT_SECRET}
      GATEWAY_POSTGRES_URL: postgres://gw:pw@postgres/gateway
      # AWS credentials: in production, omit these and use an instance
      # role. For local Compose testing, pass through your own:
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
    depends_on:
      postgres:
        condition: service_healthy
  postgres:
    image: postgres:16-alpine
    environment: { POSTGRES_USER: gw, POSTGRES_PASSWORD: pw, POSTGRES_DB: gateway }
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U gw"]
      interval: 5s
    volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: }
```

The gateway is a single Linux binary that reads the config, runs OIDC discovery against your IdP, applies its Postgres schema migrations, builds upstream clients, and starts listening. Boot is fail-closed for the config, the Postgres connection with a 5-second timeout, OIDC discovery, and upstream client construction. If any of those is unreachable or misconfigured, the gateway exits with an error rather than serving traffic in a degraded state.A successful boot doesn’t validate the inference path, because Amazon Bedrock and Google Cloud’s Agent Platform instance credentials resolve on the first request, not at boot.Watch stderr for the boot sequence. Log lines use the format `[gateway] <timestamp> <level> <message>`, audit events are single-line JSON with an `evt` field, and a startup banner, omitted below, prints between the migration and listening lines. You should see, in order:

```python
{"ts":"2026-06-10T17:03:21.114Z","evt":"config.load","path":"/etc/claude/gateway.yaml","sha256":"…"}
[gateway] 2026-06-10T17:03:21.408Z info migration 1 applied
[gateway] 2026-06-10T17:03:21.512Z info claude gateway listening on http://0.0.0.0:8080
```

If boot exits before the `claude gateway listening on` line, the last line of stderr names the problem:

- an unreachable Postgres
- a Postgres role without DDL permission
- an unreachable or invalid OIDC discovery document
- a config schema violation with the offending field path

Fix it and restart.If you already have a TLS-terminating ingress, skip Compose and run the binary directly with `claude gateway --config gateway.yaml`. Set `public_url` to the ingress origin and bind `listen` to a loopback or cluster-internal address.

5

Verify the auth surface

Three checks confirm the gateway can authenticate a real user before you hand it to a developer.The examples use the gateway’s public URL; for the local Compose setup without an ingress, substitute `http://localhost:8080` in the first two checks. The third check opens `verification_uri_complete`, which is built from `public_url`, so for local Compose set `public_url: http://localhost:8080` in `gateway.yaml`, and add `http://localhost:8080/oauth/callback` as a second redirect URI on the OAuth client from step 1, because the gateway builds the IdP `redirect_uri` from `public_url`. The verification link then opens in your local browser.In Windows PowerShell, run `curl.exe`; the bare `curl` is an alias for `Invoke-WebRequest` and rejects these flags.First, fetch the discovery document, which confirms the gateway is up, the config is valid, and all boot checks passed:

```python
curl -s https://claude-gateway.internal.example.com/.well-known/oauth-authorization-server | jq
```

```python
{
  "issuer": "https://claude-gateway.internal.example.com",
  "device_authorization_endpoint": "…/oauth/device_authorization",
  "token_endpoint": "…/oauth/token",
  "grant_types_supported": ["urn:ietf:params:oauth:grant-type:device_code", "refresh_token"]
}
```

The response includes additional fields, such as `response_types_supported` and `scopes_supported`.Second, request a device authorization, which confirms the device sign-in flow works and Postgres is reachable and writable:

```python
curl -s -X POST https://claude-gateway.internal.example.com/oauth/device_authorization | jq
```

```python
{
  "device_code": "…",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://claude-gateway.internal.example.com/device",
  "verification_uri_complete": "https://claude-gateway.internal.example.com/device?user_code=WDJB-MJHT",
  "expires_in": 600,
  "interval": 5
}
```

Third, test the browser leg by opening `verification_uri_complete` in a browser and confirming the code. You should be redirected to your IdP’s sign-in page, and after signing in, land back on the gateway with a signed-in confirmation.Use the first failing check to locate the problem:

- **First check fails**: boot didn’t complete; check stderr
- **Second check fails**: Postgres isn’t reachable from the gateway or the role can’t write; check the connection string and grants
- **Third check doesn’t reach the IdP**: check that the IdP’s redirect URI matches `https://<gateway>/oauth/callback` exactly
- **Third check reaches the IdP but bounces back with an error**: read the gateway’s audit log, which records every auth rejection with the reason, such as `email domain not allowed`

6

Log a developer in

This last step happens on a developer machine, not the server. Set `forceLoginMethod` to `"gateway"` and `forceLoginGatewayUrl` to your gateway’s `public_url` in that machine’s [managed settings file](/docs/en/settings#settings-files), then run `/login`, press Enter on the **Cloud gateway** screen, and complete the browser sign-in. [Set the gateway URL](#set-the-gateway-url) below covers distributing both keys at scale.


[​](#connect-developers)

Connect developers

Developers connect from their own laptops with one browser sign-in, using their corporate work account. They don’t need a claude.ai account, an API key, or a subscription, because requests to the model go through the gateway using the organization’s upstream credential. Connection is driven by the [client-side managed settings](/docs/en/claude-apps-gateway-config#client-side-managed-settings) you push via MDM, so there is no manual setup on the developer side; this section covers what the admin configures. The CLI fingerprints the gateway’s TLS leaf certificate on first connect and pins it per hostname. Publish the expected SHA-256 fingerprint alongside the gateway URL so developers have something to compare against. Get the fingerprint from the certificate file with `openssl x509 -noout -fingerprint -sha256 -in cert.pem`; the `/login` prompt shows the first 16 characters of the digest as lowercase hexadecimal with no separators. When the certificate rotates, every developer sees the trust prompt again, so treat rotations as a planned event and republish the fingerprint. Once signed in, the [model picker](/docs/en/model-config) shows the models in the developer’s `availableModels` allowlist, managed settings apply at startup and refresh hourly, and telemetry routes to your collector. Sessions refresh silently before `ttl_hours` expiry, and a failed refresh after IdP deprovisioning prompts a re-login.


[​](#set-the-gateway-url)

Set the gateway URL

Three keys go in the per-OS [managed settings file](/docs/en/settings#settings-files) you deploy via MDM or directly on disk. `forceLoginMethod` and `forceLoginGatewayUrl` open `/login` directly on the **Cloud gateway** screen with the URL filled in, and `parentSettingsBehavior: "merge"` lets Claude Desktop deliver the gateway’s policy to the Claude Code sessions it launches, explained in [Deliver policy to Claude Desktop sessions](#deliver-policy-to-claude-desktop-sessions):

```python
{
  "forceLoginMethod": "gateway",
  "forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
  "parentSettingsBehavior": "merge"
}
```

The developer presses Enter to connect. The [first-connect TLS fingerprint prompt](#connect-developers) still appears. A developer can’t set this up manually. The login picker has no gateway option, and `forceLoginGatewayUrl` is ignored in a developer’s own settings files. `forceLoginMethod` alone, without a URL, leaves the developer at a “Contact your IT administrator” message. The login keys belong in the file you push to machines, not in the gateway’s `managed.policies[].cli` block, which only reaches clients that are already connected.


[​](#deliver-policy-to-claude-desktop-sessions)

Deliver policy to Claude Desktop sessions

Claude Desktop runs embedded Claude Code sessions and passes the gateway’s policy to each session it launches. Claude Desktop gets that policy from the gateway itself. It’s pointed at the gateway through its own managed configuration and signs in with its own flow, separate from the `forceLoginMethod` and `forceLoginGatewayUrl` keys in [Set the gateway URL](#set-the-gateway-url). Settings passed by a launching process are parent settings. Claude Code ignores parent settings on any machine that has an admin-deployed managed source, unless the highest-priority source sets `parentSettingsBehavior: "merge"`.


[​](#which-machines-need-the-opt-in)

Which machines need the opt-in

Machines that only run Claude Desktop need it, because parent settings are the only way the gateway’s policy reaches embedded sessions. Without the opt-in those sessions run with none of the gateway’s restrictions, and nothing warns you. Machines where developers sign in through `/login` don’t need it; every Claude Code invocation fetches its policy from the gateway directly. Fleets that configure a [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) can’t use it, because the helper’s output replaces every other managed source and parent settings are never merged while a helper is configured.


[​](#set-the-opt-in)

Set the opt-in

Deploy the key, mirror it to the source that wins on each machine, then verify.

1

Deploy the opt-in in the managed settings file

The [snippet above](#set-the-gateway-url) already includes `parentSettingsBehavior: "merge"`, so the file you push to machines carries it.

2

Set the same key in any source that outranks the file

Only the highest-priority admin source’s value counts. A managed-preferences plist on macOS or an HKLM policy on Windows outranks the `managed-settings.json` file, and the gateway’s own remote managed settings outrank both, so on machines that sign in to the gateway, also set the key in the gateway policy’s [`cli` block](/docs/en/claude-apps-gateway-config#managed).

3

Check which source won

Call the Agent SDK’s [`resolveSettings()`](/docs/en/agent-sdk/typescript#resolvesettings). Its result includes a `sources` list; the managed policy entry there carries a `policyOrigin` field naming the active source. `resolveSettings()` doesn’t execute a configured `policyHelper`, so on helper fleets its answer doesn’t reflect the live session.


[​](#restrict-parent-settings)

Restrict parent settings

Once you deploy `parentSettingsBehavior: "merge"`, any host process that launches Claude Code can supply parent settings, not only Claude Desktop but also an Agent SDK application or an IDE extension. Claude Code filters parent settings against an allowlist of restrictive keys, but some allowed keys can grant access rather than restrict it. Unless you set the `allowManaged*Only` locks, permission allow rules and sandbox allowlists supplied by the host still apply. Your policy’s deny and ask rules stay in force either way; [they’re evaluated before any allow rule](/docs/en/permissions#manage-permissions).


[​](#deploy-the-locks)

Deploy the locks

To keep parent settings as close to restriction-only as the filter supports, add all five `allowManaged*Only` locks, and the allowlists they govern, to the same sources as the merge opt-in:

```python
{
  "forceLoginMethod": "gateway",
  "forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
  "parentSettingsBehavior": "merge",
  "allowManagedPermissionRulesOnly": true,
  "allowManagedMcpServersOnly": true,
  "allowManagedHooksOnly": true,
  "allowedMcpServers": [{ "serverUrl": "https://mcp.internal.example.com/*" }],
  "sandbox": {
    "network": {
      "allowManagedDomainsOnly": true,
      "allowedDomains": ["github.com", "*.npmjs.org"]
    },
    "filesystem": {
      "allowManagedReadPathsOnly": true,
      "denyRead": ["~/"],
      "allowRead": ["~/projects"]
    }
  }
}
```

An OS policy, such as an HKLM registry policy or a managed-preferences plist, outranks this file, so deliver the whole snippet through it instead of the file. The gateway’s remote managed settings outrank the OS policy and file sources but reach only connected clients. Mirror the locks, the allowlists, and the merge opt-in into the policy’s [`cli` block](/docs/en/claude-apps-gateway-config#managed) and keep this file deployed, because machines that never connect, including ones that only run Claude Desktop, get their policy from the file alone.


[​](#lock-behavior-across-sources)

Lock behavior across sources

Setting one lock doesn’t restrict the others; each key is documented in the [settings reference](/docs/en/settings#available-settings). From an admin source below the winner, the two sandbox locks still apply, and `allowManagedPermissionRulesOnly` still blocks parent-supplied allow rules and `additionalDirectories`. The hooks and MCP server locks, and `allowManagedPermissionRulesOnly`’s effect on the developer’s own rules, need the winning source. On [`policyHelper`](/docs/en/settings#compute-managed-settings-with-a-policy-helper) fleets, the locks are read from the helper’s output alone. Each lock makes Claude Code ignore the developer’s own entries for that setting, so include your organization’s allowlists next to the locks. Locking network domains with an empty managed domain list blocks all sandboxed outbound traffic, and locking MCP servers with no managed or parent-supplied `allowedMcpServers` loads every server that `deniedMcpServers` doesn’t block. `allowRead` entries only re-allow paths inside `denyRead` regions, so pair them with a managed `denyRead`.


[​](#settings-the-locks-don’t-cover)

Settings the locks don’t cover

Four parent-supplied settings are honored even with all five locks set:

- **`forceLoginOrgUUID`**: Claude Code honors a parent-supplied value when no admin source sets an org UUID. Gateway sign-in doesn’t check this key, so it matters only for fleets that also use first-party Anthropic logins. An org UUID in any admin source blocks the parent’s value, but the value Claude Code enforces comes from the highest-priority source, so set `forceLoginOrgUUID` there.
- **`allowedMcpServers`**: Claude Code honors a parent-supplied allowlist when no admin source sets one, and `allowManagedMcpServersOnly` doesn’t block it, because the lock enforces whichever list wins as the managed value, including a parent-supplied list when no admin source sets one. A list in any admin source blocks the parent’s, but the list Claude Code enforces comes from the highest-priority source, so set `allowedMcpServers` there, next to the lock.
- **`availableModels`**: Claude Code honors a parent-supplied model list when the winning managed source doesn’t set one. If your fleet restricts models, set `availableModels` in the winning source.
- **`strictPluginOnlyCustomization`**: this key passes the filter regardless of any lock, and it makes Claude Code ignore the developer’s own customization, including protective hooks. No lock blocks it.


[​](#connect-claude-desktop)

Connect Claude Desktop

[Claude Desktop](/docs/en/desktop) connects to the same gateway through a different MDM key: set `bootstrapUrl` in Claude Desktop’s [managed configuration](https://claude.com/docs/third-party/claude-desktop/configuration) to `<listen.public_url>/user/bootstrap`, and opt the user’s policy in with a `desktop` key. [Claude Desktop overlay](/docs/en/claude-apps-gateway-config#claude-desktop-overlay) covers both halves. Requires Claude Code v2.1.203 or later on the gateway server. Claude Desktop signs the developer in through the gateway’s identity provider with the same browser SSO step, then fetches its configuration from the gateway instead of from Anthropic. Model access and policy follow the same per-group rules as the CLI. A developer who uses both the CLI and Claude Desktop signs in to each separately; the gateway session isn’t shared between them.


[​](#ci-pipelines-and-remote-machines)

CI pipelines and remote machines

There is no service-token flow for unattended pipelines. Gateway sign-in always runs the browser device flow, so a CI job with no developer to approve the sign-in can’t authenticate; configure those against your provider directly. Once a developer has signed in, every Claude Code invocation on that machine uses the gateway session, including non-interactive `claude -p` runs and sessions started by the Agent SDK, and the [gateway policy applies to all of them](/docs/en/claude-apps-gateway-config#managed). The device flow separates the polling CLI from the approving browser, so a remote development box with no display still works: the developer runs `/login` over SSH on the remote machine and opens the verification link in the browser on their laptop.


[​](#what’s-enforced-on-developers)

What’s enforced on developers

These guarantees apply to every signed-in gateway session.

- **Model access**: requests for models the policy doesn’t grant return 400, and the `/model` picker is filtered to the policy’s `availableModels` allowlist. Set [`enforceAvailableModels: true`](/docs/en/model-config#default-model-behavior) in the policy so the Default option resolves to a model inside `availableModels` instead of to Claude Code’s built-in default; without it, Default stays selectable and is rejected at request time if that model isn’t granted.
- **Telemetry destination**: when [telemetry forwarding](/docs/en/claude-apps-gateway-config#telemetry) is configured, the OTLP export endpoint is pinned to the gateway, and the gateway-pushed configuration overrides locally set `OTEL_*` variables.
- **Credentials**: the gateway token is the session’s only credential. `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY`, `apiKeyHelper`, and any earlier claude.ai login are ignored while signed in, so developers don’t need to log out of claude.ai first.
- **Managed settings**: locked keys can’t be overridden locally. The CLI applies the policy at startup and on each hourly poll.
- **Startup**: signed-in sessions exit at startup with an error after about 10 seconds when the gateway is unreachable, rather than starting without their settings.
- **Deprovisioning**: a session whose user is disabled in the IdP expires within `ttl_hours` when the next refresh fails.


[​](#what-the-organization-can-see)

What the organization can see

Usage telemetry carries the developer’s identity, token counts, model, and latency to the organization’s collector. The gateway doesn’t log or store prompt or completion content. Whether richer telemetry such as logs and traces is collected, which can include commands and file paths, is the organization’s [per-destination choice](/docs/en/claude-apps-gateway-config#telemetry).


[​](#availability-and-limitations)

Availability and limitations

The table covers which Claude Code features work when developers connect through the gateway, and what the gateway server itself supports. Where something isn’t supported, the Notes column gives the alternative. The gateway delivers the [`anthropic-beta`](https://platform.claude.com/docs/en/api/beta-headers) values the CLI sends to every upstream, so operators don’t maintain a beta allowlist. For Amazon Bedrock, which ignores the header, the gateway moves the values into the request body’s `anthropic_beta` field; the other upstreams receive the header as sent. The CLI’s gateway-session beta set omits first-party-only betas and the extended-cache-ttl beta, which is why those rows below show as not available.

| Feature                                                                                                                    | Status                | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|----------------------------------------------------------------------------------------------------------------------------|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Inference forwarding (Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform, Microsoft Foundry, Anthropic) | Available             | With per-upstream model translation and failover. The Amazon Bedrock upstream uses the `bedrock-runtime` endpoint and the AWS default credential chain; the Amazon Bedrock [Mantle endpoint](/docs/en/amazon-bedrock#use-the-mantle-endpoint) is not a supported upstream. The [Claude Platform on AWS upstream](/docs/en/claude-apps-gateway-config#claude-platform-on-aws) requires Claude Code v2.1.198 or later on the gateway server. |
| Model access and managed settings by IdP group                                                                             | Available             | Model access is enforced server-side; managed settings are delivered per IdP group and applied by the CLI at the [managed settings tier](/docs/en/settings#settings-precedence)                                                                                                                                                                                                                                                            |
| Claude Desktop                                                                                                             | Available with opt-in | The gateway serves Claude Desktop’s configuration at `/user/bootstrap` once a policy [opts in with a `desktop` key](/docs/en/claude-apps-gateway-config#claude-desktop-overlay). Requires Claude Code v2.1.203 or later on the gateway server.                                                                                                                                                                                             |
| Telemetry fan-out (OTLP/HTTP)                                                                                              | Available             | Identity-stamped per export; both protobuf and JSON encodings                                                                                                                                                                                                                                                                                                                                                                              |
| OIDC identity providers                                                                                                    | Available             | Any OIDC-compliant IdP; the gateway runs standard OIDC discovery and the authorization-code flow. See [Identity provider setup](/docs/en/claude-apps-gateway-deploy#identity-provider-setup) for per-IdP configuration                                                                                                                                                                                                                     |
| Per-user and per-group spend limits                                                                                        | Available             | See [Spend limits](/docs/en/claude-apps-gateway-spend-limits)                                                                                                                                                                                                                                                                                                                                                                              |
| Server-side web search                                                                                                     | Not available         | The CLI can’t see which upstream provider the gateway routes to, so it can’t verify web search support and disables WebSearch on gateway sessions                                                                                                                                                                                                                                                                                          |
| Standard prompt caching                                                                                                    | Available             | `cache_control` breakpoints are forwarded to every upstream                                                                                                                                                                                                                                                                                                                                                                                |
| 1-hour cache TTL                                                                                                           | Not available         | The CLI omits the extended-cache-ttl beta on gateway sessions, because not every upstream the gateway can route to supports the 1-hour TTL, so prompt caching through the gateway uses the 5-minute TTL; see the beta-header note above                                                                                                                                                                                                    |
| Auto mode                                                                                                                  | Available             | Follows the [third-party provider rules](/docs/en/permission-modes#enable-auto-mode-on-bedrock-agent-platform-or-foundry): only the models eligible on third-party providers can use it. Before v2.1.207, auto mode on gateway sessions required setting `CLAUDE_CODE_ENABLE_AUTO_MODE=1`, deliverable through the managed policy `env` block                                                                                              |
| First-party-only optimizations such as global cache scope and token-efficient tools                                        | Not available         | The CLI doesn’t enable them on gateway sessions; see the beta-header note above                                                                                                                                                                                                                                                                                                                                                            |
| OTLP/gRPC                                                                                                                  | Not supported         | OTLP over HTTP only                                                                                                                                                                                                                                                                                                                                                                                                                        |
| SAML, LDAP, and other non-OIDC auth                                                                                        | Not supported         | OIDC only. Front with an OIDC bridge if needed                                                                                                                                                                                                                                                                                                                                                                                             |
| Multi-tenant (multiple OIDC issuers)                                                                                       | Not supported         | One issuer per gateway. Run separate instances                                                                                                                                                                                                                                                                                                                                                                                             |
| Windows server                                                                                                             | Not supported         | Deploy on Linux. macOS for local development only                                                                                                                                                                                                                                                                                                                                                                                          |
| Helm chart                                                                                                                 | Not available         | The gateway runs as a standard stateless Deployment; see the [deployment guide](/docs/en/claude-apps-gateway-deploy#kubernetes)                                                                                                                                                                                                                                                                                                            |
| Admin UI                                                                                                                   | Not available         | Configuration is the YAML file; redeploy to change it                                                                                                                                                                                                                                                                                                                                                                                      |


[​](#next-steps)

Next steps

The quickstart leaves you with a minimal config running under Docker Compose. To take it further:

- Expand `gateway.yaml` beyond the minimal config, for example to add per-group RBAC, multi-upstream failover, or telemetry destinations. The [configuration reference](/docs/en/claude-apps-gateway-config) covers every option.
- Move from Compose to a production deployment on Kubernetes or Cloud Run, set up your IdP properly, and review the security model. The [deployment and operations guide](/docs/en/claude-apps-gateway-deploy) covers per-IdP setup, container image requirements, health probes, and troubleshooting.
- Put spend caps on individual developers or groups so a runaway workload can’t consume your whole commitment. [Spend limits](/docs/en/claude-apps-gateway-spend-limits) covers the admin API and how enforcement works.
- For a complete worked example on AWS, with ECS Fargate or EKS, Amazon RDS, and Secrets Manager, see [Deploy on AWS](/docs/en/claude-apps-gateway-on-aws).
- For a complete worked example on Google Cloud, with Cloud Run, Cloud SQL, and Secret Manager, see [Deploy on Google Cloud](/docs/en/claude-apps-gateway-on-gcp).


---
## claude-apps-gateway-spend-limits-claude-code-docs-d10936451f.md

## On this page

- [Set a cap](#set-a-cap)
  - [Authenticate to the admin API](#authenticate-to-the-admin-api)
- [How enforcement works](#how-enforcement-works)
  - [Postgres availability](#postgres-availability)
- [Admin API reference](#admin-api-reference)
  - [/effective](#%2Feffective)
  - [/audit](#%2Faudit)
  - [Pagination](#pagination)
- [Data lifecycle](#data-lifecycle)
- [Related](#related)

Claude apps gateway

# Claude apps gateway spend limits

Copy pageCopy page

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.

Copy pageCopy page

Spend limits cap how much each developer can spend through your [Claude apps gateway](/docs/en/claude-apps-gateway) in a given day, week, or month. When a developer passes their cap, the gateway returns `429` on their next request and blocks them until the period resets or an admin raises the cap. Use spend limits to give each developer, group, or the whole organization a ceiling on a credential everyone shares. A Claude apps gateway forwards all inference through one shared upstream credential, so your provider’s bill attributes everything to that credential, not to individual developers. Without per-developer limits, one runaway agent fleet can spend the organization’s entire commitment. Spend limits are the gateway’s per-developer view and circuit breaker on top of that shared bill.


[​](#set-a-cap)

Set a cap

With the [`admin:`](/docs/en/claude-apps-gateway-config#admin) block configured in `gateway.yaml`, the gateway serves an admin API at `/v1/organizations/spend_limits` and enforces caps live on every inference request. Caps themselves are set through that API, not in `gateway.yaml`; each `POST /v1/organizations/spend_limits` request creates or replaces one cap from `{scope, amount, period}`. The API mirrors the wire shapes of Anthropic’s public [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) spend-limits endpoints, so an HTTP client written against that contract can target the gateway by changing its base URL. This request sets an org-wide default of \$500 per month for every developer:

```python
curl -sS https://claude-gateway.internal.example.com/v1/organizations/spend_limits \
  -H "x-api-key: $GATEWAY_ADMIN_WRITE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scope": {"type": "organization"}, "amount": "50000", "period": "monthly"}'
```

This request layers a tighter \$100-per-day cap on each member of the `contractors` group:

```python
curl -sS https://claude-gateway.internal.example.com/v1/organizations/spend_limits \
  -H "x-api-key: $GATEWAY_ADMIN_WRITE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scope": {"type": "rbac_group", "rbac_group_id": "contractors"}, "amount": "10000", "period": "daily"}'
```

| Field        | Values                                      | Description                                                                                                                                                                                                                                                                                                                                                                                        |
|--------------|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `scope.type` | `user`, `rbac_group`, `organization`        | `user` targets one developer by their OpenID Connect (OIDC) `sub`, the stable user ID your identity provider assigns; pass it as `scope.user_id`. `rbac_group` targets an [IdP group](/docs/en/claude-apps-gateway-config#managed) by name; pass it as `scope.rbac_group_id`. `organization` is the org-wide default. The gateway accepts all three; Anthropic’s public `POST` is user-only today. |
| `amount`     | Whole-number string of USD cents, or `null` | `null` is unlimited. `"0"` is a zero cap, which blocks every request.                                                                                                                                                                                                                                                                                                                              |
| `period`     | `daily`, `weekly`, `monthly`                | A scope can hold one cap per period, and each enforces independently: a developer is blocked if over any of them.                                                                                                                                                                                                                                                                                  |

A group or organization cap is a per-seat default that each member inherits, not a shared pool. Per period, a developer’s effective cap resolves in this order: a per-user override, then the most restrictive of their group caps, then the org default, then unlimited. [`admin.group_limit_mode: max`](/docs/en/claude-apps-gateway-config#admin) flips the multi-group tie-break to least-restrictive instead.


[​](#authenticate-to-the-admin-api)

Authenticate to the admin API

Send one of:

- An `x-api-key` header matching a key in [`admin.write_keys`](/docs/en/claude-apps-gateway-config#admin) for full access, or `admin.read_keys` for `GET`-only access. Each key carries an `id` that appears in the audit log as `admin-key:<id>`, so give Terraform, CI, and each automation its own.
- A gateway bearer token whose `groups` claim includes one of [`admin.admin_groups`](/docs/en/claude-apps-gateway-config#admin). This is full access and audits as `oidc:<sub>`, so prefer it for human admins.


[​](#how-enforcement-works)

How enforcement works

On each `/v1/messages` request, the gateway resolves the developer’s caps and period-to-date spend in one Postgres query. If they’re over any cap, the request returns `429` with `error.type: billing_error` and the header `x-should-retry: false`. The message is `spend limit reached`, followed by your [`admin.blocked_message`](/docs/en/claude-apps-gateway-config#admin) if set. `/v1/messages/count_tokens` is exempt. Token counting is free, so it runs regardless of cap state. After each response, a usage meter reads token counts off the response as it streams to the client, prices them at USD list price, and increments Postgres counters for all three period buckets. The meter is a single reader on the stream, so the client’s bytes are untouched and a metering failure doesn’t break the response. Spend limits estimate spend from token counts at USD list price; they’re a circuit breaker, not an invoice. For authoritative billing, reconcile against your provider’s own usage reporting, such as the Anthropic Usage & Cost Admin API, invocation logs on Amazon Bedrock, or Cloud Monitoring on Google Cloud. Pricing uses the same table the Claude Code CLI uses for its own cost display, with the same model-ID canonicalization across Anthropic, Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry ID forms, such as Bedrock’s `us.anthropic.…-v1:0` and Agent Platform’s `claude-…@date`. The meter resolves each request’s rate tier in order:

1.  Exact rates for the upstream model ID, the model string the gateway sends to the provider. When the table recognizes it, such as `us.anthropic.claude-…`, the meter prices the request by the model that served it.
2.  Rates for the configured [`models[].id`](/docs/en/claude-apps-gateway-config#models) you mapped to the upstream ID. This step covers upstream strings that carry no model name, such as an Amazon Bedrock application-inference-profile ARN or a Microsoft Foundry deployment name, and requires Claude Code v2.1.218 or later on the gateway server.
3.  The unknown-model default tier of \$5/\$25 per million input/output tokens. The meter prices an ID that neither the table nor your `models` config can place, including a `models[].id` that is itself a custom alias, at this tier rather than zero, so an unrecognized ID can’t bypass a cap by going unmetered.

The gateway warns at boot and once per ID at runtime when it prices a model at the unknown-model tier. Before v2.1.218, the meter skipped step 2: it priced any upstream ID the table couldn’t place at the unknown-model tier and warned about it even when the configured ID’s rates were known. Client aborts are billed too. The upstream reports output tokens only in the stream’s terminal frame, so an aborted stream doesn’t carry them. The meter keeps a conservative floor estimate from the streamed content size, about four characters per token, and bills it when and only when the terminal usage frame is missing. A complete stream always bills the upstream-reported count. Without this, a capped developer could stream output and abort each request immediately before the end, spending without ever being counted.


[​](#postgres-availability)

Postgres availability

The pre-check queries Postgres with a two-second timeout. If the store is unreachable or times out, enforcement fails open by default: the request proceeds and the gateway logs a warning. Set [`enforcement.fail_closed_on_error: true`](/docs/en/claude-apps-gateway-config#enforcement) to fail closed instead, which returns the same `429 billing_error` with the message `spend limit unavailable`. Fail-open keeps a store outage from becoming an inference outage; fail-closed guarantees no unmetered spend.


[​](#admin-api-reference)

Admin API reference

The endpoints below are served under `/v1/organizations/spend_limits`.

| Method and path                                | Description                                                  |
|------------------------------------------------|--------------------------------------------------------------|
| `GET /v1/organizations/spend_limits`           | List configured caps. Query: `?limit=&after_id=&before_id=`. |
| `POST /v1/organizations/spend_limits`          | Create or replace a cap for `{scope, period}`.               |
| `GET /v1/organizations/spend_limits/{id}`      | Fetch one cap by its `spl_`-prefixed ID.                     |
| `DELETE /v1/organizations/spend_limits/{id}`   | Delete one cap. Returns `{type: "spend_limit_deleted", id}`. |
| `GET /v1/organizations/spend_limits/effective` | Resolved cap and to-date spend per principal per period.     |
| `GET /v1/organizations/spend_limits/audit`     | Admin mutation trail, newest-first. Query: `?limit=`.        |

Conventions mirror Anthropic’s Admin API:

- A `type` on every object
- `spl_`-prefixed IDs
- Amounts as whole-number strings of USD cents; `POST` rejects any other `currency` with `400`
- The `{type: "error", error: {type, message}, request_id}` error envelope
- A `request-id` response header on every admin response, success or error, matching the body’s `request_id`

Every mutation writes a before/after row to `admin_audit` in the same transaction, attributed to `admin-key:<id>` or `oidc:<sub>`. The gateway serves the spend-limits endpoints only. Other Admin API surfaces, such as the `spend_limit_increase_requests` queue, aren’t part of the gateway’s admin API.


[​](#/effective)

`/effective`

`GET /v1/organizations/spend_limits/effective` returns Anthropic’s `SpendSummary` schema: each row is a principal for a period, with the resolved cap, period-to-date spend, and an `actor` object. Gateway-specific differences:

- `user_id` is the OIDC `sub`.
- `actor.name` and `actor.email_address` are `null` until the principal’s first inference request through the gateway. The gateway has no user directory; it records last-seen values from each user’s own session JWT.
- Each row also carries a `groups` array, the principal’s last-seen IdP groups. This is a gateway extension so an admin UI can show every cap tier that applies; Anthropic-shaped clients ignore it.
- Without a `user_ids[]` filter, it lists principals with recorded spend, because the gateway can’t enumerate all org members.

Group-sourced caps resolve against those last-seen groups with the same `group_limit_mode` tie-break that enforcement uses, so the viewer shows the cap that actually applies.

| Query parameter  | Description                                                                                             |
|------------------|---------------------------------------------------------------------------------------------------------|
| `user_ids[]`     | Repeatable. Filter to specific principals by OIDC `sub`.                                                |
| `period[]`       | Repeatable. Filter to `daily`, `weekly`, or `monthly` rows.                                             |
| `sort`           | `spend_desc` lists top spenders first. Requires exactly one `period[]`.                                 |
| `q`              | Case-insensitive substring filter over the OIDC `sub`, last-seen email, and last-seen display name.     |
| `limit` / `page` | Page size, 1–1000 with a default of 20, and the opaque cursor from the previous response’s `next_page`. |

`q=` and `user_ids[]=` ride GET query strings, so any fronting proxy or load balancer captures them in its access logs. If your PII log policy is strict, scrub these parameters there.


[​](#/audit)

`/audit`

Returns the spend-limit mutation trail: who changed which cap, before/after snapshots, and the optional reason, newest-first. `has_more` is exact. This endpoint follows the local Admin API conventions rather than a first-party wire shape.


[​](#pagination)

Pagination

The raw list pages by `after_id` and `before_id`, which are mutually exclusive `spl_…` IDs; results are ordered by creation and `has_more` reflects the traversal direction. `/effective` pages by the opaque `next_page` token passed back as `?page=`, with principals ordered ascending so pages stay stable while spend is being recorded. `limit` is 1–1000, default 20, on both.


[​](#data-lifecycle)

Data lifecycle

The gateway holds four spend-related tables; an hourly sweep enforces the retention windows:

| Table              | Contents                                                                      | Retention                                                                                                    |
|--------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| `spend`            | Per-principal period-to-date counters in cents                                | [`admin.spend_retention_months`](/docs/en/claude-apps-gateway-config#admin), default 13                      |
| `spend_limits`     | The configured caps                                                           | Until deleted via the API                                                                                    |
| `admin_audit`      | The mutation trail                                                            | [`admin.audit_retention_days`](/docs/en/claude-apps-gateway-config#admin), default 365                       |
| `principal_emails` | Each principal’s last-seen email, display name, and IdP groups. Contains PII. | [`admin.identity_retention_days`](/docs/en/claude-apps-gateway-config#admin) since last activity, default 90 |

`identity_retention_days` is deliberately shorter than `spend_retention_months`: a deprovisioned identity stops refreshing and ages out, while its anonymous spend counters remain for year-over-year reporting. When a developer leaves, delete any per-user cap via `DELETE /v1/organizations/spend_limits/{id}`; their spend and identity rows age out on the retention windows above. To erase one person immediately, for offboarding or a data subject access request (DSAR), run `DELETE FROM principal_emails WHERE principal = '<sub>'` directly against the gateway database. That removes the only table holding their email, name, and groups. The `spend` and `admin_audit` rows reference the pseudonymous OIDC `sub` only and age out on their own windows.


[​](#related)

Related

- [`admin` and `enforcement` configuration](/docs/en/claude-apps-gateway-config#admin): enabling the admin API and tuning retention
- [Deployment guide](/docs/en/claude-apps-gateway-deploy#postgres): Postgres schema and backup guidance


---
## claude-code-architecture.md

# Claude Code Architecture for Zack's Setup

> Arch Linux (omarchy) · Ryzen 9800X3D · RTX 4090 · 10Gbps fiber
> Projects: SpecHO, definitelynot.ai, llmx, iOS RE toolkits, Iconics

## Design Principles

1. **Tool Search handles main context** - Don't fight it, leverage it
2. **MCP isolation for subagents** - Purpose-built agents get specific tools
3. **llmx as primary code search** - Replace/augment built-in Explore
4. **No plugin wrappers** - That strategy is obsolete
5. **Explicit over implicit** - Clear tool boundaries, no inheritance surprises

---

## Directory Structure

```
~/.claude/
├── settings.json              # Global settings, disabled built-ins
├── settings.local.json        # Machine-specific overrides (not synced)
├── mcp.json                   # User-scope MCP servers (always available)
├── agents/
│   ├── llmx-explorer.md       # Replaces Explore, uses llmx
│   ├── web-automation.md      # Playwright isolation
│   ├── github-ops.md          # GitHub MCP isolation  
│   ├── re-analyst.md          # Reverse engineering workflow
│   ├── specwriter.md          # Documentation/spec generation
│   └── clean-task.md          # MCP-free general purpose
├── commands/
│   ├── search.md              # /search - llmx semantic search
│   ├── re.md                  # /re - reverse engineering workflow
│   ├── detect.md              # /detect - AI detection pipeline
│   └── index.md               # /index - reindex with llmx
├── skills/
│   ├── specho-analysis/
│   │   └── SKILL.md           # SpecHO fingerprinting workflow
│   ├── re-patterns/
│   │   └── SKILL.md           # iOS/binary RE patterns
│   └── api-conventions/
│       └── SKILL.md           # Your API style guide
├── hooks/
│   └── mcp-guard.py           # PreToolUse hook for MCP auditing
└── plugins/
    └── (empty - not using plugin wrappers)

# Project-level (per repo)
.claude/
├── settings.json              # Project permissions
├── agents/                    # Project-specific agents
├── skills/                    # Project-specific skills
└── CLAUDE.md                  # Project context
```

---

## MCP Server Tiers

### Tier 1: Always-On (User Scope)
Low token cost, high utility, used across all projects.

```json
// ~/.claude/mcp.json
{
  "mcpServers": {
    "llmx": {
      "command": "/home/zack/dev/llmx/target/release/llmx-mcp",
      "env": {
        "LLMX_STORAGE_DIR": "/home/zack/.llmx/indexes",
        "LLMX_MODEL_PATH": "/home/zack/.llmx/models/bge-small-en-v1.5.onnx"
      }
    }
  }
}
```

**Why llmx only?** It's your local semantic search - lightweight, always useful, no external API calls. Everything else is situational.

### Tier 2: Project-Scope (Shared with team)
Tools specific to a project, checked into repo.

```json
// ~/dev/specho/.mcp.json
{
  "mcpServers": {
    "huggingface": {
      "command": "npx",
      "args": ["-y", "@huggingface/mcp-server"],
      "env": {
        "HF_TOKEN": "${HF_TOKEN}"
      }
    }
  }
}

// ~/dev/definitelynot.ai/.mcp.json  
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@anthropic-ai/mcp-server-playwright"]
    }
  }
}
```

### Tier 3: On-Demand via Subagent
Heavy/specialized tools that should NEVER pollute main context.

These aren't configured globally - they're started by subagents or enabled per-session:

- `playwright` - Only via `web-automation` subagent
- `github` - Only via `github-ops` subagent  
- Database servers - Only via project-specific agents
- Heavy API servers (Jira, Linear, etc.)

---

## Settings Configuration

### Global Settings
```json
// ~/.claude/settings.json
{
  "permissions": {
    "deny": [
      "Task(Explore)",
      "mcp__playwright__*",
      "mcp__github__*"
    ],
    "allow": [
      "mcp__llmx__*",
      "Read",
      "Grep", 
      "Glob"
    ]
  },
  "env": {
    "ENABLE_TOOL_SEARCH": "auto:5",
    "MAX_MCP_OUTPUT_TOKENS": "50000",
    "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "85"
  },
  "model": "claude-sonnet-4-5-20250929",
  "cleanupPeriodDays": 14
}
```

**Key decisions:**
- `Task(Explore)` denied - replaced by `llmx-explorer`
- `mcp__playwright__*` denied in main context - only via subagent
- `mcp__github__*` denied in main context - only via subagent
- `ENABLE_TOOL_SEARCH=auto:5` - More aggressive lazy loading (5% threshold)
- `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=85` - Compact earlier to preserve context

### Project Settings Example
```json
// ~/dev/specho/.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__huggingface__*",
      "Bash(python *)",
      "Bash(cargo *)"
    ]
  }
}
```

---

## Subagent Definitions

### 1. llmx-explorer.md (Replaces Explore)
```yaml
---
name: llmx-explorer
description: |
  Fast semantic code search and codebase exploration. Use for:
  - Finding relevant code by meaning, not just text
  - Understanding codebase structure and patterns
  - Locating implementations, definitions, usages
  - Architectural analysis
  Replaces built-in Explore with semantic search via llmx.
model: haiku
tools: Read, Grep, Glob, mcp__llmx__search, mcp__llmx__index_status
disallowedTools: Write, Edit, Bash, mcp__playwright__*, mcp__github__*
permissionMode: plan
---

You are a semantic code explorer powered by llmx.

## Primary Tool: mcp__llmx__search
Use semantic search FIRST for any code discovery task. Query with natural language descriptions of what you're looking for.

## Fallback Tools
- `Grep` - For exact string/regex matches after semantic search narrows scope
- `Glob` - For file pattern discovery
- `Read` - To examine files found via search

## Response Format
Return findings as:
1. **Relevant Files** - Ranked by semantic relevance
2. **Key Patterns** - Architectural observations
3. **Entry Points** - Where to start for the task

Never modify files. Summarize concisely for the main agent.
```

### 2. web-automation.md (Playwright Isolation)
```yaml
---
name: web-automation
description: |
  Browser automation and web scraping tasks. Use for:
  - Automated testing with Playwright
  - Web scraping and data extraction
  - Screenshot capture and visual testing
  - Form filling and interaction recording
  MUST run in foreground (MCP required).
model: inherit
tools: Read, Write, Bash, mcp__playwright__*
disallowedTools: mcp__github__*, mcp__llmx__*
permissionMode: acceptEdits
---

You are a browser automation specialist using Playwright MCP.

## Available Playwright Tools
- Navigate, click, fill, screenshot
- Wait for selectors, extract text
- Handle multiple pages/contexts

## Constraints
- Always close browser contexts when done
- Return screenshots as base64 when visual verification needed
- Summarize extracted data, don't dump raw HTML

## Response Format
Return:
1. **Actions Taken** - What you did
2. **Results** - Data extracted or verification status
3. **Screenshots** - If visual confirmation needed
```

### 3. github-ops.md (GitHub Isolation)
```yaml
---
name: github-ops
description: |
  GitHub operations and repository management. Use for:
  - Creating/reviewing pull requests
  - Issue management and triage
  - Repository search and analysis
  - Release management
  MUST run in foreground (MCP required).
model: inherit
tools: Read, Bash, mcp__github__*
disallowedTools: mcp__playwright__*, Write, Edit
permissionMode: default
---

You are a GitHub operations specialist.

## Available GitHub Tools
- Search repositories, issues, PRs
- Create/update issues and PRs
- Manage labels, milestones, releases
- Review and comment on code

## Constraints
- Confirm destructive operations before executing
- Summarize PR/issue content, don't dump full text
- Use rate limiting awareness

## Response Format
Return:
1. **Operation** - What was done
2. **Result** - Links to created/modified resources
3. **Summary** - Key information extracted
```

### 4. re-analyst.md (Reverse Engineering)
```yaml
---
name: re-analyst
description: |
  Binary analysis and reverse engineering tasks. Use for:
  - iOS/macOS binary analysis
  - Disassembly and decompilation review
  - Protocol reverse engineering
  - Security vulnerability analysis
  Specialized for RE workflows.
model: inherit
tools: Read, Bash, Grep, Glob
disallowedTools: mcp__*, Write, Edit
permissionMode: plan
skills:
  - re-patterns
---

You are a reverse engineering analyst.

## Methodology
1. Static analysis first (strings, headers, imports)
2. Identify interesting functions via symbols/patterns
3. Trace data flow and control flow
4. Document findings systematically

## Tools Available
- `Bash` for running analysis tools (otool, nm, strings, class-dump, frida)
- `Read` for examining output files
- `Grep/Glob` for pattern matching

## Response Format
Return:
1. **Target Info** - Binary metadata, architecture
2. **Interesting Findings** - Functions, strings, patterns
3. **Recommendations** - Next analysis steps
```

### 5. clean-task.md (MCP-Free General Purpose)
```yaml
---
name: clean-task
description: |
  General purpose task execution WITHOUT external tool access. Use for:
  - Code modifications that don't need external APIs
  - File operations and refactoring
  - Local testing and validation
  - Any task where MCP would be overhead
  Lightweight alternative to general-purpose.
model: inherit
tools: Read, Write, Edit, Bash, Grep, Glob
disallowedTools: mcp__*
permissionMode: acceptEdits
---

You are a focused task executor. No external API access.

Work efficiently with local tools only. If you need external data,
tell the main agent to use a specialized subagent instead.
```

### 6. specwriter.md (Documentation)
```yaml
---
name: specwriter
description: |
  Technical documentation and specification writing. Use for:
  - API documentation generation
  - Architecture decision records
  - README and guide creation
  - Code comment generation
  Read-heavy, write-focused.
model: inherit  
tools: Read, Write, Grep, Glob, mcp__llmx__search
disallowedTools: Bash, Edit, mcp__playwright__*, mcp__github__*
permissionMode: acceptEdits
---

You are a technical writer. Read code, write documentation.

## Process
1. Use llmx to find relevant code
2. Read and understand the implementation
3. Write clear, accurate documentation
4. Use consistent formatting (your conventions)

## Output Formats
- Markdown for docs
- JSDoc/docstrings for inline
- OpenAPI for APIs
```

---

## Slash Commands

### /search - Semantic Code Search
```yaml
# ~/.claude/commands/search.md
---
description: Semantic code search using llmx
argument-hint: "<natural language query>"
---

Use the llmx-explorer subagent to search for: $ARGUMENTS

Return the top 10 most relevant results with file paths and brief context.
```

### /index - Reindex Codebase
```yaml
# ~/.claude/commands/index.md
---
description: Reindex current project with llmx
---

Run the llmx indexer on the current project:

```bash
llmx index --path . --storage ~/.llmx/indexes/$(basename $(pwd))
```

Report indexing status when complete.
```

### /re - Reverse Engineering Session
```yaml
# ~/.claude/commands/re.md
---
description: Start reverse engineering analysis
argument-hint: "<binary path or description>"
---

Use the re-analyst subagent to analyze: $ARGUMENTS

Begin with static analysis, then report findings and recommended next steps.
```

### /detect - AI Detection Pipeline
```yaml
# ~/.claude/commands/detect.md
---
description: Run SpecHO AI text detection
argument-hint: "<text or file path>"
---

Analyze the provided content using SpecHO fingerprinting:

1. Extract linguistic features (148-dimensional)
2. Compare against known model signatures
3. Report confidence scores and model attribution

Input: $ARGUMENTS
```

---

## Skills

### specho-analysis/SKILL.md
```yaml
---
name: specho-analysis
description: |
  SpecHO AI text detection and model fingerprinting workflow.
  148-dimensional linguistic analysis for identifying AI-generated text
  and attributing specific models.
disable-model-invocation: false
---

# SpecHO Analysis Workflow

## Feature Extraction Pipeline
1. **Tokenization** - Split into sentences and tokens
2. **Lexical Features** - Vocabulary richness, word length distribution
3. **Syntactic Features** - POS patterns, dependency structures  
4. **Semantic Features** - Embedding-based coherence metrics
5. **Stylometric Features** - Punctuation patterns, sentence rhythm

## Model Signatures
Known fingerprints for: GPT-4, GPT-3.5, Claude 3, Claude 2, Llama, Mistral

## Usage
```python
from specho import SpecHODetector

detector = SpecHODetector()
result = detector.analyze(text)
print(f"AI Probability: {result.ai_score:.2%}")
print(f"Likely Model: {result.attribution}")
```

## Confidence Thresholds
- >0.95: High confidence AI
- 0.70-0.95: Likely AI, needs review
- 0.30-0.70: Uncertain
- <0.30: Likely human
```

### re-patterns/SKILL.md
```yaml
---
name: re-patterns
description: |
  iOS and macOS reverse engineering patterns and techniques.
  Common analysis workflows for binary analysis.
disable-model-invocation: true
---

# iOS/macOS RE Patterns

## Initial Triage
```bash
# Binary info
file <binary>
otool -h <binary>
otool -l <binary> | grep -A2 LC_ENCRYPTION

# Symbols
nm -u <binary>  # Undefined (imports)
nm -g <binary>  # Global (exports)

# Strings
strings -a <binary> | grep -i "api\|key\|secret\|token"

# Objective-C
class-dump <binary> > headers.h
```

## Frida Patterns
```javascript
// Hook method
Interceptor.attach(ObjC.classes.ClassName["- methodName:"].implementation, {
  onEnter: function(args) {
    console.log("Called with:", ObjC.Object(args[2]));
  }
});

// Trace class
ObjC.classes.ClassName.$methods.forEach(function(m) {
  console.log(m);
});
```

## Common Targets
- `SecItemCopyMatching` - Keychain access
- `CC_SHA256` / `CCCrypt` - Crypto operations
- `NSURLSession` - Network requests
- `UIApplication openURL` - URL schemes
```

---

## Hooks

### mcp-guard.py (Audit MCP Usage)
```python
#!/usr/bin/env python3
# ~/.claude/hooks/mcp-guard.py
"""
PreToolUse hook to audit and optionally block MCP tool usage.
Logs all MCP calls for review.
"""

import json
import sys
from datetime import datetime
from pathlib import Path

LOG_FILE = Path.home() / ".claude" / "mcp-audit.log"

def main():
    input_data = json.load(sys.stdin)
    tool_name = input_data.get("tool_name", "")
    
    # Only process MCP tools
    if not tool_name.startswith("mcp__"):
        sys.exit(0)
    
    # Log the call
    log_entry = {
        "timestamp": datetime.now().isoformat(),
        "tool": tool_name,
        "session": input_data.get("session_id", "unknown"),
        "input": input_data.get("tool_input", {})
    }
    
    with open(LOG_FILE, "a") as f:
        f.write(json.dumps(log_entry) + "\n")
    
    # Allow the call (exit 0)
    # To block: exit 2 with error message
    sys.exit(0)

if __name__ == "__main__":
    main()
```

### Hook Configuration
```json
// In ~/.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__.*",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/mcp-guard.py"
          }
        ]
      }
    ]
  }
}
```

---

## CLAUDE.md Template

```markdown
# Project: [Name]

## Quick Context
[2-3 sentences about what this project does]

## Tech Stack
- Language: [Rust/Python/TypeScript/etc]
- Framework: [if applicable]
- Key deps: [important libraries]

## Directory Structure
```
src/           - Main source
tests/         - Test files
docs/          - Documentation
```

## Development Commands
```bash
# Build
cargo build --release

# Test
cargo test

# Run
./target/release/[binary]
```

## Code Conventions
- [Your style preferences]
- [Naming conventions]
- [Error handling patterns]

## Subagent Guidelines
When delegating tasks:
- **Code search**: Use llmx-explorer (semantic search)
- **Web automation**: Use web-automation (foreground only)
- **GitHub ops**: Use github-ops (foreground only)
- **General tasks**: Use clean-task (no MCP overhead)
- **NEVER** give subagents MCP tools they don't explicitly need

## Current Focus
[What you're working on - update this]
```

---

## Workflow Integration

### Daily Workflow
```
1. Start session: `claude` (llmx always available)
2. Code search: `/search <query>` or natural language
3. Tasks needing GitHub: Claude auto-delegates to github-ops
4. Tasks needing browser: Claude auto-delegates to web-automation
5. Everything else: clean-task or inline

Tool Search handles main context. Subagents handle isolation.
```

### Project Onboarding
```bash
# Index new project
cd ~/dev/new-project
llmx index --path . --storage ~/.llmx/indexes/new-project

# Create project config if needed
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
  "permissions": {
    "allow": ["Bash(cargo *)"]
  }
}
EOF

# Add project-specific MCP if needed
cat > .mcp.json << 'EOF'
{
  "mcpServers": {}
}
EOF
```

### Monitoring
```bash
# Check context usage
# In Claude Code: /context or /doctor

# Review MCP audit log
tail -f ~/.claude/mcp-audit.log | jq .

# Check llmx index status
llmx status
```

---

## Migration Checklist

- [ ] Backup existing `~/.claude/` directory
- [ ] Create directory structure above
- [ ] Move MCP servers from mcp.json to appropriate tiers
- [ ] Create subagent definitions
- [ ] Create slash commands
- [ ] Add hooks for MCP auditing
- [ ] Update CLAUDE.md in active projects
- [ ] Test subagent delegation with explicit prompts
- [ ] Verify Tool Search is working: `/doctor`

---

## Known Limitations

1. **Background subagents can't use MCP** - Always use foreground for MCP-heavy tasks
2. **Custom plugin subagents may not inherit MCP** - Known bug (#13605)
3. **No scoped MCP per-subagent** - Feature requested (#6915, #7289)
4. **Built-in agents can't be overridden by name** - Must disable + replace
5. **Tool Search threshold is global** - Can't set per-server

---

## Future Improvements (Watch These Issues)

- [ ] #6915 - MCP tools available only to subagent
- [ ] #7289 - Disable MCP in default, enable for subagents
- [ ] #13605 - Plugin subagents MCP access
- [ ] #13254 - Background subagents MCP access


---
## claude-code-built-in-tools-reference.md

This is a guide I created while exploring the built-in tools Claude Code ships with and how it’s trained/prompted to use them. Included below is every built-in tool, their parameters, usage patterns, and examples. This was basically all written by prompting Claude Code itself.

___

## Table of Contents[](https://www.vtrivedy.com/posts/claudecode-tools-reference#table-of-contents)

Open Table of Contents

-   [1\. Task](https://www.vtrivedy.com/posts/claudecode-tools-reference#1-task)
-   [2\. Bash](https://www.vtrivedy.com/posts/claudecode-tools-reference#2-bash)
-   [3\. Glob](https://www.vtrivedy.com/posts/claudecode-tools-reference#3-glob)
-   [4\. Grep](https://www.vtrivedy.com/posts/claudecode-tools-reference#4-grep)
-   [5\. Read, 6. Edit, 7. Write](https://www.vtrivedy.com/posts/claudecode-tools-reference#5-read-6-edit-7-write)
    -   [Read](https://www.vtrivedy.com/posts/claudecode-tools-reference#read)
    -   [Edit](https://www.vtrivedy.com/posts/claudecode-tools-reference#edit)
    -   [Write](https://www.vtrivedy.com/posts/claudecode-tools-reference#write)
-   [8\. NotebookEdit](https://www.vtrivedy.com/posts/claudecode-tools-reference#8-notebookedit)
-   [9\. WebFetch, 10. WebSearch](https://www.vtrivedy.com/posts/claudecode-tools-reference#9-webfetch-10-websearch)
    -   [WebFetch](https://www.vtrivedy.com/posts/claudecode-tools-reference#webfetch)
    -   [WebSearch](https://www.vtrivedy.com/posts/claudecode-tools-reference#websearch)
-   [11\. TodoWrite](https://www.vtrivedy.com/posts/claudecode-tools-reference#11-todowrite)
-   [12\. ExitPlanMode](https://www.vtrivedy.com/posts/claudecode-tools-reference#12-exitplanmode)
-   [13\. BashOutput, 14. KillShell](https://www.vtrivedy.com/posts/claudecode-tools-reference#13-bashoutput-14-killshell)
    -   [BashOutput](https://www.vtrivedy.com/posts/claudecode-tools-reference#bashoutput)
    -   [KillShell](https://www.vtrivedy.com/posts/claudecode-tools-reference#killshell)
-   [15\. SlashCommand](https://www.vtrivedy.com/posts/claudecode-tools-reference#15-slashcommand)
-   [Tool Usage Patterns & Best Practices](https://www.vtrivedy.com/posts/claudecode-tools-reference#tool-usage-patterns--best-practices)
    -   [Batch Operations](https://www.vtrivedy.com/posts/claudecode-tools-reference#batch-operations)
    -   [File Operations Workflow](https://www.vtrivedy.com/posts/claudecode-tools-reference#file-operations-workflow)
    -   [Complex Task Workflow](https://www.vtrivedy.com/posts/claudecode-tools-reference#complex-task-workflow)
    -   [Background Process Management](https://www.vtrivedy.com/posts/claudecode-tools-reference#background-process-management)
    -   [Searching Strategy](https://www.vtrivedy.com/posts/claudecode-tools-reference#searching-strategy)
    -   [Communication](https://www.vtrivedy.com/posts/claudecode-tools-reference#communication)
-   [Examples: Complete Workflows](https://www.vtrivedy.com/posts/claudecode-tools-reference#examples-complete-workflows)
    -   [Workflow 1: Add New Feature](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-1-add-new-feature)
    -   [Workflow 2: Debug Issue](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-2-debug-issue)
    -   [Workflow 3: Research Codebase](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-3-research-codebase)
    -   [Workflow 4: Refactor Code](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-4-refactor-code)
-   [Tool Selection Quick Reference](https://www.vtrivedy.com/posts/claudecode-tools-reference#tool-selection-quick-reference)
-   [Common Antipatterns to Avoid](https://www.vtrivedy.com/posts/claudecode-tools-reference#common-antipatterns-to-avoid)

## 1\. Task[](https://www.vtrivedy.com/posts/claudecode-tools-reference#1-task)

**Purpose**: Launch specialized sub-agents for complex, multi-step tasks that require autonomous work.

**Available Agent Types**:

-   `general-purpose`: Research, code search, multi-step tasks (has access to all tools)
-   `statusline-setup`: Configure status line settings (Read, Edit)
-   `output-style-setup`: Create output styles (Read, Write, Edit, Glob, Grep)

**Parameters**:

-   `subagent_type` (required): Which agent type to use
-   `prompt` (required): Detailed task description for the agent
-   `description` (required): Short 3-5 word description of the task

**When to Use**:

-   Complex tasks requiring multiple rounds of searching/reading
-   When you need an agent to work autonomously
-   Open-ended research tasks

**When NOT to Use**:

-   Reading a specific known file path (use Read instead)
-   Searching within 2-3 specific files (use Read instead)
-   Searching for specific class definitions (use Glob instead)

**Example**:

```
{
  "subagent_type": "general-purpose",
  "description": "Find authentication implementation",
  "prompt": "Search the codebase to find where user authentication is implemented. Look for login functions, JWT handling, and session management. Return the file paths and a summary of how authentication works."
}
```

**Key Notes**:

-   Launch multiple agents concurrently when possible (single message, multiple tool calls)
-   Agent returns one final message - cannot communicate back and forth
-   Agents are stateless - provide complete instructions upfront
-   Specify whether agent should write code or just research

___

## 2\. Bash[](https://www.vtrivedy.com/posts/claudecode-tools-reference#2-bash)

**Purpose**: Execute shell commands in a persistent bash session.

**Parameters**:

-   `command` (required): The shell command to execute
-   `description` (optional but recommended): Clear 5-10 word description
-   `timeout` (optional): Milliseconds before timeout (default: 120000ms, max: 600000ms)
-   `run_in_background` (optional): Boolean to run command in background

**When to Use**:

-   Terminal operations: git, npm, docker, pytest, etc.
-   Commands that modify system state
-   Running builds, tests, servers

**When NOT to Use**:

-   File reading (use Read instead of cat/head/tail)
-   File editing (use Edit instead of sed/awk)
-   File writing (use Write instead of echo >)
-   File searching (use Glob instead of find/ls)
-   Content searching (use Grep instead of grep/rg)

**Examples**:

Basic command:

```
{
  "command": "git status",
  "description": "Check git repository status"
}
```

With timeout:

```
{
  "command": "npm run build",
  "description": "Build production bundle",
  "timeout": 300000
}
```

Background process:

```
{
  "command": "npm run dev",
  "description": "Start development server",
  "run_in_background": true
}
```

Chained commands (sequential with &&):

```
{
  "command": "git add . && git commit -m \"Update features\" && git push",
  "description": "Stage, commit, and push changes"
}
```

Command with paths containing spaces:

```
{
  "command": "cd \"/path/with spaces/\" && ls",
  "description": "List files in directory with spaces"
}
```

**Git Commit Best Practices**:

1.  Run `git status`, `git diff`, and `git log` in parallel
2.  Draft commit message following repo style
3.  Add files and commit with co-authorship footer:

```
git commit -m "$(cat <<'EOF'
Your commit message here.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
EOF
)"
```

**Pull Request Creation**:

1.  Run `git status`, `git diff`, and `git log [base-branch]...HEAD` in parallel
2.  Draft PR summary from ALL commits (not just latest)
3.  Push and create PR:

```
gh pr create --title "PR title" --body "$(cat <<'EOF'
## Summary
- Bullet point 1
- Bullet point 2

## Test plan
- [ ] Test item 1
- [ ] Test item 2

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
```

___

## 3\. Glob[](https://www.vtrivedy.com/posts/claudecode-tools-reference#3-glob)

**Purpose**: Fast file pattern matching for finding files by name patterns.

**Parameters**:

-   `pattern` (required): Glob pattern to match files
-   `path` (optional): Directory to search in (defaults to current working directory)

**Pattern Examples**:

-   `**/*.js` - All JavaScript files recursively
-   `src/**/*.ts` - All TypeScript files in src/
-   `*.{json,yaml}` - All JSON and YAML files in current directory
-   `test/**/*test.js` - All test files

**Examples**:

Find all TypeScript files:

Find config files in specific directory:

```
{
  "pattern": "*.config.{js,ts}",
  "path": "/Users/project/root"
}
```

Find React components:

```
{
  "pattern": "src/components/**/*.tsx"
}
```

**Key Notes**:

-   Returns files sorted by modification time
-   Works with any codebase size
-   Faster than bash find command
-   Use for open-ended searches with Agent tool

___

## 4\. Grep[](https://www.vtrivedy.com/posts/claudecode-tools-reference#4-grep)

**Purpose**: Powerful content search built on ripgrep for finding text/code patterns in files.

**Parameters**:

-   `pattern` (required): Regular expression to search for
-   `path` (optional): File or directory to search (defaults to current directory)
-   `output_mode` (optional): “content” (lines), “files\_with\_matches” (paths), “count” (counts)
-   `glob` (optional): Filter files by glob pattern (e.g., “\*.js”)
-   `type` (optional): Filter by file type (e.g., “js”, “py”, “rust”)
-   `-A` (optional): Lines to show after match (requires output\_mode: “content”)
-   `-B` (optional): Lines to show before match (requires output\_mode: “content”)
-   `-C` (optional): Lines to show before and after match (requires output\_mode: “content”)
-   `-i` (optional): Case insensitive search (boolean)
-   `-n` (optional): Show line numbers (requires output\_mode: “content”)
-   `multiline` (optional): Enable multiline matching where . matches newlines (boolean)
-   `head_limit` (optional): Limit output to first N results

**Pattern Syntax**:

-   Uses ripgrep (not grep)
-   Literal braces need escaping: `interface\\{\\}` to find `interface{}`
-   Standard regex: `log.*Error`, `function\\s+\\w+`

**Examples**:

Find files containing pattern:

```
{
  "pattern": "function authenticate",
  "output_mode": "files_with_matches"
}
```

Show matching lines with context:

```
{
  "pattern": "TODO",
  "output_mode": "content",
  "-n": true,
  "-C": 2
}
```

Case-insensitive search in TypeScript files:

```
{
  "pattern": "errorhandler",
  "-i": true,
  "type": "ts",
  "output_mode": "content"
}
```

Count occurrences:

```
{
  "pattern": "console\\.log",
  "output_mode": "count"
}
```

Search with glob filter:

```
{
  "pattern": "import.*React",
  "glob": "*.tsx",
  "output_mode": "content"
}
```

Multiline pattern matching:

```
{
  "pattern": "struct \\{[\\s\\S]*?field",
  "multiline": true,
  "output_mode": "content"
}
```

Limited results:

```
{
  "pattern": "export function",
  "output_mode": "content",
  "head_limit": 10
}
```

___

## 5\. Read, 6. Edit, 7. Write[](https://www.vtrivedy.com/posts/claudecode-tools-reference#5-read-6-edit-7-write)

### Read[](https://www.vtrivedy.com/posts/claudecode-tools-reference#read)

**Purpose**: Read files from the filesystem.

**Parameters**:

-   `file_path` (required): Absolute path to file
-   `offset` (optional): Line number to start reading from
-   `limit` (optional): Number of lines to read

**Supported File Types**:

-   Text files
-   Images (PNG, JPG) - displayed visually
-   PDFs - processed page by page
-   Jupyter notebooks (.ipynb) - all cells with outputs

**Examples**:

Read entire file:

```
{
  "file_path": "/Users/vivektrivedy/Desktop/personal_website/vtrivedy_website/src/config.ts"
}
```

Read specific line range:

```
{
  "file_path": "/path/to/large/file.log",
  "offset": 1000,
  "limit": 100
}
```

Read image:

```
{
  "file_path": "/var/folders/tmp/Screenshot.png"
}
```

**Key Notes**:

-   Returns content with line numbers (cat -n format)
-   Lines longer than 2000 characters are truncated
-   Default reads up to 2000 lines from start
-   Batch multiple Read calls in one response for performance

___

### Edit[](https://www.vtrivedy.com/posts/claudecode-tools-reference#edit)

**Purpose**: Perform exact string replacements in files.

**Parameters**:

-   `file_path` (required): Absolute path to file
-   `old_string` (required): Exact text to replace
-   `new_string` (required): Replacement text (must differ from old\_string)
-   `replace_all` (optional): Replace all occurrences (default: false)

**Requirements**:

-   MUST read file with Read tool first
-   `old_string` must be unique in file (unless using `replace_all`)
-   Preserve exact indentation from Read output (exclude line number prefix)

**Line Number Prefix Format**:

```
[spaces][line_number][tab][actual_content]
```

Only include `[actual_content]` in old\_string/new\_string.

**Examples**:

Simple replacement:

```
{
  "file_path": "/path/to/file.ts",
  "old_string": "const port = 3000;",
  "new_string": "const port = 4321;"
}
```

Multi-line replacement:

```
{
  "file_path": "/path/to/component.tsx",
  "old_string": "export default function Header() {\n  return <h1>Old Title</h1>;\n}",
  "new_string": "export default function Header() {\n  return <h1>New Title</h1>;\n}"
}
```

Replace all occurrences (renaming):

```
{
  "file_path": "/path/to/file.ts",
  "old_string": "oldFunctionName",
  "new_string": "newFunctionName",
  "replace_all": true
}
```

**Common Mistakes to Avoid**:

-   ❌ Including line numbers in old\_string: `"25\tconst x = 5;"`
-   ✅ Correct: `"const x = 5;"`
-   ❌ Wrong indentation: `" function foo()"` when file has tabs
-   ✅ Match exact whitespace from Read output

___

### Write[](https://www.vtrivedy.com/posts/claudecode-tools-reference#write)

**Purpose**: Write or overwrite files.

**Parameters**:

-   `file_path` (required): Absolute path to file
-   `content` (required): Complete file content

**Requirements**:

-   For existing files: MUST read with Read tool first
-   Prefer Edit over Write for existing files
-   Only create new files when absolutely necessary

**Examples**:

Create new file:

```
{
  "file_path": "/path/to/new/file.ts",
  "content": "export const API_URL = 'https://api.example.com';\n"
}
```

Overwrite existing file:

```
{
  "file_path": "/path/to/existing/config.json",
  "content": "{\n  \"version\": \"2.0\",\n  \"enabled\": true\n}\n"
}
```

___

## 8\. NotebookEdit[](https://www.vtrivedy.com/posts/claudecode-tools-reference#8-notebookedit)

**Purpose**: Edit Jupyter notebook (.ipynb) cells.

**Parameters**:

-   `notebook_path` (required): Absolute path to notebook
-   `new_source` (required): New cell content
-   `cell_id` (optional): ID of cell to edit (for insert: new cell inserted after this ID)
-   `cell_type` (optional): “code” or “markdown” (required for insert mode)
-   `edit_mode` (optional): “replace” (default), “insert”, “delete”

**Examples**:

Replace cell content:

```
{
  "notebook_path": "/path/to/notebook.ipynb",
  "cell_id": "abc123",
  "new_source": "import pandas as pd\ndf = pd.read_csv('data.csv')\ndf.head()"
}
```

Insert new code cell:

```
{
  "notebook_path": "/path/to/notebook.ipynb",
  "cell_id": "xyz789",
  "cell_type": "code",
  "edit_mode": "insert",
  "new_source": "# New analysis step\nresult = df.groupby('category').sum()"
}
```

Delete cell:

```
{
  "notebook_path": "/path/to/notebook.ipynb",
  "cell_id": "def456",
  "edit_mode": "delete",
  "new_source": ""
}
```

___

## 9\. WebFetch, 10. WebSearch[](https://www.vtrivedy.com/posts/claudecode-tools-reference#9-webfetch-10-websearch)

### WebFetch[](https://www.vtrivedy.com/posts/claudecode-tools-reference#webfetch)

**Purpose**: Fetch and process web content with AI analysis.

**Parameters**:

-   `url` (required): Fully-formed valid URL
-   `prompt` (required): What information to extract from the page

**Features**:

-   Converts HTML to markdown
-   Auto-upgrades HTTP to HTTPS
-   15-minute cache for repeated requests
-   Handles redirects (requires new request with redirect URL)

**Examples**:

Fetch documentation:

```
{
  "url": "https://docs.astro.build/en/getting-started/",
  "prompt": "Extract the commands needed to create a new Astro project and start the dev server"
}
```

Analyze article:

```
{
  "url": "https://example.com/blog/best-practices",
  "prompt": "Summarize the key best practices mentioned in this article"
}
```

Check API reference:

```
{
  "url": "https://api-docs.example.com/v2/authentication",
  "prompt": "What are the authentication methods supported and their required parameters?"
}
```

**Key Notes**:

-   Prefer MCP-provided web fetch tools if available (start with “mcp\_\_”)
-   Read-only operation
-   Results may be summarized for large content
-   When redirected to different host, make new request with redirect URL

___

### WebSearch[](https://www.vtrivedy.com/posts/claudecode-tools-reference#websearch)

**Purpose**: Search the web for current information beyond Claude’s knowledge cutoff.

**Parameters**:

-   `query` (required): Search query string (min 2 characters)
-   `allowed_domains` (optional): Array of domains to include
-   `blocked_domains` (optional): Array of domains to exclude

**Availability**: US only

**Examples**:

Basic search:

```
{
  "query": "Astro 4.0 new features 2025"
}
```

Search specific domains:

```
{
  "query": "TypeScript best practices",
  "allowed_domains": ["typescript-lang.org", "github.com"]
}
```

Exclude domains:

```
{
  "query": "React hooks tutorial",
  "blocked_domains": ["pinterest.com", "youtube.com"]
}
```

**Key Notes**:

-   Consider current date when forming queries
-   Returns search result blocks
-   Use for information beyond January 2025 knowledge cutoff

___

## 11\. TodoWrite[](https://www.vtrivedy.com/posts/claudecode-tools-reference#11-todowrite)

**Purpose**: Create and manage structured task lists for tracking progress.

**Parameters**:

-   `todos` (required): Array of todo objects with:
    -   `content` (required): Imperative form (e.g., “Run tests”)
    -   `activeForm` (required): Present continuous form (e.g., “Running tests”)
    -   `status` (required): “pending”, “in\_progress”, or “completed”

**When to Use**:

-   Complex multi-step tasks (3+ steps)
-   Non-trivial complex tasks requiring planning
-   User explicitly requests todo list
-   User provides multiple tasks
-   After receiving new instructions (capture requirements)
-   When starting work (mark as in\_progress BEFORE beginning)
-   After completing tasks (mark completed, add follow-ups)

**When NOT to Use**:

-   Single straightforward task
-   Trivial tasks providing no organizational benefit
-   Tasks completable in <3 trivial steps
-   Purely conversational/informational requests

**Critical Rules**:

-   EXACTLY ONE task must be “in\_progress” at any time
-   Mark tasks completed IMMEDIATELY after finishing (no batching)
-   Only mark completed when FULLY accomplished
-   Keep task in\_progress if: tests failing, implementation partial, unresolved errors, missing dependencies
-   Remove irrelevant tasks entirely

**Examples**:

Create initial todo list:

```
{
  "todos": [
    {
      "content": "Search codebase for authentication logic",
      "activeForm": "Searching codebase for authentication logic",
      "status": "in_progress"
    },
    {
      "content": "Implement OAuth2 flow",
      "activeForm": "Implementing OAuth2 flow",
      "status": "pending"
    },
    {
      "content": "Add authentication tests",
      "activeForm": "Adding authentication tests",
      "status": "pending"
    }
  ]
}
```

Update progress:

```
{
  "todos": [
    {
      "content": "Search codebase for authentication logic",
      "activeForm": "Searching codebase for authentication logic",
      "status": "completed"
    },
    {
      "content": "Implement OAuth2 flow",
      "activeForm": "Implementing OAuth2 flow",
      "status": "in_progress"
    },
    {
      "content": "Add authentication tests",
      "activeForm": "Adding authentication tests",
      "status": "pending"
    }
  ]
}
```

___

## 12\. ExitPlanMode[](https://www.vtrivedy.com/posts/claudecode-tools-reference#12-exitplanmode)

**Purpose**: Exit plan mode after presenting an implementation plan.

**Parameters**:

-   `plan` (required): The implementation plan (supports markdown)

**When to Use**:

-   ONLY for tasks requiring code implementation planning
-   After finishing planning implementation steps

**When NOT to Use**:

-   Research tasks (gathering information, searching, reading, understanding codebase)

**Example**:

```
{
  "plan": "## Implementation Plan\n\n1. Create authentication middleware in `src/middleware/auth.ts`\n2. Add JWT verification logic\n3. Protect API routes with middleware\n4. Add tests for authentication flow\n\nShall I proceed with this plan?"
}
```

___

## 13\. BashOutput, 14. KillShell[](https://www.vtrivedy.com/posts/claudecode-tools-reference#13-bashoutput-14-killshell)

### BashOutput[](https://www.vtrivedy.com/posts/claudecode-tools-reference#bashoutput)

**Purpose**: Retrieve output from running or completed background bash shells.

**Parameters**:

-   `bash_id` (required): ID of the background shell
-   `filter` (optional): Regular expression to filter output lines

**Returns**:

-   Only new output since last check
-   stdout and stderr
-   Shell status

**Example**:

```
{
  "bash_id": "shell_12345",
  "filter": "ERROR|WARN"
}
```

**Key Notes**:

-   Find shell IDs with `/bashes` command
-   Filtered lines are consumed (no longer available to read)

___

### KillShell[](https://www.vtrivedy.com/posts/claudecode-tools-reference#killshell)

**Purpose**: Terminate a running background bash shell.

**Parameters**:

-   `shell_id` (required): ID of shell to terminate

**Example**:

```
{
  "shell_id": "shell_12345"
}
```

___

## 15\. SlashCommand[](https://www.vtrivedy.com/posts/claudecode-tools-reference#15-slashcommand)

**Purpose**: Execute slash commands within the conversation.

**Parameters**:

-   `command` (required): Slash command with arguments (e.g., “/review-pr 123”)

**Restrictions**:

-   Only available commands can be executed
-   Don’t use if command with same name is already running
-   Check command-message tags for running status

**Example**:

___

### Batch Operations[](https://www.vtrivedy.com/posts/claudecode-tools-reference#batch-operations)

**Always batch independent tool calls in a single response for optimal performance.**

Example - Multiple file reads:

```
Call Read on file1.ts, file2.ts, file3.ts in single message
```

Example - Parallel git commands:

```
Call Bash("git status") and Bash("git diff") in single message
```

### File Operations Workflow[](https://www.vtrivedy.com/posts/claudecode-tools-reference#file-operations-workflow)

1.  **Search for files**: Use Glob (not find/ls)
2.  **Search content**: Use Grep (not bash grep/rg)
3.  **Read files**: Use Read (not cat/head/tail)
4.  **Edit files**: Use Edit (not sed/awk)
5.  **Write files**: Use Write (not echo >/heredoc)

### Complex Task Workflow[](https://www.vtrivedy.com/posts/claudecode-tools-reference#complex-task-workflow)

1.  Use TodoWrite to plan and track tasks
2.  Use Task agent for multi-step research
3.  Use Bash for terminal operations only
4.  Batch independent operations together
5.  Mark todos completed immediately after finishing

### Background Process Management[](https://www.vtrivedy.com/posts/claudecode-tools-reference#background-process-management)

1.  Start process: `Bash` with `run_in_background: true`
2.  Monitor output: `BashOutput` with bash\_id
3.  Filter if needed: Use `filter` parameter with regex
4.  Terminate when done: `KillShell` with shell\_id

### Searching Strategy[](https://www.vtrivedy.com/posts/claudecode-tools-reference#searching-strategy)

-   **Known file paths**: Use Read directly
-   **File name patterns**: Use Glob
-   **Content in specific files**: Read then search locally
-   **Content across codebase**: Use Grep
-   **Complex multi-round search**: Use Task with general-purpose agent

### Communication[](https://www.vtrivedy.com/posts/claudecode-tools-reference#communication)

-   Output text directly to user (not bash echo)
-   Use markdown formatting for readability
-   Include file references as links: `[filename.ts](src/filename.ts)` or `[filename.ts:42](src/filename.ts#L42)`
-   Be concise and direct (avoid preamble/postamble)

___

## Examples: Complete Workflows[](https://www.vtrivedy.com/posts/claudecode-tools-reference#examples-complete-workflows)

### Workflow 1: Add New Feature[](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-1-add-new-feature)

```
1. TodoWrite: Plan the feature tasks
2. Grep: Find related existing implementations
3. Read: Read relevant files (batch multiple)
4. Edit: Modify existing files (or Write for new files)
5. Bash: Run tests
6. TodoWrite: Mark tasks completed
7. Bash: Commit changes (if requested)
```

### Workflow 2: Debug Issue[](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-2-debug-issue)

```
1. TodoWrite: Create debugging task list
2. Grep: Search for error messages/patterns
3. Read: Read files with issues (batch multiple)
4. Bash: Run failing tests/reproduce issue
5. Edit: Apply fixes
6. Bash: Verify fix with tests
7. TodoWrite: Mark completed
```

### Workflow 3: Research Codebase[](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-3-research-codebase)

```
1. Task: Launch general-purpose agent with research prompt
   (Agent will autonomously use Grep, Glob, Read to explore)
2. Agent returns findings
3. Present summary to user
```

### Workflow 4: Refactor Code[](https://www.vtrivedy.com/posts/claudecode-tools-reference#workflow-4-refactor-code)

```
1. TodoWrite: Break down refactoring tasks
2. Grep: Find all occurrences of code to refactor
3. Read: Read affected files (batch multiple)
4. Edit: Apply refactoring with replace_all for renames
5. Bash: Run tests and type checking
6. TodoWrite: Mark tasks completed
```

___

| Task | Use This Tool | NOT This |
| --- | --- | --- |
| Find files by name | Glob | Bash(find/ls) |
| Search content | Grep | Bash(grep/rg) |
| Read file | Read | Bash(cat/head/tail) |
| Edit file | Edit | Bash(sed/awk) |
| Create file | Write | Bash(echo >) |
| Run tests/builds | Bash | N/A |
| Multi-step research | Task | Multiple manual searches |
| Track complex tasks | TodoWrite | Comments/memory |
| Fetch web content | WebFetch | Bash(curl) |
| Search web | WebSearch | WebFetch with search engine |
| Background process | Bash(run\_in\_background) + BashOutput | Bash with & |

___

## Common Antipatterns to Avoid[](https://www.vtrivedy.com/posts/claudecode-tools-reference#common-antipatterns-to-avoid)

❌ **Don’t**: Use bash for file operations

✅ **Do**: Use Read tool

```
{"file_path": "src/config.ts"}
```

❌ **Don’t**: Use echo for communication

```
echo "Now processing files..."
```

✅ **Do**: Output text directly to user

❌ **Don’t**: Make sequential tool calls when independent

```
Call Read on file1, wait, then Read on file2, wait, then Read on file3
```

✅ **Do**: Batch independent calls

```
Call Read on file1, file2, file3 in single message
```

❌ **Don’t**: Forget to use TodoWrite for complex tasks

```
Start working without planning
```

✅ **Do**: Plan first with TodoWrite

❌ **Don’t**: Mark todos completed before actually finishing

```
{"status": "completed"} // but tests are failing
```

✅ **Do**: Only mark completed when fully done

```
{"status": "in_progress"} // keep working until tests pass
```

___

That’s all for now, I’ll try to update this guide with more tools or useful patterns as they come out. But really this is mostly just a reference to look back on when I need to.


---
## claude-code-champion-kit-4934ff2d44.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](https://code.claude.com/docs/en/quickstart)** and **[Common workflows](https://code.claude.com/docs/en/common-workflows)** 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](https://code.claude.com/docs)** before distributing this material internally.


---
## claude-code-changelog-claude-code-docs-3d68ad8e13.md

## On this page

- [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). Run `claude --version` to check your installed version.

[​](#2-1-220)

2.1.220

July 25, 2026

- Bug fixes and reliability improvements

[​](#2-1-219)

2.1.219

July 24, 2026

- Added Claude Opus 5 (`claude-opus-5`), now the default Opus model — 1M context, fast mode at $10/$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
- Fixed `claude -p` text output dropping the answer already produced when a turn dies on a mid-stream API error
- 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
- 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
- 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
- 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
- Added the current default workflow size to the running-workflow status line, with a pointer to `/config` for changing it
- 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

[​](#2-1-218)

2.1.218

July 22, 2026

- 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
- 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
- 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
- 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
- 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
- Added an announcement when fast mode changes as a result of switching models via `/config model=<x>` or Remote Control
- 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`
- Added `yes`/`no`/`on`/`off`/`1`/`0` (case-insensitive) as accepted values for skill and plugin frontmatter booleans, alongside `true`/`false`
- 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 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
- 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
- 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
- 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
- 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 subagents to no longer spawn nested subagents by default; set `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH` to allow deeper nesting
- 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 `sandbox.filesystem.disabled` setting to skip filesystem isolation while keeping network egress control
- 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
- 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
- `/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
- \[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

- 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
- 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](https://www.anthropic.com/research/end-subset-conversations)
- 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
- 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
- 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
- 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"`

[​](#2-1-212)

2.1.212

July 17, 2026

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

[​](#2-1-211)

2.1.211

July 15, 2026

- Added `--forward-subagent-text` flag and `CLAUDE_CODE_FORWARD_SUBAGENT_TEXT` environment variable to include subagent text and thinking in stream-json output
- 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
- Hardened synced skill/plugin directory naming on Windows and kept CCR web fetch/search proxies working after `/clear`
- 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
- 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
- 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 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
- 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
- Hardened the Agent tool against indirect prompt injection via content a subagent read
- 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
- 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

[​](#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 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 the Fable 5 usage-credits consent prompt to start with the decline option focused
- 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
- Improved input responsiveness while agent task lists update — task updates no longer re-render the entire UI
- 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
- 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

- Auto mode is now available without `CLAUDE_CODE_ENABLE_AUTO_MODE` opt-in on Bedrock, Vertex AI, and Foundry; disable via `disableAutoMode` in settings
- 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
- 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
- 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
- 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.
- 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
- 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 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
- `/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
- 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
- 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
- Changed agents view: Ctrl+X now permanently removes a completed session, and sessions no longer render twice; deleted background jobs stay deleted

[​](#2-1-205)

2.1.205

July 8, 2026

- Added an auto mode rule that blocks tampering with session transcript files
- 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
- Improved auto mode to ask before running `rm -rf` on a variable it can’t resolve from context
- 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 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
- `/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
- 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 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
- 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
- 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
- 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
- \[VSCode\] Added a Settings toggle for “Enable Remote Control for all sessions”

[​](#2-1-202)

2.1.202

July 6, 2026

- 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
- 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
- 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”
- 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

[​](#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 `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`
- 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
- 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

[​](#2-1-199)

2.1.199

July 2, 2026

- Stacked slash-skill invocations like `/skill-a /skill-b do XYZ` now load all leading skills (up to 5), not just the first
- 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
- 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

[​](#2-1-198)

2.1.198

July 1, 2026

- 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
- 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
- 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
- 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
- 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
- Keyboard shortcut hints now show opt/cmd instead of alt/super when connected from a Mac over SSH
- 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
- `/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

[​](#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/$2/10 per Mtok through August 31. Update to version 2.1.197 for access. [https://www.anthropic.com/news/claude-sonnet-5](https://www.anthropic.com/news/claude-sonnet-5)

[​](#2-1-196)

2.1.196

June 29, 2026

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

[​](#2-1-195)

2.1.195

June 26, 2026

- Added `CLAUDE_CODE_DISABLE_MOUSE_CLICKS` to disable mouse click/drag/hover in fullscreen mode while keeping wheel scroll
- 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
- 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

[​](#2-1-193)

2.1.193

June 25, 2026

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

[​](#2-1-191)

2.1.191

June 24, 2026

- Added `/rewind` support for resuming a conversation from before `/clear` was run
- 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
- 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
- Reduced CPU usage during streaming responses by ~37% by coalescing text updates to 100ms
- Reduced long-session memory growth from terminal output cache

[​](#2-1-190)

2.1.190

June 24, 2026

- Bug fixes and reliability improvements

[​](#2-1-187)

2.1.187

June 23, 2026

- 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
- 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
- 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
- \[VSCode\] Fixed extension becoming unresponsive when resuming a large session

[​](#2-1-186)

2.1.186

June 22, 2026

- 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
- `!` bash commands now trigger Claude to respond to the output automatically; set `"respondToBashCommands": false` in settings.json to keep the previous context-only behavior
- 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
- 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
- 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`

[​](#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

- 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
- 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 `/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`
- 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 `/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
- Upgraded the bundled Bun runtime to 1.4
- 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
- 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
- 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

- 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.
- 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
- 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/`
- 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
- 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
- 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
- `/bug` now requires a description before submitting, and no longer uses model-refusal text as the GitHub issue title
- 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

- Session titles are now generated in the language of your conversation (set the `language` setting to pin a specific language)
- Added `footerLinksRegexes` setting for regex-matched link badges in the footer row, configurable via user or managed settings
- Improved Bedrock credential caching: credentials from `awsCredentialExport` are now cached until their `Expiration` instead of a fixed 1 hour
- 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
- 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

[​](#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 `wheelScrollAccelerationEnabled` setting to disable mouse-wheel scroll acceleration in fullscreen mode
- 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
- \[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
- 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

- 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
- 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
- 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()`
- Disable mouse tracking on Windows consoles that don’t fully support it
- 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
- Improved performance in long conversations by removing redundant message normalization and avoiding full message-history transforms when streaming tool-use state is unchanged
- 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
- 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
- `/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
- \[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](https://www.anthropic.com/news/claude-fable-5-mythos-5)
- 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 `--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
- 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
- `/workflows` now opens immediately even while a turn is in progress
- 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
- 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
- Improved color contrast for skill tags in the slash-command menu
- Promo credit claims for Apple/Google-billed subscribers without a payment method now explain where to add one
- Added a tip suggesting `claude agents` when running multiple concurrent sessions

[​](#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 `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
- 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
- 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 `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
- 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
- Skills: added `\$` escape syntax to include a literal `$` before a digit in command bodies
- stdio MCP servers now receive the same `CLAUDE_CODE_SESSION_ID` as hooks/Bash on `--resume`
- 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
- 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

[​](#2-1-162)

2.1.162

June 3, 2026

- `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
- 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
- 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
- Improved background service startup and `claude update` verification to wait out endpoint-security scanning of new binaries instead of failing after 5 seconds
- 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

[​](#2-1-161)

2.1.161

June 2, 2026

- `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
- 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
- Improved terminal rendering performance by stabilizing the layout engine’s JIT compilation profile
- Improved rendering performance for large file writes
- \[VSCode\] Added a tip suggesting disabling terminal GPU acceleration (or running `/terminal-setup`) to fix garbled glyphs

[​](#2-1-160)

2.1.160

June 2, 2026

- Added a prompt before writing to shell startup files (`.zshenv`, `.zlogin`, `.bash_login`) and `~/.config/git/`, which could otherwise lead to unintended command execution
- `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
- 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$`
- 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
- 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

[​](#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

- Plugins in `.claude/skills` directories are now automatically loaded, no marketplace required
- 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
- `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
- 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
- Improved performance of long and resumed conversations by eliminating redundant message-rendering recomputations
- `/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
- \[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
- Pressing backspace right after a workflow trigger keyword now dismisses the workflow request (same as alt+w) instead of deleting a character
- Added a “Workflow keyword trigger” setting in /config to stop the word “workflow” in a prompt from triggering a dynamic workflow

[​](#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

- Opus 4.8 is here! Now defaults to high effort · /effort xhigh for your hardest tasks
- 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
- 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
- Added Claude Opus 4.8 support and 4.7 → 4.8 migration guidance to the `/claude-api` skill
- 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`
- Improved the auto-mode classifier’s detection of data exfiltration, particularly bulk transfers of repository contents
- 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
- 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
- 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 `skipLfs` option to `github`/`git` plugin marketplace sources to skip Git LFS downloads during clone and update
- 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
- 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
- `--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
- 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
- `/bg` while Claude is responding now continues the response in the background session instead of dropping it
- 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
- `/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`)

[​](#2-1-152)

2.1.152

May 27, 2026

- `/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
- Added `/reload-skills` command to re-scan skill directories without restarting the session
- `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
- 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
- `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
- Added the session entrypoint as an OpenTelemetry metric attribute (`app.entrypoint`, opt-in via `OTEL_METRICS_INCLUDE_ENTRYPOINT=true`)
- 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

- `/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
- Enterprise: added the `allowAllClaudeAiMcps` managed setting to load claude.ai cloud MCP connectors alongside `managed-mcp.json`
- 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
- Improved `/feedback` reports to include the conversation that happened before context compaction, making issues from earlier in long sessions easier to triage

[​](#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

- 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
- 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
- Prompt history no longer records consecutive duplicate entries — recalling a prompt with arrow-up and submitting it again won’t add another copy
- 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 `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
- 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
- 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
- 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

[​](#2-1-144)

2.1.144

May 19, 2026

- 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”)
- 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)
- 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
- Reduced terminal rendering glitches in VS Code by reducing spinner animation color count
- 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
- 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
- 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
- Resumed sessions now keep the model they were using instead of picking up another session’s `/model` choice
- 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
- `/bg` and `←`-detach now preserve directories added via `/add-dir`
- 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
- `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
- 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)
- 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.

[​](#2-1-143)

2.1.143

May 15, 2026

- 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
- 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
- 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
- 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
- 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`
- Worktree cleanup no longer falls back to `rm -rf` when `git worktree remove` fails, preventing loss of gitignored or in-progress files
- 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.
- `/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)
- Fixed: on Windows, pressing ← in `claude agents` while a response was streaming could leave the agents list unresponsive to all input
- `/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.
- 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 new `claude agents` flags: `--add-dir`, `--settings`, `--mcp-config`, `--plugin-dir`, `--permission-mode`, `--model`, `--effort`, and `--dangerously-skip-permissions` to configure dispatched background sessions
- 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
- 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
- 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
- Removed stale `/model claude-sonnet-4-20250514` suggestion from Usage Policy refusal messages

[​](#2-1-141)

2.1.141

May 13, 2026

- 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
- `/feedback` can now include recent sessions (last 24 hours or 7 days) for issues spanning more than the current session
- Rewind menu: added “Summarize up to here” to compress earlier context while keeping recent turns intact
- 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
- 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
- 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
- Bedrock: `awsCredentialExport` now always runs when configured instead of being skipped when ambient AWS credentials resolve, fixing auth for cross-account access
- \[VSCode\] Fixed in-chat mic showing no feedback when the microphone produced only silence — now shows “No audio detected”
- \[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

[​](#2-1-140)

2.1.140

May 12, 2026

- Improved Agent tool `subagent_type` matching to accept case- and separator-insensitive values (e.g. `"Code Reviewer"` resolves to `code-reviewer`)
- Updated agent color palette
- 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
- 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`.

[​](#2-1-139)

2.1.139

May 11, 2026

- 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](https://code.claude.com/docs/en/agent-view)
- 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
- 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
- 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
- \[VSCode\] Press Cmd/Ctrl+Shift+T to reopen the most recently closed session tab, configurable via `claudeCode.enableReopenClosedSessionShortcut`

[​](#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 `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
- 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
- WSL2: image paste from Windows clipboard now works via a PowerShell fallback when xclip/wl-paste cannot read image data
- Fixed plugin `Stop`/`UserPromptSubmit` hooks failing when cache cleanup deletes a version still in use by a running session
- 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
- 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
- Improved error message when `--worktree` collides with an existing or stale worktree
- Changed plugin marketplace removal key to `d` (matching delete elsewhere) instead of `r` which collided with retry

[​](#2-1-133)

2.1.133

May 7, 2026

- 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
- 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`
- Improved focus mode behavior
- Improved memory usage by releasing warm-spare background workers under memory pressure
- 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
- `claude --help` now lists `--remote-control` alongside `--remote-control-session-name-prefix`
- \[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 `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
- 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
- Improved visual consistency in slash command dialogs and `/login`, `/upgrade`, `/extra-usage` dialog spacing
- Updated the `/tui fullscreen` startup banner to describe additional renderer benefits (lower memory usage, mouse support, auto-copy on select)
- 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 `--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
- 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
- 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

- 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`)
- 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
- Headless `--output-format stream-json`: `init.plugin_errors` now includes `--plugin-dir` load failures in addition to dependency demotions

[​](#2-1-126)

2.1.126

May 1, 2026

- 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

- **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”

- Bounded total size of file-modified reminders when a linter touches many files at once

- 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

- 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

- 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 `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
- 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
- OpenTelemetry: added `claude_code.at_mention` log event for `@`-mention resolution
- 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
- Voice mode: keybindings bound to Caps Lock now show an error since terminals don’t deliver Caps Lock as a key event

[​](#2-1-121)

2.1.121

April 28, 2026

- 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
- 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
- OpenTelemetry: added `stop_reason`, `gen_ai.response.finish_reasons`, and `user_system_prompt` (gated behind `OTEL_LOG_USER_PROMPTS`) to LLM request spans
- \[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
- 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
- Reduced peak file descriptor usage during `find` in the Bash tool on large directory trees

[​](#2-1-120)

2.1.120

April 28, 2026

- Windows: Git for Windows (Git Bash) is no longer required — when absent, Claude Code uses PowerShell as the shell tool
- 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
- 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
- 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
- \[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`
- 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

- `/config` settings (theme, editor mode, verbose, etc.) now persist to `~/.claude/settings.json` and participate in project/local/policy override precedence
- 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
- `--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`
- 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
- Tool search is now disabled by default on Vertex AI to avoid an unsupported beta header error (opt in with `ENABLE_TOOL_SEARCH`)
- 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
- Windows: removed false-positive “Windows requires ‘cmd /c’ wrapper” MCP config warning
- \[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 vim visual mode (`v`) and visual-line mode (`V`) with selection, operators, and visual feedback
- 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"`
- Added `DISABLE_UPDATES` env var to completely block all update paths including manual `claude update` — stricter than `DISABLE_AUTOUPDATER`
- 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
- 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
- `--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
- 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

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

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

- Changed the CLI to spawn a native Claude Code binary (via a per-platform optional dependency) instead of bundled JavaScript
- Added `sandbox.network.deniedDomains` setting to block specific domains even when a broader `allowedDomains` wildcard would otherwise permit them
- 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)
- Improved `/loop`: pressing Esc now cancels pending wakeups, and wakeups display as “Claude resuming /loop wakeup” for clarity
- `/extra-usage` now works from Remote Control (mobile/web) clients
- Remote Control clients can now query `@`-file autocomplete suggestions
- Improved `/ultrareview`: faster launch with parallelized checks, diffstat in the launch dialog, and animated launching state
- 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`
- 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

- 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
- 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`
- `/effort` now opens an interactive slider when called without arguments, with arrow-key navigation between levels and Enter to confirm
- 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
- 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
- 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
- `/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
- Added `OTEL_LOG_RAW_API_BODIES` environment variable to emit full API request and response bodies as OpenTelemetry log events for debugging
- 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
- 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`
- 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
- 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
- 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

[​](#2-1-110)

2.1.110

April 15, 2026

- 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
- Changed `Ctrl+O` to toggle between normal and verbose transcript only; focus view is now toggled separately with the new `/focus` command
- 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`)
- 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
- `--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`.
- 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
- Hardened “Open in editor” actions against command injection from untrusted filenames
- 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 `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.
- 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`
- 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
- Reduced memory footprint for file reads, edits, and syntax highlighting by loading language grammars on demand
- 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
- 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 `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
- `/proactive` is now an alias for `/loop`
- 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)
- 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 `/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)
- `/ultraplan` and other remote-session features now auto-create a default cloud environment instead of requiring web setup first
- 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`
- 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 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
- LSP: Claude Code now identifies itself to language servers via `clientInfo` in the initialize request
- 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
- 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
- Updated the `/claude-api` skill to cover Managed Agents alongside Claude API
- \[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.
- Dropped `/compact` hints when `DISABLE_COMPACT` is set.

[​](#2-1-97)

2.1.97

April 8, 2026

- 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`)
- 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)
- 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
- Updated `/claude-api` skill to cover Managed Agents alongside the Claude API

[​](#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 support for Amazon Bedrock powered by Mantle, set `CLAUDE_CODE_USE_MANTLE=1`
- Changed default effort level from medium to high for API-key, Bedrock/Vertex/Foundry, Team, and Enterprise users (control this with `/effort`)
- 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
- 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
- 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
- Improved `--resume` to resume sessions from other worktrees of the same repo directly instead of printing a `cd` command
- 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\] Reduced cold-open subprocess work on starting a session
- \[VSCode\] Fixed dropdown menus selecting the wrong item when the mouse was over the list while typing or using arrow keys
- \[VSCode\] Added a warning banner when `settings.json` files fail to parse, so users know their permission rules are not being applied

[​](#2-1-92)

2.1.92

April 4, 2026

- 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
- `/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
- 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
- Improved Write tool diff computation speed for large files (60% faster on files with tabs/`&`/`$`)
- 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

[​](#2-1-91)

2.1.91

April 2, 2026

- 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)
- Plugins can now ship executables under `bin/` and invoke them as bare commands from the Bash tool
- 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
- `/feedback` now explains why it’s unavailable instead of disappearing from the slash menu
- 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`
- Edit tool now uses shorter `old_string` anchors, reducing output tokens

[​](#2-1-90)

2.1.90

April 1, 2026

- 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)
- 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
- Hardened PowerShell tool permission checks: fixed trailing `&` background job bypass, `-ErrorAction Break` debugger hang, archive-extraction TOCTOU, and parse-fail fallback deny-rule degradation
- 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
- 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)

[​](#2-1-89)

2.1.89

April 1, 2026

- 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
- Auto mode: denied commands now show a notification and appear in `/permissions` → Recent tab where you can retry with `r`
- 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)
- 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+)
- 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 50K characters to be saved to disk with a file path + 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

[​](#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 `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
- 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
- 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
- Improved prompt cache hit rate for Bedrock, Vertex, and Foundry users by removing dynamic content from tool descriptions
- 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”)
- \[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)
- Read tool now uses compact line-number format and deduplicates unchanged re-reads, reducing token usage

[​](#2-1-85)

2.1.85

March 26, 2026

- 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
- 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`
- 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
- 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
- Reduced UI stutter when compaction triggers on large sessions

[​](#2-1-84)

2.1.84

March 26, 2026

- Added PowerShell tool for Windows as an opt-in preview. Learn more at [https://code.claude.com/docs/en/tools-reference#powershell-tool](https://code.claude.com/docs/en/tools-reference#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
- 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
- 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
- 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
- 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
- \[VSCode\] Added rate limit warning banner with usage percentage and reset time
- Stats screenshot (Ctrl+S in /stats) now works in all builds and is 16× faster

[​](#2-1-83)

2.1.83

March 25, 2026

- 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)
- 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`
- 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
- 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`
- 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
- Added `CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK` env var to disable the non-streaming fallback when streaming fails
- 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
- 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\] Spinner now turns red with “Not responding” when the backend hasn’t responded for 60 seconds
- \[VSCode\] Fixed session history not loading correctly when reopening a session via URL or after restart
- \[VSCode\] Added Esc-twice (or `/rewind`) to open a keyboard-navigable rewind picker
- \[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 `--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
- 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
- Resuming a session that was in a worktree now switches back to that worktree
- 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
- 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
- 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
- \[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 `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
- 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
- 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
- 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)
- 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 `--console` flag to `claude auth login` for Anthropic Console (API billing) authentication
- Added “Show turn duration” toggle to the `/config` menu
- 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
- 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
- `CLAUDE_CODE_PLUGIN_SEED_DIR` now supports multiple seed directories separated by the platform path delimiter (`:` on Unix, `;` on Windows)
- \[VSCode\] Added `/remote-control` — bridge your session to claude.ai/code to continue from a browser or phone
- \[VSCode\] Session tabs now get AI-generated titles based on your first message
- \[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 `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
- 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
- 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
- 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
- Fixed `ANTHROPIC_BETAS` environment variable being silently ignored when using Haiku models
- Fixed queued prompts being concatenated without a newline separator
- Improved memory usage and startup time when resuming large sessions
- \[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

- 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
- Added `allowRead` sandbox filesystem setting to re-allow read access within `denyRead` regions
- `/copy` now accepts an optional index: `/copy N` copies the Nth-latest assistant response
- 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
- 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
- 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
- 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
- Improved headless mode plugin installation to compose correctly with `CLAUDE_CODE_PLUGIN_SEED_DIR`
- 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\] Improved plan preview tab titles to use the plan’s heading instead of “Claude’s Plan”
- \[VSCode\] When option+click doesn’t trigger native selection on macOS, the footer now points to the `macOptionClickForcesSelection` setting

[​](#2-1-76)

2.1.76

March 14, 2026

- 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
- 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
- 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
- Updated `--plugin-dir` to only accept one path to support subcommands — use repeated `--plugin-dir` for multiple directories
- \[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 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
- 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”
- Improved startup performance on macOS non-MDM machines by skipping unnecessary subprocess spawns
- 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`

[​](#2-1-74)

2.1.74

March 12, 2026

- 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
- 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
- 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)
- \[VSCode\] Fixed delete button not working for Untitled sessions
- \[VSCode\] Improved scroll wheel responsiveness in the integrated terminal with terminal-aware acceleration

[​](#2-1-73)

2.1.73

March 11, 2026

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

- Fixed tool search to activate even with `ANTHROPIC_BASE_URL` as long as `ENABLE_TOOL_SEARCH` is set.
- 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
- 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
- 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
- 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
- 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
- Added support for marketplace git URLs without `.git` suffix (Azure DevOps, AWS CodeCommit)
- Improved marketplace clone failure messages to show diagnostic info even when git produces no stderr
- 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
- Improved CPU utilization in long sessions
- 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
- 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

[​](#2-1-71)

2.1.71

March 7, 2026

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

[​](#2-1-70)

2.1.70

March 6, 2026

- 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
- 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
- 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.
- \[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

[​](#2-1-69)

2.1.69

March 5, 2026

- 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
- 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)
- 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)
- 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\] Added compaction display as a collapsible “Compacted chat” card with the summary inside
- \[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
- \[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 `/simplify` and `/batch` bundled slash commands
- Fixed local slash command output like /cost appearing as user-sent messages instead of system messages in the UI
- Project configs & auto memory now shared across git worktrees of the same repository
- Added `ENABLE_CLAUDEAI_MCP_SERVERS=false` env var to opt out from making claude.ai MCP servers available
- Improved `/model` command to show the currently active model in the slash command menu
- Added HTTP hooks, which can POST JSON to a URL and receive JSON instead of running a shell command
- Fixed listener leak in bridge polling loop
- Fixed listener leak in MCP OAuth flow cleanup
- 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.
- 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
- Improved memory usage in long sessions with subagents by stripping heavy progress message payloads during context compaction
- 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
- 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 `claude remote-control` subcommand for external builds, enabling local environment serving for all users.
- Updated plugin marketplace default git timeout from 30s to 120s and added `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` to configure.
- Added support for custom npm registries and specific version pinning when installing plugins from npm sources
- 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`.
- Fixed a security issue where `statusLine` and `fileSuggestion` hook commands could execute without workspace trust acceptance in interactive mode.
- Tool results larger than 50K characters are now persisted to disk (previously 100K). This reduces context window usage and improves conversation longevity.
- 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.
- 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.
- Fixed slash command autocomplete crashing when a plugin’s SKILL.md description is a YAML array or other non-string type
- 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](https://code.claude.com/docs/en/settings#settings-files)

[​](#2-1-50)

2.1.50

February 20, 2026

- 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.
- 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
- Added support for `isolation: worktree` in agent definitions, allowing agents to declaratively run in isolated git worktrees.
- `CLAUDE_CODE_SIMPLE` mode now also disables MCP tools, attachments, hooks, and CLAUDE.md file loading for a fully minimal experience.
- Fixed bug where MCP tools were not discovered when tool search is enabled and a prompt is passed in as a launch argument
- Improved memory usage during long sessions by clearing internal caches after compaction
- Added `claude agents` CLI command to list all configured agents
- Improved memory usage during long sessions by clearing large tool results after they have been processed
- 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
- Improved startup performance for headless mode (`-p` flag) by deferring Yoga WASM and UI component imports
- Fixed prompt suggestion cache regression that reduced cache hit rates
- Fixed unbounded memory growth in long sessions by capping file history snapshots
- Added `CLAUDE_CODE_DISABLE_1M_CONTEXT` environment variable to disable 1M context window support
- Opus 4.6 (fast mode) now includes the full 1M context window
- VSCode: Added `/extra-usage` command support in VS Code sessions
- 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

- Improved MCP OAuth authentication with step-up auth support and discovery caching, reducing redundant network requests during server connections
- Added `--worktree` (`-w`) flag to start Claude in an isolated git worktree
- Subagents support `isolation: "worktree"` for working in a temporary git worktree
- Added Ctrl+F keybinding to kill background agents (two-press confirmation)
- Agent definitions support `background: true` to always run as a background task
- Plugins can ship `settings.json` for default configuration
- 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
- 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.
- 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
- 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
- Fixed unbounded memory growth during long-running sessions caused by Yoga WASM linear memory never shrinking
- SDK model info now includes `supportsEffort`, `supportedEffortLevels`, and `supportsAdaptiveThinking` fields so consumers can discover model capabilities.
- Added `ConfigChange` hook event that fires when configuration files change during a session, enabling enterprise security auditing and optional blocking of settings changes.
- 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
- 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.
- 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

[​](#2-1-47)

2.1.47

February 18, 2026

- 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.
- 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.
- 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)
- 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.
- Fixed an issue where bash tool output was silently discarded on Windows when using MSYS2 or Cygwin shells.
- 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
- 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)
- Search patterns in collapsed tool results are now displayed in quotes for clarity
- Windows: Fixed CWD tracking temp files never being cleaned up, causing them to accumulate indefinitely (anthropics/claude-code#17600)
- 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.
- 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.
- Simplified teammate navigation to use only Shift+Down (with wrapping) instead of both Shift+Up and Shift+Down.
- 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.
- 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.
- 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)
- 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)
- 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)
- Increased initial session count in resume picker from 10 to 50 for faster session discovery (anthropics/claude-code#26123)
- 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)
- Moved config backup files from home directory root to `~/.claude/backups/` to reduce home directory clutter (anthropics/claude-code#26130)
- 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)
- The `/rename` command now updates the terminal tab title by default (anthropics/claude-code#25789)
- 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 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
- 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
- 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

[​](#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 guard against launching Claude Code inside another Claude Code session
- 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
- Improved model error messages for Bedrock/Vertex/Foundry users with fallback suggestions
- 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
- 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 `/rename` to auto-generate session name from conversation context when called without arguments
- Improved narrow terminal layout for prompt footer
- 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](https://code.claude.com/docs/en/fast-mode)

[​](#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

- Fixed agent teammate sessions in tmux to send and receive messages
- Fixed warnings about agent teams not being available on your current plan
- 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
- 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
- Improved error messages for API connection failures — now shows specific cause (e.g., ECONNREFUSED, SSL errors) instead of generic “Connection error”
- Errors from invalid managed settings are now surfaced
- 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
- VSCode: Fixed scroll-to-bottom under-scrolling on initial session load and session switch

[​](#2-1-32)

2.1.32

February 5, 2026

- Claude Opus 4.6 is now available!
- Added research preview agent teams feature for multi-agent collaboration (token-intensive feature, requires setting CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1)
- Claude now automatically records and recalls memories as it works
- Added “Summarize from here” to the message selector, allowing partial conversation summarization.
- Skills defined in `.claude/skills/` within additional directories (`--add-dir`) are now loaded automatically.
- Fixed `@` file completion showing incorrect relative paths when running from a subdirectory
- Updated —resume to re-use —agent value specified in previous conversation by default.
- Fixed: Bash tool no longer throws “Bad substitution” errors when heredocs contain JavaScript template literals like `${index + 1}`, which previously interrupted tool execution
- 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 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
- VSCode: Added spinner when loading past conversations list

[​](#2-1-31)

2.1.31

February 4, 2026

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

[​](#2-1-30)

2.1.30

February 3, 2026

- 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
- 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
- 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
- Changed `/model` to execute immediately instead of being queued
- \[VSCode\] Added multiline input support to the “Other” text input in question dialogs (use Shift+Enter for new lines)
- \[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 customizable spinner verbs setting (`spinnerVerbs`)
- 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
- Improved terminal rendering performance with optimized screen data layout
- Changed Bash commands to show timeout duration alongside elapsed time
- Changed merged pull requests to show a purple status indicator in the prompt footer
- \[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 support for full-width (zenkaku) number input from Japanese IME in option selection prompts
- 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
- 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)
- \[VSCode\] Added automatic Python virtual environment activation, ensuring `python` and `pip` commands use the correct interpreter (configurable via `claudeCode.usePythonEnvironment` setting)
- \[VSCode\] Fixed message action buttons having incorrect background colors

[​](#2-1-20)

2.1.20

January 27, 2026

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

[​](#2-1-19)

2.1.19

January 23, 2026

- 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
- 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
- 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)
- \[SDK\] Added replay of `queued_command` attachment messages as `SDKUserMessageReplay` events when `replayUserMessages` is enabled
- \[VSCode\] Enabled session forking and rewind functionality for all users

[​](#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](https://code.claude.com/docs/en/keybindings)

[​](#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](https://code.claude.com/docs/en/setup) 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 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
- 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
- Improved backspace to delete pasted text as a single token instead of one character at a time
- \[VSCode\] Added `/usage` command to display current plan usage

[​](#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 `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
- 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
- Improved typing responsiveness by reducing memory allocation overhead in terminal rendering
- 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
- \[VSCode\] Fixed `claudeProcessWrapper` setting passing the wrapper path instead of the Claude binary path

[​](#2-1-6)

2.1.6

January 13, 2026

- 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
- 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`
- 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
- 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
- \[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

- Merged slash commands and skills, simplifying the mental model with no change in behavior
- 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
- 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
- Improved terminal rendering stability by preventing uncontrolled writes from corrupting cursor state
- Improved slash command suggestion readability by truncating long descriptions to 2 lines
- Changed tool hook execution timeout from 60 seconds to 10 minutes
- \[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)

[​](#2-1-2)

2.1.2

January 9, 2026

- 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
- 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
- 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
- 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
- \[VSCode\] Fixed usage display not updating after manual compact

[​](#2-1-0)

2.1.0

January 7, 2026

- 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”)
- Changed Shift+Enter to work out of the box in iTerm2, WezTerm, Ghostty, and Kitty without modifying terminal configs
- 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
- 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
- Reduced permission prompts for complex bash commands
- 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
- Improved CLI help output to display options and subcommands in alphabetical order for easier navigation
- 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
- 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
- Multiple optimizations to improve startup performance
- 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
- 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
- \[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”)
- \[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 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
- 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’
- Improved `/context` command visualization with grouped skills and agents by source, slash commands, and sorted token count
- \[Windows\] Fixed issue with improper rendering
- \[VSCode\] Added gift tag pictogram for year-end promotion message

[​](#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 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
- Reduced terminal flickering
- Added scannable QR code to mobile app tip for quick app downloads
- Added loading indicator when resuming conversations for better feedback
- Fixed `/context` command not respecting custom system prompts in non-interactive mode
- Fixed order of consecutive Ctrl+K lines when pasting with Ctrl+Y
- 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
- Changed thinking toggle from Tab to Alt+T to avoid accidental triggers

[​](#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 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
- 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
- Improved memory usage by 3x for large conversations
- Improved resolution of stats screenshots copied to clipboard (Ctrl+S) for crisper images
- Removed \# shortcut for quick memory entry (tell Claude to edit your CLAUDE.md instead)
- Fix thinking mode toggle in /config not persisting correctly
- Improve UI for file creation permission dialog

[​](#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

- Thinking mode is now enabled by default for Opus 4.5
- Thinking mode configuration has moved to /config
- Added search functionality to `/permissions` command with `/` keyboard shortcut for filtering rules by tool name
- Show reason why autoupdater is disabled in `/doctor`
- 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

- 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
- 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](https://code.claude.com/docs/en/memory) for details.
- Added image dimension metadata when images are resized, enabling accurate coordinate mappings for large images
- Fixed auto-loading .env when using native installer
- Fixed `--system-prompt` being ignored when using `--continue` or `--resume` flags
- Improved `/resume` screen with grouped forked sessions and keyboard shortcuts for preview (P) and rename (R)
- VSCode: Added copy-to-clipboard button on code blocks and bash tool inputs
- VSCode: Fixed extension not working on Windows ARM64 by falling back to x64 binary via emulation
- Bedrock: Improve efficiency of token counting
- Bedrock: Add support for `aws login` AWS Management Console credentials
- Unshipped AgentOutputTool and BashOutputTool, in favor of a new unified TaskOutputTool

[​](#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](https://www.anthropic.com/news/claude-opus-4-5)
- 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 `model` parameter to prompt-based stop hooks, allowing users to specify a custom model for hook evaluation
- 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
- 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
- Plugins: Added support for sharing and installing output styles
- Teleporting a session from web will automatically set the upstream branch

[​](#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 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)
- 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
- 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
- VSCode: Restored selection indicator in input footer showing current file or code selection status

[​](#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](https://platform.claude.com/docs/en/agent-sdk/migration-guide)

[​](#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

- **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](https://code.claude.com/docs/en/plugins)
- 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

- New native VS Code extension
- 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
- Add subagents dynamically with `--agents` flag

[​](#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](https://code.claude.com/docs/en/output-styles)
- 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](https://code.claude.com/docs/en/hooks)

[​](#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


---
## claude-code-cheatsheet-c583f93815.md

# Claude Code cheatsheet

April 15, 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-449cc06a10.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](https://code.claude.com/docs/en/permissions)**

### 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](https://code.claude.com/docs/en/memory)**

### 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](https://code.claude.com/docs/en/mcp)**

### 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](https://code.claude.com/docs/en/skills)**

## Appendix: Quick reference

[TABLE]

## Appendix: Resource directory

[TABLE]

For details on `/init`, @-references, permission modes, skills, MCP, and hooks, see **[code.claude.com/docs](https://code.claude.com/docs)**. Claude Code ships frequently—verify version-specific details against **[code.claude.com/docs](https://code.claude.com/docs)** before distributing internally.


---
## claude-code-communications-kit-3498574c27.md

# Claude Code communications kit

Ready-to-send messages for Slack, Teams, and email — Enterprise admin enablement

April 29, 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](https://code.claude.com/docs/en/permissions)** 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](https://code.claude.com/docs)** before distributing internally.


---
## claude-code-desktop-in-wsl-claude-code-docs-bef5af64d4.md

## On this page

- [Requirements](#requirements)
- [Start a WSL session](#start-a-wsl-session)
- [What works in a WSL session](#what-works-in-a-wsl-session)
- [Managed devices](#managed-devices)

Claude Code on desktop

# Claude Code Desktop in WSL

Copy pageCopy page

Run Code sessions inside a WSL 2 distribution on Windows

Copy pageCopy page

On Windows, the Code tab can run a session inside a WSL 2 distribution instead of on Windows itself. The session’s Claude Code process, its tools, and git all execute inside the distribution, using its Linux toolchain and native Linux paths, the same environment your project targets. Use a WSL session when your repository lives inside the distribution’s filesystem. Working on those files from Windows goes through a network filesystem, which is slow and breaks file watching; running the session inside the distribution avoids both.


[​](#requirements)

Requirements

- Windows 10 or 11 with [WSL 2](https://learn.microsoft.com/windows/wsl/install). WSL 1 isn’t supported.
- At least one installed distribution (for example, Ubuntu).
- `git` installed inside the distribution.


[​](#start-a-wsl-session)

Start a WSL session

1

Pick a distribution

Start a new session in the Code tab and open the environment picker. Your installed WSL 2 distributions appear in a **WSL** section. Pick one.

2

Choose a folder

The session starts in the distribution’s home directory. Use the folder picker to choose a project folder. Browsing happens inside the distribution, with Linux paths like `/home/you/project`.

3

Trust the folder

The first session in a folder shows the workspace trust dialog. You grant trust per distribution and folder. A folder you trust in one distribution isn’t trusted in another distribution or at the same path on Windows.

The first session in a distribution takes a little longer while Claude sets up inside it. You can also open a `\\wsl.localhost\...` folder from the normal folder picker, and it reopens inside that distribution. Folders you’ve used recently appear in the picker per distribution, so reconnecting to a project is one click.


[​](#what-works-in-a-wsl-session)

What works in a WSL session

Parallel sessions, side chats, visual diff review, branch and pull request status, and worktrees all work, backed by the git and toolchain inside the distribution. “Open in editor” opens VS Code connected to the distribution through [Remote - WSL](https://code.visualstudio.com/docs/remote/wsl). A few features aren’t available in WSL sessions yet: the integrated terminal, connectors and plugins, session forking, the file browser pane, and file suggestions when you type `@` in the composer.


[​](#managed-devices)

Managed devices

On devices managed by an organization, WSL sessions may be unavailable. If session start fails with a message that the device is managed, that’s controlled by your administrator. Administrators: see [how settings reach devices](/docs/en/admin-setup#decide-how-settings-reach-devices) in the deployment guide.


---
## claude-code-faq-bc49f6a763.md

# Claude Code FAQ

June 18, 2026


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](https://support.claude.com/en/articles/11932705-automated-security-reviews-in-claude-code)** 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 [d**ata 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](https://support.claude.com/en/articles/9796807-creating-and-managing-workspaces-in-the-claude-console)**. 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](https://support.claude.com/en/articles/9534590-cost-and-usage-reporting-in-the-claude-console)**.

## 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](http://github.com/anthropics/claude-code-action)**.


---
## claude-code-github-actions-claude-code-docs-0d633fbd8a.md

## On this page

- [Why use Claude Code GitHub Actions?](#why-use-claude-code-github-actions)
- [What can Claude do?](#what-can-claude-do)
  - [Claude Code Action](#claude-code-action)
- [Setup](#setup)
- [Quick setup](#quick-setup)
- [Manual setup](#manual-setup)
- [Upgrading from Beta](#upgrading-from-beta)
  - [Essential changes](#essential-changes)
  - [Breaking Changes Reference](#breaking-changes-reference)
  - [Before and After Example](#before-and-after-example)
- [Example use cases](#example-use-cases)
  - [Basic workflow](#basic-workflow)
  - [Using skills](#using-skills)
  - [Custom automation with prompts](#custom-automation-with-prompts)
  - [Common use cases](#common-use-cases)
- [Best practices](#best-practices)
  - [CLAUDE.md configuration](#claude-md-configuration)
  - [Security considerations](#security-considerations)
  - [Optimizing performance](#optimizing-performance)
  - [CI costs](#ci-costs)
- [Configuration examples](#configuration-examples)
- [Using with Amazon Bedrock and Google Cloud](#using-with-amazon-bedrock-and-google-cloud)
  - [Prerequisites](#prerequisites)
  - [For Google Cloud’s Agent Platform:](#for-google-cloud%E2%80%99s-agent-platform)
  - [For Amazon Bedrock:](#for-amazon-bedrock)
  - [For Claude API (Direct):](#for-claude-api-direct-)
  - [For Google Cloud’s Agent Platform](#for-google-cloud%E2%80%99s-agent-platform)
  - [For Amazon Bedrock](#for-amazon-bedrock)
- [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)
  - [Alternative integration methods](#alternative-integration-methods)
  - [Customizing Claude’s behavior](#customizing-claude%E2%80%99s-behavior)

Code review & CI/CD

# Claude Code GitHub Actions

Copy pageCopy page

Learn about integrating Claude Code into your development workflow with Claude Code GitHub Actions

Copy pageCopy page

Claude Code GitHub Actions brings AI-powered automation to your GitHub workflow. With a simple `@claude` mention in any PR or issue, Claude can analyze your code, create pull requests, implement features, and fix bugs - all while following your project’s standards. For automatic reviews posted on every PR without a trigger, see [GitHub Code Review](/docs/en/code-review).

Claude Code GitHub Actions is built on top of the [Claude Agent SDK](/docs/en/agent-sdk/overview), which enables programmatic integration of Claude Code into your applications. You can use the SDK to build custom automation workflows beyond GitHub Actions.


[​](#why-use-claude-code-github-actions)

Why use Claude Code GitHub Actions?

- **Instant PR creation**: Describe what you need, and Claude creates a complete PR with all necessary changes
- **Automated code implementation**: Turn issues into working code with a single command
- **Follows your standards**: Claude respects your `CLAUDE.md` guidelines and existing code patterns
- **Simple setup**: Get started in minutes with our installer and API key
- **Secure by default**: Your code stays on Github’s runners


[​](#what-can-claude-do)

What can Claude do?

Claude Code provides a powerful GitHub Action that transforms how you work with code:


[​](#claude-code-action)

Claude Code Action

This GitHub Action allows you to run Claude Code within your GitHub Actions workflows. You can use this to build any custom workflow on top of Claude Code. [View repository →](https://github.com/anthropics/claude-code-action)


[​](#setup)

Setup


[​](#quick-setup)

Quick setup

Run `/install-github-app` in the Claude Code terminal to set up the integration interactively. The command installs the Claude GitHub App on your repository and then walks you through adding the GitHub Actions workflows and the API key secret. After the GitHub App is installed, the command asks whether to continue with GitHub Actions setup. In Claude Code v2.1.187 and later you can choose **Skip for now** to stop with only the App installed and return to the workflow and secret steps by running `/install-github-app` again. Earlier versions proceed straight to workflow selection.

- You must be a repository admin to install the GitHub app and add secrets
- The GitHub app will request read & write permissions for Contents, Issues, and Pull requests
- This quickstart method is only available for direct Claude API users. If you’re using Amazon Bedrock or Google Cloud’s Agent Platform, see the [Using with Amazon Bedrock and Google Cloud](#using-with-amazon-bedrock-and-google-cloud) section.


[​](#manual-setup)

Manual setup

If the `/install-github-app` command fails or you prefer manual setup, please follow these manual setup instructions:

1.  **Install the Claude GitHub app** to your repository: [https://github.com/apps/claude](https://github.com/apps/claude) The Claude GitHub app requires the following repository permissions:
    - **Contents**: Read & write (to modify repository files)
    - **Issues**: Read & write (to respond to issues)
    - **Pull requests**: Read & write (to create PRs and push changes)

    For more details on security and permissions, see the [security documentation](https://github.com/anthropics/claude-code-action/blob/main/docs/security.md).
2.  **Add ANTHROPIC_API_KEY** to your repository secrets ([Learn how to use secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions))
3.  **Copy the workflow file** from [examples/claude.yml](https://github.com/anthropics/claude-code-action/blob/main/examples/claude.yml) into your repository’s `.github/workflows/`

After completing either the quickstart or manual setup, test the action by tagging `@claude` in an issue or PR comment.


[​](#upgrading-from-beta)

Upgrading from Beta

Claude Code GitHub Actions v1.0 introduces breaking changes that require updating your workflow files in order to upgrade to v1.0 from the beta version.

If you’re currently using the beta version of Claude Code GitHub Actions, we recommend that you update your workflows to use the GA version. The new version simplifies configuration while adding powerful new features like automatic mode detection.


[​](#essential-changes)

Essential changes

All beta users must make these changes to their workflow files in order to upgrade:

1.  **Update the action version**: Change `@beta` to `@v1`
2.  **Remove mode configuration**: Delete `mode: "tag"` or `mode: "agent"` (now auto-detected)
3.  **Update prompt inputs**: Replace `direct_prompt` with `prompt`
4.  **Move CLI options**: Convert `max_turns`, `model`, `custom_instructions`, etc. to `claude_args`


[​](#breaking-changes-reference)

Breaking Changes Reference

| Old Beta Input        | New v1.0 Input                        |
|-----------------------|---------------------------------------|
| `mode`                | *(Removed - auto-detected)*           |
| `direct_prompt`       | `prompt`                              |
| `override_prompt`     | `prompt` with GitHub variables        |
| `custom_instructions` | `claude_args: --append-system-prompt` |
| `max_turns`           | `claude_args: --max-turns`            |
| `model`               | `claude_args: --model`                |
| `allowed_tools`       | `claude_args: --allowedTools`         |
| `disallowed_tools`    | `claude_args: --disallowedTools`      |
| `claude_env`          | `settings` JSON format                |


[​](#before-and-after-example)

Before and After Example

**Beta version:**

```python
- uses: anthropics/claude-code-action@beta
  with:
    mode: "tag"
    direct_prompt: "Review this PR for security issues"
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    custom_instructions: "Follow our coding standards"
    max_turns: "10"
    model: "claude-sonnet-5"
```

**GA version (v1.0):**

```python
- uses: anthropics/claude-code-action@v1
  with:
    prompt: "Review this PR for security issues"
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    claude_args: |
      --append-system-prompt "Follow our coding standards"
      --max-turns 10
      --model claude-sonnet-5
```

The action now automatically detects whether to run in interactive mode (responds to `@claude` mentions) or automation mode (runs immediately with a prompt) based on your configuration.


[​](#example-use-cases)

Example use cases

Claude Code GitHub Actions can help you with a variety of tasks. The [examples directory](https://github.com/anthropics/claude-code-action/tree/main/examples) contains ready-to-use workflows for different scenarios.


[​](#basic-workflow)

Basic workflow

```python
name: Claude Code
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
jobs:
  claude:
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          # Responds to @claude mentions in comments
```


[​](#using-skills)

Using skills

The `prompt` input accepts a [skill](/docs/en/skills) invocation as well as plain text:

- For a skill in your repository’s `.claude/skills/` directory, run `actions/checkout` before the action step and pass `/skill-name`.
- For a skill packaged in a plugin, install the plugin with the `plugin_marketplaces` and `plugins` inputs and pass the namespaced `/plugin-name:skill-name`.

The following workflow installs the `code-review` plugin and runs its skill on each new or updated pull request:

```python
name: Code Review
on:
  pull_request:
    types: [opened, synchronize]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - 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 ${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
```


[​](#custom-automation-with-prompts)

Custom automation with prompts

```python
name: Daily Report
on:
  schedule:
    - cron: "0 9 * * *"
jobs:
  report:
    runs-on: ubuntu-latest
    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 opus"
```


[​](#common-use-cases)

Common use cases

In issue or PR comments:

```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 will automatically analyze the context and respond appropriately.


[​](#best-practices)

Best practices


[​](#claude-md-configuration)

CLAUDE.md configuration

Create a `CLAUDE.md` file in your repository root to define code style guidelines, review criteria, project-specific rules, and preferred patterns. This file guides Claude’s understanding of your project standards.


[​](#security-considerations)

Security considerations

Never commit API keys directly to your repository.

For comprehensive security guidance including permissions, authentication, and best practices, see the [Claude Code Action security documentation](https://github.com/anthropics/claude-code-action/blob/main/docs/security.md). Always use GitHub Secrets for API keys:

- Add your API key as a repository secret named `ANTHROPIC_API_KEY`
- Reference it in workflows: `anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}`
- Limit action permissions to only what’s necessary
- Review Claude’s suggestions before merging

Always use GitHub Secrets (for example, `${{ secrets.ANTHROPIC_API_KEY }}`) rather than hardcoding API keys directly in your workflow files.


[​](#optimizing-performance)

Optimizing performance

Use issue templates to provide context, keep your `CLAUDE.md` concise and focused, and configure appropriate timeouts for your workflows.


[​](#ci-costs)

CI costs

When using Claude Code GitHub Actions, be aware of the associated costs: **GitHub Actions costs:**

- Claude Code 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 detailed pricing and minute limits

**API costs:**

- Each Claude interaction consumes API tokens based on the length of prompts and responses
- Token usage varies by task complexity and codebase size
- See [Claude’s pricing page](https://claude.com/platform/api) for current token rates

**Cost optimization tips:**

- Use specific `@claude` commands to reduce unnecessary API calls
- Configure appropriate `--max-turns` in `claude_args` to prevent excessive iterations
- Set workflow-level timeouts to avoid runaway jobs
- Consider using GitHub’s concurrency controls to limit parallel runs


[​](#configuration-examples)

Configuration examples

The Claude Code Action v1 simplifies configuration with unified parameters:

```python
- uses: anthropics/claude-code-action@v1
  with:
    anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    prompt: "Your instructions here" # Optional
    claude_args: "--max-turns 5" # Optional CLI arguments
```

Key features:

- **Unified prompt interface** - Use `prompt` for all instructions
- **Skills** - Invoke installed [skills](/docs/en/skills) directly from the prompt
- **CLI passthrough** - Any Claude Code CLI argument via `claude_args`
- **Flexible triggers** - Works with any GitHub event

Visit the [examples directory](https://github.com/anthropics/claude-code-action/tree/main/examples) for complete workflow files.

When responding to issue or PR comments, Claude automatically responds to @claude mentions. For other events, use the `prompt` parameter to provide instructions.


[​](#using-with-amazon-bedrock-and-google-cloud)

Using with Amazon Bedrock and Google Cloud

For enterprise environments, you can use Claude Code GitHub Actions with your own cloud infrastructure. This approach gives you control over data residency and billing while maintaining the same functionality.


[​](#prerequisites)

Prerequisites

Before setting up Claude Code GitHub Actions with cloud providers, you need:


[​](#for-google-cloud’s-agent-platform)

For Google Cloud’s Agent Platform:

1.  A Google Cloud Project with Google Cloud’s Agent Platform enabled
2.  Workload Identity Federation configured for GitHub Actions
3.  A service account with the required permissions
4.  A GitHub App (recommended) or use the default GITHUB_TOKEN


[​](#for-amazon-bedrock)

For Amazon Bedrock:

1.  An AWS account with Amazon Bedrock enabled
2.  GitHub OIDC Identity Provider configured in AWS
3.  An IAM role with Amazon Bedrock permissions
4.  A GitHub App (recommended) or use the default GITHUB_TOKEN

1

Create a custom GitHub App (Recommended for 3P Providers)

For best control and security when using 3P providers like Google Cloud’s Agent Platform or Amazon Bedrock, we recommend creating your own GitHub App:

1.  Go to [https://github.com/settings/apps/new](https://github.com/settings/apps/new)
2.  Fill in the basic information:
    - **GitHub App name**: Choose a unique name (e.g., “YourOrg Claude Assistant”)
    - **Homepage URL**: Your organization’s website or the repository URL
3.  Configure the app settings:
    - **Webhooks**: Uncheck “Active” (not needed for this integration)
4.  Set the required permissions:
    - **Repository permissions**:
      - Contents: Read & Write
      - Issues: Read & Write
      - Pull requests: Read & Write
5.  Click “Create GitHub App”
6.  After creation, click “Generate a private key” and save the downloaded `.pem` file
7.  Note your App ID from the app settings page
8.  Install the app to your repository:
    - From your app’s settings page, click “Install App” in the left sidebar
    - Select your account or organization
    - Choose “Only select repositories” and select the specific repository
    - Click “Install”
9.  Add the private key as a secret to your repository:
    - Go to your repository’s Settings → Secrets and variables → Actions
    - Create a new secret named `APP_PRIVATE_KEY` with the contents of the `.pem` file
10. Add the App ID as a secret:

- Create a new secret named `APP_ID` with your GitHub App’s ID

This app will be used with the [actions/create-github-app-token](https://github.com/actions/create-github-app-token) action to generate authentication tokens in your workflows.

**Alternative for Claude API or if you don’t want to setup your own Github app**: Use the official Anthropic app:

1.  Install from: [https://github.com/apps/claude](https://github.com/apps/claude)
2.  No additional configuration needed for authentication

2

Configure cloud provider authentication

Choose your cloud provider and set up secure authentication:

Amazon Bedrock

**Configure AWS to allow GitHub Actions to authenticate securely without storing credentials.**

> **Security Note**: Use repository-specific configurations and grant only the minimum required permissions.

**Required Setup**:

1.  **Enable Amazon Bedrock**:
    - Request access to Claude models in Amazon Bedrock
    - For cross-region models, request access in all required regions
2.  **Set up GitHub OIDC Identity Provider**:
    - Provider URL: `https://token.actions.githubusercontent.com`
    - Audience: `sts.amazonaws.com`
3.  **Create IAM Role for GitHub Actions**:
    - Trusted entity type: Web identity
    - Identity provider: `token.actions.githubusercontent.com`
    - Permissions: `AmazonBedrockFullAccess` policy
    - Configure trust policy for your specific repository

**Required Values**:After setup, you’ll need:

- **AWS_ROLE_TO_ASSUME**: The ARN of the IAM role you created

OIDC is more secure than using static AWS access keys because credentials are temporary and automatically rotated.

See [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html) for detailed OIDC setup instructions.

Google Cloud's Agent Platform

**Configure Google Cloud to allow GitHub Actions to authenticate securely without storing credentials.**

> **Security Note**: Use repository-specific configurations and grant only the minimum required permissions.

**Required Setup**:

1.  **Enable APIs** in your Google Cloud project:
    - IAM Credentials API
    - Security Token Service (STS) API
    - Google Cloud’s Agent Platform API
2.  **Create Workload Identity Federation resources**:
    - Create a Workload Identity Pool
    - Add a GitHub OIDC provider with:
      - Issuer: `https://token.actions.githubusercontent.com`
      - Attribute mappings for repository and owner
      - **Security recommendation**: Use repository-specific attribute conditions
3.  **Create a Service Account**:
    - Grant only `Vertex AI User` role
    - **Security recommendation**: Create a dedicated service account per repository
4.  **Configure IAM bindings**:
    - Allow the Workload Identity Pool to impersonate the service account
    - **Security recommendation**: Use repository-specific principal sets

**Required Values**:After setup, you’ll need:

- **GCP_WORKLOAD_IDENTITY_PROVIDER**: The full provider resource name
- **GCP_SERVICE_ACCOUNT**: The service account email address

Workload Identity Federation eliminates the need for downloadable service account keys, improving security.

For detailed setup instructions, consult the [Google Cloud Workload Identity Federation documentation](https://cloud.google.com/iam/docs/workload-identity-federation).

3

Add Required Secrets

Add the following secrets to your repository (Settings → Secrets and variables → Actions):


[​](#for-claude-api-direct-)

For Claude API (Direct):

1.  **For API Authentication**:
    - `ANTHROPIC_API_KEY`: Your Claude API key from [console.anthropic.com](https://console.anthropic.com)
2.  **For GitHub App (if using your own app)**:
    - `APP_ID`: Your GitHub App’s ID
    - `APP_PRIVATE_KEY`: The private key (.pem) content


[​](#for-google-cloud’s-agent-platform)

For Google Cloud’s Agent Platform

1.  **For GCP Authentication**:
    - `GCP_WORKLOAD_IDENTITY_PROVIDER`
    - `GCP_SERVICE_ACCOUNT`
2.  **For GitHub App (if using your own app)**:
    - `APP_ID`: Your GitHub App’s ID
    - `APP_PRIVATE_KEY`: The private key (.pem) content


[​](#for-amazon-bedrock)

For Amazon Bedrock

1.  **For AWS Authentication**:
    - `AWS_ROLE_TO_ASSUME`
2.  **For GitHub App (if using your own app)**:
    - `APP_ID`: Your GitHub App’s ID
    - `APP_PRIVATE_KEY`: The private key (.pem) content

4

Create workflow files

Create GitHub Actions workflow files that integrate with your cloud provider. The examples below show complete configurations for both Amazon Bedrock and Google Cloud’s Agent Platform:

Amazon Bedrock workflow

**Prerequisites:**

- Amazon Bedrock access enabled with Claude model permissions
- GitHub configured as an OIDC identity provider in AWS
- IAM role with Amazon Bedrock permissions that trusts GitHub Actions

**Required GitHub secrets:**

| Secret Name          | Description                                       |
|----------------------|---------------------------------------------------|
| `AWS_ROLE_TO_ASSUME` | ARN of the IAM role for Amazon Bedrock access     |
| `APP_ID`             | Your GitHub App ID (from app settings)            |
| `APP_PRIVATE_KEY`    | The private key you generated for your GitHub App |

```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, assigned]

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'))
    runs-on: ubuntu-latest
    env:
      AWS_REGION: us-west-2
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - 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 --max-turns 10'
```

The model ID format for Amazon Bedrock includes a region prefix (for example, `us.anthropic.claude-sonnet-4-6`).

Google Cloud's Agent Platform workflow

**Prerequisites:**

- Google Cloud’s Agent Platform API enabled in your GCP project
- Workload Identity Federation configured for GitHub
- Service account with Google Cloud’s Agent Platform permissions

**Required GitHub secrets:**

| Secret Name                      | Description                                                     |
|----------------------------------|-----------------------------------------------------------------|
| `GCP_WORKLOAD_IDENTITY_PROVIDER` | Workload identity provider resource name                        |
| `GCP_SERVICE_ACCOUNT`            | Service account email with Google Cloud’s Agent Platform access |
| `APP_ID`                         | Your GitHub App ID (from app settings)                          |
| `APP_PRIVATE_KEY`                | The private key you generated for your GitHub App               |

```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, assigned]

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'))
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - 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 }}
          trigger_phrase: "@claude"
          use_vertex: "true"
          claude_args: '--model claude-sonnet-4-5@20250929 --max-turns 10'
        env:
          ANTHROPIC_VERTEX_PROJECT_ID: ${{ steps.auth.outputs.project_id }}
          CLOUD_ML_REGION: us-east5
          VERTEX_REGION_CLAUDE_4_5_SONNET: us-east5
```

The project ID is automatically retrieved from the Google Cloud authentication step, so you don’t need to hardcode it.


[​](#troubleshooting)

Troubleshooting


[​](#claude-not-responding-to-@claude-commands)

Claude not responding to @claude commands

Verify the GitHub App is installed correctly, check that workflows are enabled, ensure API key is set in repository secrets, and confirm the comment contains `@claude` (not `/claude`).


[​](#ci-not-running-on-claude’s-commits)

CI not running on Claude’s commits

Ensure you’re using the GitHub App or custom app (not Actions user), check workflow triggers include the necessary events, and verify app permissions include CI triggers.


[​](#authentication-errors)

Authentication errors

Confirm API key is valid and has sufficient permissions. For Amazon Bedrock or Google Cloud’s Agent Platform, check credentials configuration and ensure secrets are named correctly in workflows.


[​](#advanced-configuration)

Advanced configuration


[​](#action-parameters)

Action parameters

The Claude Code Action v1 uses a simplified configuration:

| Parameter             | Description                                                             | Required |
|-----------------------|-------------------------------------------------------------------------|----------|
| `prompt`              | Instructions for Claude (plain text or a [skill](/docs/en/skills) name) | No\*     |
| `claude_args`         | CLI arguments passed to Claude Code                                     | No       |
| `plugin_marketplaces` | Newline-separated list of plugin marketplace Git URLs                   | No       |
| `plugins`             | Newline-separated list of plugin names to install before execution      | No       |
| `anthropic_api_key`   | Claude API key                                                          | Yes\*\*  |
| `github_token`        | GitHub token for API access                                             | No       |
| `trigger_phrase`      | Custom trigger phrase (default: “@claude”)                              | No       |
| `use_bedrock`         | Use Amazon Bedrock instead of Claude API                                | No       |
| `use_vertex`          | Use Google Cloud’s Agent Platform instead of Claude API                 | No       |

\*Prompt is optional - when omitted for issue/PR comments, Claude responds to trigger phrase  
\*\*Required for direct Claude API, not for Amazon Bedrock or Google Cloud’s Agent Platform


[​](#pass-cli-arguments)

Pass CLI arguments

The `claude_args` parameter accepts any Claude Code CLI arguments:

```python
claude_args: "--max-turns 5 --model claude-sonnet-5 --mcp-config /path/to/config.json"
```

Common arguments:

- `--max-turns`: Maximum conversation turns (default: 10)
- `--model`: Model to use (for example, `claude-sonnet-5`)
- `--mcp-config`: Path to MCP configuration
- `--allowedTools`: Comma-separated list of allowed tools. The `--allowed-tools` alias also works.
- `--debug`: Enable debug output


[​](#alternative-integration-methods)

Alternative integration methods

While the `/install-github-app` command is the recommended approach, you can also:

- **Custom GitHub App**: For organizations needing branded usernames or custom authentication flows. Create your own GitHub App with required permissions (contents, issues, pull requests) and use the actions/create-github-app-token action to generate tokens in your workflows.
- **Manual GitHub Actions**: Direct workflow configuration for maximum flexibility
- **MCP Configuration**: Dynamic loading of Model Context Protocol servers

See the [Claude Code Action documentation](https://github.com/anthropics/claude-code-action/blob/main/docs) for detailed guides on authentication, security, and advanced configuration.


[​](#customizing-claude’s-behavior)

Customizing Claude’s behavior

You can configure Claude’s behavior in two ways:

1.  **CLAUDE.md**: Define coding standards, review criteria, and project-specific rules in a `CLAUDE.md` file at the root of your repository. Claude will follow these guidelines when creating PRs and responding to requests. Check out our [Memory documentation](/docs/en/memory) for more details.
2.  **Custom prompts**: Use the `prompt` parameter in the workflow file to provide workflow-specific instructions. This allows you to customize Claude’s behavior for different workflows or tasks.

Claude will follow these guidelines when creating PRs and responding to requests.


---
## claude-code-gitlab-ci-cd-claude-code-docs-fbcd915fee.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)
  - [Basic .gitlab-ci.yml (Claude API)](#basic-gitlab-ci-yml-claude-api)
  - [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)
- [Security and governance](#security-and-governance)
- [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](/docs/en/agent-sdk/overview), 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?

Claude Code enables powerful CI/CD workflows that transform how you work with code:

- 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
  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`** (see examples below)
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

**Required values to store in CI/CD variables:**

- `AWS_ROLE_TO_ASSUME`
- `AWS_REGION`

Add variables in Settings → CI/CD → Variables:

```python
# For Amazon Bedrock:
- AWS_ROLE_TO_ASSUME
- AWS_REGION
```

Use the Amazon Bedrock job example above to exchange the GitLab job 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 for WIF:
    - `GCP_WORKLOAD_IDENTITY_PROVIDER` (full resource name)
    - `GCP_SERVICE_ACCOUNT` (service account email)


[​](#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

**Required values to store in CI/CD variables:**

- `GCP_WORKLOAD_IDENTITY_PROVIDER`
- `GCP_SERVICE_ACCOUNT`

Add variables in Settings → CI/CD → Variables:

```python
# For Google Cloud's Agent Platform:
- GCP_WORKLOAD_IDENTITY_PROVIDER
- GCP_SERVICE_ACCOUNT
- CLOUD_ML_REGION (for example, us-east5)
```

Use the job example above for Google Cloud’s Agent Platform to authenticate without storing keys.


[​](#configuration-examples)

Configuration examples

Below are ready-to-use snippets you can adapt to your pipeline.


[​](#basic-gitlab-ci-yml-claude-api)

Basic .gitlab-ci.yml (Claude API)

```python
stages:
  - ai

claude:
  stage: ai
  image: node:24-alpine3.21
  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
  script:
    - /bin/gitlab-mcp-server || true
    - >
      claude
      -p "${AI_FLOW_INPUT:-'Summarize recent changes and suggest improvements'}"
      --permission-mode acceptEdits
      --allowedTools "Bash Read Edit Write mcp__gitlab"
      --debug
  # Claude Code will use ANTHROPIC_API_KEY from CI/CD variables
```


[​](#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`)

```python
claude-bedrock:
  stage: ai
  image: node:24-alpine3.21
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  before_script:
    - apk add --no-cache bash curl jq git python3 py3-pip
    - pip install --no-cache-dir awscli
    - curl -fsSL https://claude.ai/install.sh | bash
    # Exchange GitLab OIDC token for AWS credentials
    - export AWS_WEB_IDENTITY_TOKEN_FILE="${CI_JOB_JWT_FILE:-/tmp/oidc_token}"
    - if [ -n "${CI_JOB_JWT_V2}" ]; then printf "%s" "$CI_JOB_JWT_V2" > "$AWS_WEB_IDENTITY_TOKEN_FILE"; fi
    - >
      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"
```

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`: Full provider resource name
- `GCP_SERVICE_ACCOUNT`: Service account email
- `CLOUD_ML_REGION`: Google Cloud’s Agent Platform region (for example, `us-east5`)

```python
claude-vertex:
  stage: ai
  image: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  before_script:
    - apt-get update && apt-get install -y git && apt-get clean
    - curl -fsSL https://claude.ai/install.sh | bash
    # Authenticate to Google Cloud via WIF (no downloaded keys)
    - >
      gcloud auth login --cred-file=<(cat <<EOF
      {
        "type": "external_account",
        "audience": "${GCP_WORKLOAD_IDENTITY_PROVIDER}",
        "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
        "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SERVICE_ACCOUNT}:generateAccessToken",
        "token_url": "https://sts.googleapis.com/v1/token"
      }
      EOF
      )
    - gcloud config set project "$(gcloud projects list --format='value(projectId)' --filter="name:${CI_PROJECT_NAMESPACE}" | head -n1)" || true
  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"
```

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
- Configure sensible job timeouts to avoid runaway runs
- 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](https://platform.claude.com/docs/en/about-claude/pricing) 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


[​](#security-and-governance)

Security and governance

- Each job runs in an isolated container with restricted network access
- Claude’s changes flow through MRs so reviewers see every diff
- Branch protection and approval rules apply to AI-generated code
- Claude Code uses workspace-scoped permissions to constrain writes
- Costs remain under your control because you bring your own provider credentials


[​](#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 CI/CD variables (`ANTHROPIC_API_KEY` or cloud provider settings) are present and unmasked
- 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

Claude Code supports these commonly used inputs:

- `prompt` / `prompt_file`: Provide instructions inline (`-p`) or via a file
- `max_turns`: Limit the number of back-and-forth iterations
- `timeout_minutes`: Limit total execution time
- `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 `prompt`/`prompt_file` in the job. Use different prompts for different jobs (for example, review, implement, refactor).


---
## claude-code-in-slack-claude-code-docs-c62a093e92.md

## On this page

- [Use cases](#use-cases)
- [Prerequisites](#prerequisites)
- [Setting up Claude Code in Slack](#setting-up-claude-code-in-slack)
- [How it works](#how-it-works)
  - [Automatic detection](#automatic-detection)
  - [Context gathering](#context-gathering)
  - [Session flow](#session-flow)
- [User interface elements](#user-interface-elements)
  - [App Home](#app-home)
  - [Message actions](#message-actions)
  - [Repository selection](#repository-selection)
- [Access and permissions](#access-and-permissions)
  - [User-level access](#user-level-access)
  - [Workspace-level access](#workspace-level-access)
  - [Channel-based access control](#channel-based-access-control)
- [What’s accessible where](#what%E2%80%99s-accessible-where)
- [Best practices](#best-practices)
  - [Writing effective requests](#writing-effective-requests)
  - [When to use Slack vs. web](#when-to-use-slack-vs-web)
- [Troubleshooting](#troubleshooting)
  - [”Claude Code is not enabled for your account”](#%E2%80%9Dclaude-code-is-not-enabled-for-your-account%E2%80%9D)
  - [Sessions not starting](#sessions-not-starting)
  - [Sessions from a Claude Tag channel fail to start](#sessions-from-a-claude-tag-channel-fail-to-start)
  - [Repository not showing](#repository-not-showing)
  - [Wrong repository selected](#wrong-repository-selected)
  - [Authentication errors](#authentication-errors)
  - [Session expiration](#session-expiration)
- [Current limitations](#current-limitations)
- [Related resources](#related-resources)

Platforms and integrations

# Claude Code in Slack

Copy pageCopy page

Delegate coding tasks directly from your Slack workspace. Anthropic is retiring this earlier version for Team and Enterprise workspaces in favor of Claude Tag; it remains the setup path on Pro and Max plans.

Copy pageCopy page

This page documents the earlier Claude Code in Slack, which runs each session under an individual user’s account.

- **Team and Enterprise plans:** Anthropic is retiring this version in favor of [Claude Tag](https://claude.com/docs/claude-tag/overview), which runs @Claude as your organization’s shared identity with admin-configured access. Your existing Slack app and @Claude handle stay, and your Anthropic account team can tell you the cutover date. Set up Claude Tag for a new workspace; to move one that already uses this version, see [Migrate from the earlier Claude in Slack](https://claude.com/docs/claude-tag/admins/migrate-from-earlier).
- **Pro and Max plans:** Claude Tag isn’t available on individual plans, so this page remains the setup path.

Claude Code in Slack brings the power of Claude Code directly into your Slack workspace. When you mention `@Claude` with a coding task, Claude automatically detects the intent and creates a Claude Code session on the web, allowing you to delegate development work without leaving your team conversations. This integration is built on the existing Claude for Slack app but adds intelligent routing to Claude Code on the web for coding-related requests. Each session runs under your own Claude account, using your connected repositories and your plan limits.


[​](#use-cases)

Use cases

- **Bug investigation and fixes**: Ask Claude to investigate and fix bugs as soon as they’re reported in Slack channels.
- **Quick code reviews and modifications**: Have Claude implement small features or refactor code based on team feedback.
- **Collaborative debugging**: When team discussions provide crucial context (e.g., error reproductions or user reports), Claude can use that information to inform its debugging approach.
- **Parallel task execution**: Kick off coding tasks in Slack while you continue other work, receiving notifications when complete.


[​](#prerequisites)

Prerequisites

Before using Claude Code in Slack, ensure you have the following:

| Requirement            | Details                                                                                           |
|:-----------------------|:--------------------------------------------------------------------------------------------------|
| Claude Plan            | Pro, Max, Team, or Enterprise with Claude Code access (premium seats or Chat + Claude Code seats) |
| Claude Code on the web | Access to [Claude Code on the web](/docs/en/claude-code-on-the-web) must be enabled               |
| GitHub Account         | Connected to Claude Code on the web with at least one repository authenticated                    |
| Slack Authentication   | Your Slack account linked to your Claude account via the Claude app                               |


[​](#setting-up-claude-code-in-slack)

Setting up Claude Code in Slack

1

Install the Claude App in Slack

A workspace administrator must install the Claude app from the Slack App Marketplace. Visit the [Slack App Marketplace](https://slack.com/marketplace/A08SF47R6P4) and click “Add to Slack” to begin the installation process.

2

Connect your Claude account

After the app is installed, authenticate your individual Claude account:

1.  Open the Claude app in Slack by clicking on “Claude” in your Apps section
2.  Navigate to the App Home tab
3.  Click “Connect” to link your Slack account with your Claude account
4.  Complete the authentication flow in your browser

3

Configure Claude Code on the web

Ensure your Claude Code on the web is properly configured:

- Visit [claude.ai/code](https://claude.ai/code) and sign in with the same account you connected to Slack
- Connect your GitHub account if not already connected
- Authenticate at least one repository that you want Claude to work with

4

Choose your routing mode

After connecting your accounts, configure how Claude handles your messages in Slack. Navigate to the Claude App Home in Slack to find the **Routing Mode** setting.

| Mode            | Behavior                                                                                                                                                                                                                                 |
|:----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Code only**   | Claude routes all @mentions to Claude Code sessions. Best for teams using Claude in Slack exclusively for development tasks.                                                                                                             |
| **Code + Chat** | Claude analyzes each message and intelligently routes between Claude Code (for coding tasks) and Claude Chat (for writing, analysis, and general questions). Best for teams who want a single @Claude entry point for all types of work. |

In Code + Chat mode, if Claude routes a message to Chat but you wanted a coding session, you can click “Retry as Code” to create a Claude Code session instead. Similarly, if it’s routed to Code but you wanted a Chat session, you can choose that option in that thread.

5

Add Claude to channels

Claude is not automatically added to any channels after installation. To use Claude in a channel, invite it by typing `/invite @Claude` in that channel. Claude can only respond to @mentions in channels where it has been added.


[​](#how-it-works)

How it works


[​](#automatic-detection)

Automatic detection

When you mention @Claude in a Slack channel or thread, Claude automatically analyzes your message to determine if it’s a coding task. If Claude detects coding intent, it will route your request to Claude Code on the web instead of responding as a regular chat assistant. You can also explicitly tell Claude to handle a request as a coding task, even if it doesn’t automatically detect it.

Claude Code in Slack only works in channels (public or private). It does not work in direct messages (DMs).


[​](#context-gathering)

Context gathering

**From threads**: When you @mention Claude in a thread, it gathers context from all messages in that thread to understand the full conversation. **From channels**: When mentioned directly in a channel, Claude looks at recent channel messages for relevant context. This context helps Claude understand the problem, select the appropriate repository, and inform its approach to the task.

When @Claude is invoked in Slack, Claude is given access to the conversation context to better understand your request. Claude may follow directions from other messages in the context, so users should make sure to only use Claude in trusted Slack conversations.


[​](#session-flow)

Session flow

1.  **Initiation**: You @mention Claude with a coding request
2.  **Detection**: Claude analyzes your message and detects coding intent
3.  **Session creation**: A new Claude Code session is created on claude.ai/code
4.  **Progress updates**: Claude posts status updates to your Slack thread as work progresses
5.  **Completion**: When finished, Claude @mentions you with a summary and action buttons
6.  **Review**: Click “View Session” to see the full transcript, or “Create PR” to open a pull request


[​](#user-interface-elements)

User interface elements


[​](#app-home)

App Home

The App Home tab shows your connection status and allows you to connect or disconnect your Claude account from Slack.


[​](#message-actions)

Message actions

- **View Session**: Opens the full Claude Code session in your browser where you can see all work performed, continue the session, or make additional requests.
- **Create PR**: Creates a pull request directly from the session’s changes.
- **Retry as Code**: If Claude initially responds as a chat assistant but you wanted a coding session, click this button to retry the request as a Claude Code task.
- **Change Repo**: Allows you to select a different repository if Claude chose incorrectly.


[​](#repository-selection)

Repository selection

Claude automatically selects a repository based on context from your Slack conversation. If multiple repositories could apply, Claude may display a dropdown allowing you to choose the correct one.


[​](#access-and-permissions)

Access and permissions


[​](#user-level-access)

User-level access

| Access Type          | Requirement                                                     |
|:---------------------|:----------------------------------------------------------------|
| Claude Code Sessions | Each user runs sessions under their own Claude account          |
| Usage & Rate Limits  | Sessions count against the individual user’s plan limits        |
| Repository Access    | Users can only access repositories they’ve personally connected |
| Session History      | Sessions appear in your Claude Code history on claude.ai/code   |


[​](#workspace-level-access)

Workspace-level access

Slack workspace administrators control whether the Claude app is available in their workspace:

| Control                      | Description                                                                                                       |
|:-----------------------------|:------------------------------------------------------------------------------------------------------------------|
| App installation             | Workspace admins decide whether to install the Claude app from the Slack App Marketplace                          |
| Enterprise Grid distribution | For Enterprise Grid organizations, organization admins can control which workspaces have access to the Claude app |
| App removal                  | Removing the app from a workspace immediately revokes access for all users in that workspace                      |


[​](#channel-based-access-control)

Channel-based access control

Claude is not automatically added to any channels after installation. Users must explicitly invite Claude to channels where they want to use it:

- **Invite required**: Type `/invite @Claude` in any channel to add Claude to that channel
- **Channel membership controls access**: Claude can only respond to @mentions in channels where it has been added
- **Access gating through channels**: Admins can control who uses Claude Code by managing which channels Claude is invited to and who has access to those channels
- **Private channel support**: Claude works in both public and private channels, giving teams flexibility in controlling visibility

This channel-based model allows teams to restrict Claude Code usage to specific channels, providing an additional layer of access control beyond workspace-level permissions.


[​](#what’s-accessible-where)

What’s accessible where

**In Slack**: You’ll see status updates, completion summaries, and action buttons. The full transcript is preserved and always accessible. **On the web**: The complete Claude Code session with full conversation history, all code changes, file operations, and the ability to continue the session or create pull requests. For Enterprise and Team accounts, sessions created from Claude in Slack are automatically visible to the organization. See [Claude Code on the Web sharing](/docs/en/claude-code-on-the-web#share-sessions) for more details.


[​](#best-practices)

Best practices


[​](#writing-effective-requests)

Writing effective requests

- **Be specific**: Include file names, function names, or error messages when relevant.
- **Provide context**: Mention the repository or project if it’s not clear from the conversation.
- **Define success**: Explain what “done” looks like—should Claude write tests? Update documentation? Create a PR?
- **Use threads**: Reply in threads when discussing bugs or features so Claude can gather the full context.


[​](#when-to-use-slack-vs-web)

When to use Slack vs. web

**Use Slack when**: Context already exists in a Slack discussion, you want to kick off a task asynchronously, or you’re collaborating with teammates who need visibility. **Use the web directly when**: You need to upload files, want real-time interaction during development, or are working on longer, more complex tasks.


[​](#troubleshooting)

Troubleshooting


[​](#”claude-code-is-not-enabled-for-your-account”)

”Claude Code is not enabled for your account”

This error means your Claude account has no cloud environment yet, not that an admin needs to enable anything. Sign in at [claude.ai/code](https://claude.ai/code) once with the same account you connected to Slack. The first visit creates your default cloud environment, and the error clears on your next mention. Each user must do this individually.


[​](#sessions-not-starting)

Sessions not starting

1.  Verify your Claude account is connected in the Claude App Home
2.  Check that you have Claude Code on the web access enabled
3.  Ensure you have at least one GitHub repository connected to Claude Code


[​](#sessions-from-a-claude-tag-channel-fail-to-start)

Sessions from a Claude Tag channel fail to start

This entry applies to workspaces using [Claude Tag](https://claude.com/docs/claude-tag/overview), where Claude works in channels as your organization’s shared identity, not as any member’s account. If you created the channel’s cloud environment at [claude.ai/code](https://claude.ai/code), it belongs to your personal account, and Claude can’t start channel sessions in a personal environment. Claude Code fails the session immediately, and retrying doesn’t help. If you’re an Owner or admin, recreate the environment as an [organization-shared environment](/docs/en/cloud-environments#organization-shared-environments) from the **Cloud environments** page in [admin settings](https://claude.ai/admin-settings). You can apply it in two ways:

- Set it as the organization default at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code).
- [Set it on the 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.

If you’re not an Owner or admin, send this entry to one.


[​](#repository-not-showing)

Repository not showing

1.  Connect the repository in Claude Code on the web at [claude.ai/code](https://claude.ai/code)
2.  Verify your GitHub permissions for that repository
3.  Try disconnecting and reconnecting your GitHub account


[​](#wrong-repository-selected)

Wrong repository selected

1.  Click the “Change Repo” button to select a different repository
2.  Include the repository name in your request for more accurate selection


[​](#authentication-errors)

Authentication errors

1.  Disconnect and reconnect your Claude account in the App Home
2.  Ensure you’re signed into the correct Claude account in your browser
3.  Check that your Claude plan includes Claude Code access


[​](#session-expiration)

Session expiration

1.  Sessions remain accessible in your Claude Code history on the web
2.  You can continue or reference past sessions from [claude.ai/code](https://claude.ai/code)


[​](#current-limitations)

Current limitations

- **GitHub only**: Currently supports repositories on GitHub.
- **One PR at a time**: Each session can create one pull request.
- **Rate limits apply**: Sessions use your individual Claude plan’s rate limits.
- **Web access required**: Users must have Claude Code on the web access; those without it will only get standard Claude chat responses.


[​](#related-resources)

Related resources

## Claude Code on the web

Learn more about Claude Code on the web

## Claude for Slack

General Claude for Slack documentation

## Claude Tag

Organization-managed @Claude in Slack with admin-configured access

## Slack App Marketplace

Install the Claude app from the Slack Marketplace

## Claude Help Center

Get additional support


---
## claude-code-on-amazon-bedrock-claude-code-docs-435e92efd0.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)
  - [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)
- [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)
  - [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. The command works when typed even though it isn’t listed in the command menu until Bedrock is configured.

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 picks up your region, verifies which Claude models your account can invoke, and lets you pin them. It saves the result to the `env` block of your [user settings file](/docs/en/settings), 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`](/docs/en/env-vars#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.  Navigate 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. Set up your credentials using one of these methods: **Option A: AWS CLI configuration**

```python
aws configure
```

**Option B: Environment variables (access key)**

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

**Option C: Environment variables (SSO 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. In v2.1.207, the Amazon Bedrock region overrode `sso_region`, so a profile whose IAM Identity Center instance is in a different region failed to authenticate with a `Session token not found or invalid` error. **Option D: AWS Management Console credentials**

```python
aws login
```

[Learn more](https://docs.aws.amazon.com/signin/latest/userguide/command-line-sign-in.html) about `aws login`. **Option E: Amazon Bedrock API keys**

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

Amazon Bedrock API keys provide a simpler authentication method without needing full AWS credentials. [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. Before v2.1.207, Claude Code resolved the chain on every API request, so an SSO-backed profile requested fresh credentials from IAM Identity Center each time and could be throttled in large deployments. The cache covers every credential option above except an Amazon Bedrock API key, which doesn’t use the provider chain. To resolve the chain on every request instead, set [`CLAUDE_CODE_SKIP_AWS_CRED_CACHE=1`](/docs/en/env-vars). Each resolve of the chain times out after 60 seconds. If a step in the chain stalls, for example a `credential_process` helper that waits for input it can’t receive, the request fails with [`AWS default-chain credential resolve timed out`](/docs/en/errors#aws-default-chain-credential-resolve-timed-out). If your chain runs an interactive sign-in that legitimately needs longer, such as browser-based SSO with MFA through a wrapper like `aws-vault`, raise the limit in milliseconds with [`CLAUDE_CODE_AWS_CHAIN_RESOLVE_TIMEOUT_MS`](/docs/en/env-vars). Before v2.1.207, a stalled credential resolution left the request waiting indefinitely.


[​](#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](/docs/en/settings) 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.

##### 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. This command runs whenever credentials need to be refreshed, not only when credentials are expired. 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"
  }
}
```

As of Claude Code v2.1.181, 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. As of Claude Code v2.1.176, when the command returns a valid ISO 8601 `Expiration`, Claude Code caches the credentials until five minutes before that time. Without it, or on earlier versions, 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. Before v2.1.206, startup also re-resolved the default provider chain, which made a live SSO or STS call outside your proxy configuration and could block the first prompt for several minutes on networks with restricted egress.


[​](#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:

- As of v2.1.172, 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`

  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, `/status` also notes the source. On v2.1.171 and earlier, Claude Code does not read the AWS config files, so set `AWS_REGION` explicitly.
- 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](/docs/en/tools-reference#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](/docs/en/settings) 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, 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 variables use cross-region inference profile IDs (with the `us.` prefix). If you use a different region prefix or application inference profiles, adjust accordingly. In AWS GovCloud regions, use the `us-gov.` prefix. For current and legacy model IDs, see [Models overview](https://platform.claude.com/docs/en/about-claude/models/overview). See [Model configuration](/docs/en/model-config#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    | `us.anthropic.claude-opus-5`                   |
| Small/fast model | `us.anthropic.claude-sonnet-4-5-20250929-v1:0` |

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. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` counts as a selection too, 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 a deployment that doesn’t pin a primary model is billed at the Opus rate once it updates to v2.1.207 or later. To keep 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.

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. Before v2.1.207, the primary model defaulted to Sonnet 4.5, the `opus` alias resolved to Opus 4.6, and background tasks always used the primary model. 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](/docs/en/prompt-caching#cache-lifetime).

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](/docs/en/settings#settings-files) 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](/docs/en/model-config#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](/docs/en/settings) 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, with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](/docs/en/settings), 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.

Before v2.1.211, Claude Code checked the default model’s availability even when a session model was explicitly configured, and could show a fallback notice for a default the session didn’t use.


[​](#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

Claude Sonnet 5, Opus 4.6 and later, and Sonnet 4.6 support the [1M token context window](https://platform.claude.com/docs/en/build-with-claude/context-windows#context-window-sizes-by-model) on Amazon Bedrock. Sonnet 5 is served through the [Mantle endpoint](#use-the-mantle-endpoint) and always runs with the 1M window, with no `[1m]` variant to select. For the other models, Claude Code automatically enables the extended context window when you select a 1M model variant. The [setup wizard](#sign-in-with-bedrock) offers a 1M context option when it pins models. To enable it for a manually pinned model instead, append `[1m]` to the model ID. See [Pin models for third-party deployments](/docs/en/model-config#pin-models-for-third-party-deployments) for details.


[​](#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](/docs/en/settings). 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"
  }
}
```


[​](#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, IAM permissions, and `awsAuthRefresh` configuration described earlier on this page.


[​](#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. As of v2.1.172, the region is resolved with the same precedence as [Amazon Bedrock above](#3-configure-claude-code); earlier versions use `AWS_REGION` only. 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](/docs/en/settings). This setting also restricts the picker to the listed entries. Listing `anthropic.claude-haiku-4-5` removes the bare `haiku` alias from the picker, so also list version prefixes or full IDs for the versions you want to keep selectable. The Mantle ID and the `haiku` alias resolve to the same model family, so the merge keeps only the more specific entry. See [Merge behavior](/docs/en/model-config#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 routed to Mantle. Replace `anthropic.claude-haiku-4-5` with the model ID your account has been granted. See [Restrict model selection](/docs/en/model-config#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](/docs/en/llm-gateway) that injects AWS credentials server-side, disable client-side authentication so Claude Code sends requests without SigV4 signatures or `x-api-key` headers:

```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](/docs/en/env-vars) 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 tabs spawn repeatedly when using AWS SSO, remove the `awsAuthRefresh` setting from your [settings file](/docs/en/settings). This can occur when corporate VPNs or TLS inspection proxies interrupt the SSO browser flow. Claude Code treats the interrupted connection as an authentication failure, re-runs `awsAuthRefresh`, and loops indefinitely. 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`.


[​](#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

If streaming requests fail with an error that begins `Bedrock streaming response has content-type`, a gateway or proxy between Claude Code and Amazon Bedrock is transforming the streaming response. Amazon Bedrock streams responses in a binary event-stream format with the content-type `application/vnd.amazon.eventstream`, and Claude Code rejects a successful streaming response that reports a different content-type instead of decoding a body it can’t read. The error names the content-type it received, commonly `text/event-stream` from an Amazon API Gateway and Lambda integration that re-emits the stream as server-sent events. Before v2.1.208, the same misconfiguration surfaced as `API Error: Truncated event message received` after the whole response had been buffered. To fix it, configure the gateway to pass the `InvokeModelWithResponseStream` response body and its `Content-Type` header through unmodified. If the gateway rewrites only the header and passes the binary body through intact, set [`CLAUDE_CODE_DISABLE_BEDROCK_CONTENT_TYPE_GUARD=1`](/docs/en/env-vars) to skip the check until the gateway is fixed. With the check off, a response body that was transformed fails with `Truncated event message received` again.


[​](#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](/docs/en/settings). A `403` from the Mantle endpoint with valid credentials means 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)


---
## claude-code-on-amazon-bedrock-claude-code-docs.md

# Claude Code on Amazon Bedrock


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


## 

Prerequisites

Before configuring Claude Code with Bedrock, ensure you have:

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

If you are deploying Claude Code to multiple users, [pin your model versions](#4-pin-model-versions) to prevent breakage when Anthropic releases new models.

## 

Setup

### 

1. Submit use case details

First-time users of Anthropic models are required to submit use case details before invoking a model. This is done once per account.

1.  Ensure you have the right IAM permissions (see more on that below)
2.  Navigate to the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)
3.  Select **Chat/Text playground**
4.  Choose any Anthropic model and you will be prompted to fill out the use case form

### 

2. Configure AWS credentials

Claude Code uses the default AWS SDK credential chain. Set up your credentials using one of these methods: **Option A: AWS CLI configuration**

Report incorrect code

Copy


``` shiki
aws configure
```

**Option B: Environment variables (access key)**

Report incorrect code

Copy


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

**Option C: Environment variables (SSO profile)**

Report incorrect code

Copy


``` shiki
aws sso login --profile=<your-profile-name>

export AWS_PROFILE=your-profile-name
```

**Option D: AWS Management Console credentials**

Report incorrect code

Copy


``` shiki
aws login
```

[Learn more](https://docs.aws.amazon.com/signin/latest/userguide/command-line-sign-in.html) about `aws login`. **Option E: Bedrock API keys**

Report incorrect code

Copy


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

Bedrock API keys provide a simpler authentication method without needing full AWS credentials. [Learn more about Bedrock API keys](https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/).

#### 

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](/docs/en/settings) for file locations). When Claude Code detects that your AWS credentials are expired (either locally based on their timestamp or when Bedrock returns a credential error), it will automatically run your configured `awsAuthRefresh` and/or `awsCredentialExport` commands to obtain new credentials before retrying the request.

##### Example configuration

Report incorrect code

Copy


``` shiki
{
  "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:

Report incorrect code

Copy


``` shiki
{
  "Credentials": {
    "AccessKeyId": "value",
    "SecretAccessKey": "value",
    "SessionToken": "value"
  }
}
```

### 

3. Configure Claude Code

Set the following environment variables to enable Bedrock:

Report incorrect code

Copy


``` shiki
# Enable Bedrock integration
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=us-east-1  # or your preferred region

# Optional: Override the region for the small/fast model (Haiku)
export ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION=us-west-2
```

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

- `AWS_REGION` is a required environment variable. Claude Code does not read from the `.aws` config file for this setting.
- When using Bedrock, the `/login` and `/logout` commands are disabled since authentication is handled through AWS credentials.
- You can use settings files for environment variables like `AWS_PROFILE` that you don’t want to leak to other processes. See [Settings](/docs/en/settings) for more information.

### 

4. Pin model versions

Pin specific model versions for every deployment. If you use model aliases (`sonnet`, `opus`, `haiku`) without pinning, Claude Code may attempt to use a newer model version that isn’t available in your Bedrock account, breaking existing users when Anthropic releases updates.

Set these environment variables to specific Bedrock model IDs:

Report incorrect code

Copy


``` shiki
export ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-6-v1'
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 variables use cross-region inference profile IDs (with the `us.` prefix). If you use a different region prefix or application inference profiles, adjust accordingly. For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview.md). See [Model configuration](/docs/en/model-config#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    | `global.anthropic.claude-sonnet-4-6`          |
| Small/fast model | `us.anthropic.claude-haiku-4-5-20251001-v1:0` |

To customize models further, use one of these methods:

Report incorrect code

Copy


``` shiki
# Using inference profile ID
export ANTHROPIC_MODEL='global.anthropic.claude-sonnet-4-6'
export ANTHROPIC_SMALL_FAST_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
```

[Prompt caching](../10-Prompting-Guides/build-with-claude-prompt-caching.md) may not be available in all regions.

#### 

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](/docs/en/settings#settings-files) instead. This example maps three Opus versions to distinct ARNs so users can switch between them without bypassing your organization’s inference profiles:

Report incorrect code

Copy


``` shiki
{
  "modelOverrides": {
    "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 Bedrock with the mapped ARN. Versions without an override fall back to the built-in Bedrock model ID or any matching inference profile discovered at startup. See [Override model IDs per version](/docs/en/model-config#override-model-ids-per-version) for details on how overrides interact with `availableModels` and other model settings.

## 

IAM configuration

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

Report incorrect code

Copy


``` shiki
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowModelAndInferenceProfileAccess",
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream",
        "bedrock:ListInferenceProfiles"
      ],
      "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. For details, see [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.

## 

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](/docs/en/settings). Enable Cross-Region inference on your Guardrail if you’re using cross-region inference profiles. Example configuration:

Report incorrect code

Copy


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

## 

Troubleshooting

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 Bedrock [Invoke API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_InvokeModelWithResponseStream.html) and does not support the Converse API.

## 

Additional resources

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


---
## claude-code-on-claude-platform-on-aws-claude-code-docs-2466cb4340.md

## On this page

- [Prerequisites](#prerequisites)
- [Setup](#setup)
  - [1. Configure AWS credentials](#1-configure-aws-credentials)
  - [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](https://platform.claude.com/docs) on the same release schedule. Client-side features that Claude Code turns on through Anthropic’s feature-flag service, such as [`/loop` self-pacing](/docs/en/scheduled-tasks#let-claude-choose-the-interval), are off by default, and the [advisor tool](/docs/en/advisor) is not available. See the [feature availability matrix](/docs/en/feature-availability#summary-by-provider) for the full list. You authenticate with AWS credentials or a workspace API key, and you pay through AWS Marketplace. 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](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws).

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. **Option A: 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`](/docs/en/amazon-bedrock#advanced-credential-configuration) so Claude Code re-runs your login command and retries instead of failing. Automatic refresh on Claude Platform on AWS requires Claude Code v2.1.198 or later; earlier versions stop with a prompt to run `/login`, which can’t refresh AWS credentials. Add the command to your [settings file](/docs/en/settings), 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. Before v2.1.212, the panel was titled `Cloud authentication`. With `awsAuthRefresh` configured, `/login` shows a **Claude Platform on AWS · refresh credentials** option under **Using 3rd-party platforms**. Selecting it runs the configured command and re-reads your AWS credentials without restarting Claude Code. **Option B: 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](/docs/en/settings) `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. The exception is the **refresh credentials** option `/login` shows when `awsAuthRefresh` is configured, which re-reads your AWS credentials as described above.


[​](#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 and is sent 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. The base URL is computed from `AWS_REGION` as `https://aws-external-anthropic.{region}.api.aws`. 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. Before v2.1.219, it resolved to Opus 4.8, and before v2.1.207 to Opus 4.7. 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](https://platform.claude.com/docs/en/about-claude/models/overview). For other model-related variables, see [Model configuration](/docs/en/model-config). [Prompt caching](/docs/en/prompt-caching) 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](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing) for the rates.


[​](#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](/docs/en/agent-sdk/overview) 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](/docs/en/agent-sdk/overview).


[​](#route-through-a-corporate-proxy)

Route through a corporate proxy

To route traffic through a proxy or [LLM gateway](/docs/en/llm-gateway), 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](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions). 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](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws): subscription, workspace setup, and product reference
- [IAM action reference](https://platform.claude.com/docs/en/api/claude-platform-on-aws-iam-actions): permissions and managed policies


---
## claude-code-on-google-cloud-x27-s-agent-platform-claude-code-docs-2acd050a7a.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)
- [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 detects 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](/docs/en/settings), 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`](/docs/en/env-vars#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.  Navigate 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 v2.1.121 or later 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 uses `ANTHROPIC_VERTEX_PROJECT_ID` as the project ID for Google Cloud’s Agent Platform requests. The `GCLOUD_PROJECT` and `GOOGLE_CLOUD_PROJECT` environment variables and the credential file referenced by `GOOGLE_APPLICATION_CREDENTIALS` take precedence over it. If none of these are set, the project ID is resolved from your `gcloud` configuration or the attached service account.


[​](#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](/docs/en/settings), 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"
  }
}
```

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`, the command runs only after you accept the workspace trust prompt.


[​](#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

# 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

# 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](/docs/en/env-vars) 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. [Prompt caching](/docs/en/prompt-caching) 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. For heightened 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 disables [MCP tool search](/docs/en/mcp#scale-with-mcp-tool-search) by default on Google Cloud’s Agent Platform, so MCP tool definitions load upfront. Google Cloud’s Agent Platform supports tool search for Claude Sonnet 4.5 and later and Claude Opus 4.5 and later. Set `ENABLE_TOOL_SEARCH=true` to enable it on those models. Earlier models on Google Cloud’s Agent Platform do not accept the required beta header, and requests fail if you enable tool search with them.


[​](#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, 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](https://platform.claude.com/docs/en/about-claude/models/overview). See [Model configuration](/docs/en/model-config#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`              |
| 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. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` counts as a selection too, 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 a deployment that doesn’t pin a primary model is billed at the Opus rate once it updates to v2.1.207 or later. To keep 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.

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. Before v2.1.207, the primary model defaulted to Sonnet 4.5, the `opus` alias resolved to Opus 4.6, and background tasks always used the primary model. 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](/docs/en/settings).


[​](#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](/docs/en/settings) 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, with `--model`, `ANTHROPIC_MODEL`, or the [`model` setting](/docs/en/settings), 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.

Before v2.1.211, Claude Code checked the default model’s availability even when a session model was explicitly configured, and could show a fallback notice for a default the session didn’t use.


[​](#iam-configuration)

IAM configuration

Assign the required IAM permissions: The `roles/aiplatform.user` role 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

Claude Sonnet 5, Opus 4.6 and later, and Sonnet 4.6 support the [1M token context window](https://platform.claude.com/docs/en/build-with-claude/context-windows#context-window-sizes-by-model) on Google Cloud’s Agent Platform. Sonnet 5 always runs with the 1M window, with no `[1m]` variant to select. For the other models, Claude Code automatically enables the extended context window when you select a 1M model 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](/docs/en/model-config#pin-models-for-third-party-deployments) for details.


[​](#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 `VERTEX_REGION_<MODEL_NAME>` environment 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)


---
## claude-code-on-google-vertex-ai-claude-code-docs.md

# Claude Code on Google Vertex AI


Learn about configuring Claude Code through Google Vertex AI, including setup, IAM configuration, and troubleshooting.


## 

Prerequisites

Before configuring Claude Code with Vertex AI, ensure you have:

- A Google Cloud Platform (GCP) account with billing enabled
- A GCP project with Vertex AI 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

If you are deploying Claude Code to multiple users, [pin your model versions](#5-pin-model-versions) to prevent breakage when Anthropic releases new models.

## 

Region Configuration

Claude Code can be used with both Vertex AI [global](https://cloud.google.com/blog/products/ai-machine-learning/global-endpoint-for-claude-models-generally-available-on-vertex-ai) and regional endpoints.

Vertex AI may not support the Claude Code default models in all [regions](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#genai-partner-models) or on [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 region, use a regional endpoint, or specify a supported model.

## 

Setup

### 

1. Enable Vertex AI API

Enable the Vertex AI API in your GCP project:

Report incorrect code

Copy


``` shiki
# Set your project ID
gcloud config set project YOUR-PROJECT-ID

# Enable Vertex AI API
gcloud services enable aiplatform.googleapis.com
```

### 

2. Request model access

Request access to Claude models in Vertex AI:

1.  Navigate to the [Vertex AI 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

Claude Code uses standard Google Cloud authentication. For more information, see [Google Cloud authentication documentation](https://cloud.google.com/docs/authentication).

When authenticating, Claude Code will automatically use the project ID from the `ANTHROPIC_VERTEX_PROJECT_ID` environment variable. To override this, set one of these environment variables: `GCLOUD_PROJECT`, `GOOGLE_CLOUD_PROJECT`, or `GOOGLE_APPLICATION_CREDENTIALS`.

### 

4. Configure Claude Code

Set the following environment variables:

Report incorrect code

Copy


``` shiki
# Enable Vertex AI integration
export CLAUDE_CODE_USE_VERTEX=1
export CLOUD_ML_REGION=global
export ANTHROPIC_VERTEX_PROJECT_ID=YOUR-PROJECT-ID

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

# When CLOUD_ML_REGION=global, override region for unsupported models
export VERTEX_REGION_CLAUDE_3_5_HAIKU=us-east5

# Optional: Override regions for other specific models
export VERTEX_REGION_CLAUDE_3_5_SONNET=us-east5
export VERTEX_REGION_CLAUDE_3_7_SONNET=us-east5
export VERTEX_REGION_CLAUDE_4_0_OPUS=europe-west1
export VERTEX_REGION_CLAUDE_4_0_SONNET=us-east5
export VERTEX_REGION_CLAUDE_4_1_OPUS=europe-west1
```

[Prompt caching](../10-Prompting-Guides/build-with-claude-prompt-caching.md) is automatically supported when you specify the `cache_control` ephemeral flag. To disable it, set `DISABLE_PROMPT_CACHING=1`. For heightened rate limits, contact Google Cloud support. When using Vertex AI, the `/login` and `/logout` commands are disabled since authentication is handled through Google Cloud credentials.

### 

5. Pin model versions

Pin specific model versions for every deployment. If you use model aliases (`sonnet`, `opus`, `haiku`) without pinning, Claude Code may attempt to use a newer model version that isn’t enabled in your Vertex AI project, breaking existing users when Anthropic releases updates.

Set these environment variables to specific Vertex AI model IDs:

Report incorrect code

Copy


``` shiki
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-6'
export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-4-6'
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](/docs/en/model-config#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-sonnet-4-6`         |
| Small/fast model | `claude-haiku-4-5@20251001` |

To customize models further:

Report incorrect code

Copy


``` shiki
export ANTHROPIC_MODEL='claude-opus-4-6'
export ANTHROPIC_SMALL_FAST_MODEL='claude-haiku-4-5@20251001'
```

## 

IAM configuration

Assign the required IAM permissions: The `roles/aiplatform.user` role 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 [Vertex 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

Claude Opus 4.6, Sonnet 4.6, Sonnet 4.5, and Sonnet 4 support the [1M token context window](../04-API-Reference/Guides/build-with-claude-context-windows-13ca780d1d.md#1m-token-context-window) on Vertex AI. Claude Code automatically enables the extended context window when you select a 1M model variant. To enable the 1M context window for your pinned model, append `[1m]` to the model ID. See [Pin models for third-party deployments](/docs/en/model-config#pin-models-for-third-party-deployments) for details.

## 

Troubleshooting

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 you have access to the specified region
- 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_SMALL_FAST_MODEL`, or
  - Set a regional endpoint using `VERTEX_REGION_<MODEL_NAME>` environment 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

- [Vertex AI documentation](https://cloud.google.com/vertex-ai/docs)
- [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing)
- [Vertex AI quotas and limits](https://cloud.google.com/vertex-ai/docs/quotas)


---
## claude-code-on-microsoft-foundry-claude-code-docs-ee35d755a6.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)
  - [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)
- [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.  Navigate 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](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry#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. **Option A: API key authentication**

1.  Navigate to your resource in the Microsoft Foundry portal
2.  Go to 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
```

**Option B: Microsoft Entra ID authentication** When neither `ANTHROPIC_FOUNDRY_API_KEY` nor `ANTHROPIC_FOUNDRY_AUTH_TOKEN` is set, Claude Code automatically 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 local environments, you commonly may use the Azure CLI:

```python
az login
```

**Option C: Bearer token authentication** 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. Requires Claude Code v2.1.203 or later. 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.

When using Microsoft Foundry, the `/logout` command is unavailable since authentication is handled through Azure credentials.


[​](#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
```


[​](#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](https://platform.claude.com/docs/en/about-claude/models/overview). See [Model configuration](/docs/en/model-config#pin-models-for-third-party-deployments) for the full list of environment variables. [Prompt caching](/docs/en/prompt-caching) 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
```


[​](#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).


[​](#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/)


---
## claude-code-on-microsoft-foundry-claude-code-docs.md

# Claude Code on Microsoft Foundry


Learn about configuring Claude Code through Microsoft Foundry, including setup, configuration, and troubleshooting.


## 

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) to prevent breakage when Anthropic releases new models.

## 

Setup

### 

1. Provision Microsoft Foundry resource

First, create a Claude resource in Azure:

1.  Navigate 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:
    - Claude Opus
    - Claude Sonnet
    - Claude Haiku

### 

2. Configure Azure credentials

Claude Code supports two authentication methods for Microsoft Foundry. Choose the method that best fits your security requirements. **Option A: API key authentication**

1.  Navigate to your resource in the Microsoft Foundry portal
2.  Go to the **Endpoints and keys** section
3.  Copy **API Key**
4.  Set the environment variable:

Report incorrect code

Copy


``` shiki
export ANTHROPIC_FOUNDRY_API_KEY=your-azure-api-key
```

**Option B: Microsoft Entra ID authentication** When `ANTHROPIC_FOUNDRY_API_KEY` is not set, Claude Code automatically 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 local environments, you commonly may use the Azure CLI:

Report incorrect code

Copy


``` shiki
az login
```

When using Microsoft Foundry, the `/login` and `/logout` commands are disabled since authentication is handled through Azure credentials.

### 

3. Configure Claude Code

Set the following environment variables to enable Microsoft Foundry:

Report incorrect code

Copy


``` shiki
# 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
```

### 

4. Pin model versions

Pin specific model versions for every deployment. If you use model aliases (`sonnet`, `opus`, `haiku`) without pinning, Claude Code may attempt to use a newer model version that isn’t available in your Foundry account, breaking existing users when Anthropic releases updates. 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:

Report incorrect code

Copy


``` shiki
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-4-6'
export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-4-6'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='claude-haiku-4-5'
```

For current and legacy model IDs, see [Models overview](../20-Models/about-claude-models-overview.md). See [Model configuration](/docs/en/model-config#pin-models-for-third-party-deployments) for the full list of environment variables.

## 

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:

Report incorrect code

Copy


``` shiki
{
  "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).

## 

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

## 

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/)


---
## claude-code-on-mobile-claude-code-docs-8e56ba8e27.md

## On this page

- [Get the app](#get-the-app)
- [Work from your phone](#work-from-your-phone)
  - [Start and monitor cloud sessions](#start-and-monitor-cloud-sessions)
  - [Continue a local session with Remote Control](#continue-a-local-session-with-remote-control)
  - [Get push notifications](#get-push-notifications)
- [Limitations](#limitations)
- [Related resources](#related-resources)

Platforms and integrations

# Claude Code on mobile

Copy pageCopy page

Start, monitor, and steer Claude Code tasks from your phone with the Claude app for iOS and Android.

Copy pageCopy page

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) is a client for Claude Code sessions rather than a place where code runs. From your phone you reach [cloud sessions](#start-and-monitor-cloud-sessions) on Anthropic-managed infrastructure, a session running on your own machine through [Remote Control](#continue-a-local-session-with-remote-control), or the Desktop app through [Dispatch](/docs/en/desktop#sessions-from-dispatch).

Claude Code doesn’t have a separate mobile app: cloud sessions and Remote Control both live in the **Code** tab in the Claude app, and Dispatch is a task you message in the app.


[​](#get-the-app)

Get the app

1

Download the Claude app

Install 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). On an iPad, install the same iOS app.

Run `/mobile` in a Claude Code session to display a download QR code you can scan. `/ios` and `/android` do the same thing.

2

Sign in

Sign in with the same claude.ai account and organization you use for Claude Code. Cloud sessions and Remote Control require a claude.ai account, so they aren’t reachable with an Anthropic Console API key or from a third-party provider such as Amazon Bedrock.

3

Open the Code tab

Tap **Code** in the app’s navigation to reach your sessions, or open [claude.ai/code/new](https://claude.ai/code/new) on your phone to start a new Code session in the app. If you don’t see the Code tab, your plan or organization may not include these features; see [availability by subscription plan](/docs/en/feature-availability#availability-by-subscription-plan).


[​](#work-from-your-phone)

Work from your phone

From the app you can start cloud sessions, drive a Claude Code session running on your computer, or message Dispatch a task. The app is the same for all three; they differ in where the work happens.

| Feature                                                   | What you connect to                                 | When to use                                                                                                                                               |
|:----------------------------------------------------------|:----------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Claude Code on the web](/docs/en/claude-code-on-the-web) | A cloud session on Anthropic-managed infrastructure | Your repository is on GitHub and the task should keep running after you put your phone away. See the [web quickstart](/docs/en/web-quickstart) to set up. |
| [Remote Control](/docs/en/remote-control)                 | A Claude Code session running on your computer      | The work needs your local filesystem, tools, or MCP servers.                                                                                              |
| [Dispatch](/docs/en/desktop#sessions-from-dispatch)       | The Desktop app on your computer                    | You want to message a task and let Dispatch decide how to run it. Requires a Pro or Max plan.                                                             |

If your computer will be off, use cloud sessions: they run on Anthropic’s infrastructure and continue with your laptop closed. Remote Control and Dispatch drive your own machine, so it needs to stay on with Claude Code or the Desktop app running. If your machine sleeps during a Remote Control session, the session reconnects when it comes back online. For a fuller comparison that also covers Channels, Slack, and scheduled tasks, see [work when you are away from your terminal](/docs/en/platforms#work-when-you-are-away-from-your-terminal). Cloud sessions and Remote Control run from the **Code** tab and are covered below. For Dispatch, which you message as a task in the app, see [sessions from Dispatch](/docs/en/desktop#sessions-from-dispatch).


[​](#start-and-monitor-cloud-sessions)

Start and monitor cloud sessions

Claude Code on the web runs tasks on Anthropic-managed cloud infrastructure, so a session continues after you put your phone away. From the Code tab, select a repository and branch, describe the task, and submit it. Sessions persist across devices: a task you start on your laptop is ready to review from your phone, and one you start from your phone is waiting when you’re back at your desk. Open a session in the app to check progress, answer Claude’s questions, or steer it in a new direction. You can also tell Claude to [watch a pull request](/docs/en/claude-code-on-the-web#auto-fix-pull-requests) and fix CI failures or review comments as they arrive. To connect GitHub and set up your environment, follow the [web quickstart](/docs/en/web-quickstart), and see [Claude Code on the web](/docs/en/claude-code-on-the-web) for everything cloud sessions can do.


[​](#continue-a-local-session-with-remote-control)

Continue a local session with Remote Control

Remote Control connects the Claude app to a Claude Code session running on your machine, so code execution and filesystem access stay local while you drive the session from your phone. Start the session on your computer with `claude remote-control`, or run `/remote-control` in a session that’s already open. Then scan the session QR code the terminal can display, or open the Claude app, tap **Code**, and pick the session from the list. See [connect from another device](/docs/en/remote-control#connect-from-another-device) for each option. Attachments you add in the Claude app reach the local session too: Claude Code downloads the image or file to your machine and passes it to Claude as an `@` file reference. For requirements, invocation modes, and troubleshooting, see the [Remote Control overview](/docs/en/remote-control).


[​](#get-push-notifications)

Get push notifications

When Remote Control is active, Claude can send push notifications to your phone, typically when a long-running task finishes or when it needs a decision from you. You can also ask for one in your prompt, such as `notify me when the tests finish`. See [mobile push notifications](/docs/en/remote-control#mobile-push-notifications) for the two `/config` toggles and delivery troubleshooting. Dispatch sends its own notification when a Code session it spawned finishes or needs your approval, described in [sessions from Dispatch](/docs/en/desktop#sessions-from-dispatch).


[​](#limitations)

Limitations

The mobile client covers most of what a session needs, with a few limitations:

- **Local-only commands**: commands that only run in the terminal interface, such as `/plugin` and `/resume`, don’t work from the app. The [Remote Control limitations](/docs/en/remote-control#limitations) list the commands that do work from mobile and how their behavior differs.
- **Permission modes**: cloud sessions offer Accept edits, Plan, and Auto in the mode dropdown, and Remote Control sessions offer Manual, Accept edits, and Plan. You can’t select Bypass permissions from the app in either case, and you can’t select Auto for a Remote Control session. See [switch permission modes](/docs/en/permission-modes#switch-permission-modes).
- **Dispatch plans**: Dispatch requires a Pro or Max plan and isn’t available on Team or Enterprise.


[​](#related-resources)

Related resources

- [Platforms and integrations](/docs/en/platforms): compare every surface Claude Code runs on
- [Claude Code on the web](/docs/en/claude-code-on-the-web): how cloud sessions run and how to move work to and from your terminal
- [Configure cloud environments](/docs/en/cloud-environments): network access levels, environment variables, and setup scripts for cloud sessions
- [Remote Control](/docs/en/remote-control): continue a local session from any device
- [Sessions from Dispatch](/docs/en/desktop#sessions-from-dispatch): how Dispatch tasks become Code sessions in the Desktop app
- [Channels](/docs/en/channels): ask Claude something from your phone via Telegram, Discord, or iMessage while the work runs on your machine
- [Claude Code in Slack](/docs/en/slack): delegate coding tasks from your Slack workspace by mentioning `@Claude`


---
## claude-code-on-the-web-69d53821d4.md

> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Claude Code on the web

> Configure cloud environments, setup scripts, network access, and Docker in Anthropic's sandbox. Move sessions between web and terminal with `--remote` and `--teleport`.

<Note>
  Claude Code on the web is in research preview for Pro, Max, and Team users, and for Enterprise users with premium seats or Chat + Claude Code seats.
</Note>

Claude Code on the web runs tasks on Anthropic-managed cloud infrastructure at [claude.ai/code](https://claude.ai/code). Sessions persist even if you close your browser, and you can monitor them from the Claude mobile app.

<Tip>
  New to Claude Code on the web? Start with [Get started](web-quickstart-de55c74651.md) to connect your GitHub account and submit your first task.
</Tip>

This page covers:

* [GitHub authentication options](#github-authentication-options): two ways to connect GitHub
* [The cloud environment](#the-cloud-environment): what config carries over, what tools are installed, and how to configure environments
* [Setup scripts](#setup-scripts) and dependency management
* [Network access](#network-access): levels, proxies, and the default allowlist
* [Move tasks between web and terminal](#move-tasks-between-web-and-terminal) with `--remote` and `--teleport`
* [Work with sessions](#work-with-sessions): reviewing, sharing, archiving, deleting
* [Auto-fix pull requests](#auto-fix-pull-requests): respond automatically to CI failures and review comments
* [Security and isolation](#security-and-isolation): how sessions are isolated
* [Limitations](#limitations): rate limits and platform restrictions

## 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 it works                                                                                                                                 | Best for                                        |
| :--------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------- |
| **GitHub App**   | Install the Claude GitHub App on specific repositories during [web onboarding](web-quickstart-de55c74651.md). Access is scoped per repository.         | Teams that want explicit per-repo authorization |
| **`/web-setup`** | Run `/web-setup` in your terminal to sync your local `gh` CLI token to your Claude account. Access matches whatever your `gh` token can see. | Individual developers who already use `gh`      |

Either method works. [`/schedule`](routines-3111c7bd3a.md) checks for either form of access and prompts you to run `/web-setup` if neither is configured. See [Connect from your terminal](/en/web-quickstart#connect-from-your-terminal) for the `/web-setup` walkthrough.

The GitHub App is required for [Auto-fix](#auto-fix-pull-requests), which uses the App to receive PR webhooks. If you connect with `/web-setup` and later want Auto-fix, install the App on those repositories.

Team and Enterprise admins can disable `/web-setup` with the Quick web setup toggle at [claude.ai/admin-settings/claude-code](https://claude.ai/admin-settings/claude-code).

<Note>
  Organizations with [Zero Data Retention](../22-Safety-Policy/zero-data-retention-claude-code-docs-6ec9ee63f1.md) enabled cannot use `/web-setup` or other cloud session features.
</Note>

## The cloud environment

Each session runs in a fresh Anthropic-managed VM with your repository cloned. This section covers what's available when a session starts and how to customize it.

### What's available in cloud sessions

Cloud sessions start from a fresh clone of your repository. Anything committed to the repo is available. Anything you've installed or configured only on your own machine is not.

|                                                                       | Available in cloud sessions | Why                                                                                                                                              |
| :-------------------------------------------------------------------- | :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| Your repo's `CLAUDE.md`                                               | Yes                         | Part of the clone                                                                                                                                |
| Your repo's `.claude/settings.json` hooks                             | Yes                         | Part of the clone                                                                                                                                |
| Your repo's `.mcp.json` MCP servers                                   | Yes                         | Part of the clone                                                                                                                                |
| 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 declared in `.claude/settings.json`                           | Yes                         | Installed at session start from the [marketplace](../08-Plugins-Skills/create-and-distribute-a-plugin-marketplace-claude-code-docs-34a8f3c5e8.md) you declared. Requires network access to reach the marketplace source |
| Your user `~/.claude/CLAUDE.md`                                       | No                          | Lives on your machine, not in the repo                                                                                                           |
| Plugins enabled only in your user settings                            | No                          | User-scoped `enabledPlugins` lives in `~/.claude/settings.json`. Declare them in the repo's `.claude/settings.json` instead                      |
| MCP servers you added with `claude mcp add`                           | No                          | Those write to your local user config, not the repo. Declare the server in [`.mcp.json`](/en/mcp#project-scope) instead                          |
| Static API tokens and credentials                                     | No                          | No dedicated secrets store exists yet. See below                                                                                                 |
| Interactive auth like AWS SSO                                         | No                          | Not supported. SSO requires browser-based login that can't run in a cloud session                                                                |

To make configuration available in cloud sessions, commit it to the repo. A dedicated secrets store is not yet available. Both environment variables and setup scripts are stored in the environment configuration, visible to anyone who can edit that environment. If you need secrets in a cloud session, add them as environment variables with that visibility in mind.

### 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 via nvm, with npm, yarn, pnpm, bun¹, eslint, prettier, chromedriver |
| **Ruby**      | 3.1, 3.2, 3.3 with gem, bundler, rbenv                                             |
| **PHP**       | 8.4 with Composer                                                                  |
| **Java**      | OpenJDK 21 with Maven and Gradle                                                   |
| **Go**        | latest stable 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, jq, yq, ripgrep, tmux, vim, nano                                              |

¹ Bun is installed but has known [proxy compatibility issues](#install-dependencies-with-a-sessionstart-hook) for package fetching.

For exact versions, ask Claude to run `check-tools` in a cloud session. This command only exists in cloud sessions.

### 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](#github-authentication-options), so your token never enters the container.

The `gh` CLI is not pre-installed. If you need a `gh` command the built-in tools don't cover, like `gh release` or `gh workflow run`, install and authenticate it yourself:

<Steps>
  <Step title="Install gh in your setup script">
    Add `apt update && apt install -y gh` to your [setup script](#setup-scripts).
  </Step>

  <Step title="Provide a token">
    Add a `GH_TOKEN` environment variable to your [environment settings](#configure-your-environment) with a GitHub personal access token. `gh` reads `GH_TOKEN` automatically, so no `gh auth login` step is needed.
  </Step>
</Steps>

### Link artifacts 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.

Ask Claude to construct the link from the environment variable. The following command prints the URL:

```bash theme={null}
echo "https://claude.ai/code/${CLAUDE_CODE_REMOTE_SESSION_ID}"
```

### Run tests, start services, and add packages

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 like pytest, jest, and cargo test work out of the box since they're pre-installed.

PostgreSQL and Redis are pre-installed but not running by default. Ask Claude to start each one during the session:

```bash theme={null}
service postgresql start
```

```bash theme={null}
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 pulled images are saved in the [cached environment](#environment-caching), so each new session has them on disk. The cache stores files only, not running processes, so Claude still starts the containers each session.

To add packages that aren't pre-installed, use a [setup script](#setup-scripts). The script's output is [cached](#environment-caching), 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

Cloud sessions run with approximate resource ceilings that may change over time:

* 4 vCPUs
* 16 GB of RAM
* 30 GB of disk

Tasks requiring significantly more memory, such as large build jobs or memory-intensive tests, may fail or be terminated. For workloads beyond these limits, use [Remote Control](continue-local-sessions-from-any-device-with-remote-control-claude-code-docs-c1c03fd914.md) to run Claude Code on your own hardware.

### Configure your environment

Environments control [network access](#network-access), environment variables, and the [setup script](#setup-scripts) that runs before a session starts. See [Installed tools](#installed-tools) for what's available without any configuration. You can manage environments from the web interface or the terminal:

| Action                         | How                                                                                                                                                                                                                      |
| :----------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Add an environment             | Select the current environment to open the selector, then select **Add environment**. The dialog includes name, network access level, environment variables, and setup script.                                           |
| Edit an environment            | Select the settings icon to the right of the environment name.                                                                                                                                                           |
| Archive an environment         | Open the environment for editing and select **Archive**. Archived environments are hidden from the selector but existing sessions keep running.                                                                          |
| Set the default for `--remote` | Run `/remote-env` in your terminal. If you have a single environment, this command shows your current configuration. `/remote-env` only selects the default; add, edit, and archive environments from the web interface. |

Environment variables use `.env` format with one `KEY=value` pair per line. Don't wrap values in quotes, since quotes are stored as part of the value.

```text theme={null}
NODE_ENV=development
LOG_LEVEL=debug
DATABASE_URL=postgres://localhost:5432/myapp
```

## 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 the `gh` CLI, which isn't pre-installed:

```bash theme={null}
#!/bin/bash
apt update && apt install -y gh
```

If the script exits non-zero, the session fails to start. Append `|| true` to non-critical commands to avoid blocking the session on an intermittent install failure.

<Note>
  Setup scripts that install packages need network access to reach registries. The default **Trusted** network access allows connections to [common package registries](#default-allowed-domains) including npm, PyPI, RubyGems, and crates.io. Scripts will fail to install packages if your environment uses **None** network access.
</Note>

### Environment caching

The setup script runs the first time you start a session in an environment. After it completes, 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 the setup script step is skipped. This keeps startup fast even when the script installs large toolchains or pulls container images.

The cache captures files, not running processes. Anything the setup script writes to disk carries over. Services or containers it starts do not, so 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. Resuming an existing session never re-runs the setup script.

You don't need to enable caching or manage snapshots yourself.

### Setup scripts vs. SessionStart hooks

Use a setup script to install things the cloud needs but your laptop already has, like a language runtime or CLI tool. Use a [SessionStart hook](/en/hooks#sessionstart) for project setup that should run everywhere, cloud and local, like `npm install`.

Both run at the start of a session, but they belong to different places:

|               | Setup scripts                                                                                | SessionStart hooks                                             |
| ------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Attached to   | The cloud environment                                                                        | Your repository                                                |
| Configured in | Cloud environment UI                                                                         | `.claude/settings.json` in your repo                           |
| Runs          | Before Claude Code launches, when no [cached environment](#environment-caching) is available | After Claude Code launches, on every session including resumed |
| Scope         | Cloud environments only                                                                      | Both local and cloud                                           |

SessionStart hooks can also be defined in your user-level `~/.claude/settings.json` locally, but user-level settings don't carry over to cloud sessions. In the cloud, only hooks committed to the repo run.

### Install dependencies with a SessionStart hook

To install dependencies only in cloud sessions, add a SessionStart hook to your repo's `.claude/settings.json`:

```json theme={null}
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/scripts/install_pkgs.sh"
          }
        ]
      }
    ]
  }
}
```

Create the script at `scripts/install_pkgs.sh` and make it executable with `chmod +x`. The `CLAUDE_CODE_REMOTE` environment variable is set to `true` in cloud sessions, so you can use it to skip local execution:

```bash theme={null}
#!/bin/bash

if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then
  exit 0
fi

npm install
pip install -r requirements.txt
exit 0
```

SessionStart hooks have some limitations in cloud sessions:

* **No cloud-only scoping**: hooks run in both local and cloud sessions. To skip local execution, check the `CLAUDE_CODE_REMOTE` environment variable as shown above.
* **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**: all outbound traffic passes through a [security proxy](#security-proxy). Some package managers don't work correctly with this proxy. Bun is a known example.
* **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 checking whether dependencies are already present before reinstalling.

To persist environment variables for subsequent Bash commands, write to the file at `$CLAUDE_ENV_FILE`. See [SessionStart hooks](/en/hooks#sessionstart) for details.

Replacing the base image with your own Docker image is not yet supported. Use a setup script to install what you need on top of the [provided image](#installed-tools), or run your image as a container alongside Claude with `docker compose`.

## Network access

Network access controls outbound connections from the cloud environment. Each environment specifies one access level, and you can extend it with custom allowed domains. The default is **Trusted**, which allows package registries and other [allowlisted domains](#default-allowed-domains).

### Access levels

Choose an access level when you create or edit an environment:

| Level       | Outbound connections                                                                         |
| :---------- | :------------------------------------------------------------------------------------------- |
| **None**    | No outbound network access                                                                   |
| **Trusted** | [Allowlisted domains](#default-allowed-domains) only: package registries, GitHub, cloud SDKs |
| **Full**    | Any domain                                                                                   |
| **Custom**  | Your own allowlist, optionally including the defaults                                        |

GitHub operations use a [separate proxy](#github-proxy) that is independent of this setting.

### Allow specific domains

To allow domains that aren't in the Trusted list, select **Custom** in the environment's network access settings. An **Allowed domains** field appears. Enter one domain per line:

```text theme={null}
api.example.com
*.internal.example.com
registry.example.com
```

Use `*.` for wildcard subdomain matching. Check **Also include default list of common package managers** to keep the [Trusted domains](#default-allowed-domains) alongside your custom entries, or leave it unchecked to allow only what you list.

### GitHub proxy

For security, all GitHub operations go through a dedicated proxy service that transparently handles all git interactions. Inside the sandbox, the git client authenticates using a custom-built scoped credential. This proxy:

* Manages GitHub authentication securely: the git client uses a scoped credential inside the sandbox, which the proxy verifies and translates to your actual GitHub authentication token
* Restricts git push operations to the current working branch for safety
* Enables cloning, fetching, and PR operations while maintaining security boundaries

### Security proxy

Environments run behind an HTTP/HTTPS network proxy for security and abuse prevention purposes. All outbound internet traffic passes through this proxy, which provides:

* Protection against malicious requests
* Rate limiting and abuse prevention
* Content filtering for enhanced security

### Default allowed domains

When using **Trusted** network access, the following domains are allowed by default. Domains marked with `*` indicate wildcard subdomain matching, so `*.gcr.io` allows any subdomain of `gcr.io`.

<AccordionGroup>
  <Accordion title="Anthropic services">
    * api.anthropic.com
    * statsig.anthropic.com
    * docs.claude.com
    * platform.claude.com
    * code.claude.com
    * claude.ai
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="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
    * download.docker.com
    * gcr.io
    * \*.gcr.io
    * ghcr.io
    * mcr.microsoft.com
    * \*.data.mcr.microsoft.com
    * public.ecr.aws
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="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)
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="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)
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="JVM package managers">
    * maven.org
    * repo.maven.org
    * central.maven.org
    * repo1.maven.org
    * repo.maven.apache.org
    * jcenter.bintray.com
    * gradle.org
    * [www.gradle.org](http://www.gradle.org)
    * services.gradle.org
    * plugins.gradle.org
    * kotlinlang.org
    * [www.kotlinlang.org](http://www.kotlinlang.org)
    * spring.io
    * repo.spring.io
  </Accordion>

  <Accordion title="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)
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="Cloud services and monitoring">
    * statsig.com
    * [www.statsig.com](http://www.statsig.com)
    * api.statsig.com
    * sentry.io
    * \*.sentry.io
    * downloads.sentry-cdn.com
    * http-intake.logs.datadoghq.com
    * \*.datadoghq.com
    * \*.datadoghq.eu
    * api.honeycomb.io
  </Accordion>

  <Accordion title="Content delivery and mirrors">
    * sourceforge.net
    * \*.sourceforge.net
    * packagecloud.io
    * \*.packagecloud.io
    * fonts.googleapis.com
    * fonts.gstatic.com
  </Accordion>

  <Accordion title="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)
  </Accordion>

  <Accordion title="Model Context Protocol">
    * \*.modelcontextprotocol.io
  </Accordion>
</AccordionGroup>

## Move tasks between web and terminal

These workflows require the [Claude Code CLI](../01-Getting-Started/quickstart-claude-code-docs-a21b84bdea.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.

<Note>
  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 web. The `--remote` flag creates a new cloud session for your current repository. The [Desktop app](/en/desktop#continue-in-another-surface) provides a Continue in menu that can send a local session to the web.
</Note>

### From terminal to web

Start a cloud session from the command line with the `--remote` flag:

```bash theme={null}
claude --remote "Fix the authentication bug in src/auth/login.ts"
```

This creates a new cloud session on claude.ai. The session clones your current directory's GitHub remote at your current branch, so push first if you have local commits, since the VM clones from GitHub rather than your machine. `--remote` works with a single repository at a time. The task runs in the cloud while you continue working locally.

<Note>
  `--remote` creates cloud sessions. `--remote-control` is unrelated: it exposes a local CLI session for monitoring from the web. See [Remote Control](continue-local-sessions-from-any-device-with-remote-control-claude-code-docs-c1c03fd914.md).
</Note>

Use `/tasks` in the Claude Code CLI to check progress, or open the session on claude.ai or the Claude mobile app to interact directly. From there you can steer Claude, provide feedback, or answer questions just like any other conversation.

#### Tips for cloud tasks

**Plan locally, execute remotely**: for complex tasks, start Claude in plan mode to collaborate on the approach, then send work to the cloud:

```bash theme={null}
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:

```bash theme={null}
claude --remote "Execute the migration plan in docs/migration-plan.md"
```

This pattern gives you control over the strategy while letting Claude execute autonomously in the cloud.

**Plan in the cloud with ultraplan**: to draft and review the plan itself in a web session, use [ultraplan](ultraplan-14dfb476fe.md). Claude generates the plan on Claude Code on the web while you keep working, then you comment on sections in your browser and choose to execute remotely or send the plan back to your terminal.

**Run tasks in parallel**: each `--remote` command creates its own cloud session that runs independently. You can start multiple tasks and they'll all run simultaneously in separate sessions:

```bash theme={null}
claude --remote "Fix the flaky test in auth.spec.ts"
claude --remote "Update the API documentation"
claude --remote "Refactor the logger to use structured output"
```

Monitor all sessions with `/tasks` in the Claude Code CLI. When a session completes, you can create a PR from the web interface or [teleport](#from-web-to-terminal) the session to your terminal to continue working.

#### Send local repositories without GitHub

When you run `claude --remote` from a repository that isn't connected to GitHub, Claude Code bundles your local repository and uploads it directly to the cloud session. The bundle includes your full repository history across all branches, plus any uncommitted changes to tracked files.

This fallback activates automatically when GitHub access isn't available. To force it even when GitHub is connected, set `CCR_FORCE_BUNDLE=1`:

```bash theme={null}
CCR_FORCE_BUNDLE=1 claude --remote "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 only if the snapshot is still too large
* Untracked files are not included; run `git add` on files you want the cloud session to see
* Sessions created from a bundle can't push back to a remote unless you also have [GitHub authentication](#github-authentication-options) configured

### From web to 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 the web interface**: select **Open in CLI** to copy a command you can paste into your terminal

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.

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

#### `--teleport` is unavailable

Teleport requires claude.ai subscription authentication. If you're authenticated via API key, Bedrock, Vertex AI, or Microsoft Foundry, run `/login` to sign in with your claude.ai account instead. If you're already signed in via claude.ai and `--teleport` is still unavailable, your organization may have disabled cloud 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.

### Manage context

Cloud sessions support [built-in commands](built-in-commands-claude-code-docs.md) that produce text output. Commands that open an interactive terminal picker, like `/model` or `/config`, are not available.

For context management specifically:

| 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`   | No                      | Start a new session from the sidebar instead                                                                             |

Auto-compaction runs automatically when the context window approaches capacity, the same as in the CLI. To trigger it earlier, set [`CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`](env-vars-5c624d392b.md) in your [environment variables](#configure-your-environment). For example, `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=70` compacts at 70% capacity instead of the default \~95%. To change the effective window size for compaction calculations, use [`CLAUDE_CODE_AUTO_COMPACT_WINDOW`](env-vars-5c624d392b.md).

[Subagents](../09-Agents-Patterns/create-custom-subagents-claude-code-docs-7dc93e85c0.md) work the same way they do locally. Claude can spawn them with the Task tool to offload research or parallel work into a separate context window, keeping the main conversation lighter. Subagents defined in your repo's `.claude/agents/` are picked up automatically. [Agent teams](../09-Agents-Patterns/agent-teams-e29da6ed1b.md) are off by default but can be enabled by adding `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` to your [environment variables](#configure-your-environment).

### 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. See [Review and iterate](/en/web-quickstart#review-and-iterate) for the full walkthrough including PR creation. To have Claude monitor the PR for CI failures and review comments automatically, see [Auto-fix pull requests](#auto-fix-pull-requests).

### 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

For Enterprise and Team accounts, the two visibility options are **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 account's display name is visible to all recipients with access. [Claude in Slack](../14-Connectors/claude-code-in-slack-claude-code-docs-c62a093e92.md) sessions are automatically shared with Team visibility.

#### Share from a Max or Pro account

For Max and Pro accounts, the two visibility options are **Private** and **Public**. Public visibility makes the session visible to any user logged into claude.ai.

Check your session for sensitive content before sharing. Sessions may contain code and credentials from private GitHub repositories. Repository access verification is not enabled by default.

To require recipients to have repository access, or to hide your name from shared sessions, go to Settings > Claude Code > Sharing settings.

### 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

Deleting a session permanently removes the session and its data. This action cannot 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

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.

<Note>
  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) or when prompted during [setup](/en/web-quickstart#connect-github-and-create-an-environment).
</Note>

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 Claude Code on the web**: open the CI status bar and select **Auto-fix**
* **From your terminal**: run [`/autofix-pr`](built-in-commands-claude-code-docs.md) while on the PR's branch. Claude Code detects the open PR with `gh`, spawns a web 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

### 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

Claude may reply to review comment threads on GitHub as part of resolving them. These replies are posted using your GitHub account, so they appear under your username, but each reply is labeled as coming from Claude Code so reviewers know it was written by the agent and not by you directly.

<Warning>
  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.
</Warning>

## 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
* **Network access controls**: network access is limited by default, and can be disabled. 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**: sensitive credentials such as git credentials or signing keys are never inside the sandbox with Claude Code. Authentication is handled through a secure proxy using scoped credentials.
* **Secure analysis**: code is analyzed and modified within isolated VMs before creating PRs

## 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-8648349cb4.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

If a new session fails to start with `Session creation failed` or stalls at provisioning, Claude Code could not allocate a cloud environment.

* Check [status.claude.com](https://status.claude.com) for cloud session incidents
* Retry after a minute, as capacity is provisioned on demand
* Confirm your repository is reachable. Private repositories require either the GitHub App installed with access to that repository, or a `gh` token synced via `/web-setup`. See [GitHub authentication options](#github-authentication-options).

### 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 has 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`, your admin has not enabled remote sessions for your plan

### Environment expired

Cloud sessions stop after a period of inactivity and the underlying environment is reclaimed. From a local terminal, this surfaces as `Could not resume session ... its environment has expired. Creating a fresh session instead.` On the web, the session is marked expired in the session list.

Reopen the session from [claude.ai/code](https://claude.ai/code) to provision a fresh environment with your conversation history restored.

## Limitations

Before relying on cloud sessions for a workflow, account for these constraints:

* **Rate limits**: Claude Code on the web shares rate limits with all other Claude and Claude Code usage within your account. Running multiple tasks in parallel consumes more rate limits proportionately. There is no separate compute charge for the cloud VM.
* **Repository authentication**: you can only move sessions from web to local when you are authenticated to the same account
* **Platform restrictions**: repository cloning and pull request creation require GitHub. Self-hosted [GitHub Enterprise Server](../03-IDE-Integrations/github-enterprise-server.md) instances are supported for Team and Enterprise plans. GitLab, Bitbucket, and other non-GitHub repositories can be sent to cloud sessions as a [local bundle](#send-local-repositories-without-github), but the session can't push results back to the remote

## Related resources

* [Ultraplan](ultraplan-14dfb476fe.md): draft a plan in a cloud session and review it in your browser
* [Ultrareview](ultrareview-78bb971406.md): run a deep multi-agent code review in a cloud sandbox
* [Routines](routines-3111c7bd3a.md): automate work on a schedule, via API call, or in response to GitHub events
* [Hooks configuration](../07-Hooks/hooks-9168ed62a4.md): run scripts at session lifecycle events
* [Settings reference](claude-code-settings-claude-code-docs-d4420b4b52.md): all configuration options
* [Security](../22-Safety-Policy/security-claude-code-docs-7538e94c51.md): isolation guarantees and data handling
* [Data usage](../22-Safety-Policy/data-usage-claude-code-docs-06b2864aaa.md): what Anthropic retains from cloud sessions


---
## claude-code-on-the-web-c576e75f98.md

# Claude Code on the web

March 16, 2026


Claude Code on the web runs Claude Code tasks remotely, working with code from your GitHub repositories. This article explains how it works, when to use it instead of running Claude Code in your terminal or IDE, and what workflows it enables.

## What Claude Code on the web provides

Claude Code on the web lets you delegate tasks to Claude that run without your active supervision. In your browser, you select a GitHub repository, describe what you want done, and Claude works on the task in a remote environment. 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.

Claude Code for web enables asynchronous development workflows. With Claude Code 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. Claude Code on the web 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 task, Claude Code on the web 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 Claude Code on the web vs. terminal

Claude Code on the web is a new way of working with Claude Code. Some tasks are well-suited for asynchronous execution on the web, while others will continue to be best run with Claude Code via your terminal or IDE.

### Use Claude Code on the web 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, the web interface 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, Claude Code on the web 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 tasks on the web and review the results later. This lets you batch similar work or delegate tasks during times when you're focused on something else.

### Use Claude Code in your terminal/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 on the web 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 for the web 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 on the web 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


---
## claude-code-on-the-web.md

> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code on the web

> Run Claude Code tasks asynchronously on secure cloud infrastructure

<Note>
  Claude Code on the web is currently in research preview.
</Note>

## What is Claude Code on the web?

Claude Code on the web lets developers kick off Claude Code from the Claude app. This is perfect for:

* **Answering questions**: Ask about code architecture and how features are implemented
* **Bug fixes and routine tasks**: Well-defined tasks that don't require frequent steering
* **Parallel work**: Tackle multiple bug fixes in parallel
* **Repositories not on your local machine**: Work on code you don't have checked out locally
* **Backend changes**: Where Claude Code can write tests and then write code to pass those tests

Claude Code is also available on the Claude iOS app for kicking off tasks on the go and monitoring work in progress.

You can move between local and remote development: [send tasks from your terminal to run on the web](#from-terminal-to-web) with the `&` prefix, or [teleport web sessions back to your terminal](#from-web-to-terminal) to continue locally.

## Who can use Claude Code on the web?

Claude Code on the web is available in research preview to:

* **Pro users**
* **Max users**
* **Team premium seat users**
* **Enterprise premium seat users**

## Getting started

1. Visit [claude.ai/code](https://claude.ai/code)
2. Connect your GitHub account
3. Install the Claude GitHub app in your repositories
4. Select your default environment
5. Submit your coding task
6. Review changes in diff view, iterate with comments, then create a pull request

## How it works

When you start a task on Claude Code on the web:

1. **Repository cloning**: Your repository is cloned to an Anthropic-managed virtual machine
2. **Environment setup**: Claude prepares a secure cloud environment with your code
3. **Network configuration**: Internet access is configured based on your settings
4. **Task execution**: Claude analyzes code, makes changes, runs tests, and checks its work
5. **Completion**: You're notified when finished and can create a PR with the changes
6. **Results**: Changes are pushed to a branch, ready for pull request creation

## Review changes with diff view

Diff view lets you see exactly what Claude changed before creating a pull request. Instead of clicking "Create PR" to review changes in GitHub, view the diff directly in the app and iterate with Claude until the changes are ready.

When Claude makes changes to files, a diff stats indicator appears showing the number of lines added and removed (for example, `+12 -1`). Select this indicator to open the diff viewer, which displays a file list on the left and the changes for each file on the right.

From the diff view, you can:

* Review changes file by file
* Comment on specific changes to request modifications
* Continue iterating with Claude based on what you see

This lets you refine changes through multiple rounds of feedback without creating draft PRs or switching to GitHub.

## Moving tasks between web and terminal

You can start tasks on the web and continue them in your terminal, or send tasks from your terminal to run on the web. Web sessions persist even if you close your laptop, and you can monitor them from anywhere including the Claude iOS app.

<Note>
  Session handoff is one-way: you can pull web sessions into your terminal, but you can't push an existing terminal session to the web. The [`&` prefix](#from-terminal-to-web) creates a *new* web session with your current conversation context.
</Note>

### From terminal to web

Start a message with `&` inside Claude Code to send a task to run on the web:

```
& Fix the authentication bug in src/auth/login.ts
```

This creates a new web session on claude.ai with your current conversation context. The task runs in the cloud while you continue working locally. Use `/tasks` to check progress, or open the session on claude.ai or the Claude iOS app to interact directly. From there you can steer Claude, provide feedback, or answer questions just like any other conversation.

You can also start a web session directly from the command line:

```bash  theme={null}
claude --remote "Fix the authentication bug in src/auth/login.ts"
```

#### Tips for background tasks

**Plan locally, execute remotely**: For complex tasks, start Claude in plan mode to collaborate on the approach before sending work to the web:

```bash  theme={null}
claude --permission-mode plan
```

In plan mode, Claude can only read files and explore the codebase. Once you're satisfied with the plan, send it to the web for autonomous execution:

```
& Execute the migration plan we discussed
```

This pattern gives you control over the strategy while letting Claude execute autonomously in the cloud.

**Run tasks in parallel**: Each `&` command creates its own web session that runs independently. You can kick off multiple tasks and they'll all run simultaneously in separate sessions:

```
& Fix the flaky test in auth.spec.ts
& Update the API documentation
& Refactor the logger to use structured output
```

Monitor all sessions with `/tasks`. When a session completes, you can create a PR from the web interface or [teleport](#from-web-to-terminal) the session to your terminal to continue working.

### From web to terminal

There are several ways to pull a web session into your terminal:

* **Using `/teleport`**: From within Claude Code, run `/teleport` (or `/tp`) to see an interactive picker of your web sessions. If you have uncommitted changes, you'll be prompted to stash them first.
* **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.
* **From `/tasks`**: Run `/tasks` to see your background sessions, then press `t` to teleport into one
* **From the web interface**: Click "Open in CLI" to copy a command you can paste into your terminal

When you teleport a session, Claude verifies you're in the correct repository, fetches and checks out the branch from the remote session, and loads the full conversation history into your terminal.

#### Requirements for teleporting

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.                                          |
| Branch available   | The branch from the web 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 web session.                                       |

## Cloud environment

### Default image

We build and maintain a universal image with common toolchains and language ecosystems pre-installed. This image includes:

* Popular programming languages and runtimes
* Common build tools and package managers
* Testing frameworks and linters

#### Checking available tools

To see what's pre-installed in your environment, ask Claude Code to run:

```bash  theme={null}
check-tools
```

This command displays:

* Programming languages and their versions
* Available package managers
* Installed development tools

#### Language-specific setups

The universal image includes pre-configured environments for:

* **Python**: Python 3.x with pip, poetry, and common scientific libraries
* **Node.js**: Latest LTS versions with npm, yarn, pnpm, and bun
* **Ruby**: Versions 3.1.6, 3.2.6, 3.3.6 (default: 3.3.6) with gem, bundler, and rbenv for version management
* **PHP**: Version 8.4.14
* **Java**: OpenJDK with Maven and Gradle
* **Go**: Latest stable version with module support
* **Rust**: Rust toolchain with cargo
* **C++**: GCC and Clang compilers

#### Databases

The universal image includes the following databases:

* **PostgreSQL**: Version 16
* **Redis**: Version 7.0

### Environment configuration

When you start a session in Claude Code on the web, here's what happens under the hood:

1. **Environment preparation**: We clone your repository and run any configured Claude hooks for initialization. The repo will be cloned with the default branch on your GitHub repo. If you would like to check out a specific branch, you can specify that in the prompt.

2. **Network configuration**: We configure internet access for the agent. Internet access is limited by default, but you can configure the environment to have no internet or full internet access based on your needs.

3. **Claude Code execution**: Claude Code runs to complete your task, writing code, running tests, and checking its work. You can guide and steer Claude throughout the session via the web interface. Claude respects context you've defined in your `CLAUDE.md`.

4. **Outcome**: When Claude completes its work, it will push the branch to remote. You will be able to create a PR for the branch.

<Note>
  Claude operates entirely through the terminal and CLI tools available in the environment. It uses the pre-installed tools in the universal image and any additional tools you install through hooks or dependency management.
</Note>

**To add a new environment:** Select the current environment to open the environment selector, and then select "Add environment". This will open a dialog where you can specify the environment name, network access level, and any environment variables you want to set.

**To update an existing environment:** Select the current environment, to the right of the environment name, and select the settings button. This will open a dialog where you can update the environment name, network access, and environment variables.

**To select your default environment from the terminal:** If you have multiple environments configured, run `/remote-env` to choose which one to use when starting web sessions from your terminal with `&` or `--remote`. With a single environment, this command shows your current configuration.

<Note>
  Environment variables must be specified as key-value pairs, in [`.env` format](https://www.dotenv.org/). For example:

  ```
  API_KEY=your_api_key
  DEBUG=true
  ```
</Note>

### Dependency management

Configure automatic dependency installation using [SessionStart hooks](/en/hooks#sessionstart). This can be configured in your repository's `.claude/settings.json` file:

```json  theme={null}
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/scripts/install_pkgs.sh"
          }
        ]
      }
    ]
  }
}
```

Create the corresponding script at `scripts/install_pkgs.sh`:

```bash  theme={null}
#!/bin/bash
npm install
pip install -r requirements.txt
exit 0
```

Make it executable: `chmod +x scripts/install_pkgs.sh`

#### Local vs remote execution

By default, all hooks execute both locally and in remote (web) environments. To run a hook only in one environment, check the `CLAUDE_CODE_REMOTE` environment variable in your hook script.

```bash  theme={null}
#!/bin/bash

# Example: Only run in remote environments
if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then
  exit 0
fi

npm install
pip install -r requirements.txt
```

#### Persisting environment variables

SessionStart hooks can persist environment variables for subsequent bash commands by writing to the file specified in the `CLAUDE_ENV_FILE` environment variable. For details, see [SessionStart hooks](/en/hooks#sessionstart) in the hooks reference.

## Network access and security

### Network policy

#### GitHub proxy

For security, all GitHub operations go through a dedicated proxy service that transparently handles all git interactions. Inside the sandbox, the git client authenticates using a custom-built scoped credential. This proxy:

* Manages GitHub authentication securely - the git client uses a scoped credential inside the sandbox, which the proxy verifies and translates to your actual GitHub authentication token
* Restricts git push operations to the current working branch for safety
* Enables seamless cloning, fetching, and PR operations while maintaining security boundaries

#### Security proxy

Environments run behind an HTTP/HTTPS network proxy for security and abuse prevention purposes. All outbound internet traffic passes through this proxy, which provides:

* Protection against malicious requests
* Rate limiting and abuse prevention
* Content filtering for enhanced security

### Access levels

By default, network access is limited to [allowlisted domains](#default-allowed-domains).

You can configure custom network access, including disabling network access.

### Default allowed domains

When using "Limited" network access, the following domains are allowed by default:

#### Anthropic Services

* api.anthropic.com
* statsig.anthropic.com
* docs.claude.com
* code.claude.com
* claude.ai

#### 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
* 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
* 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

#### Package Managers - JavaScript/Node

* 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

#### Package Managers - Python

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

#### Package Managers - Ruby

* 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

#### Package Managers - Rust

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

#### Package Managers - Go

* proxy.golang.org
* sum.golang.org
* index.golang.org
* golang.org
* [www.golang.org](http://www.golang.org)
* goproxy.io
* pkg.go.dev

#### Package Managers - JVM

* maven.org
* repo.maven.org
* central.maven.org
* repo1.maven.org
* jcenter.bintray.com
* gradle.org
* [www.gradle.org](http://www.gradle.org)
* services.gradle.org
* plugins.gradle.org
* kotlin.org
* [www.kotlin.org](http://www.kotlin.org)
* spring.io
* repo.spring.io

#### Package Managers - Other Languages

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

#### Development Tools & 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)

#### Cloud Services & Monitoring

* statsig.com
* [www.statsig.com](http://www.statsig.com)
* api.statsig.com
* sentry.io
* \*.sentry.io
* http-intake.logs.datadoghq.com
* \*.datadoghq.com
* \*.datadoghq.eu

#### Content Delivery & Mirrors

* sourceforge.net
* \*.sourceforge.net
* packagecloud.io
* \*.packagecloud.io

#### Schema & 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

<Note>
  Domains marked with `*` indicate wildcard subdomain matching. For example, `*.gcr.io` allows access to any subdomain of `gcr.io`.
</Note>

### Security best practices for customized network access

1. **Principle of least privilege**: Only enable the minimum network access required
2. **Audit regularly**: Review allowed domains periodically
3. **Use HTTPS**: Always prefer HTTPS endpoints over HTTP

## Security and isolation

Claude Code on the web provides strong security guarantees:

* **Isolated virtual machines**: Each session runs in an isolated, Anthropic-managed VM
* **Network access controls**: Network access is limited by default, and can be disabled

<Note>
  When running with network access disabled, Claude Code is allowed to communicate with the Anthropic API which may still allow data to exit the isolated Claude Code VM.
</Note>

* **Credential protection**: Sensitive credentials (such as git credentials or signing keys) are never inside the sandbox with Claude Code. Authentication is handled through a secure proxy using scoped credentials
* **Secure analysis**: Code is analyzed and modified within isolated VMs before creating PRs

## Pricing and rate limits

Claude Code on the web shares rate limits with all other Claude and Claude Code usage within your account. Running multiple tasks in parallel will consume more rate limits proportionately.

## Limitations

* **Repository authentication**: You can only move sessions from web to local when you are authenticated to the same account
* **Platform restrictions**: Claude Code on the web only works with code hosted in GitHub. GitLab and other non-GitHub repositories cannot be used with cloud sessions

## Best practices

1. **Use Claude Code hooks**: Configure [SessionStart hooks](/en/hooks#sessionstart) to automate environment setup and dependency installation.
2. **Document requirements**: Clearly specify dependencies and commands in your `CLAUDE.md` file. If you have an `AGENTS.md` file, you can source it in your `CLAUDE.md` using `@AGENTS.md` to maintain a single source of truth.

## Related resources

* [Hooks configuration](../07-Hooks/hooks-reference-claude-code-docs.md)
* [Settings reference](claude-code-settings-claude-code-docs-d4420b4b52.md)
* [Security](security-claude-code-docs.md)
* [Data usage](../22-Safety-Policy/data-usage-claude-code-docs-06b2864aaa.md)


---
## claude-code-overview-claude-code-docs-c23f3e7cbb.md

# Claude Code overview


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.


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

Choose your environment to get started. Most surfaces require a [Claude subscription](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=overview_pricing) or [Anthropic Console](https://console.anthropic.com/) account. The Terminal CLI and VS Code also support [third-party providers](/docs/en/third-party-integrations).

- 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, use one of the following methods:

- Native Install (Recommended)

- Homebrew

- WinGet

**macOS, Linux, WSL:**

```python
curl -fsSL https://claude.ai/install.sh | bash
```

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

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. Your prompt shows `PS C:\` when you’re in PowerShell and `C:\` without the `PS` when you’re in CMD.**Native Windows setups require [Git for Windows](https://git-scm.com/downloads/win).** Install it first if you don’t have it. WSL setups do not need it.

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](/docs/en/setup#install-with-linux-package-managers) on Debian, Fedora, RHEL, and Alpine.Then start Claude Code in any project:

```python
cd your-project
claude
```

You’ll be prompted to log in on first use. That’s it! [Continue with the Quickstart →](/docs/en/quickstart)

See [advanced setup](/docs/en/setup) for installation options, manual updates, or uninstallation instructions. Visit [troubleshooting](/docs/en/troubleshooting) 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 →](/docs/en/vs-code#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 kick off 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)

After installing, launch Claude, sign in, and click the **Code** tab to start coding. A [paid subscription](https://claude.com/pricing?utm_source=claude_code&utm_medium=docs&utm_content=overview_desktop_pricing) is required.[Learn more about the desktop app →](/docs/en/desktop-quickstart)

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. Available on desktop browsers and the Claude iOS app.Start coding at [claude.ai/code](https://claude.ai/code).[Get started on the web →](/docs/en/web-quickstart)

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.[Get started with JetBrains →](/docs/en/jetbrains)


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](/docs/en/common-workflows) 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](/docs/en/github-actions) or [GitLab CI/CD](/docs/en/gitlab-ci-cd).

Connect your tools with MCP

The [Model Context Protocol (MCP)](/docs/en/mcp) 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.

Customize with instructions, skills, and hooks

[`CLAUDE.md`](/docs/en/memory) 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. Claude also builds [auto memory](/docs/en/memory#auto-memory) as it works, saving learnings like build commands and debugging insights across sessions without you writing anything.Create [custom commands](/docs/en/skills) to package repeatable workflows your team can share, like `/review-pr` or `/deploy-staging`.[Hooks](/docs/en/hooks) 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 agent teams and build custom agents

Spawn [multiple Claude Code agents](/docs/en/sub-agents) that work on different parts of a task simultaneously. A lead agent coordinates the work, assigns subtasks, and merges results.For fully custom workflows, the [Agent SDK](/docs/en/agent-sdk/overview) 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](/docs/en/cli-reference) 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.

- [Routines](/docs/en/routines) run on Anthropic-managed infrastructure, 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](/docs/en/desktop-scheduled-tasks) run on your machine, with direct access to your local files and tools
- [`/loop`](/docs/en/scheduled-tasks) repeats a prompt within a CLI session for quick polling

Work from anywhere

Sessions aren’t tied to a single surface. Move work between environments as your context changes:

- Step away from your desk and keep working from your phone or any browser with [Remote Control](/docs/en/remote-control)
- Message [Dispatch](/docs/en/desktop#sessions-from-dispatch) a task from your phone and open the Desktop session it creates
- Kick off a long-running task on the [web](/docs/en/claude-code-on-the-web) or [iOS app](https://apps.apple.com/app/claude-by-anthropic/id6473753684), then pull it into your terminal with `claude --teleport`
- Hand off a terminal session to the [Desktop app](/docs/en/desktop) with `/desktop` for visual diff review
- Route tasks from team chat: mention `@Claude` in [Slack](/docs/en/slack) with a bug report and get a pull request back


Use Claude Code everywhere

Each surface connects to the same underlying Claude Code engine, so your CLAUDE.md files, settings, and MCP servers work across all of them. Beyond the [Terminal](/docs/en/quickstart), [VS Code](/docs/en/vs-code), [JetBrains](/docs/en/jetbrains), [Desktop](/docs/en/desktop), and [Web](/docs/en/claude-code-on-the-web) environments above, Claude Code integrates with CI/CD, chat, and browser workflows:

| I want to… | Best option |
|----|----|
| Continue a local session from my phone or another device | [Remote Control](/docs/en/remote-control) |
| Push events from Telegram, Discord, iMessage, or my own webhooks into a session | [Channels](/docs/en/channels) |
| Start a task locally, continue on mobile | [Web](/docs/en/claude-code-on-the-web) or [Claude iOS app](https://apps.apple.com/app/claude-by-anthropic/id6473753684) |
| Run Claude on a recurring schedule | [Routines](/docs/en/routines) or [Desktop scheduled tasks](/docs/en/desktop-scheduled-tasks) |
| Automate PR reviews and issue triage | [GitHub Actions](/docs/en/github-actions) or [GitLab CI/CD](/docs/en/gitlab-ci-cd) |
| Get automatic code review on every PR | [GitHub Code Review](/docs/en/code-review) |
| Route bug reports from Slack to pull requests | [Slack](/docs/en/slack) |
| Debug live web applications | [Chrome](/docs/en/chrome) |
| Build custom agents for your own workflows | [Agent SDK](/docs/en/agent-sdk/overview) |


Next steps

Once you’ve installed Claude Code, these guides help you go deeper.

- [Quickstart](/docs/en/quickstart): walk through your first real task, from exploring a codebase to committing a fix
- [Store instructions and memories](/docs/en/memory): give Claude persistent instructions with CLAUDE.md files and auto memory
- [Common workflows](/docs/en/common-workflows) and [best practices](/docs/en/best-practices): patterns for getting the most out of Claude Code
- [Settings](/docs/en/settings): customize Claude Code for your workflow
- [Troubleshooting](/docs/en/troubleshooting): solutions for common issues
- [code.claude.com](https://code.claude.com/): demos, pricing, and product details


---
## claude-code-overview-claude-code-docs.md

# Claude Code overview


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.


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

Choose your environment to get started. Most surfaces require a [Claude subscription](https://claude.com/pricing) or [Anthropic Console](https://console.anthropic.com/) account. The Terminal CLI and VS Code also support [third-party providers](/docs/en/third-party-integrations).

- 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, use one of the following methods:

- Native Install (Recommended)

- Homebrew

- WinGet

**macOS, Linux, WSL:**

Report incorrect code

Copy


``` shiki
curl -fsSL https://claude.ai/install.sh | bash
```

**Windows PowerShell:**

Report incorrect code

Copy


``` shiki
irm https://claude.ai/install.ps1 | iex
```

**Windows CMD:**

Report incorrect code

Copy


``` shiki
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
```

**Windows requires [Git for Windows](https://git-scm.com/downloads/win).** Install it first if you don’t have it.

Native installations automatically update in the background to keep you on the latest version.

Report incorrect code

Copy


``` shiki
brew install --cask claude-code
```

Homebrew installations do not auto-update. Run `brew upgrade claude-code` periodically to get the latest features and security fixes.

Report incorrect code

Copy


``` shiki
winget install Anthropic.ClaudeCode
```

WinGet installations do not auto-update. Run `winget upgrade Anthropic.ClaudeCode` periodically to get the latest features and security fixes.

Then start Claude Code in any project:

Report incorrect code

Copy


``` shiki
cd your-project
claude
```

You’ll be prompted to log in on first use. That’s it! [Continue with the Quickstart →](/docs/en/quickstart)

See [advanced setup](/docs/en/setup) for installation options, manual updates, or uninstallation instructions. Visit [troubleshooting](/docs/en/troubleshooting) 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 →](/docs/en/vs-code#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 kick off 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/exe/latest/redirect?utm_source=claude_code&utm_medium=docs) (x64)
- [Windows ARM64](https://claude.ai/api/desktop/win32/arm64/exe/latest/redirect?utm_source=claude_code&utm_medium=docs) (remote sessions only)

After installing, launch Claude, sign in, and click the **Code** tab to start coding. A [paid subscription](https://claude.com/pricing) is required.[Learn more about the desktop app →](/docs/en/desktop-quickstart)

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. Available on desktop browsers and the Claude iOS app.Start coding at [claude.ai/code](https://claude.ai/code).[Get started on the web →](/docs/en/claude-code-on-the-web#getting-started)

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.[Get started with JetBrains →](/docs/en/jetbrains)

## 

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.

Report incorrect code

Copy


``` shiki
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](/docs/en/common-workflows) 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.

Report incorrect code

Copy


``` shiki
claude "commit my changes with a descriptive message"
```

In CI, you can automate code review and issue triage with [GitHub Actions](/docs/en/github-actions) or [GitLab CI/CD](/docs/en/gitlab-ci-cd).

Connect your tools with MCP

The [Model Context Protocol (MCP)](/docs/en/mcp) 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.

Customize with instructions, skills, and hooks

[`CLAUDE.md`](/docs/en/memory) 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. Claude also builds [auto memory](/docs/en/memory#auto-memory) as it works, saving learnings like build commands and debugging insights across sessions without you writing anything.Create [custom commands](/docs/en/skills) to package repeatable workflows your team can share, like `/review-pr` or `/deploy-staging`.[Hooks](/docs/en/hooks) 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 agent teams and build custom agents

Spawn [multiple Claude Code agents](/docs/en/sub-agents) that work on different parts of a task simultaneously. A lead agent coordinates the work, assigns subtasks, and merges results.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:

Report incorrect code

Copy


``` shiki
# Monitor logs and get alerted
tail -f 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](/docs/en/cli-reference) for the full set of commands and flags.

Work from anywhere

Sessions aren’t tied to a single surface. Move work between environments as your context changes:

- Step away from your desk and keep working from your phone or any browser with [Remote Control](/docs/en/remote-control)
- Kick off a long-running task on the [web](/docs/en/claude-code-on-the-web) or [iOS app](https://apps.apple.com/app/claude-by-anthropic/id6473753684), then pull it into your terminal with `/teleport`
- Hand off a terminal session to the [Desktop app](/docs/en/desktop) with `/desktop` for visual diff review
- Route tasks from team chat: mention `@Claude` in [Slack](/docs/en/slack) with a bug report and get a pull request back

## 

Use Claude Code everywhere

Each surface connects to the same underlying Claude Code engine, so your CLAUDE.md files, settings, and MCP servers work across all of them. Beyond the [Terminal](/docs/en/quickstart), [VS Code](/docs/en/vs-code), [JetBrains](/docs/en/jetbrains), [Desktop](/docs/en/desktop), and [Web](/docs/en/claude-code-on-the-web) environments above, Claude Code integrates with CI/CD, chat, and browser workflows:

| I want to… | Best option |
|----|----|
| Continue a local session from my phone or another device | [Remote Control](/docs/en/remote-control) |
| Start a task locally, continue on mobile | [Web](/docs/en/claude-code-on-the-web) or [Claude iOS app](https://apps.apple.com/app/claude-by-anthropic/id6473753684) |
| Automate PR reviews and issue triage | [GitHub Actions](/docs/en/github-actions) or [GitLab CI/CD](/docs/en/gitlab-ci-cd) |
| Route bug reports from Slack to pull requests | [Slack](/docs/en/slack) |
| Debug live web applications | [Chrome](/docs/en/chrome) |
| Build custom agents for your own workflows | [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md) |

## 

Next steps

Once you’ve installed Claude Code, these guides help you go deeper.

- [Quickstart](/docs/en/quickstart): walk through your first real task, from exploring a codebase to committing a fix
- [Store instructions and memories](/docs/en/memory): give Claude persistent instructions with CLAUDE.md files and auto memory
- [Common workflows](/docs/en/common-workflows) and [best practices](/docs/en/best-practices): patterns for getting the most out of Claude Code
- [Settings](/docs/en/settings): customize Claude Code for your workflow
- [Troubleshooting](/docs/en/troubleshooting): solutions for common issues
- [code.claude.com](https://code.claude.com/): demos, pricing, and product details


---
## claude-code-plan-mode.md

# Claude Code Plan Mode Configuration

Comprehensive guide to plan mode behavior, environment variables, and agent configuration.

## Two Plan Mode Variants

### V2 Phase-Based Mode (Default)
Structured 3-phase workflow with **mandatory parallel subagents**.

**Phases:**
1. **Phase 1: Initial Understanding** - Parallel exploration with Explore agents
2. **Phase 2: Design** - Architecture planning with Plan agents
3. **Phase 3: Review** - Main agent asks clarifying questions

**Characteristics:**
- Always spawns subagents (minimum 1 per phase)
- Structured workflow
- Less interactive upfront
- Gather everything → design → review

### Interview/Iterative Mode
Conversational plan mode with **optional subagents**.

**Workflow:**
- Iterative loop: Explore code → Update plan file → Ask user → Repeat
- Subagents are available but not mandatory
- More interactive and conversational
- Pair-planning approach

**Enable with:**
```bash
export CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE=true
```

---

## Environment Variables

### CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE

**Purpose:** Switch between V2 phase-based mode and interview mode.

**Accepted Values:**

Truthy (enable interview mode):
- `1`
- `true`
- `yes`
- `on`

Falsy (disable, use V2 phase-based):
- `0`
- `false`
- `no`
- `off`

**Notes:**
- Case-insensitive
- Values are trimmed
- Falls back to tengu flag `tengu_plan_mode_interview_phase` if unset (default: false)

**Implementation:**
```javascript
function tH(H) {  // isTruthy
  if (!H) return false;
  if (typeof H === "boolean") return H;
  let $ = H.toLowerCase().trim();
  return ["1", "true", "yes", "on"].includes($);
}

function CK(H) {  // isFalsy
  if (H === void 0) return false;
  if (typeof H === "boolean") return !H;
  if (!H) return false;
  let $ = H.toLowerCase().trim();
  return ["0", "false", "no", "off"].includes($);
}
```

---

### CLAUDE_CODE_PLAN_V2_AGENT_COUNT

**Purpose:** Number of Plan agents spawned in Phase 2.

**Validation:** Must be integer 1-10 (0 is rejected).

**Defaults:**
- `1` - standard models
- `3` - if model is "max" AND config is "default_claude_max_20x"
- `3` - if model is "enterprise" or "team"

**Implementation:**
```javascript
function a_D() {
  if (process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT) {
    let A = parseInt(process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT, 10);
    if (!isNaN(A) && A > 0 && A <= 10) return A;
  }
  let H = C9(), $ = Qb();
  if (H === "max" && $ === "default_claude_max_20x") return 3;
  if (H === "enterprise" || H === "team") return 3;
  return 1;
}
```

**Setting to 0:** Falls back to defaults (does NOT disable subagents).

---

### CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT

**Purpose:** Number of Explore agents spawned in Phase 1.

**Validation:** Must be integer 1-10 (0 is rejected).

**Default:** `3`

**Implementation:**
```javascript
function t_D() {
  if (process.env.CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT) {
    let H = parseInt(process.env.CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT, 10);
    if (!isNaN(H) && H > 0 && H <= 10) return H;
  }
  return 3;
}
```

**Setting to 0:** Falls back to 3 (does NOT disable subagents).

---

## Agent Configuration by Phase

### Phase 1: Initial Understanding

| Property | Value |
|----------|-------|
| **Agent Type** | `Explore` (zp.agentType) |
| **Default Count** | 3 |
| **Env Override** | `CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT` |
| **Valid Range** | 1-10 |
| **Model** | Haiku |
| **Mode** | READ-ONLY |

**Disallowed Tools:**
- Edit
- Write
- NotebookEdit
- EnterPlanMode
- ExitPlanMode

**Allowed Tools:**
- Read, Grep, Glob, Bash
- Agent (nested subagents)
- AskUserQuestion
- TaskCreate/TaskUpdate/TaskGet
- All MCP tools

**Template Variables:**
- `${A}` = explore agent count (3 default)
- `${zp.agentType}` = "Explore"

---

### Phase 2: Design

| Property | Value |
|----------|-------|
| **Agent Type** | `Plan` (UG$.agentType) |
| **Default Count** | 1 (or 3 for max/enterprise/team) |
| **Env Override** | `CLAUDE_CODE_PLAN_V2_AGENT_COUNT` |
| **Valid Range** | 1-10 |
| **Model** | Inherit from parent |
| **Mode** | READ-ONLY |

**Tool Restrictions:** Same as Phase 1 (references zp.tools)

**Template Variables:**
- `${$}` = plan agent count (1 or 3 default)
- `${UG$.agentType}` = "Plan"

---

### Phase 3: Review

| Property | Value |
|----------|-------|
| **Agent Type** | Main agent (no subagent) |
| **Tool Used** | `AskUserQuestion` (g7) |
| **Purpose** | Clarify remaining questions |

**Template Variable:**
- `${g7}` = AskUserQuestion tool

---

## Plan File Tools

Both modes use these tools for plan file management:

- `${Oj.name}` = Edit tool (for editing existing plan)
- `${fj.name}` = Write tool (for creating new plan)
- `${CY.name}` = Tool to request plan approval

---

## Interview Mode Details

When `CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE=true`:

### Workflow
```
Repeat until plan is complete:
1. Explore - Use Read/Grep/Glob/Bash or optionally Explore agents
2. Update plan file - Capture findings incrementally
3. Ask user - Use AskUserQuestion when needed
```

### Key Differences from V2
- **No mandatory subagents** - direct tool use preferred for simple queries
- **Explore agents optional** - "You can use the Explore agent type... though for straightforward queries direct tools are simpler"
- **Incremental planning** - update plan file as you go
- **More user interaction** - ask questions throughout, not just at the end

### Turn Endings
Each turn must end with either:
- `AskUserQuestion` - to gather more information
- Plan approval tool - when plan is ready

### Plan File Structure
- **Context section** - why the change is needed
- **Recommended approach** - single approach, not all alternatives
- **Critical files** - paths to files to be modified
- **Reusable code** - existing functions/utilities with paths
- **Verification** - how to test changes

---

## Token Optimization Configuration

**Minimal subagent spawning:**
```bash
export CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE=true  # Enable interview mode
export CLAUDE_CODE_PLAN_V2_AGENT_COUNT=1           # Minimum Plan agents if spawned
export CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT=1   # Minimum Explore agents if spawned
```

**Effect:**
- Interview mode makes subagents optional
- If subagents ARE spawned, only 1 will be created
- Most work happens in main agent context
- Significant token savings

---

## Function Reference

**Plan mode entry point:** `pe6()`
```javascript
// Selects between Interview and V2 modes
if (OP()) return Ue6(H);  // Interview mode
// else: V2 phase-based mode
```

**Mode selector:** `OP()`
```javascript
function OP() {
  let H = process.env.CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE;
  if (tH(H)) return true;   // Interview mode
  if (CK(H)) return false;  // V2 mode
  return IA("tengu_plan_mode_interview_phase", false);  // Default: V2
}
```

**Interview mode template:** `Ue6(H)`
- Returns iterative workflow instructions
- No mandatory subagent spawning
- Emphasis on incremental planning

**V2 mode template:** (default pe6 path)
- Returns 3-phase structured workflow
- Mandatory parallel subagent spawning
- Explore → Plan → Review phases

---

## Summary Table

| Aspect | Interview Mode | V2 Phase-Based |
|--------|---------------|----------------|
| **Trigger** | `CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE=true` | Default |
| **Subagents** | Optional | Mandatory |
| **Default Explore Count** | N/A (optional) | 3 |
| **Default Plan Count** | N/A (optional) | 1-3 |
| **Workflow** | Iterative loop | 3 structured phases |
| **User Interaction** | Throughout | Primarily at end |
| **Plan File Updates** | Incremental | After phase completion |
| **Token Usage** | Lower (fewer subagents) | Higher (parallel agents) |

---

## Validated in Binary Version

- **2.1.75** - All values confirmed via cli.js extraction
- Functions: `OP()`, `tH()`, `CK()`, `a_D()`, `t_D()`, `pe6()`, `Ue6()`


---
*Truncated: 241 more documents not shown (size limit)*
