35 ファイル変更 +539 -150
この更新の概要
管理者向けの導入設定ガイドが新設され、組織全体でのポリシー適用やプロバイダー選択の基準が明確化されました。SDKにおけるフック機能の拡充が行われ、新たに一括ツール実行後にトリガーされるPostToolBatchイベントが追加されています。また、一部のコマンド名が/costから/usageに変更されるなど、CLIインターフェースの使い勝手に関わる修正も含まれています。
@@ -0,0 +1,131 @@
---
title: admin-setup
source: https://code.claude.com/docs/en/admin-setup.md
---
# 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.
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](https://support.claude.com/en/articles/11845131-use-claude-code-with-your-team-or-enterprise-plan) for those steps.
| Decision | What you're choosing | Reference |
| :- | :- | :- |
| [Choose your API provider](#choose-your-api-provider) | Where Claude Code authenticates and how it's billed | [Authentication](/en/authentication), [Bedrock](/en/amazon-bedrock), [Vertex AI](/en/google-vertex-ai), [Foundry](/en/microsoft-foundry) |
| [Decide how settings reach devices](#decide-how-settings-reach-devices) | How managed policy reaches developer machines | [Server-managed settings](/en/server-managed-settings), [Settings files](/en/settings#settings-files) |
| [Decide what to enforce](#decide-what-to-enforce) | Which tools, commands, and integrations are allowed | [Permissions](/en/permissions), [Sandboxing](/en/sandboxing) |
| [Set up usage visibility](#set-up-usage-visibility) | How you track spend and adoption | [Analytics](/en/analytics), [Monitoring](/en/monitoring-usage), [Costs](/en/costs) |
| [Review data handling](#review-data-handling) | Data retention and compliance posture | [Data usage](/en/data-usage), [Security](/en/security) |
## 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](/en/third-party-integrations). Each provider's auth setup is in [Authentication](/en/authentication).
Proxy and firewall requirements in [Network configuration](/en/network-config) apply regardless of provider. If you want a single endpoint in front of multiple providers or centralized request logging, see [LLM gateway](/en/llm-gateway).
## 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` plistWindows: `HKLM\SOFTWARE\Policies\ClaudeCode` | High | macOS, Windows |
| File-based managed | macOS: `/Library/Application Support/ClaudeCode/managed-settings.json`Linux and WSL: `/etc/claude-code/managed-settings.json`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](/en/server-managed-settings) 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](/en/server-managed-settings) 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](/en/permissions) | 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](/en/sandboxing) | 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](/en/settings) | 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](/en/security).
## 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](/en/monitoring-usage) |
| Analytics dashboard | Per-user metrics, contribution tracking, leaderboard | Anthropic only | [Analytics](/en/analytics) |
| Cost tracking | Spend limits, rate limits, and usage attribution | Anthropic only | [Costs](/en/costs) |
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](/en/data-usage) |
| Zero Data Retention (ZDR) | Nothing stored after the request completes. Available on Claude for Enterprise | [Zero data retention](/en/zero-data-retention) |
| Security architecture | Network model, encryption, authentication, audit trail | [Security](/en/security) |
If you need request-level audit logging or to route traffic by data sensitivity, place an [LLM gateway](/en/llm-gateway) between developers and your provider. For regulatory requirements and certifications, see [Legal and compliance](/en/legal-and-compliance).
## 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](/en/quickstart): first-session walkthrough from install to working with a project
- [Common workflows](/en/common-workflows): 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](/en/server-managed-settings): deliver managed policy from the Claude admin console
- [Settings reference](/en/settings): every setting key, file location, and precedence rule
- [Amazon Bedrock](/en/amazon-bedrock), [Google Vertex AI](/en/google-vertex-ai), [Microsoft Foundry](/en/microsoft-foundry): provider-specific deployment
- [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide): SSO, SCIM, seat management, and rollout playbook
@@ -231,7 +231,7 @@ for await (const message of query({
| Hook type | Best for |
| :- | :- |
| **Filesystem** (`settings.json`) | Sharing hooks between CLI and SDK sessions. Supports `"command"` (shell scripts), `"http"` (POST to an endpoint), `"prompt"` (LLM evaluates a prompt), and `"agent"` (spawns a verifier agent). These fire in the main agent and any subagents it spawns. |
| **Filesystem** (`settings.json`) | Sharing hooks between CLI and SDK sessions. Supports `"command"` (shell scripts), `"http"` (POST to an endpoint), `"mcp_tool"` (call a connected MCP server's tool), `"prompt"` (LLM evaluates a prompt), and `"agent"` (spawns a verifier agent). These fire in the main agent and any subagents it spawns. |
| **Programmatic** (callbacks in `query()`) | Application-specific logic; returning structured decisions; in-process integration. Scoped to the main session only. |
The TypeScript SDK supports additional hook events beyond Python, including `SessionStart`, `SessionEnd`, `TeammateIdle`, and `TaskCompleted`. See the [hooks guide](/en/agent-sdk/hooks) for the full event compatibility table.
@@ -133,6 +133,7 @@ The SDK provides hooks for different stages of agent execution. Some hooks are a
| `PreToolUse` | Yes | Yes | Tool call request (can block or modify) | Block dangerous shell commands |
| `PostToolUse` | Yes | Yes | Tool execution result | Log all file changes to audit trail |
| `PostToolUseFailure` | Yes | Yes | Tool execution failure | Handle or log tool errors |
| `PostToolBatch` | No | Yes | A full batch of tool calls resolves, once per batch before the next model call | Inject conventions once for the whole batch |
| `UserPromptSubmit` | Yes | Yes | User prompt submission | Inject additional context into prompts |
| `Stop` | Yes | Yes | Agent execution stop | Save session state before exit |
| `SubagentStart` | Yes | Yes | Subagent initialization | Track parallel task spawning |
@@ -1765,7 +1765,7 @@ HookEvent = Literal[
]
```
The TypeScript SDK supports additional hook events not yet available in Python: `SessionStart`, `SessionEnd`, `Setup`, `TeammateIdle`, `TaskCompleted`, `ConfigChange`, `WorktreeCreate`, and `WorktreeRemove`.
The TypeScript SDK supports additional hook events not yet available in Python: `SessionStart`, `SessionEnd`, `Setup`, `TeammateIdle`, `TaskCompleted`, `ConfigChange`, `WorktreeCreate`, `WorktreeRemove`, and `PostToolBatch`.
### `HookCallback`
@@ -22,7 +22,7 @@ for await (const message of query({
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available slash commands:", message.slash_commands);
// Example output: ["/compact", "/context", "/cost"]
// Example output: ["/compact", "/context", "/usage"]
}
}
```
@@ -35,7 +35,7 @@ async def main():
async for message in query(prompt="Hello Claude", options=ClaudeAgentOptions(max_turns=1)):
if isinstance(message, SystemMessage) and message.subtype == "init":
print("Available slash commands:", message.data["slash_commands"])
# Example output: ["/compact", "/context", "/cost"]
# Example output: ["/compact", "/context", "/usage"]
asyncio.run(main())
```
@@ -185,7 +185,7 @@ for await (const message of query({
if (message.type === "system" && message.subtype === "init") {
// Will include both built-in and custom commands
console.log("Available commands:", message.slash_commands);
// Example: ["/compact", "/context", "/cost", "/refactor", "/security-check"]
// Example: ["/compact", "/context", "/usage", "/refactor", "/security-check"]
}
}
```
@@ -209,7 +209,7 @@ async def main():
if isinstance(message, SystemMessage) and message.subtype == "init":
# Will include both built-in and custom commands
print("Available commands:", message.data["slash_commands"])
# Example: ["/compact", "/context", "/cost", "/refactor", "/security-check"]
# Example: ["/compact", "/context", "/usage", "/refactor", "/security-check"]
asyncio.run(main())
```
@@ -1017,6 +1017,7 @@ type HookEvent =
| "PreToolUse"
| "PostToolUse"
| "PostToolUseFailure"
| "PostToolBatch"
| "Notification"
| "UserPromptSubmit"
| "SessionStart"
@@ -1067,6 +1068,7 @@ type HookInput =
| PreToolUseHookInput
| PostToolUseHookInput
| PostToolUseFailureHookInput
| PostToolBatchHookInput
| NotificationHookInput
| UserPromptSubmitHookInput
| SessionStartHookInput
@@ -1135,6 +1137,24 @@ type PostToolUseFailureHookInput = BaseHookInput & {
};
```
#### `PostToolBatchHookInput`
Fires once after every tool call in a batch has resolved, before the next model request. `tool_response` carries the serialized `tool_result` content the model sees; the shape differs from `PostToolUseHookInput`'s structured `Output` object.
```typescript
type PostToolBatchHookInput = BaseHookInput & {
hook_event_name: "PostToolBatch";
tool_calls: PostToolBatchToolCall[];
};
type PostToolBatchToolCall = {
tool_name: string;
tool_input: unknown;
tool_use_id: string;
tool_response?: unknown;
};
```
#### `NotificationHookInput`
```typescript
@@ -1354,6 +1374,10 @@ type SyncHookJSONOutput = {
hookEventName: "PostToolUseFailure";
additionalContext?: string;
}
| {
hookEventName: "PostToolBatch";
additionalContext?: string;
}
| {
hookEventName: "Notification";
additionalContext?: string;
@@ -1389,7 +1413,6 @@ type ToolInputSchemas =
| AskUserQuestionInput
| BashInput
| TaskOutputInput
| ConfigInput
| EnterWorktreeInput
| ExitPlanModeInput
| FileEditInput
@@ -1689,19 +1712,6 @@ type ReadMcpResourceInput = {
Reads a specific MCP resource from a server.
### Config
**Tool name:** `Config`
```typescript
type ConfigInput = {
setting: string;
value?: string | boolean | number;
};
```
Gets or sets a configuration value.
### EnterWorktree
**Tool name:** `EnterWorktree`
@@ -1728,7 +1738,6 @@ type ToolOutputSchemas =
| AgentOutput
| AskUserQuestionOutput
| BashOutput
| ConfigOutput
| EnterWorktreeOutput
| ExitPlanModeOutput
| FileEditOutput
@@ -2144,24 +2153,6 @@ type ReadMcpResourceOutput = {
Returns the contents of the requested MCP resource.
### Config
**Tool name:** `Config`
```typescript
type ConfigOutput = {
success: boolean;
operation?: "get" | "set";
setting?: string;
value?: unknown;
previousValue?: unknown;
newValue?: unknown;
error?: string;
};
```
Returns the result of a configuration get or set operation.
### EnterWorktree
**Tool name:** `EnterWorktree`
@@ -2741,7 +2732,7 @@ type SDKRateLimitEvent = {
### `SDKLocalCommandOutputMessage`
Output from a local slash command (for example, `/voice` or `/cost`). Displayed as assistant-style text in the transcript.
Output from a local slash command (for example, `/voice` or `/usage`). Displayed as assistant-style text in the transcript.
```typescript
type SDKLocalCommandOutputMessage = {
@@ -247,11 +247,7 @@ Each teammate has its own context window. When spawned, a teammate loads the sam
- **Automatic message delivery**: when teammates send messages, they're delivered automatically to recipients. The lead doesn't need to poll for updates.
- **Idle notifications**: when a teammate finishes and stops, they automatically notify the lead.
- **Shared task list**: all agents can see task status and claim available work.
**Teammate messaging:**
- **message**: send a message to one specific teammate
- **broadcast**: send to all teammates simultaneously. Use sparingly, as costs scale with team size.
- **Teammate messaging**: send a message to one specific teammate by name. To reach everyone, send one message per recipient.
The lead assigns every teammate a name when it spawns them, and any teammate can message any other by that name. To get predictable names you can reference in later prompts, tell the lead what to call each teammate in your spawn instruction.
@@ -44,12 +44,13 @@ The classifier is a second gate that runs after the [permissions system](/en/per
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.
Setting `environment` replaces the default environment list, which includes the entry that trusts the working repo and its remotes. Run `claude auto-mode defaults` to print the defaults, then include them alongside your own entries so you extend the list rather than narrow it.
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
{
"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",
@@ -74,6 +75,7 @@ A useful starting template: fill in the bracketed fields and remove any lines th
{
"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}",
@@ -102,34 +104,36 @@ Inside the classifier, precedence works in three tiers:
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.
Setting any of `environment`, `allow`, or `soft_deny` replaces the entire default list for that section. If you set `soft_deny` with a single entry, every built-in block rule is discarded: force push, data exfiltration, `curl | bash`, production deploys, and all other default block rules become allowed. To customize safely, run `claude auto-mode defaults` to print the built-in rules, copy them into your settings file, then review each rule against your own pipeline and risk tolerance. Only remove rules for risks your infrastructure already mitigates.
To loosen: remove rules from `soft_deny` when the defaults block something your pipeline already guards against with PR review, CI, or staging environments, or 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, or remove from `allow` to hold a default exception to the block rules. In all cases, run `claude auto-mode defaults` to get the full default lists, then copy and edit: never start from an empty list.
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
{
"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",
"...copy full default soft_deny list here first, then add your rules..."
"Never modify files under infra/terraform/prod/: production infrastructure changes go through the review workflow"
]
}
}
```
Each section replaces only its own default, so setting `environment` alone leaves the default `allow` and `soft_deny` lists intact.
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.
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
Because setting any of the three arrays replaces its defaults, start any customization by copying the full default lists. Three CLI subcommands help you inspect and validate.
Three CLI subcommands help you inspect and validate your configuration.
Print the built-in `environment`, `allow`, and `soft_deny` rules as JSON:
@@ -149,7 +153,7 @@ Get AI feedback on your custom `allow` and `soft_deny` rules:
claude auto-mode critique
```
Save the output of `claude auto-mode defaults` to a file, edit the lists to match your policy, and paste the result into your settings file. After saving, run `claude auto-mode config` to confirm the effective rules are what you expect. 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.
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
@@ -75,6 +75,7 @@ Click a filename to open that node in the explorer above.
| [`~/.claude.json`](#ce-claude-json) | Global only | | App state, OAuth, UI toggles, personal MCP servers | [Global config](/en/settings#global-config-settings) |
| [`projects/<project>/memory/`](#ce-global-projects) | Global only | | Auto memory: Claude's notes to itself across sessions | [Auto memory](/en/memory#auto-memory) |
| [`keybindings.json`](#ce-keybindings) | Global only | | Custom keyboard shortcuts | [Keybindings](/en/keybindings) |
| [`themes/*.json`](#ce-themes) | Global only | | Custom color themes | [Custom themes](/en/terminal-config#create-a-custom-theme) |
## Troubleshoot configuration
@@ -108,7 +109,7 @@ The following paths are not covered by automatic cleanup and persist indefinitel
| Path under `~/.claude/` | Contents |
| - | - |
| `history.jsonl` | Every prompt you've typed, with timestamp and project path. Used for up-arrow recall. |
| `stats-cache.json` | Aggregated token and cost counts shown by `/cost` |
| `stats-cache.json` | Aggregated token and cost counts shown by `/usage` |
| `todos/` | Legacy per-session task lists. No longer written by current versions; safe to delete. |
Other small cache and lock files appear depending on which features you use and are safe to delete.
@@ -130,7 +131,7 @@ You can delete any of the application-data paths above at any time. New sessions
| `~/.claude/projects/` | Resume, continue, and rewind for past sessions |
| `~/.claude/history.jsonl` | Up-arrow prompt recall |
| `~/.claude/file-history/` | Checkpoint restore for past sessions |
| `~/.claude/stats-cache.json` | Historical totals shown by `/cost` |
| `~/.claude/stats-cache.json` | Historical totals shown by `/usage` |
| `~/.claude/debug/`, `~/.claude/plans/`, `~/.claude/paste-cache/`, `~/.claude/image-cache/`, `~/.claude/session-env/`, `~/.claude/tasks/`, `~/.claude/shell-snapshots/`, `~/.claude/backups/` | Nothing user-facing |
| `~/.claude/todos/` | Nothing. Legacy directory not written by current versions. |
@@ -21,6 +21,7 @@ You can start sessions, pipe content, resume conversations, and manage updates w
| `claude -c -p "query"` | Continue via SDK | `claude -c -p "Check for type errors"` |
| `claude -r "<session>" "query"` | Resume session by ID or name | `claude -r "auth-refactor" "Finish this PR"` |
| `claude update` | Update to latest version | `claude update` |
| `claude install [version]` | Install or reinstall the native binary. Accepts a version like `2.1.118`, or `stable` or `latest`. See [Install a specific version](/en/setup#install-a-specific-version) | `claude install stable` |
| `claude auth login` | Sign in to your Anthropic account. Use `--email` to pre-fill your email address, `--sso` to force SSO authentication, and `--console` to sign in with Anthropic Console for API usage billing instead of a Claude subscription | `claude auth login --console` |
| `claude auth logout` | Log out from your Anthropic account | `claude auth logout` |
| `claude auth status` | Show authentication status as JSON. Use `--text` for human-readable output. Exits with code 0 if logged in, 1 if not | `claude auth status` |
@@ -50,7 +51,7 @@ Customize Claude Code's behavior with these command-line flags. `claude --help`
| `--betas` | Beta headers to include in API requests (API key users only) | `claude --betas interleaved-thinking` |
| `--channels` | (Research preview) MCP servers whose [channel](/en/channels) notifications Claude should listen for in this session. Space-separated list of `plugin:<name>@<marketplace>` entries. Requires Claude.ai authentication | `claude --channels plugin:my-notifier@my-marketplace` |
| `--chrome` | Enable [Chrome browser integration](/en/chrome) for web automation and testing | `claude --chrome` |
| `--continue`, `-c` | Load the most recent conversation in the current directory | `claude --continue` |
| `--continue`, `-c` | Load the most recent conversation in the current directory. Includes sessions that added this directory with `/add-dir` | `claude --continue` |
| `--dangerously-load-development-channels` | Enable [channels](/en/channels-reference#test-during-the-research-preview) that are not on the approved allowlist, for local development. Accepts `plugin:<name>@<marketplace>` and `server:<name>` entries. Prompts for confirmation | `claude --dangerously-load-development-channels server:webhook` |
| `--dangerously-skip-permissions` | Skip permission prompts. Equivalent to `--permission-mode bypassPermissions`. See [permission modes](/en/permission-modes#skip-all-checks-with-bypasspermissions-mode) for what this does and does not skip | `claude --dangerously-skip-permissions` |
| `--debug` | Enable debug mode with optional category filtering (for example, `"api,hooks"` or `"!statsig,!file"`) | `claude --debug "api,mcp"` |
@@ -87,7 +88,7 @@ Customize Claude Code's behavior with these command-line flags. `claude --help`
| `--remote-control`, `--rc` | Start an interactive session with [Remote Control](/en/remote-control#start-a-remote-control-session) enabled so you can also control it from claude.ai or the Claude app. Optionally pass a name for the session | `claude --remote-control "My Project"` |
| `--remote-control-session-name-prefix <prefix>` | Prefix for auto-generated [Remote Control](/en/remote-control) session names when no explicit name is set. Defaults to your machine's hostname, producing names like `myhost-graceful-unicorn`. Set `CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX` for the same effect | `claude remote-control --remote-control-session-name-prefix dev-box` |
| `--replay-user-messages` | Re-emit user messages from stdin back on stdout for acknowledgment. Requires `--input-format stream-json` and `--output-format stream-json` | `claude -p --input-format stream-json --output-format stream-json --replay-user-messages` |
| `--resume`, `-r` | Resume a specific session by ID or name, or show an interactive picker to choose a session | `claude --resume auth-refactor` |
| `--resume`, `-r` | Resume a specific session by ID or name, or show an interactive picker to choose a session. Includes sessions that added this directory with `/add-dir` | `claude --resume auth-refactor` |
| `--session-id` | Use a specific session ID for the conversation (must be a valid UUID) | `claude --session-id "550e8400-e29b-41d4-a716-446655440000"` |
| `--setting-sources` | Comma-separated list of setting sources to load (`user`, `project`, `local`) | `claude --setting-sources user,project` |
| `--settings` | Path to a settings JSON file or a JSON string to load additional settings from | `claude --settings ./settings.json` |
@@ -19,7 +19,7 @@ In the table below, `<arg>` indicates a required argument and `[arg]` indicates
| Command | Purpose |
| :- | :- |
| `/add-dir <path>` | Add a working directory for file access during the current session. Most `.claude/` configuration is [not discovered](/en/permissions#additional-directories-grant-file-access-not-configuration) from the added directory |
| `/add-dir <path>` | Add a working directory for file access during the current session. Most `.claude/` configuration is [not discovered](/en/permissions#additional-directories-grant-file-access-not-configuration) from the added directory. You can later resume the session from the added directory with `--continue` or `--resume` |
| `/agents` | Manage [agent](/en/sub-agents) configurations |
| `/autofix-pr [prompt]` | Spawn a [Claude Code on the web](/en/claude-code-on-the-web#auto-fix-pull-requests) session that watches the current branch's PR and pushes fixes when CI fails or reviewers leave comments. Detects the open PR from your checked-out branch with `gh pr view`; to watch a different PR, check out its branch first. By default the remote session is told to fix every CI failure and review comment; pass a prompt to give it different instructions, for example `/autofix-pr only fix lint and type errors`. Requires the `gh` CLI and access to [Claude Code on the web](/en/claude-code-on-the-web#who-can-use-claude-code-on-the-web) |
| `/batch <instruction>` | **[Skill](/en/skills#bundled-skills).** Orchestrate large-scale changes across a codebase in parallel. Researches the codebase, decomposes the work into 5 to 30 independent units, and presents a plan. Once approved, spawns one background agent per unit in an isolated [git worktree](/en/common-workflows#run-parallel-claude-code-sessions-with-git-worktrees). Each agent implements its unit, runs tests, and opens a pull request. Requires a git repository. Example: `/batch migrate src/ from Solid to React` |
@@ -28,12 +28,12 @@ In the table below, `<arg>` indicates a required argument and `[arg]` indicates
| `/chrome` | Configure [Claude in Chrome](/en/chrome) settings |
| `/claude-api` | **[Skill](/en/skills#bundled-skills).** Load Claude API reference material for your project's language (Python, TypeScript, Java, Go, Ruby, C#, PHP, or cURL) and Managed Agents reference. Covers tool use, streaming, batches, structured outputs, and common pitfalls. Also activates automatically when your code imports `anthropic` or `@anthropic-ai/sdk` |
| `/clear` | Start a new conversation with empty context. The previous conversation stays available in `/resume`. To free up context while continuing the same conversation, use `/compact` instead. 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 |
| `/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. When [Remote Control](/en/remote-control) is connected, the color syncs to claude.ai/code |
| `/compact [instructions]` | Free up context by summarizing the conversation so far. Optionally pass focus instructions for the summary. See [how compaction handles rules, skills, and memory files](/en/context-window#what-survives-compaction) |
| `/config` | Open the [Settings](/en/settings) interface to adjust theme, model, [output style](/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 [N]` | Copy the last assistant response to clipboard. Pass a number `N` to copy the Nth-latest response: `/copy 2` copies the second-to-last. When code blocks are present, shows an interactive picker to select individual blocks or the full response. Press `w` in the picker to write the selection to a file instead of the clipboard, which is useful over SSH |
| `/cost` | Show token usage statistics. See [cost tracking guide](/en/costs#using-the-cost-command) for subscription-specific details |
| `/cost` | Alias for `/usage` |
| `/debug [description]` | **[Skill](/en/skills#bundled-skills).** Enable debug logging for the current session and troubleshoot issues by reading the session debug log. Debug logging is off by default unless you started with `claude --debug`, so running `/debug` mid-session starts capturing logs from that point forward. Optionally describe the issue to focus the analysis |
| `/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 |
@@ -85,7 +85,7 @@ In the table below, `<arg>` indicates a required argument and `[arg]` indicates
| `/setup-vertex` | Configure [Google Vertex AI](/en/google-vertex-ai) authentication, project, region, and model pins through an interactive wizard. Only visible when `CLAUDE_CODE_USE_VERTEX=1` is set. First-time Vertex AI users can also access this wizard from the login screen |
| `/simplify [focus]` | **[Skill](/en/skills#bundled-skills).** Review your recently changed files for code reuse, quality, and efficiency issues, then fix them. Spawns three review agents in parallel, aggregates their findings, and applies fixes. Pass text to focus on specific concerns: `/simplify focus on memory efficiency` |
| `/skills` | List available [skills](/en/skills). Press `t` to sort by token count |
| `/stats` | Visualize daily usage, session history, streaks, and model preferences |
| `/stats` | Alias for `/usage`. Opens on the Stats tab |
| `/status` | Open the Settings interface (Status tab) showing version, model, account, and connectivity. Works while Claude is responding, without waiting for the current response to finish |
| `/statusline` | Configure Claude Code's [status line](/en/statusline). Describe what you want, or run without arguments to auto-configure from your shell prompt |
| `/stickers` | Order Claude Code stickers |
@@ -93,12 +93,12 @@ In the table below, `<arg>` indicates a required argument and `[arg]` indicates
| `/team-onboarding` | Generate a team onboarding guide from your Claude Code usage history. Claude analyzes your sessions, commands, and MCP server usage from the past 30 days and produces a markdown guide a teammate can paste as a first message to get set up quickly |
| `/teleport` | Pull a [Claude Code on the web](/en/claude-code-on-the-web#from-web-to-terminal) session into this terminal: opens a picker, then fetches the branch and conversation. Also available as `/tp`. Requires a claude.ai subscription |
| `/terminal-setup` | Configure terminal keybindings for Shift+Enter and other shortcuts. Only visible in terminals that need it, like VS Code, Cursor, Windsurf, Alacritty, or Zed |
| `/theme` | Change the color theme. Includes an `auto` option that matches your terminal's light or dark background, light and dark variants, colorblind-accessible (daltonized) themes, and ANSI themes that use your terminal's color palette |
| `/theme` | Change the color theme. Includes an `auto` option that matches your terminal's light or dark background, light and dark variants, colorblind-accessible (daltonized) themes, ANSI themes that use your terminal's color palette, and any [custom themes](/en/terminal-config#create-a-custom-theme) from `~/.claude/themes/` or plugins. Select **New custom theme…** to create one |
| `/tui [default\|fullscreen]` | Set the terminal UI renderer and relaunch into it with your conversation intact. `fullscreen` enables the [flicker-free alt-screen renderer](/en/fullscreen). With no argument, prints the active renderer |
| `/ultraplan <prompt>` | Draft a plan in an [ultraplan](/en/ultraplan) session, review it in your browser, then execute remotely or send it back to your terminal |
| `/ultrareview [PR]` | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](/en/ultrareview). Includes 3 free runs on Pro and Max through May 5, 2026, then requires [extra usage](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) |
| `/upgrade` | Open the upgrade page to switch to a higher plan tier |
| `/usage` | Show plan usage limits and rate limit status |
| `/usage` | Show session cost, plan usage limits, and activity stats. See the [cost tracking guide](/en/costs#using-the-%2Fusage-command) for subscription-specific details. `/cost` and `/stats` are aliases |
| `/vim` | Removed in v2.1.92. To toggle between Vim and Normal editing modes, use `/config` → Editor mode |
| `/voice [hold\|tap\|off]` | Toggle [voice dictation](/en/voice-dictation), or enable it in a specific mode. Requires a Claude.ai account |
| `/web-setup` | Connect your GitHub account to [Claude Code on the web](/en/web-quickstart#connect-from-your-terminal) using your local `gh` CLI credentials. `/schedule` prompts for this automatically if GitHub isn't connected |
@@ -453,7 +453,7 @@ From inside an active session, use `/resume` to switch to a different conversati
When the selected session is old and large enough that re-reading it would consume a substantial share of your usage limits, `--resume`, `--continue`, and `/resume` offer to resume from a summary instead of loading the full transcript. This prompt is not available on Amazon Bedrock, Google Cloud Vertex AI, or Microsoft Foundry.
Sessions are stored per project directory. By default, the `/resume` picker shows interactive sessions from the current worktree, with keyboard shortcuts to widen the list to other worktrees or projects, search, preview, and rename. See [Use the session picker](#use-the-session-picker) below for the full shortcut reference.
Sessions are stored per project directory. By default, the `/resume` picker shows interactive sessions from the current worktree, with keyboard shortcuts to widen the list to other worktrees or projects, search, preview, and rename. Sessions started elsewhere that added the current directory with `/add-dir` are also included by default. See [Use the session picker](#use-the-session-picker) below for the full shortcut reference.
When you select a session from another worktree of the same repository, Claude Code resumes it directly without requiring you to switch directories first. Selecting a session from an unrelated project copies a `cd` and resume command to your clipboard instead.
@@ -15,11 +15,11 @@ This page covers how to [track your costs](#track-your-costs), [manage costs for
## Track your costs
### Using the `/cost` command
### Using the `/usage` command
The `/cost` command shows API token usage and is intended for API users. Claude Max and Pro subscribers have usage included in their subscription, so `/cost` data isn't relevant for billing purposes. Subscribers can use `/stats` to view usage patterns.
The Session block in `/usage` shows API token usage and is intended for API users. Claude Max and Pro subscribers have usage included in their subscription, so the session cost figure isn't relevant for billing purposes. Subscribers see plan usage bars and activity stats on the same screen.
The `/cost` command provides detailed token usage statistics for your current session. The dollar figure is an estimate computed locally from token counts and may differ from your actual bill. For authoritative billing, see the Usage page in the [Claude Console](https://platform.claude.com/usage).
The `/usage` command provides detailed token usage statistics for your current session. The dollar figure is an estimate computed locally from token counts and may differ from your actual bill. For authoritative billing, see the Usage page in the [Claude Console](https://platform.claude.com/usage).
```text
Total cost: $0.55
@@ -77,7 +77,7 @@ The following strategies help you keep context small and reduce per-message cost
### Manage context proactively
Use `/cost` to check your current token usage, or [configure your status line](/en/statusline#context-window-usage) to display it continuously.
Use `/usage` to check your current token usage, or [configure your status line](/en/statusline#context-window-usage) to display it continuously.
- **Clear between tasks**: Use `/clear` to start fresh when switching to unrelated work. Stale context wastes tokens on every subsequent message. Use `/rename` before clearing so you can easily find the session later, then `/resume` to return to it.
- **Add custom compaction instructions**: `/compact Focus on code samples and API usage` tells Claude what to preserve during summarization.
@@ -183,7 +183,7 @@ For longer or more complex work, these habits help avoid wasted tokens from goin
Claude Code uses tokens for some background functionality even when idle:
- **Conversation summarization**: Background jobs that summarize previous conversations for the `claude --resume` feature
- **Command processing**: Some commands like `/cost` may generate requests to check status
- **Command processing**: Some commands like `/usage` may generate requests to check status
These background processes consume a small amount of tokens (typically under $0.04 per session) even without active interaction.
@@ -60,9 +60,18 @@ For all first party users, you can learn more about what data is logged for [loc
The diagram below shows how Claude Code connects to external services during installation and normal operation. Solid lines indicate required connections, while dashed lines represent optional or user-initiated data flows.
Claude Code is installed from [NPM](https://www.npmjs.com/package/@anthropic-ai/claude-code). Claude Code runs locally. In order to interact with the LLM, Claude Code sends data over the network. This data includes all user prompts and model outputs. The data is encrypted in transit via TLS and is not encrypted at rest. Claude Code is compatible with most popular VPNs and LLM proxies.
Claude Code runs locally. To interact with the LLM, Claude Code sends data over the network. This data includes all user prompts and model outputs, encrypted in transit via TLS 1.2+. Claude Code is compatible with most popular VPNs and LLM proxies.
Claude Code is built on Anthropic's APIs. For details regarding our API's security controls, including our API logging procedures, please refer to compliance artifacts offered in the [Anthropic Trust Center](https://trust.anthropic.com).
Encryption at rest depends on your model provider:
| Provider | Encryption at rest |
| - | - |
| Anthropic API | Infrastructure-level disk encryption (AES-256). Enable [Zero Data Retention](/en/zero-data-retention) for no server-side persistence. |
| Amazon Bedrock | AES-256 with AWS-managed keys. Customer-managed keys available via AWS KMS. |
| Google Cloud Vertex AI | Google-managed encryption keys. CMEK available. |
| Microsoft Foundry | Requests route to Anthropic infrastructure with AES-256 disk encryption. |
Claude Code is built on Anthropic's APIs. For details on API security controls, including API logging procedures, see the compliance artifacts in the [Anthropic Trust Center](https://trust.anthropic.com).
### Cloud execution: Data flow and dependencies
@@ -81,7 +90,7 @@ Claude Code connects from users' machines to the Statsig service to log operatio
Claude Code connects from users' machines to Sentry for operational error logging. The data is encrypted in transit using TLS and at rest using 256-bit AES encryption. Read more in the [Sentry security documentation](https://sentry.io/security/). To opt out of error logging, set the `DISABLE_ERROR_REPORTING` environment variable.
When users run the `/feedback` command, a copy of their full conversation history including code is sent to Anthropic. The data is encrypted in transit and at rest. Optionally, a Github issue is created in our public repository. To opt out, set the `DISABLE_FEEDBACK_COMMAND` environment variable to `1`.
When users run the `/feedback` command, a copy of their full conversation history including code is sent to Anthropic. The data is encrypted in transit via TLS. Optionally, a GitHub issue is created in the public repository. To opt out, set the `DISABLE_FEEDBACK_COMMAND` environment variable to `1`.
## Default behaviors by API provider
@@ -11,7 +11,7 @@ By default, scheduled tasks start a new session automatically at a time and freq
## Compare scheduling options
Claude Code offers three ways to schedule recurring work:
Claude Code offers three ways to schedule recurring or one-off work:
| | [Cloud](/en/routines) | [Desktop](/en/desktop-scheduled-tasks) | [`/loop`](/en/scheduled-tasks) |
| :- | :- | :- | :- |
@@ -155,7 +155,7 @@ Claude Code supports the following environment variables to control its behavior
| `CLAUDE_ENV_FILE` | Path to a shell script whose contents Claude Code runs before each Bash command in the same shell process, so exports in the file are visible to the command. Use to persist virtualenv or conda activation across commands. Also populated dynamically by [SessionStart](/en/hooks#persist-environment-variables), [CwdChanged](/en/hooks#cwdchanged), and [FileChanged](/en/hooks#filechanged) hooks |
| `CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX` | Prefix for auto-generated [Remote Control](/en/remote-control) session names when no explicit name is provided. Defaults to your machine's hostname, producing names like `myhost-graceful-unicorn`. The `--remote-control-session-name-prefix` CLI flag sets the same value for a single invocation |
| `CLAUDE_STREAM_IDLE_TIMEOUT_MS` | Timeout in milliseconds before the streaming idle watchdog closes a stalled connection. For the byte-level watchdog on the Anthropic API: default and minimum `300000` (5 minutes); lower values are silently clamped to absorb extended thinking pauses and proxy buffering. For the event-level watchdog: default `90000` (90 seconds), no minimum. For third-party providers, requires `CLAUDE_ENABLE_STREAM_WATCHDOG=1` |
| `DISABLE_AUTOUPDATER` | Set to `1` to disable automatic updates |
| `DISABLE_AUTOUPDATER` | Set to `1` to disable automatic background updates. Manual `claude update` still works. Use `DISABLE_UPDATES` to block both |
| `DISABLE_AUTO_COMPACT` | Set to `1` to disable automatic compaction when approaching the context limit. The manual `/compact` command remains available. Use when you want explicit control over when compaction occurs |
| `DISABLE_COMPACT` | Set to `1` to disable all compaction: both automatic compaction and the manual `/compact` command |
| `DISABLE_COST_WARNINGS` | Set to `1` to disable cost warning messages |
@@ -173,6 +173,7 @@ Claude Code supports the following environment variables to control its behavior
| `DISABLE_PROMPT_CACHING_OPUS` | Set to `1` to disable prompt caching for Opus models |
| `DISABLE_PROMPT_CACHING_SONNET` | Set to `1` to disable prompt caching for Sonnet models |
| `DISABLE_TELEMETRY` | Set to `1` to opt out of Statsig telemetry (note that Statsig events do not include user data like code, file paths, or bash commands) |
| `DISABLE_UPDATES` | Set to `1` to block all updates including manual `claude update` and `claude install`. Stricter than `DISABLE_AUTOUPDATER`. Use when distributing Claude Code through your own channels and users should not self-update |
| `DISABLE_UPGRADE_COMMAND` | Set to `1` to hide the `/upgrade` command |
| `ENABLE_CLAUDEAI_MCP_SERVERS` | Set to `false` to disable [claude.ai MCP servers](/en/mcp#use-mcp-servers-from-claude-ai) in Claude Code. Enabled by default for logged-in users |
| `ENABLE_PROMPT_CACHING_1H` | Set to `1` to request a 1-hour prompt cache TTL instead of the default 5 minutes. Intended for API key, [Bedrock](/en/amazon-bedrock), [Vertex](/en/google-vertex-ai), and [Foundry](/en/microsoft-foundry) users. Subscription users receive 1-hour TTL automatically. 1-hour cache writes are billed at a higher rate |
@@ -22,7 +22,7 @@ Extensions plug into different parts of the agentic loop:
- **[MCP](/en/mcp)** connects Claude to external services and tools
- **[Subagents](/en/sub-agents)** run their own loops in isolated context, returning summaries
- **[Agent teams](/en/agent-teams)** coordinate multiple independent sessions with shared tasks and peer-to-peer messaging
- **[Hooks](/en/hooks)** run outside the loop entirely as deterministic scripts
- **[Hooks](/en/hooks-guide)** fire on lifecycle events and can run a script, HTTP request, prompt, or subagent
- **[Plugins](/en/plugins)** and **[marketplaces](/en/plugin-marketplaces)** package and distribute these features
[Skills](/en/skills) are the most flexible extension. A skill is a markdown file containing knowledge, workflows, or instructions. You can invoke skills with a command like `/deploy`, or Claude can load them automatically when relevant. Skills can run in your current conversation or in an isolated context via subagents.
@@ -38,7 +38,7 @@ Features range from always-on context that Claude sees every session, to on-dema
| **Subagent** | Isolated execution context that returns summarized results | Context isolation, parallel tasks, specialized workers | Research task that reads many files but returns only key findings |
| **[Agent teams](/en/agent-teams)** | Coordinate multiple independent Claude Code sessions | Parallel research, new feature development, debugging with competing hypotheses | Spawn reviewers to check security, performance, and tests simultaneously |
| **MCP** | Connect to external services | External data or actions | Query your database, post to Slack, control a browser |
| **Hook** | Deterministic script that runs on events | Predictable automation, no LLM involved | Run ESLint after every file edit |
| **Hook** | Script, HTTP request, prompt, or subagent triggered by events | Automation that must run on every matching event | Run ESLint after every file edit |
**[Plugins](/en/plugins)** are the packaging layer. A plugin bundles skills, hooks, subagents, and MCP servers into a single installable unit. Plugin skills are namespaced (like `/my-plugin:review`) so multiple plugins can coexist. Use plugins when you want to reuse the same setup across multiple repositories or distribute to others via a **[marketplace](/en/plugin-marketplaces)**.
@@ -145,6 +145,24 @@ These solve different problems and work well together:
Example: An MCP server connects Claude to your database. A skill teaches Claude your data model, common query patterns, and which tables to use for different tasks.
A hook fires on a lifecycle event; a skill is loaded into context for Claude to apply.
| Aspect | Hook | Skill |
| - | - | - |
| **Runs** | A shell command, HTTP request, LLM prompt, or subagent | Instructions Claude reads and follows |
| **Triggered by** | [Lifecycle events](/en/hooks#hook-events) such as `PostToolUse` or `SessionStart` | You typing `/<name>`, or Claude matching the description to your task |
| **Determinism** | Always fires on its event; the trigger is guaranteed | Claude interprets the instructions; outcome can vary |
| **Context cost** | Zero unless the hook returns output | Description loads each session; full content loads when used |
| **Best for** | Linting after edits, blocking unsafe commands, logging, notifications | Workflows that need reasoning, reference material, multi-step tasks |
**Use a hook** when the action must happen the same way every time and doesn't need Claude to think. For example: format on save, reject `rm -rf /`, post a Slack message when a session ends.
**Use a skill** when Claude should decide how to apply the steps, or when the content is knowledge rather than a script. For example: a `/release` checklist, your API style guide, a debugging playbook.
**Put guardrails in hooks.** An instruction like "never edit `.env`" in CLAUDE.md or a skill is a request, not a guarantee. A `PreToolUse` hook that blocks the edit is enforcement. If a rule must hold every time, make it a hook rather than a prompt instruction.
**Hook output lands in context.** A `PostToolUse` hook that runs your linter feeds results back as text Claude reads; a `/fix-lint` skill tells Claude how to resolve them.
### Understand how features layer
Features can be defined at multiple levels: user-wide, per-project, via plugins, or through managed policies. You can also nest CLAUDE.md files in subdirectories or place skills in specific packages of a monorepo. When the same feature exists at multiple levels, here's how they layer:
@@ -236,7 +254,7 @@ Use subagents for work that doesn't need your full conversation context. Their i
**When:** On trigger. Hooks fire at specific lifecycle events like tool execution, session boundaries, prompt submission, permission requests, and compaction. See [Hooks](/en/hooks) for the full list.
**What loads:** Nothing by default. Hooks run as external scripts.
**What loads:** Nothing by default. Hooks execute outside the main conversation.
**Context cost:** Zero, unless the hook returns output that gets added as messages to your conversation.
@@ -402,6 +402,7 @@ Hook events fire at specific lifecycle points in Claude Code. When an event fire
| `PermissionDenied` | When a tool call is denied by the auto mode classifier. Return `{retry: true}` to tell the model it may retry the denied tool call |
| `PostToolUse` | After a tool call succeeds |
| `PostToolUseFailure` | After a tool call fails |
| `PostToolBatch` | After a full batch of parallel tool calls resolves, before the next model call |
| `Notification` | When Claude Code sends a notification |
| `SubagentStart` | When a subagent is spawned |
| `SubagentStop` | When a subagent finishes |
@@ -424,9 +425,10 @@ Hook events fire at specific lifecycle points in Claude Code. When an event fire
When multiple hooks match, each one returns its own result. For decisions, Claude Code picks the most restrictive answer. A `PreToolUse` hook returning `deny` cancels the tool call no matter what the others return. One hook returning `ask` forces the permission prompt even if the rest return `allow`. Text from `additionalContext` is kept from every hook and passed to Claude together.
Each hook has a `type` that determines how it runs. Most hooks use `"type": "command"`, which runs a shell command. Three other types are available:
Each hook has a `type` that determines how it runs. Most hooks use `"type": "command"`, which runs a shell command. Four other types are available:
- `"type": "http"`: POST event data to a URL. See [HTTP hooks](#http-hooks).
- `"type": "mcp_tool"`: call a tool on an already-connected MCP server. See [MCP tool hooks](/en/hooks#mcp-tool-hook-fields).
- `"type": "prompt"`: single-turn LLM evaluation. See [Prompt-based hooks](#prompt-based-hooks).
- `"type": "agent"`: multi-turn verification with tool access. Agent hooks are experimental and may change. See [Agent-based hooks](#agent-based-hooks).
@@ -546,7 +548,7 @@ Each event type matches on a specific field:
| `ElicitationResult` | MCP server name | same values as `Elicitation` |
| `FileChanged` | literal filenames to watch (see [FileChanged](/en/hooks#filechanged)) | `.envrc\|.env` |
| `UserPromptExpansion` | command name | your skill or command names |
| `UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged` | no matcher support | always fires on every occurrence |
| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged` | no matcher support | always fires on every occurrence |
A few more examples showing matchers on different event types:
@@ -643,7 +645,7 @@ For example, to run a hook only when Claude uses `git` commands rather than all
The hook process only spawns when a subcommand of the Bash command matches `git *`, or when the command is too complex to parse into subcommands. For compound commands like `npm test && git push`, Claude Code evaluates each subcommand and fires the hook because `git push` matches. The `if` field accepts the same patterns as permission rules: `"Bash(git *)"`, `"Edit(*.ts)"`, and so on. To match multiple tool names, use separate handlers each with its own `if` value, or match at the `matcher` level where pipe alternation is supported.
`if` only works on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, and `PermissionRequest`. Adding it to any other event prevents the hook from running.
`if` only works on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, and `PermissionDenied`. Adding it to any other event prevents the hook from running.
### Configure hook location
@@ -27,6 +27,7 @@ The table below summarizes when each event fires. The [Hook events](#hook-events
| `PermissionDenied` | When a tool call is denied by the auto mode classifier. Return `{retry: true}` to tell the model it may retry the denied tool call |
| `PostToolUse` | After a tool call succeeds |
| `PostToolUseFailure` | After a tool call fails |
| `PostToolBatch` | After a full batch of parallel tool calls resolves, before the next model call |
| `Notification` | When Claude Code sends a notification |
| `SubagentStart` | When a subagent is spawned |
| `SubagentStop` | When a subagent finishes |
@@ -130,7 +131,7 @@ Hooks are defined in JSON settings files. The configuration has three levels of
See [How a hook resolves](#how-a-hook-resolves) above for a complete walkthrough with an annotated example.
This page uses specific terms for each level: **hook event** for the lifecycle point, **matcher group** for the filter, and **hook handler** for the shell command, HTTP endpoint, prompt, or agent that runs. "Hook" on its own refers to the general feature.
This page uses specific terms for each level: **hook event** for the lifecycle point, **matcher group** for the filter, and **hook handler** for the shell command, HTTP endpoint, MCP tool, prompt, or agent that runs. "Hook" on its own refers to the general feature.
### Hook locations
@@ -178,7 +179,7 @@ Each event type matches on a different field:
| `UserPromptExpansion` | command name | your skill or command names |
| `Elicitation` | MCP server name | your configured MCP server names |
| `ElicitationResult` | MCP server name | same values as `Elicitation` |
| `UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove` | no matcher support | always fires on every occurrence |
| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove` | no matcher support | always fires on every occurrence |
The matcher runs against a field from the [JSON input](#hook-input-and-output) that Claude Code sends to your hook on stdin. For tool events, that field is `tool_name`. Each [hook event](#hook-events) section lists the full set of matcher values and the input schema for that event.
@@ -202,7 +203,7 @@ This example runs a linting script only when Claude writes or edits a file:
}
```
`UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, and `CwdChanged` don't support matchers and always fire on every occurrence. If you add a `matcher` field to these events, it is silently ignored.
`UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, and `CwdChanged` don't support matchers and always fire on every occurrence. If you add a `matcher` field to these events, it is silently ignored.
For tool events, you can filter more narrowly by setting the [`if` field](#common-fields) on individual hook handlers. `if` uses [permission rule syntax](/en/permissions) to match against the tool name and arguments together, so `"Bash(git *)"` runs when any subcommand of the Bash input matches `git *` and `"Edit(*.ts)"` runs only for TypeScript files.
@@ -252,10 +253,11 @@ This example logs all memory server operations and validates write operations fr
### Hook handler fields
Each object in the inner `hooks` array is a hook handler: the shell command, HTTP endpoint, LLM prompt, or agent that runs when the matcher matches. There are four types:
Each object in the inner `hooks` array is a hook handler: the shell command, HTTP endpoint, MCP tool, LLM prompt, or agent that runs when the matcher matches. There are five types:
- **[Command hooks](#command-hook-fields)** (`type: "command"`): run a shell command. Your script receives the event's [JSON input](#hook-input-and-output) on stdin and communicates results back through exit codes and stdout.
- **[HTTP hooks](#http-hook-fields)** (`type: "http"`): send the event's JSON input as an HTTP POST request to a URL. The endpoint communicates results back through the response body using the same [JSON output format](#json-output) as command hooks.
- **[MCP tool hooks](#mcp-tool-hook-fields)** (`type: "mcp_tool"`): call a tool on an already-connected [MCP server](/en/mcp). The tool's text output is treated like command-hook stdout.
- **[Prompt hooks](#prompt-and-agent-hook-fields)** (`type: "prompt"`): send a prompt to a Claude model for single-turn evaluation. The model returns a yes/no decision as JSON. See [Prompt-based hooks](#prompt-based-hooks).
- **[Agent hooks](#prompt-and-agent-hook-fields)** (`type: "agent"`): spawn a subagent that can use tools like Read, Grep, and Glob to verify conditions before returning a decision. Agent hooks are experimental and may change. See [Agent-based hooks](#agent-based-hooks).
@@ -265,8 +267,8 @@ These fields apply to all hook types:
| Field | Required | Description |
| :- | :- | :- |
| `type` | yes | `"command"`, `"http"`, `"prompt"`, or `"agent"` |
| `if` | no | Permission rule syntax to filter when this hook runs, such as `"Bash(git *)"` or `"Edit(*.ts)"`. The hook only spawns if the tool call matches the pattern, or if a Bash command is too complex to parse. Only evaluated on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, and `PermissionRequest`. On other events, a hook with `if` set never runs. Uses the same syntax as [permission rules](/en/permissions) |
| `type` | yes | `"command"`, `"http"`, `"mcp_tool"`, `"prompt"`, or `"agent"` |
| `if` | no | Permission rule syntax to filter when this hook runs, such as `"Bash(git *)"` or `"Edit(*.ts)"`. The hook only spawns if the tool call matches the pattern, or if a Bash command is too complex to parse. Only evaluated on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, and `PermissionDenied`. On other events, a hook with `if` set never runs. Uses the same syntax as [permission rules](/en/permissions) |
| `timeout` | no | Seconds before canceling. Defaults: 600 for command, 30 for prompt, 60 for agent |
| `statusMessage` | no | Custom spinner message displayed while the hook runs |
| `once` | no | If `true`, runs once per session then is removed. Only honored for hooks declared in [skill frontmatter](#hooks-in-skills-and-agents); ignored in settings files and agent frontmatter |
@@ -323,6 +325,42 @@ This example sends `PreToolUse` events to a local validation service, authentica
}
```
#### MCP tool hook fields
In addition to the [common fields](#common-fields), MCP tool hooks accept these fields:
| Field | Required | Description |
| :- | :- | :- |
| `server` | yes | Name of a configured MCP server. The server must already be connected; the hook never triggers an OAuth or connection flow |
| `tool` | yes | Name of the tool to call on that server |
| `input` | no | Arguments passed to the tool. String values support `${path}` substitution from the hook's [JSON input](#hook-input-and-output), such as `"${tool_input.file_path}"` |
The tool's text content is treated like command-hook stdout: if it parses as valid [JSON output](#json-output) it is processed as a decision, otherwise it is shown as plain text. If the named server is not connected, or the tool returns `isError: true`, the hook produces a non-blocking error and execution continues.
MCP tool hooks are available on every hook event once Claude Code has connected to your MCP servers. `SessionStart` and `Setup` typically fire before servers finish connecting, so hooks on those events should expect the "not connected" error on first run.
This example calls the `security_scan` tool on the `my_server` MCP server after each `Write` or `Edit`, passing the edited file's path:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "mcp_tool",
"server": "my_server",
"tool": "security_scan",
"input": { "file_path": "${tool_input.file_path}" }
}
]
}
]
}
}
```
#### Prompt and agent hook fields
In addition to the [common fields](#common-fields), prompt and agent hooks accept these fields:
@@ -417,7 +455,7 @@ Agents use the same format in their YAML frontmatter.
Type `/hooks` in Claude Code to open a read-only browser for your configured hooks. The menu shows every hook event with a count of configured hooks, lets you drill into matchers, and shows the full details of each hook handler. Use it to verify configuration, check which settings file a hook came from, or inspect a hook's command, prompt, or URL.
The menu displays all four hook types: `command`, `prompt`, `agent`, and `http`. Each hook is labeled with a `[type]` prefix and a source indicating where it was defined:
The menu displays all five hook types: `command`, `prompt`, `agent`, `http`, and `mcp_tool`. Each hook is labeled with a `[type]` prefix and a source indicating where it was defined:
- `User`: from `~/.claude/settings.json`
- `Project`: from `.claude/settings.json`
@@ -525,6 +563,7 @@ Exit code 2 is the way a hook signals "stop, don't do this." The effect depends
| `StopFailure` | No | Output and exit code are ignored |
| `PostToolUse` | No | Shows stderr to Claude (tool already ran) |
| `PostToolUseFailure` | No | Shows stderr to Claude (tool already failed) |
| `PostToolBatch` | Yes | Stops the agentic loop before the next model call |
| `PermissionDenied` | No | Exit code and stderr are ignored (denial already occurred). Use JSON `hookSpecificOutput.retry: true` to tell the model it may retry |
| `Notification` | No | Shows stderr to user only |
| `SubagentStart` | No | Shows stderr to user only |
@@ -587,7 +626,7 @@ Not every event supports blocking or controlling behavior through JSON. The even
| Events | Decision pattern | Key fields |
| :- | :- | :- |
| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, Stop, SubagentStop, ConfigChange, PreCompact | Top-level `decision` | `decision: "block"`, `reason` |
| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact | Top-level `decision` | `decision: "block"`, `reason` |
| TeammateIdle, TaskCreated, TaskCompleted | Exit code or `continue: false` | Exit code 2 blocks the action with stderr feedback. JSON `{"continue": false, "stopReason": "..."}` also stops the teammate entirely, matching `Stop` hook behavior |
| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask/defer), `permissionDecisionReason` |
| PermissionRequest | `hookSpecificOutput` | `decision.behavior` (allow/deny) |
@@ -599,7 +638,7 @@ Not every event supports blocking or controlling behavior through JSON. The even
Here are examples of each pattern in action:
Used by `UserPromptSubmit`, `UserPromptExpansion`, `PostToolUse`, `PostToolUseFailure`, `Stop`, `SubagentStop`, `ConfigChange`, and `PreCompact`. The only value is `"block"`. To allow the action to proceed, omit `decision` from your JSON, or exit 0 without any JSON at all:
Used by `UserPromptSubmit`, `UserPromptExpansion`, `PostToolUse`, `PostToolUseFailure`, `PostToolBatch`, `Stop`, `SubagentStop`, `ConfigChange`, and `PreCompact`. The only value is `"block"`. To allow the action to proceed, omit `decision` from your JSON, or exit 0 without any JSON at all:
```json theme={null}
{
@@ -646,7 +685,7 @@ Each event corresponds to a point in Claude Code's lifecycle where hooks can run
Runs when Claude Code starts a new session or resumes an existing session. Useful for loading development context like existing issues or recent changes to your codebase, or setting up environment variables. For static context that does not require a script, use [CLAUDE.md](/en/memory) instead.
SessionStart runs on every session, so keep these hooks fast. Only `type: "command"` hooks are supported.
SessionStart runs on every session, so keep these hooks fast. Only `type: "command"` and `type: "mcp_tool"` hooks are supported.
The matcher value corresponds to how the session was initiated:
@@ -1240,6 +1279,65 @@ PostToolUseFailure hooks receive the same `tool_name` and `tool_input` fields as
}
```
### PostToolBatch
Runs once after every tool call in a batch has resolved, before Claude Code sends the next request to the model. `PostToolUse` fires once per tool, which means it fires concurrently when Claude makes parallel tool calls. `PostToolBatch` fires exactly once with the full batch, so it is the right place to inject context that depends on the set of tools that ran rather than on any single tool. There is no matcher for this event.
#### PostToolBatch input
In addition to the [common input fields](#common-input-fields), PostToolBatch hooks receive `tool_calls`, an array describing every tool call in the batch:
```json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PostToolBatch",
"tool_calls": [
{
"tool_name": "Read",
"tool_input": {"file_path": "/.../ledger/accounts.py"},
"tool_use_id": "toolu_01...",
"tool_response": " 1\tfrom __future__ import annotations\n 2\t..."
},
{
"tool_name": "Read",
"tool_input": {"file_path": "/.../ledger/transactions.py"},
"tool_use_id": "toolu_02...",
"tool_response": " 1\tfrom __future__ import annotations\n 2\t..."
}
]
}
```
`tool_response` contains the same content the model receives in the corresponding `tool_result` block. The value is a serialized string or content-block array, exactly as the tool emitted it. For `Read`, that means line-number-prefixed text rather than raw file contents. Responses can be large, so parse only the fields you need.
The `tool_response` shape differs from `PostToolUse`'s. `PostToolUse` passes the tool's structured `Output` object, such as `{filePath: "...", success: true}` for `Write`; `PostToolBatch` passes the serialized `tool_result` content the model sees.
#### PostToolBatch decision control
`PostToolBatch` hooks can inject context for Claude. In addition to the [JSON output fields](#json-output) available to all hooks, your hook script can return these event-specific fields:
| Field | Description |
| :- | :- |
| `additionalContext` | Context string injected once before the next model call |
```json
{
"hookSpecificOutput": {
"hookEventName": "PostToolBatch",
"additionalContext": "These files are part of the ledger module. Run pytest before marking the task complete."
}
}
```
Injected `additionalContext` is persisted to the session transcript. On `--continue` or `--resume`, the saved text is replayed from disk and the hook does not re-run for past turns. Prefer static context such as conventions or file-type guidance over dynamic values like timestamps or the current commit SHA, since those become stale on resume.
Frame the context as factual information rather than imperative system instructions. Text written as out-of-band system commands can trigger Claude's prompt-injection defenses, which surfaces the injection to the user instead of acting on it.
Returning `decision: "block"` or `continue: false` stops the agentic loop before the next model call.
### PermissionDenied
Runs when the [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) classifier denies a tool call. This hook only fires in auto mode: it does not run when you manually deny a permission dialog, when a `PreToolUse` hook blocks a call, or when a `deny` rule matches. Use it to log classifier denials, adjust configuration, or tell the model it may retry the tool call.
@@ -2071,11 +2169,12 @@ Exit code 2 blocks the response, changing the effective action to `decline`.
## Prompt-based hooks
In addition to command and HTTP hooks, Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action, and agent hooks (`type: "agent"`) that spawn an agentic verifier with tool access. Not all events support every hook type.
In addition to command, HTTP, and MCP tool hooks, Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action, and agent hooks (`type: "agent"`) that spawn an agentic verifier with tool access. Not all events support every hook type.
Events that support all four hook types (`command`, `http`, `prompt`, and `agent`):
Events that support all five hook types (`command`, `http`, `mcp_tool`, `prompt`, and `agent`):
- `PermissionRequest`
- `PostToolBatch`
- `PostToolUse`
- `PostToolUseFailure`
- `PreToolUse`
@@ -2086,7 +2185,7 @@ Events that support all four hook types (`command`, `http`, `prompt`, and `agent
- `UserPromptExpansion`
- `UserPromptSubmit`
Events that support `command` and `http` hooks but not `prompt` or `agent`:
Events that support `command`, `http`, and `mcp_tool` hooks but not `prompt` or `agent`:
- `ConfigChange`
- `CwdChanged`
@@ -2105,7 +2204,7 @@ Events that support `command` and `http` hooks but not `prompt` or `agent`:
- `WorktreeCreate`
- `WorktreeRemove`
`SessionStart` supports only `command` hooks.
`SessionStart` and `Setup` support `command` and `mcp_tool` hooks. They do not support `http`, `prompt`, or `agent` hooks.
### How prompt-based hooks work
@@ -112,13 +112,15 @@ Enable vim-style editing via `/config` → Editor mode.
| Command | Action | From mode |
| :- | :- | :- |
| `Esc` | Enter NORMAL mode | INSERT |
| `Esc` | Enter NORMAL mode | INSERT, VISUAL |
| `i` | Insert before cursor | NORMAL |
| `I` | Insert at beginning of line | NORMAL |
| `a` | Insert after cursor | NORMAL |
| `A` | Insert at end of line | NORMAL |
| `o` | Open line below | NORMAL |
| `O` | Open line above | NORMAL |
| `v` | Start character-wise visual selection | NORMAL |
| `V` | Start line-wise visual selection | NORMAL |
### Navigation (NORMAL mode)
@@ -177,6 +179,26 @@ Text objects work with operators like `d`, `c`, and `y`:
| `i[`/`a[` | Inner/around brackets |
| `i{`/`a{` | Inner/around braces |
### Visual mode
Press `v` for character-wise selection or `V` for line-wise selection. Motions extend the selection, and operators act on it directly.
| Command | Action |
| :- | :- |
| `d`/`x` | Delete selection |
| `y` | Yank selection |
| `c`/`s` | Change selection |
| `p` | Replace selection with register contents |
| `r{char}` | Replace every selected character with `{char}` |
| `~`/`u`/`U` | Toggle, lowercase, or uppercase selection |
| `>`/`<` | Indent or dedent selected lines |
| `J` | Join selected lines |
| `o` | Swap cursor and anchor |
| `iw`/`aw`/`i"`/… | Select a text object |
| `v`/`V` | Toggle between character-wise and line-wise, or exit |
Block-wise visual mode with `Ctrl+V` is not supported.
## Command history
Claude Code maintains command history for the current session:
@@ -104,9 +104,9 @@ Actions available in the `Chat` context:
| `chat:clearInput` | Ctrl+L | Clear prompt input and force a full screen redraw |
| `chat:killAgents` | Ctrl+X Ctrl+K | Kill all background agents |
| `chat:cycleMode` | Shift+Tab\* | Cycle permission modes |
| `chat:modelPicker` | Cmd+P / Meta+P | Open model picker |
| `chat:modelPicker` | Meta+P | Open model picker |
| `chat:fastMode` | Meta+O | Toggle fast mode |
| `chat:thinkingToggle` | Cmd+T / Meta+T | Toggle extended thinking |
| `chat:thinkingToggle` | Meta+T | Toggle extended thinking |
| `chat:submit` | Enter | Submit message |
| `chat:newline` | Ctrl+J | Insert a newline without submitting |
| `chat:undo` | Ctrl+\_, Ctrl+Shift+- | Undo last action |
@@ -342,16 +342,18 @@ Actions available in the `Scroll` context when [fullscreen rendering](/en/fullsc
Use modifier keys with the `+` separator:
- `ctrl` or `control` - Control key
- `alt`, `opt`, or `option` - Alt/Option key
- `shift` - Shift key
- `meta`, `cmd`, or `command` - Meta/Command key
- `alt`, `opt`, `option`, or `meta` - Alt key on Windows and Linux, Option key on macOS
- `cmd`, `command`, `super`, or `win` - Command key on macOS, Windows key on Windows, Super key on Linux
The `cmd` group is only detected in terminals that report the Super modifier, such as those supporting the Kitty keyboard protocol or xterm's `modifyOtherKeys` mode. Most terminals do not send it, so use `ctrl` or `meta` for bindings you want to work everywhere.
For example:
```text
ctrl+k Single key with modifier
ctrl+k Ctrl + K
shift+tab Shift + Tab
meta+p Command/Meta + P
meta+p Option + P on macOS, Alt + P elsewhere
ctrl+shift+c Multiple modifiers
```
@@ -79,7 +79,7 @@ Example settings file:
Enterprise administrators can use `availableModels` in [managed or policy settings](/en/settings#settings-files) to restrict which models users can select.
When `availableModels` is set, users cannot switch to models not in the list via `/model`, `--model` flag, Config tool, or `ANTHROPIC_MODEL` environment variable.
When `availableModels` is set, users cannot switch to models not in the list via `/model`, `--model` flag, or `ANTHROPIC_MODEL` environment variable.
```json
{
@@ -310,7 +310,7 @@ The `settings.availableModels` allowlist still applies when using third-party pr
When you pin a model on a third-party provider, the provider-specific ID appears as-is in the `/model` picker and Claude Code may not recognize which features the model supports. You can override the display name and declare capabilities with companion environment variables for each pinned model.
These variables only take effect on third-party providers such as Bedrock, Vertex AI, and Foundry. They have no effect when using the Anthropic API directly.
These variables take effect on third-party providers such as Bedrock, Vertex AI, and Foundry. The `_NAME` and `_DESCRIPTION` variables also take effect when `ANTHROPIC_BASE_URL` points to an [LLM gateway](/en/llm-gateway). They have no effect when connecting directly to `api.anthropic.com`.
| Environment variable | Description |
| - | - |
@@ -32,7 +32,7 @@ You can switch modes mid-session, at startup, or as a persistent default. The mo
**During a session**: press `Shift+Tab` to cycle `default` → `acceptEdits` → `plan`. The current mode appears in the status bar. Not every mode is in the default cycle:
- `auto`: appears when your account meets the [auto mode requirements](#eliminate-prompts-with-auto-mode)
- `auto`: appears when your account meets the [auto mode requirements](#eliminate-prompts-with-auto-mode); cycling to auto shows an opt-in prompt until you accept it, or select **No, don't ask again** to remove auto from the cycle
- `bypassPermissions`: appears after you start with `--permission-mode bypassPermissions`, `--dangerously-skip-permissions`, or `--allow-dangerously-skip-permissions`; the `--allow-` variant adds the mode to the cycle without activating it
- `dontAsk`: never appears in the cycle; set it with `--permission-mode dontAsk`
@@ -289,6 +289,7 @@ The following settings are only read from managed settings. Placing them in user
| `sandbox.filesystem.allowManagedReadPathsOnly` | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |
| `sandbox.network.allowManagedDomainsOnly` | When `true`, only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings are respected. Non-allowed domains are blocked automatically without prompting the user. Denied domains still merge from all sources |
| `strictKnownMarketplaces` | Controls which plugin marketplace sources users can add and install plugins from. See [managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) |
| `wslInheritsWindowsSettings` | When `true` in the Windows HKLM registry key or `C:\Program Files\ClaudeCode\managed-settings.json`, WSL reads managed settings from the Windows policy chain in addition to `/etc/claude-code`. See [Settings files](/en/settings#settings-files) |
`disableBypassPermissionsMode` is typically placed in managed settings to enforce organizational policy, but it works from any scope. A user can set it in their own settings to lock themselves out of bypass mode.
@@ -81,17 +81,20 @@ If the field is missing or does not include the target marketplace, install fail
Version constraints resolve against git tags on the marketplace repository. For Claude Code to find a dependency's available versions, the upstream plugin's releases must be tagged using a specific naming convention.
Tag each release as `{plugin-name}--v{version}`, where `{version}` matches the `version` field in that commit's `plugin.json`.
Tag each release as `{plugin-name}--v{version}`, where `{version}` matches the `version` field in that commit's `plugin.json`. From the plugin directory, run:
```bash
git tag secrets-vault--v2.1.0
git push origin secrets-vault--v2.1.0
claude plugin tag --push
```
The `claude plugin tag` command derives the tag name from the plugin's manifest and the enclosing marketplace entry. Before creating the tag, it validates the plugin contents, checks that `plugin.json` and the marketplace entry agree on the version, requires a clean working tree under the plugin directory, and refuses if the tag already exists. Add `--dry-run` to see what would be tagged without creating it. Running `git tag secrets-vault--v2.1.0` directly is equivalent if you keep `plugin.json` and the marketplace entry in sync yourself.
The plugin name prefix lets one marketplace repository host multiple plugins with independent version lines. The `--v` separator is parsed as a prefix match on the full plugin name, so plugin names that contain hyphens are handled correctly.
When you install a plugin that declares `{ "name": "secrets-vault", "version": "~2.1.0" }`, Claude Code lists the marketplace's tags, filters to those starting with `secrets-vault--v`, and fetches the highest version satisfying `~2.1.0`. If no matching tag exists, the dependent plugin is disabled with an error listing the available versions.
The resolved tag's semver is recorded separately from `plugin.json`'s `version`, so constraint checks use the tag that was actually fetched even if `plugin.json` at that commit has a stale value. The cache directory name for a tag-resolved install includes a 12-character commit-SHA suffix, so if a maintainer force-moves a tag to a different commit, the next install gets a fresh cache directory instead of reusing stale content.
For `npm` marketplace sources, the constraint does not control which version is fetched, since tag-based resolution applies only to git-backed sources. The constraint is still checked at load time, and the dependent plugin is disabled with `dependency-version-unsatisfied` if the installed version does not satisfy it.
## How constraints interact
@@ -104,7 +107,7 @@ When several installed plugins constrain the same dependency, Claude Code inters
| `~2.1` | `~3.0` | Install of plugin B fails with `range-conflict`. Plugin A and the dependency stay as they were. |
| `=2.1.0` | none | The dependency stays at `2.1.0`. Auto-update skips newer versions while plugin A is installed. |
Auto-update checks each constrained dependency against every installed plugin's range before applying an update. If the marketplace moves a dependency to a version outside any range, the update is skipped and the skip message names the constraining plugin.
Auto-update checks each constrained dependency against every installed plugin's range before applying an update. If the marketplace moves a dependency to a version outside any range, the update is skipped and the skip appears in `/doctor` and the `/plugin` Errors tab, naming the constraining plugin.
When you uninstall the last plugin that constrains a dependency, the dependency is no longer held and resumes tracking its marketplace entry on the next update.
@@ -126,4 +129,4 @@ To check for these errors programmatically, run `claude plugin list --json` and
- [Create plugins](/en/plugins): build plugins with skills, agents, and hooks
- [Create and distribute a plugin marketplace](/en/plugin-marketplaces): host plugins for your team
- [Plugins reference](/en/plugins-reference#plugin-manifest-schema): the full `plugin.json` schema
- [Version management](/en/plugins-reference#version-management): semantic versioning guidance for plugin releases
- [Version management](/en/plugins-reference#version-management): how a plugin's own version is resolved and used as the cache key
@@ -59,6 +59,8 @@ Create a `plugin.json` file that describes the plugin. The manifest goes in the
}
```
Setting `version` means users only receive updates when you change this field, so bump it on every release. If you omit `version` and host this marketplace in git, every commit automatically counts as a new version. See [Version resolution](#version-resolution-and-release-channels) to choose the right approach.
Create the marketplace catalog that lists your plugin.
```json my-marketplace/.claude-plugin/marketplace.json theme={null}
@@ -177,7 +179,7 @@ Each plugin entry in the `plugins` array describes a plugin and where to find it
| Field | Type | Description |
| :- | :- | :- |
| `description` | string | Brief plugin description |
| `version` | string | Plugin version |
| `version` | string | Plugin version. If set (here or in `plugin.json`), the plugin is pinned to this string and users only receive updates when it changes. Omit to fall back to the git commit SHA. See [Version resolution](#version-resolution-and-release-channels). |
| `author` | object | Plugin author information (`name` required, `email` optional) |
| `homepage` | string | Plugin homepage or documentation URL |
| `repository` | string | Source code repository URL |
@@ -665,15 +667,25 @@ For complete configuration details including all supported source types and comp
### Version resolution and release channels
Plugin versions determine cache paths and update detection. You can specify the version in the plugin manifest (`plugin.json`) or in the marketplace entry (`marketplace.json`).
Plugin versions determine cache paths and update detection: if the resolved version matches what a user already has, `/plugin update` and auto-update skip the plugin.
Claude Code resolves a plugin's version from the first of these that is set:
1. `version` in the plugin's `plugin.json`
2. `version` in the plugin's marketplace entry
3. The git commit SHA of the plugin's source
For the git-based source types `github`, `url`, `git-subdir`, and relative paths inside a git-hosted marketplace, you can omit `version` entirely and every new commit is treated as a new version. This is the simplest setup for internal or actively-developed plugins.
When possible, avoid setting the version in both places. The plugin manifest always wins silently, which can cause the marketplace version to be ignored. For relative-path plugins, set the version in the marketplace entry. For all other plugin sources, set it in the plugin manifest.
Setting `version` pins the plugin. If `plugin.json` declares `"version": "1.0.0"`, pushing new commits without changing that string does nothing for existing users, because Claude Code sees the same version and keeps the cached copy. Bump the field on every release, or omit it to use the commit SHA.
Avoid setting `version` in both `plugin.json` and the marketplace entry. The `plugin.json` value always wins silently, so a stale manifest version can mask a version you set in `marketplace.json`.
#### Set up release channels
To support "stable" and "latest" release channels for your plugins, you can set up two marketplaces that point to different refs or SHAs of the same repo. You can then assign the two marketplaces to different user groups through [managed settings](/en/settings#settings-files).
The plugin's `plugin.json` must declare a different `version` at each pinned ref or commit. If two refs or commits have the same manifest version, Claude Code treats them as identical and skips the update.
Each channel must resolve to a different version. If you use explicit versions, `plugin.json` must declare a different `version` at each pinned ref. If you omit `version`, the distinct commit SHAs already distinguish the channels. If two refs resolve to the same version string, Claude Code treats them as identical and skips the update.
##### Example
@@ -741,6 +753,10 @@ The early-access group receives `latest-tools` instead:
}
```
#### Pin dependency versions
A plugin can constrain its dependencies to a semver range so that updates to a dependency do not break the dependent plugin. See [Constrain plugin dependency versions](/en/plugin-dependencies) for the `{plugin-name}--v{version}` git-tag convention, range syntax, and how multiple constraints on the same dependency are combined.
## Validation and testing
Test your marketplace before sharing.
@@ -117,6 +117,7 @@ Plugin hooks respond to the same lifecycle events as [user-defined hooks](/en/ho
| `PermissionDenied` | When a tool call is denied by the auto mode classifier. Return `{retry: true}` to tell the model it may retry the denied tool call |
| `PostToolUse` | After a tool call succeeds |
| `PostToolUseFailure` | After a tool call fails |
| `PostToolBatch` | After a full batch of parallel tool calls resolves, before the next model call |
| `Notification` | When Claude Code sends a notification |
| `SubagentStart` | When a subagent is spawned |
| `SubagentStop` | When a subagent finishes |
@@ -141,6 +142,7 @@ Plugin hooks respond to the same lifecycle events as [user-defined hooks](/en/ho
- `command`: execute shell commands or scripts
- `http`: send the event JSON as a POST request to a URL
- `mcp_tool`: call a tool on a configured [MCP server](/en/mcp)
- `prompt`: evaluate a prompt with an LLM (uses `$ARGUMENTS` placeholder for context)
- `agent`: run an agentic verifier with tools for complex verification tasks
@@ -311,6 +313,24 @@ The `command` value supports the same [variable substitutions](#environment-vari
Disabling a plugin mid-session does not stop monitors that are already running. They stop when the session ends.
### Themes
Plugins can ship color themes that appear in `/theme` alongside the built-in presets and the user's local themes. A theme is a JSON file in `themes/` with a `base` preset and a sparse `overrides` map of color tokens.
```json
{
"name": "Dracula",
"base": "dark",
"overrides": {
"claude": "#bd93f9",
"error": "#ff5555",
"success": "#50fa7b"
}
}
```
Selecting a plugin theme persists `custom:<plugin-name>:<slug>` in the user's config. Plugin themes are read-only; pressing `Ctrl+E` on one in `/theme` copies it into `~/.claude/themes/` so the user can edit the copy.
***
## Plugin installation scopes
@@ -356,6 +376,7 @@ The manifest is optional. If omitted, Claude Code auto-discovers components in [
"hooks": "./config/hooks.json",
"mcpServers": "./mcp-config.json",
"outputStyles": "./styles/",
"themes": "./themes/",
"lspServers": "./.lsp.json",
"monitors": "./monitors.json",
"dependencies": [
@@ -381,7 +402,7 @@ agent `agent-creator` for the plugin with name `plugin-dev` will appear as
| Field | Type | Description | Example |
| :- | :- | :- | :- |
| `version` | string | Semantic version. If also set in the marketplace entry, `plugin.json` takes priority. You only need to set it in one place. | `"2.1.0"` |
| `version` | string | Optional. Semantic version. Setting this pins the plugin to that version string, so users only receive updates when you bump it. If omitted, Claude Code falls back to the git commit SHA, so every commit is treated as a new version. If also set in the marketplace entry, `plugin.json` wins. See [Version management](#version-management). | `"2.1.0"` |
| `description` | string | Brief explanation of plugin purpose | `"Deployment automation tools"` |
| `author` | object | Author information | `{"name": "Dev Team", "email": "dev@company.com"}` |
| `homepage` | string | Documentation URL | `"https://docs.example.com"` |
@@ -399,6 +420,7 @@ agent `agent-creator` for the plugin with name `plugin-dev` will appear as
| `hooks` | string\|array\|object | Hook config paths or inline config | `"./my-extra-hooks.json"` |
| `mcpServers` | string\|array\|object | MCP config paths or inline config | `"./my-extra-mcp-config.json"` |
| `outputStyles` | string\|array | Custom output style files/directories (replaces default `output-styles/`) | `"./styles/"` |
| `themes` | string\|array | Color theme files/directories (replaces default `themes/`). See [Themes](#themes) | `"./themes/"` |
| `lspServers` | string\|array\|object | [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) configs for code intelligence (go to definition, find references, etc.) | `"./.lsp.json"` |
| `monitors` | string\|array | Background [Monitor](/en/tools-reference#monitor-tool) configurations that start automatically when the plugin is active. See [Monitors](#monitors) | `"./monitors.json"` |
| `userConfig` | object | User-configurable values prompted at enable time. See [User configuration](#user-configuration) | See below |
@@ -475,7 +497,7 @@ The `server` field is required and must match a key in the plugin's `mcpServers`
### Path behavior rules
For `skills`, `commands`, `agents`, `outputStyles`, and `monitors`, a custom path replaces the default. If the manifest specifies `skills`, the default `skills/` directory is not scanned; if it specifies `monitors`, the default `monitors/monitors.json` is not loaded. [Hooks](#hooks), [MCP servers](#mcp-servers), and [LSP servers](#lsp-servers) have different semantics for handling multiple sources.
For `skills`, `commands`, `agents`, `outputStyles`, `themes`, and `monitors`, a custom path replaces the default. If the manifest specifies `skills`, the default `skills/` directory is not scanned; if it specifies `monitors`, the default `monitors/monitors.json` is not loaded. [Hooks](#hooks), [MCP servers](#mcp-servers), and [LSP servers](#lsp-servers) have different semantics for handling multiple sources.
- All paths must be relative to the plugin root and start with `./`
- Components from custom paths use the same naming and namespacing rules
@@ -624,6 +646,8 @@ enterprise-plugin/
│ └── compliance-checker.md
├── output-styles/ # Output style definitions
│ └── terse.md
├── themes/ # Color theme definitions
│ └── dracula.json
├── monitors/ # Background monitor configurations
│ └── monitors.json
├── hooks/ # Hook configurations
@@ -642,7 +666,7 @@ enterprise-plugin/
└── CHANGELOG.md # Version history
```
The `.claude-plugin/` directory contains the `plugin.json` file. All other directories (commands/, agents/, skills/, output-styles/, monitors/, hooks/) must be at the plugin root, not inside `.claude-plugin/`.
The `.claude-plugin/` directory contains the `plugin.json` file. All other directories (commands/, agents/, skills/, output-styles/, themes/, monitors/, hooks/) must be at the plugin root, not inside `.claude-plugin/`.
### File locations reference
@@ -653,6 +677,7 @@ The `.claude-plugin/` directory contains the `plugin.json` file. All other direc
| **Commands** | `commands/` | Skills as flat Markdown files. Use `skills/` for new plugins |
| **Agents** | `agents/` | Subagent Markdown files |
| **Output styles** | `output-styles/` | Output style definitions |
| **Themes** | `themes/` | Color theme definitions |
| **Hooks** | `hooks/hooks.json` | Hook configuration |
| **MCP servers** | `.mcp.json` | MCP server definitions |
| **LSP servers** | `.lsp.json` | Language server configurations |
@@ -799,6 +824,23 @@ claude plugin list [options]
| `--available` | Include available plugins from marketplaces. Requires `--json` | |
| `-h, --help` | Display help for command | |
### plugin tag
Create a release git tag for the plugin in the current directory. Run from inside the plugin's folder. See [Tag plugin releases](/en/plugin-dependencies#tag-plugin-releases-for-version-resolution).
```bash
claude plugin tag [options]
```
**Options:**
| Option | Description | Default |
| :- | :- | :- |
| `--push` | Push the tag to the remote after creating it | |
| `--dry-run` | Print what would be tagged without creating the tag | |
| `-f, --force` | Create the tag even if the working tree is dirty or the tag already exists | |
| `-h, --help` | Display help for command | |
***
## Debugging and development tools
@@ -852,7 +894,7 @@ This shows:
1. Verify the event name is correct (case-sensitive): `PostToolUse`, not `postToolUse`
2. Check the matcher pattern matches your tools: `"matcher": "Write|Edit"` for file operations
3. Confirm the hook type is valid: `command`, `http`, `prompt`, or `agent`
3. Confirm the hook type is valid: `command`, `http`, `mcp_tool`, `prompt`, or `agent`
### MCP server troubleshooting
@@ -898,31 +940,25 @@ If your components are inside `.claude-plugin/`, move them to the plugin root.
### Version management
Follow semantic versioning for plugin releases:
Claude Code uses the plugin's version as the cache key that determines whether an update is available. When you run `/plugin update` or auto-update fires, Claude Code computes the current version and skips the update if it matches what's already installed.
```json
{
"name": "my-plugin",
"version": "2.1.0"
}
```
**Version format**: `MAJOR.MINOR.PATCH`
The version is resolved from the first of these that is set:
- **MAJOR**: Breaking changes (incompatible API changes)
- **MINOR**: New features (backward-compatible additions)
- **PATCH**: Bug fixes (backward-compatible fixes)
1. The `version` field in the plugin's `plugin.json`
2. The `version` field in the plugin's marketplace entry in `marketplace.json`
3. The git commit SHA of the plugin's source, for `github`, `url`, `git-subdir`, and relative-path sources in a git-hosted marketplace
4. `unknown`, for `npm` sources or local directories not inside a git repository
**Best practices**:
This gives you two ways to version a plugin:
- Start at `1.0.0` for your first stable release
- Update the version in `plugin.json` before distributing changes
- Document changes in a `CHANGELOG.md` file
- Use pre-release versions like `2.0.0-beta.1` for testing
| Approach | How | Update behavior | Best for |
| :- | :- | :- | :- |
| **Explicit version** | Set `"version": "2.1.0"` in `plugin.json` | Users get updates only when you bump this field. Pushing new commits without bumping it has no effect, and `/plugin update` reports "already at the latest version". | Published plugins with stable release cycles |
| **Commit-SHA version** | Omit `version` from both `plugin.json` and the marketplace entry | Users get updates on every new commit to the plugin's git source | Internal or team plugins under active development |
Claude Code uses the version to determine whether to update your plugin. If you change your plugin's code but don't bump the version in `plugin.json`, your plugin's existing users won't see your changes due to caching.
If you set `version` in `plugin.json`, you must bump it every time you want users to receive changes. Pushing new commits alone is not enough, because Claude Code sees the same version string and keeps the cached copy. If you're iterating quickly, leave `version` unset so the git commit SHA is used instead.
If your plugin is within a [marketplace](/en/plugin-marketplaces) directory, you can manage the version through `marketplace.json` instead and omit the `version` field from `plugin.json`.
If you use explicit versions, follow [semantic versioning](https://semver.org) (`MAJOR.MINOR.PATCH`): bump MAJOR for breaking changes, MINOR for new features, PATCH for bug fixes. Document changes in a `CHANGELOG.md`.
***
@@ -80,7 +80,7 @@ Then create `my-first-plugin/.claude-plugin/plugin.json` with this content:
| :- | :- |
| `name` | Unique identifier and skill namespace. Skills are prefixed with this (e.g., `/my-first-plugin:hello`). |
| `description` | Shown in the plugin manager when browsing or installing plugins. |
| `version` | Track releases using [semantic versioning](/en/plugins-reference#version-management). |
| `version` | Optional. If set, users only receive updates when you bump this field. If omitted and your plugin is distributed via git, the commit SHA is used and every commit counts as a new version. See [version management](/en/plugins-reference#version-management). |
| `author` | Optional. Helpful for attribution. |
For additional fields like `homepage`, `repository`, and `license`, see the [full manifest schema](/en/plugins-reference#plugin-manifest-schema).
@@ -301,7 +301,7 @@ If your plugin isn't working as expected:
When your plugin is ready to share:
1. **Add documentation**: Include a `README.md` with installation and usage instructions
2. **Version your plugin**: Use [semantic versioning](/en/plugins-reference#version-management) in your `plugin.json`
2. **Choose a versioning strategy**: Decide whether to set an explicit `version` or rely on the git commit SHA. See [version management](/en/plugins-reference#version-management)
3. **Create or use a marketplace**: Distribute through [plugin marketplaces](/en/plugin-marketplaces) for installation
4. **Test with others**: Have team members test the plugin before wider distribution
@@ -163,7 +163,7 @@ If notifications don't arrive:
- **Local process must keep running**: Remote Control runs as a local process. If you close the terminal, quit VS Code, or otherwise stop the `claude` process, the session ends.
- **Extended network outage**: if your machine is awake but unable to reach the network for more than roughly 10 minutes, the session times out and the process exits. Run `claude remote-control` again to start a new session.
- **Ultraplan disconnects Remote Control**: starting an [ultraplan](/en/ultraplan) session disconnects any active Remote Control session because both features occupy the claude.ai/code interface and only one can be connected at a time.
- **Some commands are local-only**: commands that open an interactive picker in the terminal, such as `/mcp`, `/plugin`, or `/resume`, work only from the local CLI. Commands that produce text output, including `/compact`, `/clear`, `/context`, `/cost`, `/exit`, `/extra-usage`, `/recap`, and `/reload-plugins`, work from mobile and web.
- **Some commands are local-only**: commands that open an interactive picker in the terminal, such as `/mcp`, `/plugin`, or `/resume`, work only from the local CLI. Commands that produce text output, including `/compact`, `/clear`, `/context`, `/usage`, `/exit`, `/extra-usage`, `/recap`, and `/reload-plugins`, work from mobile and web.
## Troubleshooting
@@ -13,7 +13,7 @@ A routine is a saved Claude Code configuration: a prompt, one or more repositori
Each routine can have one or more triggers attached to it:
- **Scheduled**: run on a recurring cadence like hourly, nightly, or weekly
- **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
@@ -71,7 +71,7 @@ A **Default** environment is provided. To use a custom environment, [create one]
Under **Select a trigger**, choose how the routine starts. You can pick one trigger type or combine several.
Pick a preset frequency: hourly, daily, weekdays, or weekly. See [Add a schedule trigger](#add-a-schedule-trigger) for timezone handling, stagger, and custom cron intervals.
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.
@@ -85,7 +85,7 @@ Each run creates a new session alongside your other sessions, where you can see
### Create from the CLI
Run `/schedule` in any session to create a scheduled routine conversationally. You can also pass a description directly, as in `/schedule daily PR review at 9am`. Claude walks through the same information the web form collects, then saves the routine to your account.
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.
`/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).
@@ -101,12 +101,30 @@ A routine starts when one of its triggers matches. You can attach any combinatio
### Add a schedule trigger
A schedule trigger runs the routine on a recurring cadence. 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.
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
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.
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.
```text
/schedule tomorrow at 9am, summarize yesterday's merged PRs
```
```text
/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
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.
@@ -257,6 +275,8 @@ Routines draw down subscription usage the same way interactive sessions do. In a
When a routine hits the daily cap or your subscription usage limit, organizations with extra usage enabled can keep running routines on metered overage. Without extra usage, additional runs are rejected until the window resets. Enable extra usage from **Settings > Billing** on claude.ai.
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.
## Related resources
- [`/loop` and in-session scheduling](/en/scheduled-tasks): schedule local tasks within an open CLI session
@@ -15,7 +15,7 @@ Tasks are session-scoped: they live in the current conversation and stop when yo
## Compare scheduling options
Claude Code offers three ways to schedule recurring work:
Claude Code offers three ways to schedule recurring or one-off work:
| | [Cloud](/en/routines) | [Desktop](/en/desktop-scheduled-tasks) | [`/loop`](/en/scheduled-tasks) |
| :- | :- | :- | :- |
@@ -164,9 +164,9 @@ The published schema is updated periodically and may not include settings added
| `apiKeyHelper` | Custom script, to be executed in `/bin/sh`, to generate an auth value. This value will be sent as `X-Api-Key` and `Authorization: Bearer` headers for model requests | `/bin/generate_temp_api_key.sh` |
| `attribution` | Customize attribution for git commits and pull requests. See [Attribution settings](#attribution-settings) | `{"commit": "🤖 Generated with Claude Code", "pr": ""}` |
| `autoMemoryDirectory` | Custom directory for [auto memory](/en/memory#storage-location) storage. Accepts `~/`-expanded paths. Not accepted in project settings (`.claude/settings.json`) to prevent shared repos from redirecting memory writes to sensitive locations. Accepted from policy, local, and user settings | `"~/my-memory-dir"` |
| `autoMode` | Customize what the [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) classifier blocks and allows. Contains `environment`, `allow`, and `soft_deny` arrays of prose rules. See [Configure auto mode](/en/auto-mode-config). Not read from shared project settings | `{"environment": ["Trusted repo: github.example.com/acme"]}` |
| `autoMode` | Customize what the [auto mode](/en/permission-modes#eliminate-prompts-with-auto-mode) classifier blocks and allows. Contains `environment`, `allow`, and `soft_deny` arrays of prose rules. Include the literal string `"$defaults"` in an array to inherit the built-in rules at that position. See [Configure auto mode](/en/auto-mode-config). Not read from shared project settings | `{"soft_deny": ["$defaults", "Never run terraform apply"]}` |
| `autoUpdatesChannel` | Release channel to follow for updates. Use `"stable"` for a version that is typically about one week old and skips versions with major regressions, or `"latest"` (default) for the most recent release | `"stable"` |
| `availableModels` | Restrict which models users can select via `/model`, `--model`, Config tool, or `ANTHROPIC_MODEL`. Does not affect the Default option. See [Restrict model selection](/en/model-config#restrict-model-selection) | `["sonnet", "haiku"]` |
| `availableModels` | Restrict which models users can select via `/model`, `--model`, or `ANTHROPIC_MODEL`. Does not affect the Default option. See [Restrict model selection](/en/model-config#restrict-model-selection) | `["sonnet", "haiku"]` |
| `awaySummaryEnabled` | Show a one-line session recap when you return to the terminal after a few minutes away. Set to `false` or turn off Session recap in `/config` to disable. Same as [`CLAUDE_CODE_ENABLE_AWAY_SUMMARY`](/en/env-vars) | `true` |
| `awsAuthRefresh` | Custom script that modifies the `.aws` directory (see [advanced credential configuration](/en/amazon-bedrock#advanced-credential-configuration)) | `aws sso login --profile myprofile` |
| `awsCredentialExport` | Custom script that outputs JSON with AWS credentials (see [advanced credential configuration](/en/amazon-bedrock#advanced-credential-configuration)) | `/bin/generate_aws_grant.sh` |
@@ -220,6 +220,7 @@ The published schema is updated periodically and may not include settings added
| `viewMode` | Default transcript view mode on startup: `"default"`, `"verbose"`, or `"focus"`. Overrides the sticky `/focus` selection when set | `"verbose"` |
| `voice` | [Voice dictation](/en/voice-dictation) settings: `enabled` turns dictation on, `mode` selects `"hold"` or `"tap"`, and `autoSubmit` sends the prompt on key release in hold mode. Written automatically when you run `/voice`. Requires a Claude.ai account | `{ "enabled": true, "mode": "tap" }` |
| `voiceEnabled` | Legacy alias for `voice.enabled`. Prefer the `voice` object | `true` |
| `wslInheritsWindowsSettings` | (Windows managed settings only) When `true`, Claude Code on WSL reads managed settings from the Windows policy chain in addition to `/etc/claude-code`, with Windows sources taking priority. Only honored when set in the HKLM registry key or `C:\Program Files\ClaudeCode\managed-settings.json`, both of which require Windows admin to write. For HKCU policy to also apply on WSL, the flag must additionally be set in HKCU itself. Has no effect on native Windows | `true` |
### Global config settings
@@ -218,6 +218,8 @@ Set `DISABLE_AUTOUPDATER` to `"1"` in the `env` key of your [`settings.json`](/e
}
```
`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`](/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
To apply an update immediately without waiting for the next background check, run:
@@ -157,7 +157,7 @@ Claude Code sends the following JSON fields to your script via stdin:
| `transcript_path` | Path to conversation transcript file |
| `version` | Claude Code version |
| `output_style.name` | Name of the current output style |
| `vim.mode` | Current vim mode (`NORMAL` or `INSERT`) when [vim mode](/en/interactive-mode#vim-editor-mode) is enabled |
| `vim.mode` | Current vim mode (`NORMAL`, `INSERT`, `VISUAL`, or `VISUAL LINE`) when [vim mode](/en/interactive-mode#vim-editor-mode) is enabled |
| `agent.name` | Agent name when running with the `--agent` flag or agent settings configured |
| `worktree.name` | Name of the active worktree. Present only during `--worktree` sessions |
| `worktree.path` | Absolute path to the worktree directory |
@@ -94,10 +94,42 @@ The `allow-passthrough` line lets notifications and progress updates reach iTerm
## Match the color theme
Use the `/theme` command, or the theme picker in `/config`, to choose a Claude Code theme that matches your terminal. Selecting the auto option detects your terminal's light or dark background, so the theme follows OS appearance changes whenever your terminal does. The available themes are built in; there is no custom theme file. Claude Code does not control the terminal's own color scheme, which is set by the terminal application.
Use the `/theme` command, or the theme picker in `/config`, to choose a Claude Code theme that matches your terminal. Selecting the auto option detects your terminal's light or dark background, so the theme follows OS appearance changes whenever your terminal does. Claude Code does not control the terminal's own color scheme, which is set by the terminal application.
To customize what appears at the bottom of the interface, configure a [custom status line](/en/statusline) that shows the current model, working directory, git branch, or other context.
### Create a custom theme
Custom themes require Claude Code v2.1.118 or later.
In addition to the built-in presets, `/theme` lists any custom themes you have defined and any themes contributed by installed [plugins](/en/plugins-reference#themes). Select **New custom theme…** at the end of the list to create one interactively: you name the theme, then pick individual color tokens to override. Press `Ctrl+E` while a custom theme is highlighted to edit it.
Each custom theme is a JSON file in `~/.claude/themes/`. The filename without the `.json` extension is the theme's slug, and selecting the theme stores `custom:<slug>` as your theme preference. The file has three optional fields:
| Field | Type | Description |
| :- | :- | :- |
| `name` | string | Display label shown in `/theme`. Defaults to the filename slug |
| `base` | string | Built-in preset the theme starts from: `dark`, `light`, `dark-daltonized`, `light-daltonized`, `dark-ansi`, or `light-ansi`. Defaults to `dark` |
| `overrides` | object | Map of color token names to color values. Tokens not listed here fall through to the base preset |
Color values accept `#rrggbb`, `#rgb`, `rgb(r,g,b)`, `ansi256(n)`, or `ansi:<name>` where `<name>` is one of the 16 standard ANSI color names such as `red` or `cyanBright`. Unknown tokens and invalid color values are ignored, so a typo cannot break rendering.
The following example defines a theme that keeps the dark preset but recolors the prompt accent, error text, and success text:
```json ~/.claude/themes/dracula.json theme={null}
{
"name": "Dracula",
"base": "dark",
"overrides": {
"claude": "#bd93f9",
"error": "#ff5555",
"success": "#50fa7b"
}
}
```
Claude Code watches `~/.claude/themes/` and reloads when a file changes, so edits made in your editor apply to a running session without a restart.
## Switch to fullscreen rendering
If the display flickers or the scroll position jumps while Claude is working, switch to [fullscreen rendering mode](/en/fullscreen). It draws to a separate screen the terminal reserves for full-screen apps instead of appending to your normal scrollback, which keeps memory usage flat and adds mouse support for scrolling and selection. In this mode you scroll with the mouse or PageUp inside Claude Code rather than with your terminal's native scrollback; see the [fullscreen page](/en/fullscreen#search-and-review-the-conversation) for how to search and copy.
@@ -130,7 +162,7 @@ The VS Code integrated terminal can drop characters from very large pastes befor
Claude Code includes a Vim-style editing mode for the prompt input. Enable it through `/config` → Editor mode, or by setting the [`editorMode`](/en/settings#global-config-settings) global config key to `"vim"` in `~/.claude.json`. Set Editor mode back to `normal` to turn it off.
Vim mode supports a subset of NORMAL-mode motions and operators, such as `hjkl` navigation and `d`/`c`/`y` with text objects. See the [Vim editor mode reference](/en/interactive-mode#vim-editor-mode) for the full key table. Vim motions are not remappable through the keybindings file.
Vim mode supports a subset of NORMAL- and VISUAL-mode motions and operators, such as `hjkl` navigation, `v`/`V` selection, and `d`/`c`/`y` with text objects. See the [Vim editor mode reference](/en/interactive-mode#vim-editor-mode) for the full key table. Vim motions are not remappable through the keybindings file.
Pressing Enter still submits your prompt in INSERT mode, unlike standard Vim. Use `o` or `O` in NORMAL mode, or Ctrl+J, to insert a newline instead.