System requirements, platform-specific installation, version management, and uninstallation for Claude Code.
This page covers system requirements, platform-specific installation details, updates, and uninstallation. For a guided walkthrough of your first session, see the quickstart. If you've never used a terminal before, see the terminal guide.
Claude Code runs on the following platforms and configurations:
Tip
Prefer a graphical interface? lets you use Claude Code without the terminal. Download it for macOS or Windows.
New to the terminal? See the terminal guide for step-by-step instructions.
To install Claude Code, use one of the following methods:
macOS, Linux, WSL:
curl -fsSL https://claude.ai/install.sh | bash
Windows PowerShell:
irm https://claude.ai/install.ps1 | iex
Native Windows setups require Git for Windows. Install it first if you don't have it. WSL setups do not need it.
Info
Native installations automatically update in the background to keep you on the latest version.
brew install --cask claude-code
Homebrew offers two casks. claude-code tracks the stable release channel, which is typically about a week behind and skips releases with major regressions. claude-code@latest tracks the latest channel and receives new versions as soon as they ship.
Info
Homebrew installations do not auto-update. Run brew upgrade claude-code or brew upgrade claude-code@latest, depending on which cask you installed, to get the latest features and security fixes.
After installation completes, open a terminal in the project you want to work in and start Claude Code:
claude
If you encounter any issues during installation, see the troubleshooting guide.
You can run Claude Code natively on Windows or inside WSL. Pick based on where your projects are located and which features you need:
| Option | Requires | Sandboxing | When to use |
|---|---|---|---|
| Native Windows | Git for Windows | Not supported | Windows-native projects and tools |
| WSL 2 | WSL 2 enabled | Supported | Linux toolchains or sandboxed command execution |
| WSL 1 | WSL 1 enabled | Not supported | If WSL 2 is unavailable |
Option 1: Native Windows with Git Bash
Install Git for Windows, then run the install command from PowerShell or CMD. You do not need to run as Administrator.
Whether you install from PowerShell or CMD only affects which install command you run. Your prompt shows PS C:\Users\YourName> in PowerShell and C:\Users\YourName> without the PS in CMD. If you're new to the terminal, the terminal guide walks through each step.
After installation, launch claude from PowerShell, CMD, or Git Bash. Claude Code uses Git Bash internally to execute commands regardless of where you launched it. If Claude Code can't find your Git Bash installation, set the path in your settings.json file:
{
"env": {
"CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe"
}
}
Claude Code can also run PowerShell natively on Windows as an opt-in preview. See PowerShell tool for setup and limitations.
Option 2: WSL
Open your WSL distribution and run the Linux installer from the install instructions above. You install and launch claude inside the WSL terminal, not from PowerShell or CMD.
The native installer on Alpine and other musl/uClibc-based distributions requires libgcc, libstdc++, and ripgrep. Install these using your distribution's package manager, then set USE_BUILTIN_RIPGREP=0.
This example installs the required packages on Alpine:
apk add libgcc libstdc++ ripgrep
Then set USE_BUILTIN_RIPGREP to 0 in your settings.json file:
{
"env": {
"USE_BUILTIN_RIPGREP": "0"
}
}
After installing, confirm Claude Code is working:
claude --version
For a more detailed check of your installation and configuration, run claude doctor:
claude doctor
Claude Code requires a Pro, Max, Team, Enterprise, or Console account. The free Claude.ai plan does not include Claude Code access. You can also use Claude Code with a third-party API provider like Amazon Bedrock, Google Vertex AI, or Microsoft Foundry.
After installing, log in by running claude and following the browser prompts. See Authentication for all account types and team setup options.
Native installations automatically update in the background. You can configure the release channel to control whether you receive updates immediately or on a delayed stable schedule, or disable auto-updates entirely. Homebrew installations require manual updates.
Claude Code checks for updates on startup and periodically while running. Updates download and install in the background, then take effect the next time you start Claude Code.
Note
Homebrew installations do not auto-update. For Homebrew, run brew upgrade claude-code or brew upgrade claude-code@latest, depending on which cask you installed.
Known issue: Claude Code may notify you of updates before the new version is available in these package managers. If an upgrade fails, wait and try again later.
Homebrew keeps old versions on disk after upgrades. Run brew cleanup periodically to reclaim disk space.
Control which release channel Claude Code follows for auto-updates and claude update with the autoUpdatesChannel setting:
"latest", the default: receive new features as soon as they're released"stable": use a version that is typically about one week old, skipping releases with major regressionsConfigure this via /config → Auto-update channel, or add it to your settings.json file:
{
"autoUpdatesChannel": "stable"
}
For enterprise deployments, you can enforce a consistent release channel across your organization using managed settings.
Homebrew installations choose a channel by cask name instead of this setting: claude-code tracks stable and claude-code@latest tracks latest.
Set DISABLE_AUTOUPDATER to "1" in the env key of your settings.json file:
{
"env": {
"DISABLE_AUTOUPDATER": "1"
}
}
To apply an update immediately without waiting for the next background check, run:
claude update
These options are for version pinning, migrating from npm, and verifying binary integrity.
The native installer accepts either a specific version number or a release channel (latest or stable). The channel you choose at install time becomes your default for auto-updates. See configure release channel for more information.
To install the latest version (default):
curl -fsSL https://claude.ai/install.sh | bash
irm https://claude.ai/install.ps1 | iex
To install the stable version:
curl -fsSL https://claude.ai/install.sh | bash -s stable
& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) stable
To install a specific version number:
curl -fsSL https://claude.ai/install.sh | bash -s 2.1.89
& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) 2.1.89
npm installation is deprecated. The native installer is faster, requires no dependencies, and auto-updates in the background. Use the native installation method when possible.
If you previously installed Claude Code with npm, switch to the native installer:
# Install the native binary
curl -fsSL https://claude.ai/install.sh | bash
# Remove the old npm installation
npm uninstall -g @anthropic-ai/claude-code
You can also run claude install from an existing npm installation to install the native binary alongside it, then remove the npm version.
If you need npm installation for compatibility reasons, you must have Node.js 18+ installed. Install the package globally:
npm install -g @anthropic-ai/claude-code
Warning
Do NOT use sudo npm install -g as this can lead to permission issues and security risks. If you encounter permission errors, see troubleshooting permission errors.
Each release publishes a manifest.json containing SHA256 checksums for every platform binary. The manifest is signed with an Anthropic GPG key, so verifying the signature on the manifest transitively verifies every binary it lists.
Steps 1-3 require a POSIX shell with gpg and curl. On Windows, run them in Git Bash or WSL. Step 4 includes a PowerShell option.
The release signing key is published at a fixed URL.
curl -fsSL https://downloads.claude.ai/keys/claude-code.asc | gpg --import
Display the fingerprint of the imported key.
gpg --fingerprint [email protected]
Confirm the output includes this fingerprint:
31DD DE24 DDFA B679 F42D 7BD2 BAA9 29FF 1A7E CACE
Set VERSION to the release you want to verify.
REPO=https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases
VERSION=2.1.89
curl -fsSLO "$REPO/$VERSION/manifest.json"
curl -fsSLO "$REPO/$VERSION/manifest.json.sig"
Verify the detached signature against the manifest.
gpg --verify manifest.json.sig manifest.json
A valid result reports Good signature from "Anthropic Claude Code Release Signing <[email protected]>".
gpg also prints WARNING: This key is not certified with a trusted signature! for any freshly imported key. This is expected. The Good signature line confirms the cryptographic check passed. The fingerprint comparison in Step 1 confirms the key itself is authentic.
Compare the SHA256 checksum of your downloaded binary with the value listed under platforms.<platform>.checksum in manifest.json.
sha256sum claude
shasum -a 256 claude
(Get-FileHash claude.exe -Algorithm SHA256).Hash.ToLower()
Note
Manifest signatures are available for releases from 2.1.89 onward. Earlier releases publish checksums in manifest.json without a detached signature.
In addition to the signed manifest, individual binaries carry platform-native code signatures where supported.
codesign --verify --verbose ./claude.Get-AuthenticodeSignature .\claude.exe.To remove Claude Code, follow the instructions for your installation method.
Remove the Claude Code binary and version files:
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude
Remove-Item -Path "$env:USERPROFILE\.local\bin\claude.exe" -Force
Remove-Item -Path "$env:USERPROFILE\.local\share\claude" -Recurse -Force
Remove the Homebrew cask you installed. If you installed the stable cask:
brew uninstall --cask claude-code
If you installed the latest cask:
brew uninstall --cask claude-code@latest
Remove the global npm package:
npm uninstall -g @anthropic-ai/claude-code
Warning
Removing configuration files will delete all your settings, allowed tools, MCP server configurations, and session history.
To remove Claude Code settings and cached data:
# Remove user settings and state rm -rf ~/.claude rm ~/.claude.jsonRemove project-specific settings (run from your project directory)
rm -rf .claude rm -f .mcp.json
# Remove user settings and state Remove-Item -Path "$env:USERPROFILE\.claude" -Recurse -Force Remove-Item -Path "$env:USERPROFILE\.claude.json" -ForceRemove project-specific settings (run from your project directory)
Remove-Item -Path ".claude" -Recurse -Force Remove-Item -Path ".mcp.json" -Force
Log in to Claude Code and configure authentication for individuals, teams, and organizations.
Claude Code supports multiple authentication methods depending on your setup. Individual users can log in with a Claude.ai account, while teams can use Claude for Teams or Enterprise, the Claude Console, or a cloud provider like Amazon Bedrock, Google Vertex AI, or Microsoft Foundry.
After installing Claude Code, run claude in your terminal. On first launch, Claude Code opens a browser window for you to log in.
If the browser doesn't open automatically, press c to copy the login URL to your clipboard, then paste it into your browser.
If your browser shows a login code instead of redirecting back after you sign in, paste it into the terminal at the Paste code here if prompted prompt.
You can authenticate with any of these account types:
claude. No browser login is needed.To log out and re-authenticate, type /logout at the Claude Code prompt.
If you're having trouble logging in, see authentication troubleshooting.
For teams and organizations, you can configure Claude Code access in one of these ways:
Claude for Teams and Claude for Enterprise provide the best experience for organizations using Claude Code. Team members get access to both Claude Code and Claude on the web with centralized billing and team management.
Subscribe to Claude for Teams or contact sales for Claude for Enterprise.
Invite team members from the admin dashboard.
Team members install Claude Code and log in with their Claude.ai accounts.
For organizations that prefer API-based billing, you can set up access through the Claude Console.
Use your existing Claude Console account or create a new one.
You can add users through either method:
When inviting users, assign one of:
Each invited user needs to:
For teams using Amazon Bedrock, Google Vertex AI, or Microsoft Foundry:
Follow the Bedrock docs, Vertex docs, or Microsoft Foundry docs.
Distribute the environment variables and instructions for generating cloud credentials to your users. Read more about how to manage configuration here.
Users can install Claude Code.
Claude Code securely manages your authentication credentials:
~/.claude/.credentials.json, or under $CLAUDE_CONFIG_DIR if that variable is set. On Linux, the file is written with mode 0600; on Windows, it inherits the access controls of your user profile directory.apiKeyHelper setting can be configured to run a shell script that returns an API key.apiKeyHelper is called after 5 minutes or on HTTP 401 response. Set CLAUDE_CODE_API_KEY_HELPER_TTL_MS environment variable for custom refresh intervals.apiKeyHelper takes longer than 10 seconds to return a key, Claude Code displays a warning notice in the prompt bar showing the elapsed time. If you see this notice regularly, check whether your credential script can be optimized.apiKeyHelper, ANTHROPIC_API_KEY, and ANTHROPIC_AUTH_TOKEN apply to terminal CLI sessions only. Claude Desktop and remote sessions use OAuth exclusively and do not call apiKeyHelper or read API key environment variables.
When multiple credentials are present, Claude Code chooses one in this order:
CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, or CLAUDE_CODE_USE_FOUNDRY is set. See third-party integrations for setup.ANTHROPIC_AUTH_TOKEN environment variable. Sent as the Authorization: Bearer header. Use this when routing through an LLM gateway or proxy that authenticates with bearer tokens rather than Anthropic API keys.ANTHROPIC_API_KEY environment variable. Sent as the X-Api-Key header. Use this for direct Anthropic API access with a key from the Claude Console. In interactive mode, you are prompted once to approve or decline the key, and your choice is remembered. To change it later, use the "Use custom API key" toggle in /config. In non-interactive mode (-p), the key is always used when present.apiKeyHelper script output. Use this for dynamic or rotating credentials, such as short-lived tokens fetched from a vault.CLAUDE_CODE_OAUTH_TOKEN environment variable. A long-lived OAuth token generated by claude setup-token. Use this for CI pipelines and scripts where browser login isn't available./login. This is the default for Claude Pro, Max, Team, and Enterprise users.If you have an active Claude subscription but also have ANTHROPIC_API_KEY set in your environment, the API key takes precedence once approved. This can cause authentication failures if the key belongs to a disabled or expired organization. Run unset ANTHROPIC_API_KEY to fall back to your subscription, and check /status to confirm which method is active.
Claude Code on the Web always uses your subscription credentials. ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN in the sandbox environment do not override them.
For CI pipelines, scripts, or other environments where interactive browser login isn't available, generate a one-year OAuth token with claude setup-token:
claude setup-token
The command walks you through OAuth authorization and prints a token to the terminal. It does not save the token anywhere; copy it and set it as the CLAUDE_CODE_OAUTH_TOKEN environment variable wherever you want to authenticate:
export CLAUDE_CODE_OAUTH_TOKEN=your-token
This token authenticates with your Claude subscription and requires a Pro, Max, Team, or Enterprise plan. It is scoped to inference only and cannot establish Remote Control sessions.
Bare mode does not read CLAUDE_CODE_OAUTH_TOKEN. If your script passes --bare, authenticate with ANTHROPIC_API_KEY or an apiKeyHelper instead.
Learn about Claude Code's security safeguards and best practices for safe usage.
Your code's security is paramount. Claude Code is built with security at its core, developed according to Anthropic's comprehensive security program. Learn more and access resources (SOC 2 Type 2 report, ISO 27001 certificate, etc.) at Anthropic Trust Center.
Claude Code uses strict read-only permissions by default. When additional actions are needed (editing files, running tests, executing commands), Claude Code requests explicit permission. Users control whether to approve actions once or allow them automatically.
We designed Claude Code to be transparent and secure. For example, we require approval for bash commands before executing them, giving you direct control. This approach enables users and organizations to configure permissions directly.
For detailed permission configuration, see Permissions.
To mitigate risks in agentic systems:
/sandbox to define boundaries where Claude Code can work autonomouslyClaude Code only has the permissions you grant it. You're responsible for reviewing proposed code and commands for safety before approval.
Prompt injection is a technique where an attacker attempts to override or manipulate an AI assistant's instructions by inserting malicious text. Claude Code includes several safeguards against these attacks:
curl and wget by default. When explicitly allowed, be aware of permission pattern limitationsWe have implemented several safeguards to protect your data, including:
For full details, please review our Commercial Terms of Service (for Team, Enterprise, and API users) or Consumer Terms (for Free, Pro, and Max users) and Privacy Policy.
-p flagWarning
Windows WebDAV security risk: When running Claude Code on Windows, we recommend against enabling WebDAV or allowing Claude Code to access paths such as \\* that may contain WebDAV subdirectories. WebDAV has been deprecated by Microsoft due to security risks. Enabling WebDAV may allow Claude Code to trigger network requests to remote hosts, bypassing the permission system.
Best practices for working with untrusted content:
/feedbackWarning
While these protections significantly reduce risk, no system is completely immune to all attacks. Always maintain good security practices when working with any AI tool.
Claude Code allows users to configure Model Context Protocol (MCP) servers. The list of allowed MCP servers is configured in your source code, as part of Claude Code settings engineers check into source control.
We encourage either writing your own MCP servers or using MCP servers from providers that you trust. You are able to configure Claude Code permissions for MCP servers. Anthropic does not manage or audit any MCP servers.
See VS Code security and privacy for more information on running Claude Code in an IDE.
When using Claude Code on the web, additional security controls are in place:
For more details on cloud execution, see Claude Code on the web.
Remote Control sessions work differently: the web interface connects to a Claude Code process running on your local machine. All code execution and file access stays local, and the same data that flows during any local Claude Code session travels through the Anthropic API over TLS. No cloud VMs or sandboxing are involved. The connection uses multiple short-lived, narrowly scoped credentials, each limited to a specific purpose and expiring independently, to limit the blast radius of any single compromised credential.
/permissionsConfigChange hooksIf you discover a security vulnerability in Claude Code:
Centrally configure Claude Code for your organization through server-delivered settings, without requiring device management infrastructure.
Server-managed settings allow administrators to centrally configure Claude Code through a web-based interface on Claude.ai. Claude Code clients automatically receive these settings when users authenticate with their organization credentials.
This approach is designed for organizations that do not have device management infrastructure in place, or need to manage settings for users on unmanaged devices.
Note
Server-managed settings are available for Claude for Teams and Claude for Enterprise customers.
To use server-managed settings, you need:
api.anthropic.comClaude Code supports two approaches for centralized configuration. Server-managed settings deliver configuration from Anthropic's servers. Endpoint-managed settings are deployed directly to devices through native OS policies (macOS managed preferences, Windows registry) or managed settings files.
| Approach | Best for | Security model |
|---|---|---|
| Server-managed settings | Organizations without MDM, or users on unmanaged devices | Settings delivered from Anthropic's servers at authentication time |
| Endpoint-managed settings | Organizations with MDM or endpoint management | Settings deployed to devices via MDM configuration profiles, registry policies, or managed settings files |
If your devices are enrolled in an MDM or endpoint management solution, endpoint-managed settings provide stronger security guarantees because the settings file can be protected from user modification at the OS level.
In Claude.ai, navigate to Admin Settings > Claude Code > Managed settings.
Add your configuration as JSON. All settings available in settings.json are supported, including hooks, environment variables, and managed-only settings like allowManagedPermissionRulesOnly.
This example enforces a permission deny list, prevents users from bypassing permissions, and restricts permission rules to those defined in managed settings:
{
"permissions": {
"deny": [
"Bash(curl *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
],
"disableBypassPermissionsMode": "disable"
},
"allowManagedPermissionRulesOnly": true
}
Hooks use the same format as in settings.json.
This example runs an audit script after every file edit across the organization:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "/usr/local/bin/audit-edit.sh" }
]
}
]
}
}
To configure the auto mode classifier so it knows which repos, buckets, and domains your organization trusts:
{
"autoMode": {
"environment": [
"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"
]
}
}
Because hooks execute shell commands, users see a security approval dialog before they're applied. See Configure the auto mode classifier for how the autoMode entries affect what the classifier blocks and important warnings about the allow and soft_deny fields.
Save your changes. Claude Code clients receive the updated settings on their next startup or hourly polling cycle.
To confirm that settings are being applied, ask a user to restart Claude Code. If the configuration includes settings that trigger the security approval dialog, the user sees a prompt describing the managed settings on startup. You can also verify that managed permission rules are active by having a user run /permissions to view their effective permission rules.
The following roles can manage server-managed settings:
Restrict access to trusted personnel, as settings changes apply to all users in the organization.
Most settings keys work in any scope. A handful of keys are only read from managed settings and have no effect when placed in user or project settings files. See managed-only settings for the full list. Any setting not on that list can still be placed in managed settings and takes the highest precedence.
Server-managed settings have the following limitations:
Server-managed settings and endpoint-managed settings both occupy the highest tier in the Claude Code settings hierarchy. No other settings level can override them, including command line arguments.
Within the managed tier, the first source that delivers a non-empty configuration wins. Server-managed settings are checked first, then endpoint-managed settings. Sources do not merge: if server-managed settings deliver any keys at all, endpoint-managed settings are ignored entirely. If server-managed settings deliver nothing, endpoint-managed settings apply.
If you clear your server-managed configuration in the admin console with the intent of falling back to an endpoint-managed plist or registry policy, be aware that cached settings persist on client machines until the next successful fetch. Run /status to see which managed source is active.
Claude Code fetches settings from Anthropic's servers at startup and polls for updates hourly during active sessions.
First launch without cached settings:
Subsequent launches with cached settings:
Claude Code applies settings updates automatically without a restart, except for advanced settings like OpenTelemetry configuration, which require a full restart to take effect.
By default, if the remote settings fetch fails at startup, the CLI continues without managed settings. For environments where this brief unenforced window is unacceptable, set forceRemoteSettingsRefresh: true in your managed settings.
When this setting is active, the CLI blocks at startup until remote settings are freshly fetched. If the fetch fails, the CLI exits rather than proceeding without the policy. This setting self-perpetuates: once delivered from the server, it is also cached locally so that subsequent startups enforce the same behavior even before the first successful fetch of a new session.
To enable this, add the key to your managed settings configuration:
{
"forceRemoteSettingsRefresh": true
}
Before enabling this setting, ensure your network policies allow connectivity to api.anthropic.com. If that endpoint is unreachable, the CLI exits at startup and users cannot start Claude Code.
Certain settings that could pose security risks require explicit user approval before being applied:
When these settings are present, users see a security dialog explaining what is being configured. Users must approve to proceed. If a user rejects the settings, Claude Code exits.
Note
In non-interactive mode with the -p flag, Claude Code skips security dialogs and applies settings without user approval.
Server-managed settings require a direct connection to api.anthropic.com and are not available when using third-party model providers:
ANTHROPIC_BASE_URL or LLM gatewaysAudit log events for settings changes are available through the compliance API or audit log export. Contact your Anthropic account team for access.
Audit events include the type of action performed, the account and device that performed the action, and references to the previous and new values.
Server-managed settings provide centralized policy enforcement, but they operate as a client-side control. On unmanaged devices, users with admin or sudo access can modify the Claude Code binary, filesystem, or network configuration.
| Scenario | Behavior |
|---|---|
| User edits the cached settings file | Tampered file applies at startup, but correct settings restore on the next server fetch |
| User deletes the cached settings file | First-launch behavior occurs: settings fetch asynchronously with a brief unenforced window |
| API is unavailable | Cached settings apply if available, otherwise managed settings are not enforced until the next successful fetch. With forceRemoteSettingsRefresh: true, the CLI exits instead of continuing |
| User authenticates with a different organization | Settings are not delivered for accounts outside the managed organization |
User sets a non-default ANTHROPIC_BASE_URL |
Server-managed settings are bypassed when using third-party API providers |
To detect runtime configuration changes, use ConfigChange hooks to log modifications or block unauthorized changes before they take effect.
For stronger enforcement guarantees, use endpoint-managed settings on devices enrolled in an MDM solution.
Related pages for managing Claude Code configuration:
Learn about Anthropic's data usage policies for Claude
Consumer users (Free, Pro, and Max plans): We give you the choice to allow your data to be used to improve future Claude models. We will train new models using data from Free, Pro, and Max accounts when this setting is on (including when you use Claude Code from these accounts).
Commercial users: (Team and Enterprise plans, API, 3rd-party platforms, and Claude Gov) maintain existing policies: Anthropic does not train generative models using code or prompts sent to Claude Code under commercial terms, unless the customer has chosen to provide their data to us for model improvement (for example, the Developer Partner Program).
If you explicitly opt in to methods to provide us with materials to train on, such as via the Development Partner Program, we may use those materials provided to train our models. An organization admin can expressly opt-in to the Development Partner Program for their organization. Note that this program is available only for Anthropic first-party API, and not for Bedrock or Vertex users.
/feedback commandIf you choose to send us feedback about Claude Code using the /feedback command, we may use your feedback to improve our products and services. Transcripts shared via /feedback are retained for 5 years.
When you see the "How is Claude doing this session?" prompt in Claude Code, responding to this survey (including selecting "Dismiss"), only your numeric rating (1, 2, 3, or dismiss) is recorded. We do not collect or store any conversation transcripts, inputs, outputs, or other session data as part of this survey. Unlike thumbs up/down feedback or /feedback reports, this session quality survey is a simple product satisfaction metric. Your responses to this survey do not impact your data training preferences and cannot be used to train our AI models.
To disable these surveys, set CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1. The survey is also disabled when DISABLE_TELEMETRY or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set. To control frequency instead of disabling, set feedbackSurveyRate in your settings file to a probability between 0 and 1.
Anthropic retains Claude Code data based on your account type and preferences.
Consumer users (Free, Pro, and Max plans):
Commercial users (Team, Enterprise, and API):
~/.claude/projects/ for 30 days by default to enable session resumption. Adjust the period with cleanupPeriodDays. See application data for what's stored and how to clear it.You can delete individual Claude Code on the web sessions at any time. Deleting a session permanently removes the session's event data. For instructions on how to delete sessions, see Delete sessions.
Learn more about data retention practices in our Privacy Center.
For full details, please review our Commercial Terms of Service (for Team, Enterprise, and API users) or Consumer Terms (for Free, Pro, and Max users) and Privacy Policy.
For all first party users, you can learn more about what data is logged for local Claude Code and remote Claude Code. Remote Control sessions follow the local data flow since all execution happens on your machine. Note for remote Claude Code, Claude accesses the repository where you initiate your Claude Code session. Claude does not access repositories that you have connected but have not started a session in.
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. 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 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.
When using Claude Code on the web, sessions run in Anthropic-managed virtual machines instead of locally. In cloud environments:
For security details about cloud execution, see Security.
Claude Code connects from users' machines to the Statsig service to log operational metrics such as latency, reliability, and usage patterns. This logging does not include any code or file paths. Data is encrypted in transit using TLS and at rest using 256-bit AES encryption. Read more in the Statsig security documentation. To opt out of Statsig telemetry, set the DISABLE_TELEMETRY environment variable.
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. 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.
By default, error reporting, telemetry, and bug reporting are disabled when using Bedrock, Vertex, or Foundry. Session quality surveys are the exception and appear regardless of provider. You can opt out of all non-essential traffic, including surveys, at once by setting CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC. Here are the full default behaviors:
| Service | Claude API | Vertex API | Bedrock API | Foundry API |
|---|---|---|---|---|
| Statsig (Metrics) | Default on.DISABLE_TELEMETRY=1 to disable. |
Default off.CLAUDE_CODE_USE_VERTEX must be 1. |
Default off.CLAUDE_CODE_USE_BEDROCK must be 1. |
Default off.CLAUDE_CODE_USE_FOUNDRY must be 1. |
| Sentry (Errors) | Default on.DISABLE_ERROR_REPORTING=1 to disable. |
Default off.CLAUDE_CODE_USE_VERTEX must be 1. |
Default off.CLAUDE_CODE_USE_BEDROCK must be 1. |
Default off.CLAUDE_CODE_USE_FOUNDRY must be 1. |
Claude API (/feedback reports) |
Default on.DISABLE_FEEDBACK_COMMAND=1 to disable. |
Default off.CLAUDE_CODE_USE_VERTEX must be 1. |
Default off.CLAUDE_CODE_USE_BEDROCK must be 1. |
Default off.CLAUDE_CODE_USE_FOUNDRY must be 1. |
| Session quality surveys | Default on.CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 to disable. |
Default on.CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 to disable. |
Default on.CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 to disable. |
Default on.CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 to disable. |
All environment variables can be checked into settings.json (see settings reference).
Learn about Zero Data Retention (ZDR) for Claude Code on Claude for Enterprise, including scope, disabled features, and how to request enablement.
Zero Data Retention (ZDR) is available for Claude Code when used through Claude for Enterprise. When ZDR is enabled, prompts and model responses generated during Claude Code sessions are processed in real time and not stored by Anthropic after the response is returned, except where needed to comply with law or combat misuse.
ZDR on Claude for Enterprise gives enterprise customers the ability to use Claude Code with zero data retention and access administrative capabilities:
ZDR for Claude Code on Claude for Enterprise applies only to Anthropic's direct platform. For Claude deployments on AWS Bedrock, Google Vertex AI, or Microsoft Foundry, refer to those platforms' data retention policies.
ZDR covers Claude Code inference on Claude for Enterprise.
Warning
ZDR is enabled on a per-organization basis. Each new organization requires ZDR to be enabled separately by your Anthropic account team. ZDR does not automatically apply to new organizations created under the same account. Contact your account team to enable ZDR for any new organizations.
ZDR covers model inference calls made through Claude Code on Claude for Enterprise. When you use Claude Code in your terminal, the prompts you send and the responses Claude generates are not retained by Anthropic. This applies regardless of which Claude model is used.
ZDR does not extend to the following, even for organizations with ZDR enabled. These features follow standard data retention policies:
| Feature | Details |
|---|---|
| Chat on claude.ai | Chat conversations through the Claude for Enterprise web interface are not covered by ZDR. |
| Cowork | Cowork sessions are not covered by ZDR. |
| Claude Code Analytics | Does not store prompts or model responses, but collects productivity metadata such as account emails and usage statistics. Contribution metrics are not available for ZDR organizations; the analytics dashboard shows usage metrics only. |
| User and seat management | Administrative data such as account emails and seat assignments is retained under standard policies. |
| Third-party integrations | Data processed by third-party tools, MCP servers, or other external integrations is not covered by ZDR. Review those services' data handling practices independently. |
When ZDR is enabled for a Claude Code organization on Claude for Enterprise, certain features that require storing prompts or completions are automatically disabled at the backend level:
| Feature | Reason |
|---|---|
| Claude Code on the Web | Requires server-side storage of conversation history. |
Feedback submission (/feedback) |
Submitting feedback sends conversation data to Anthropic. |
These features are blocked in the backend regardless of client-side display. If you see a disabled feature in the Claude Code terminal during startup, attempting to use it returns an error indicating the organization's policies do not allow that action.
Future features may also be disabled if they require storing prompts or completions.
Even with ZDR enabled, Anthropic may retain data where required by law or to address Usage Policy violations. If a session is flagged for a policy violation, Anthropic may retain the associated inputs and outputs for up to 2 years, consistent with Anthropic's standard ZDR policy.
To request ZDR for Claude Code on Claude for Enterprise, contact your Anthropic account team. Your account team will submit the request internally, and Anthropic will review and enable ZDR on your organization after confirming eligibility. All enablement actions are audit-logged.
If you are currently using ZDR for Claude Code via pay-as-you-go API keys, you can transition to Claude for Enterprise to gain access to administrative features while maintaining ZDR for Claude Code. Contact your account team to coordinate the migration.
Learn how to enable and configure OpenTelemetry for Claude Code.
Track Claude Code usage, costs, and tool activity across your organization by exporting telemetry data through OpenTelemetry (OTel). Claude Code exports metrics as time series data via the standard metrics protocol, events via the logs/events protocol, and optionally distributed traces via the traces protocol. Configure your metrics, logs, and traces backends to match your monitoring requirements.
Configure OpenTelemetry using environment variables:
# 1. Enable telemetry
export CLAUDE_CODE_ENABLE_TELEMETRY=1
# 2. Choose exporters (both are optional - configure only what you need)
export OTEL_METRICS_EXPORTER=otlp # Options: otlp, prometheus, console, none
export OTEL_LOGS_EXPORTER=otlp # Options: otlp, console, none
# 3. Configure OTLP endpoint (for OTLP exporter)
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# 4. Set authentication (if required)
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"
# 5. For debugging: reduce export intervals
export OTEL_METRIC_EXPORT_INTERVAL=10000 # 10 seconds (default: 60000ms)
export OTEL_LOGS_EXPORT_INTERVAL=5000 # 5 seconds (default: 5000ms)
# 6. Run Claude Code
claude
Note
The default export intervals are 60 seconds for metrics and 5 seconds for logs. During setup, you may want to use shorter intervals for debugging purposes. Remember to reset these for production use.
For full configuration options, see the OpenTelemetry specification.
Administrators can configure OpenTelemetry settings for all users through the managed settings file. This allows for centralized control of telemetry settings across an organization. See the settings precedence for more information about how settings are applied.
Example managed settings configuration:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317",
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer example-token"
}
}
Note
Managed settings can be distributed via MDM (Mobile Device Management) or other device management solutions. Environment variables defined in the managed settings file have high precedence and cannot be overridden by users.
| Environment Variable | Description | Example Values |
|---|---|---|
CLAUDE_CODE_ENABLE_TELEMETRY |
Enables telemetry collection (required) | 1 |
OTEL_METRICS_EXPORTER |
Metrics exporter types, comma-separated. Use none to disable |
console, otlp, prometheus, none |
OTEL_LOGS_EXPORTER |
Logs/events exporter types, comma-separated. Use none to disable |
console, otlp, none |
OTEL_EXPORTER_OTLP_PROTOCOL |
Protocol for OTLP exporter, applies to all signals | grpc, http/json, http/protobuf |
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP collector endpoint for all signals | http://localhost:4317 |
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL |
Protocol for metrics, overrides general setting | grpc, http/json, http/protobuf |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT |
OTLP metrics endpoint, overrides general setting | http://localhost:4318/v1/metrics |
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL |
Protocol for logs, overrides general setting | grpc, http/json, http/protobuf |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT |
OTLP logs endpoint, overrides general setting | http://localhost:4318/v1/logs |
OTEL_EXPORTER_OTLP_HEADERS |
Authentication headers for OTLP | Authorization=Bearer token |
OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY |
Client key for mTLS authentication | Path to client key file |
OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE |
Client certificate for mTLS authentication | Path to client cert file |
OTEL_METRIC_EXPORT_INTERVAL |
Export interval in milliseconds (default: 60000) | 5000, 60000 |
OTEL_LOGS_EXPORT_INTERVAL |
Logs export interval in milliseconds (default: 5000) | 1000, 10000 |
OTEL_LOG_USER_PROMPTS |
Enable logging of user prompt content (default: disabled) | 1 to enable |
OTEL_LOG_TOOL_DETAILS |
Enable logging of tool parameters and input arguments in tool events and trace span attributes: Bash commands, MCP server and tool names, skill names, and tool input (default: disabled) | 1 to enable |
OTEL_LOG_TOOL_CONTENT |
Enable logging of tool input and output content in span events (default: disabled). Requires tracing. Content is truncated at 60 KB | 1 to enable |
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE |
Metrics temporality preference (default: delta). Set to cumulative if your backend expects cumulative temporality |
delta, cumulative |
CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS |
Interval for refreshing dynamic headers (default: 1740000ms / 29 minutes) | 900000 |
The following environment variables control which attributes are included in metrics to manage cardinality:
| Environment Variable | Description | Default Value | Example to Disable |
|---|---|---|---|
OTEL_METRICS_INCLUDE_SESSION_ID |
Include session.id attribute in metrics | true |
false |
OTEL_METRICS_INCLUDE_VERSION |
Include app.version attribute in metrics | false |
true |
OTEL_METRICS_INCLUDE_ACCOUNT_UUID |
Include user.account_uuid and user.account_id attributes in metrics | true |
false |
These variables help control the cardinality of metrics, which affects storage requirements and query performance in your metrics backend. Lower cardinality generally means better performance and lower storage costs but less granular data for analysis.
Distributed tracing exports spans that link each user prompt to the API requests and tool executions it triggers, so you can view a full request as a single trace in your tracing backend.
Tracing is off by default. To enable it, set both CLAUDE_CODE_ENABLE_TELEMETRY=1 and CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1, then set OTEL_TRACES_EXPORTER to choose where spans are sent. Traces reuse the common OTLP configuration for endpoint, protocol, and headers.
| Environment Variable | Description | Example Values |
|---|---|---|
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA |
Enable span tracing (required). ENABLE_ENHANCED_TELEMETRY_BETA is also accepted |
1 |
OTEL_TRACES_EXPORTER |
Traces exporter types, comma-separated. Use none to disable |
console, otlp, none |
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL |
Protocol for traces, overrides OTEL_EXPORTER_OTLP_PROTOCOL |
grpc, http/json, http/protobuf |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
OTLP traces endpoint, overrides OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4318/v1/traces |
OTEL_TRACES_EXPORT_INTERVAL |
Span batch export interval in milliseconds (default: 5000) | 1000, 10000 |
Spans redact user prompt text, tool input details, and tool content by default. Set OTEL_LOG_USER_PROMPTS=1, OTEL_LOG_TOOL_DETAILS=1, and OTEL_LOG_TOOL_CONTENT=1 to include them.
When tracing is active, Bash and PowerShell subprocesses automatically inherit a TRACEPARENT environment variable containing the W3C trace context of the active tool execution span. This lets any subprocess that reads TRACEPARENT parent its own spans under the same trace, enabling end-to-end distributed tracing through scripts and commands that Claude runs.
For enterprise environments that require dynamic authentication, you can configure a script to generate headers dynamically:
Add to your .claude/settings.json:
{
"otelHeadersHelper": "/bin/generate_opentelemetry_headers.sh"
}
The script must output valid JSON with string key-value pairs representing HTTP headers:
#!/bin/bash
# Example: Multiple headers
echo "{\"Authorization\": \"Bearer $(get-token.sh)\", \"X-API-Key\": \"$(get-api-key.sh)\"}"
The headers helper script runs at startup and periodically thereafter to support token refresh. By default, the script runs every 29 minutes. Customize the interval with the CLAUDE_CODE_OTEL_HEADERS_HELPER_DEBOUNCE_MS environment variable.
Organizations with multiple teams or departments can add custom attributes to distinguish between different groups using the OTEL_RESOURCE_ATTRIBUTES environment variable:
# Add custom attributes for team identification
export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"
These custom attributes will be included in all metrics and events, allowing you to:
Warning
Important formatting requirements for OTEL_RESOURCE_ATTRIBUTES:
The OTEL_RESOURCE_ATTRIBUTES environment variable uses comma-separated key=value pairs with strict formatting requirements:
user.organizationName=My Company is invalidkey1=value1,key2=value2Examples:
# ❌ Invalid - contains spaces
export OTEL_RESOURCE_ATTRIBUTES="org.name=John's Organization"
# ✅ Valid - use underscores or camelCase instead
export OTEL_RESOURCE_ATTRIBUTES="org.name=Johns_Organization"
export OTEL_RESOURCE_ATTRIBUTES="org.name=JohnsOrganization"
# ✅ Valid - percent-encode special characters if needed
export OTEL_RESOURCE_ATTRIBUTES="org.name=John%27s%20Organization"
Note: wrapping values in quotes doesn't escape spaces. For example, org.name="My Company" results in the literal value "My Company" (with quotes included), not My Company.
Set these environment variables before running claude. Each block shows a complete configuration for a different exporter or deployment scenario:
# Console debugging (1-second intervals)
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console
export OTEL_METRIC_EXPORT_INTERVAL=1000
# OTLP/gRPC
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# Prometheus
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=prometheus
# Multiple exporters
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console,otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
# Different endpoints/backends for metrics and logs
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://metrics.example.com:4318
export OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://logs.example.com:4317
# Metrics only (no events/logs)
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# Events/logs only (no metrics)
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
All metrics and events share these standard attributes:
| Attribute | Description | Controlled By |
|---|---|---|
session.id |
Unique session identifier | OTEL_METRICS_INCLUDE_SESSION_ID (default: true) |
app.version |
Current Claude Code version | OTEL_METRICS_INCLUDE_VERSION (default: false) |
organization.id |
Organization UUID (when authenticated) | Always included when available |
user.account_uuid |
Account UUID (when authenticated) | OTEL_METRICS_INCLUDE_ACCOUNT_UUID (default: true) |
user.account_id |
Account ID in tagged format matching Anthropic admin APIs (when authenticated), such as user_01BWBeN28... |
OTEL_METRICS_INCLUDE_ACCOUNT_UUID (default: true) |
user.id |
Anonymous device/installation identifier, generated per Claude Code installation | Always included |
user.email |
User email address (when authenticated via OAuth) | Always included when available |
terminal.type |
Terminal type, such as iTerm.app, vscode, cursor, or tmux |
Always included when detected |
Events additionally include the following attributes. These are never attached to metrics because they would cause unbounded cardinality:
prompt.id: UUID correlating a user prompt with all subsequent events until the next prompt. See Event correlation attributes.workspace.host_paths: host workspace directories selected in the desktop app, as a string arrayClaude Code exports the following metrics:
| Metric Name | Description | Unit |
|---|---|---|
claude_code.session.count |
Count of CLI sessions started | count |
claude_code.lines_of_code.count |
Count of lines of code modified | count |
claude_code.pull_request.count |
Number of pull requests created | count |
claude_code.commit.count |
Number of git commits created | count |
claude_code.cost.usage |
Cost of the Claude Code session | USD |
claude_code.token.usage |
Number of tokens used | tokens |
claude_code.code_edit_tool.decision |
Count of code editing tool permission decisions | count |
claude_code.active_time.total |
Total active time in seconds | s |
Each metric includes the standard attributes listed above. Metrics with additional context-specific attributes are noted below.
Incremented at the start of each session.
Attributes:
Incremented when code is added or removed.
Attributes:
type: ("added", "removed")Incremented when creating pull requests via Claude Code.
Attributes:
Incremented when creating git commits via Claude Code.
Attributes:
Incremented after each API request.
Attributes:
model: Model identifier (for example, "claude-sonnet-4-6")Incremented after each API request.
Attributes:
type: ("input", "output", "cacheRead", "cacheCreation")model: Model identifier (for example, "claude-sonnet-4-6")Incremented when user accepts or rejects Edit, Write, or NotebookEdit tool usage.
Attributes:
tool_name: Tool name ("Edit", "Write", "NotebookEdit")decision: User decision ("accept", "reject")source: Decision source - "config", "hook", "user_permanent", "user_temporary", "user_abort", or "user_reject"language: Programming language of the edited file, such as "TypeScript", "Python", "JavaScript", or "Markdown". Returns "unknown" for unrecognized file extensions.Tracks actual time spent actively using Claude Code, excluding idle time. This metric is incremented during user interactions (typing, reading responses) and during CLI processing (tool execution, AI response generation).
Attributes:
type: "user" for keyboard interactions, "cli" for tool execution and AI responsesClaude Code exports the following events via OpenTelemetry logs/events (when OTEL_LOGS_EXPORTER is configured):
When a user submits a prompt, Claude Code may make multiple API calls and run several tools. The prompt.id attribute lets you tie all of those events back to the single prompt that triggered them.
| Attribute | Description |
|---|---|
prompt.id |
UUID v4 identifier linking all events produced while processing a single user prompt |
To trace all activity triggered by a single prompt, filter your events by a specific prompt.id value. This returns the user_prompt event, any api_request events, and any tool_result events that occurred while processing that prompt.
Note
prompt.id is intentionally excluded from metrics because each prompt generates a unique ID, which would create an ever-growing number of time series. Use it for event-level analysis and audit trails only.
Logged when a user submits a prompt.
Event Name: claude_code.user_prompt
Attributes:
event.name: "user_prompt"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessionprompt_length: Length of the promptprompt: Prompt content (redacted by default, enable with OTEL_LOG_USER_PROMPTS=1)Logged when a tool completes execution.
Event Name: claude_code.tool_result
Attributes:
event.name: "tool_result"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessiontool_name: Name of the toolsuccess: "true" or "false"duration_ms: Execution time in millisecondserror: Error message (if failed)decision_type: Either "accept" or "reject"decision_source: Decision source - "config", "hook", "user_permanent", "user_temporary", "user_abort", or "user_reject"tool_result_size_bytes: Size of the tool result in bytesmcp_server_scope: MCP server scope identifier (for MCP tools)tool_parameters (when OTEL_LOG_TOOL_DETAILS=1): JSON string containing tool-specific parameters:bash_command, full_command, timeout, description, dangerouslyDisableSandbox, and git_commit_id (the commit SHA, when a git commit command succeeds)mcp_server_name, mcp_tool_nameskill_nametool_input (when OTEL_LOG_TOOL_DETAILS=1): JSON-serialized tool arguments. Individual values over 512 characters are truncated, and the full payload is bounded to ~4 K characters. Applies to all tools including MCP tools.Logged for each API request to Claude.
Event Name: claude_code.api_request
Attributes:
event.name: "api_request"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessionmodel: Model used (for example, "claude-sonnet-4-6")cost_usd: Estimated cost in USDduration_ms: Request duration in millisecondsinput_tokens: Number of input tokensoutput_tokens: Number of output tokenscache_read_tokens: Number of tokens read from cachecache_creation_tokens: Number of tokens used for cache creationspeed: "fast" or "normal", indicating whether fast mode was activeLogged when an API request to Claude fails.
Event Name: claude_code.api_error
Attributes:
event.name: "api_error"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessionmodel: Model used (for example, "claude-sonnet-4-6")error: Error messagestatus_code: HTTP status code as a string, or "undefined" for non-HTTP errorsduration_ms: Request duration in millisecondsattempt: Total number of attempts made, including the initial request (1 means no retries occurred)speed: "fast" or "normal", indicating whether fast mode was activeLogged when a tool permission decision is made (accept/reject).
Event Name: claude_code.tool_decision
Attributes:
event.name: "tool_decision"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessiontool_name: Name of the tool (for example, "Read", "Edit", "Write", "NotebookEdit")decision: Either "accept" or "reject"source: Decision source - "config", "hook", "user_permanent", "user_temporary", "user_abort", or "user_reject"Logged when a plugin finishes installing, from both the claude plugin install CLI command and the interactive /plugin UI.
Event Name: claude_code.plugin_installed
Attributes:
event.name: "plugin_installed"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessionplugin.name: Name of the installed pluginplugin.version: Plugin version when declared in the marketplace entrymarketplace.name: Marketplace the plugin was installed frommarketplace.is_official: "true" if the marketplace is an official Anthropic marketplace, "false" otherwiseinstall.trigger: "cli" or "ui"Logged when a skill is invoked.
Event Name: claude_code.skill_activated
Attributes:
event.name: "skill_activated"event.timestamp: ISO 8601 timestampevent.sequence: monotonically increasing counter for ordering events within a sessionskill.name: Name of the skillskill.source: Where the skill was loaded from (for example, "bundled", "userSettings", "projectSettings", "plugin")plugin.name: Name of the owning plugin when the skill is provided by a pluginmarketplace.name: Marketplace the owning plugin was installed from, when the skill is provided by a pluginThe exported metrics and events support a range of analyses:
| Metric | Analysis Opportunity |
|---|---|
claude_code.token.usage |
Break down by type (input/output), user, team, or model |
claude_code.session.count |
Track adoption and engagement over time |
claude_code.lines_of_code.count |
Measure productivity by tracking code additions/removals |
claude_code.commit.count & claude_code.pull_request.count |
Understand impact on development workflows |
The claude_code.cost.usage metric helps with:
Note
Cost metrics are approximations. For official billing data, refer to your API provider (Claude Console, AWS Bedrock, or Google Cloud Vertex).
Common alerts to consider:
All metrics can be segmented by user.account_uuid, user.account_id, organization.id, session.id, model, and app.version.
Claude Code retries failed API requests internally and emits a single claude_code.api_error event only after it gives up, so the event itself is the terminal signal for that request. Intermediate retry attempts are not logged as separate events.
The attempt attribute on the event records how many attempts were made in total. A value greater than CLAUDE_CODE_MAX_RETRIES (default 10) indicates the request exhausted all retries on a transient error. A lower value indicates a non-retryable error such as a 400 response.
To distinguish a session that recovered from one that stalled, group events by session.id and check whether a later api_request event exists after the error.
The event data provides detailed insights into Claude Code interactions:
Tool Usage Patterns: analyze tool result events to identify:
Performance Monitoring: track API request durations and tool execution times to identify performance bottlenecks.
Your choice of metrics, logs, and traces backends determines the types of analyses you can perform:
Choose a backend that supports distributed trace storage and span correlation:
For organizations requiring Daily/Weekly/Monthly Active User (DAU/WAU/MAU) metrics, consider backends that support efficient unique value queries.
All metrics and events are exported with the following resource attributes:
service.name: claude-codeservice.version: Current Claude Code versionos.type: Operating system type (for example, linux, darwin, windows)os.version: Operating system version stringhost.arch: Host architecture (for example, amd64, arm64)wsl.version: WSL version number (only present when running on Windows Subsystem for Linux)com.anthropic.claude_codeFor a comprehensive guide on measuring return on investment for Claude Code, including telemetry setup, cost analysis, productivity metrics, and automated reporting, see the Claude Code ROI Measurement Guide. This repository provides ready-to-use Docker Compose configurations, Prometheus and OpenTelemetry setups, and templates for generating productivity reports integrated with tools like Linear.
OTEL_LOG_TOOL_CONTENT bullet belowuser.email is included in telemetry attributes. If this is a concern for your organization, work with your telemetry backend to filter or redact this fieldOTEL_LOG_USER_PROMPTS=1OTEL_LOG_TOOL_DETAILS=1. When enabled, tool_result events include a tool_parameters attribute with Bash commands, MCP server and tool names, and skill names, plus a tool_input attribute with file paths, URLs, search patterns, and other arguments. Trace spans include the same tool_input attribute and input-derived attributes such as file_path. Individual values over 512 characters are truncated and the total is bounded to ~4 K characters, but the arguments may still contain sensitive values. Configure your telemetry backend to filter or redact these attributes as neededOTEL_LOG_TOOL_CONTENT=1. When enabled, span events include full tool input and output content truncated at 60 KB per span. This can include raw file contents from Read tool results and Bash command output. Configure your telemetry backend to filter or redact these attributes as neededFor detailed Claude Code usage monitoring guidance for Amazon Bedrock, see Claude Code Monitoring Implementation (Bedrock).
Track token usage, set team spend limits, and reduce Claude Code costs with context management, model selection, extended thinking settings, and preprocessing hooks.
Claude Code charges by API token consumption. For subscription plan pricing (Pro, Max, Team, Enterprise), see claude.com/pricing. Per-developer costs vary widely based on model selection, codebase size, and usage patterns such as running multiple instances or automation.
Across enterprise deployments, the average cost is around $13 per developer per active day and $150-250 per developer per month, with costs remaining below $30 per active day for 90% of users. To estimate spend for your own team, start with a small pilot group and use the tracking tools below to establish a baseline before wider rollout.
This page covers how to track your costs, manage costs for teams, and reduce token usage.
/cost commandNote
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 /cost command provides detailed token usage statistics for your current session:
Total cost: $0.55
Total duration (API): 6m 19.7s
Total duration (wall): 6h 33m 10.2s
Total code changes: 0 lines added, 0 lines removed
When using Claude API, you can set workspace spend limits on the total Claude Code workspace spend. Admins can view cost and usage reporting in the Console.
Note
When you first authenticate Claude Code with your Claude Console account, a workspace called "Claude Code" is automatically created for you. This workspace provides centralized cost tracking and management for all Claude Code usage in your organization. You cannot create API keys for this workspace; it is exclusively for Claude Code authentication and usage.
For organizations with custom rate limits, Claude Code traffic in this workspace counts toward your organization's overall API rate limits. You can set a workspace rate limit on this workspace's Limits page in the Claude Console to cap Claude Code's share and protect other production workloads.
On Bedrock, Vertex, and Foundry, Claude Code does not send metrics from your cloud. To get cost metrics, several large enterprises reported using LiteLLM, which is an open-source tool that helps companies track spend by key. This project is unaffiliated with Anthropic and has not been audited for security.
When setting up Claude Code for teams, consider these Token Per Minute (TPM) and Request Per Minute (RPM) per-user recommendations based on your organization size:
| Team size | TPM per user | RPM per user |
|---|---|---|
| 1-5 users | 200k-300k | 5-7 |
| 5-20 users | 100k-150k | 2.5-3.5 |
| 20-50 users | 50k-75k | 1.25-1.75 |
| 50-100 users | 25k-35k | 0.62-0.87 |
| 100-500 users | 15k-20k | 0.37-0.47 |
| 500+ users | 10k-15k | 0.25-0.35 |
For example, if you have 200 users, you might request 20k TPM for each user, or 4 million total TPM (200*20,000 = 4 million).
The TPM per user decreases as team size grows because fewer users tend to use Claude Code concurrently in larger organizations. These rate limits apply at the organization level, not per individual user, which means individual users can temporarily consume more than their calculated share when others aren't actively using the service.
Note
If you anticipate scenarios with unusually high concurrent usage (such as live training sessions with large groups), you may need higher TPM allocations per user.
Agent teams spawn multiple Claude Code instances, each with its own context window. Token usage scales with the number of active teammates and how long each one runs.
To keep agent team costs manageable:
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 in your settings.json or environment to enable them. See enable agent teams.Token costs scale with context size: the more context Claude processes, the more tokens you use. Claude Code automatically optimizes costs through prompt caching (which reduces costs for repeated content like system prompts) and auto-compaction (which summarizes conversation history when approaching context limits).
The following strategies help you keep context small and reduce per-message costs.
Use /cost to check your current token usage, or configure your status line to display it continuously.
/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./compact Focus on code samples and API usage tells Claude what to preserve during summarization.You can also customize compaction behavior in your CLAUDE.md:
# Compact instructions
When you are using compact, please focus on test output and code changes
Sonnet handles most coding tasks well and costs less than Opus. Reserve Opus for complex architectural decisions or multi-step reasoning. Use /model to switch models mid-session, or set a default in /config. For simple subagent tasks, specify model: haiku in your subagent configuration.
MCP tool definitions are deferred by default, so only tool names enter context until Claude uses a specific tool. Run /context to see what's consuming space.
gh, aws, gcloud, and sentry-cli are still more context-efficient than MCP servers because they don't add any per-tool listing. Claude can run CLI commands directly./mcp to see configured servers and disable any you're not actively using.Code intelligence plugins give Claude precise symbol navigation instead of text-based search, reducing unnecessary file reads when exploring unfamiliar code. A single "go to definition" call replaces what might otherwise be a grep followed by reading multiple candidate files. Installed language servers also report type errors automatically after edits, so Claude catches mistakes without running a compiler.
Custom hooks can preprocess data before Claude sees it. Instead of Claude reading a 10,000-line log file to find errors, a hook can grep for ERROR and return only matching lines, reducing context from tens of thousands of tokens to hundreds.
A skill can give Claude domain knowledge so it doesn't have to explore. For example, a "codebase-overview" skill could describe your project's architecture, key directories, and naming conventions. When Claude invokes the skill, it gets this context immediately instead of spending tokens reading multiple files to understand the structure.
For example, this PreToolUse hook filters test output to show only failures:
Add this to your settings.json to run the hook before every Bash command:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/filter-test-output.sh"
}
]
}
]
}
}
The hook calls this script, which checks if the command is a test runner and modifies it to show only failures:
#!/bin/bash input=$(cat) cmd=$(echo "$input" | jq -r '.tool_input.command')If running tests, filter to show only failures
if [[ "$cmd" =~ ^(npm test|pytest|go test) ]]; then filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100" echo "{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","updatedInput":{"command":"$filtered_cmd"}}}" else echo "{}" fi
Your CLAUDE.md file is loaded into context at session start. If it contains detailed instructions for specific workflows (like PR reviews or database migrations), those tokens are present even when you're doing unrelated work. Skills load on-demand only when invoked, so moving specialized instructions into skills keeps your base context smaller. Aim to keep CLAUDE.md under 200 lines by including only essentials.
Extended thinking is enabled by default because it significantly improves performance on complex planning and reasoning tasks. Thinking tokens are billed as output tokens, and the default budget can be tens of thousands of tokens per request depending on the model. For simpler tasks where deep reasoning isn't needed, you can reduce costs by lowering the effort level with /effort or in /model, disabling thinking in /config, or lowering the budget with MAX_THINKING_TOKENS=8000.
Running tests, fetching documentation, or processing log files can consume significant context. Delegate these to subagents so the verbose output stays in the subagent's context while only a summary returns to your main conversation.
Agent teams use approximately 7x more tokens than standard sessions when teammates run in plan mode, because each teammate maintains its own context window and runs as a separate Claude instance. Keep team tasks small and self-contained to limit per-teammate token usage. See agent teams for details.
Vague requests like "improve this codebase" trigger broad scanning. Specific requests like "add input validation to the login function in auth.ts" let Claude work efficiently with minimal file reads.
For longer or more complex work, these habits help avoid wasted tokens from going down the wrong path:
/rewind or double-tap Escape to restore conversation and code to a previous checkpoint.Claude Code uses tokens for some background functionality even when idle:
claude --resume feature/cost may generate requests to check statusThese background processes consume a small amount of tokens (typically under $0.04 per session) even without active interaction.
Claude Code regularly receives updates that may change how features work, including cost reporting. Run claude --version to check your current version. For specific billing questions, contact Anthropic support through your Console account.
View Claude Code usage metrics, track adoption, and measure engineering velocity in the analytics dashboard.
Claude Code provides analytics dashboards to help organizations understand developer usage patterns, track contribution metrics, and measure how Claude Code impacts engineering velocity. Access the dashboard for your plan:
| Plan | Dashboard URL | Includes | Read more |
|---|---|---|---|
| Claude for Teams / Enterprise | claude.ai/analytics/claude-code | Usage metrics, contribution metrics with GitHub integration, leaderboard, data export | Details |
| API (Claude Console) | platform.claude.com/claude-code | Usage metrics, spend tracking, team insights | Details |
Navigate to claude.ai/analytics/claude-code. Admins and Owners can view the dashboard.
The Team and Enterprise dashboard includes:
Note
Contribution metrics are in public beta and available on Claude for Teams and Claude for Enterprise plans. These metrics only cover users within your claude.ai organization. Usage through the Claude Console API or third-party integrations is not included.
Usage and adoption data is available for all Claude for Teams and Claude for Enterprise accounts. Contribution metrics require additional setup to connect your GitHub organization.
You need the Owner role to configure analytics settings. A GitHub admin must install the GitHub app.
Warning
Contribution metrics are not available for organizations with Zero Data Retention enabled. The analytics dashboard will show usage metrics only.
A GitHub admin installs the Claude GitHub app on your organization's GitHub account at github.com/apps/claude.
A Claude Owner navigates to claude.ai/admin-settings/claude-code and enables the Claude Code analytics feature.
On the same page, enable the "GitHub analytics" toggle.
Complete the GitHub authentication flow and select which GitHub organizations to include in the analysis.
Data typically appears within 24 hours after enabling, with daily updates. If no data appears, you may see one of these messages:
Contribution metrics support GitHub Cloud and GitHub Enterprise Server.
Note
These metrics are deliberately conservative and represent an underestimate of Claude Code's actual impact. Only lines and PRs where there is high confidence in Claude Code's involvement are counted.
The dashboard displays these summary metrics at the top:
The dashboard includes several charts to visualize trends over time.
The Adoption chart shows daily usage trends:
This chart displays individual developer activity over time:
Use this to understand how individual productivity changes as Claude Code adoption increases.
The Pull requests chart shows a daily breakdown of merged PRs:
Toggle to Lines of code view to see the same breakdown by lines of code rather than PR count.
The Leaderboard shows the top 10 users ranked by contribution volume. Toggle between:
Click Export all users to download complete contribution data for all users as a CSV file. The export includes all users, not just the top 10 displayed.
When contribution metrics are enabled, Claude Code analyzes merged pull requests to determine which code was written with Claude Code assistance. This is done by matching Claude Code session activity against the code in each PR.
PRs are tagged as "with Claude Code" if they contain at least one line of code written during a Claude Code session. The system uses conservative matching: only code where there is high confidence in Claude Code's involvement is counted as assisted.
When a pull request is merged:
Before comparison, lines are normalized: whitespace is trimmed, multiple spaces are collapsed, quotes are standardized, and text is converted to lowercase.
Merged pull requests containing Claude Code-assisted lines are labeled as claude-code-assisted in GitHub.
Sessions from 21 days before to 2 days after the PR merge date are considered for attribution matching.
Certain files are automatically excluded from analysis because they are auto-generated:
Keep these additional details in mind when interpreting attribution data:
Use contribution metrics to demonstrate ROI, identify adoption patterns, and find team members who can help others get started.
Track the Adoption chart and user counts to identify:
Contribution metrics help answer "Is this tool worth the investment?" with data from your own codebase:
The Leaderboard helps you find team members with high Claude Code adoption who can:
To query this data through GitHub, search for PRs labeled with claude-code-assisted.
API customers using the Claude Console can access analytics at platform.claude.com/claude-code. You need the UsageView permission to access the dashboard, which is granted to Developer, Billing, Admin, Owner, and Primary Owner roles.
Note
Contribution metrics with GitHub integration are not currently available for API customers. The Console dashboard shows usage and spend metrics only.
The Console dashboard displays:
The team insights table shows per-user metrics:
Note
Spend figures in the Console dashboard are estimates for analytics purposes. For actual costs, refer to your billing page.
Build and host plugin marketplaces to distribute Claude Code extensions across teams and communities.
A plugin marketplace is a catalog that lets you distribute plugins to others. Marketplaces provide centralized discovery, version tracking, automatic updates, and support for multiple source types (git repositories, local paths, and more). This guide shows you how to create your own marketplace to share plugins with your team or community.
Looking to install plugins from an existing marketplace? See Discover and install prebuilt plugins.
Creating and distributing a marketplace involves:
marketplace.json that lists your plugins and where to find them (see Create the marketplace file)./plugin marketplace add and install individual plugins (see Discover and install plugins).Once your marketplace is live, you can update it by pushing changes to your repository. Users refresh their local copy with /plugin marketplace update.
This example creates a marketplace with one plugin: a /quality-review skill for code reviews. You'll create the directory structure, add a skill, create the plugin manifest and marketplace catalog, then install and test it.
mkdir -p my-marketplace/.claude-plugin
mkdir -p my-marketplace/plugins/quality-review-plugin/.claude-plugin
mkdir -p my-marketplace/plugins/quality-review-plugin/skills/quality-review
Create a SKILL.md file that defines what the /quality-review skill does.
---
description: Review code for bugs, security, and performance
disable-model-invocation: true
---
Review the code I've selected or the recent changes for:
- Potential bugs or edge cases
- Security concerns
- Performance issues
- Readability improvements
Be concise and actionable.
Create a plugin.json file that describes the plugin. The manifest goes in the .claude-plugin/ directory.
{
"name": "quality-review-plugin",
"description": "Adds a /quality-review skill for quick code reviews",
"version": "1.0.0"
}
Create the marketplace catalog that lists your plugin.
{
"name": "my-plugins",
"owner": {
"name": "Your Name"
},
"plugins": [
{
"name": "quality-review-plugin",
"source": "./plugins/quality-review-plugin",
"description": "Adds a /quality-review skill for quick code reviews"
}
]
}
Add the marketplace and install the plugin.
/plugin marketplace add ./my-marketplace
/plugin install quality-review-plugin@my-plugins
Select some code in your editor and run your new skill.
/quality-review
To learn more about what plugins can do, including hooks, agents, MCP servers, and LSP servers, see Plugins.
Note
How plugins are installed: When users install a plugin, Claude Code copies the plugin directory to a cache location. This means plugins can't reference files outside their directory using paths like ../shared-utils, because those files won't be copied.
If you need to share files across plugins, use symlinks. See Plugin caching and file resolution for details.
Create .claude-plugin/marketplace.json in your repository root. This file defines your marketplace's name, owner information, and a list of plugins with their sources.
Each plugin entry needs at minimum a name and source (where to fetch it from). See the full schema below for all available fields.
{
"name": "company-tools",
"owner": {
"name": "DevTools Team",
"email": "[email protected]"
},
"plugins": [
{
"name": "code-formatter",
"source": "./plugins/formatter",
"description": "Automatic code formatting on save",
"version": "2.1.0",
"author": {
"name": "DevTools Team"
}
},
{
"name": "deployment-tools",
"source": {
"source": "github",
"repo": "company/deploy-plugin"
},
"description": "Deployment automation tools"
}
]
}
| Field | Type | Description | Example |
|---|---|---|---|
name |
string | Marketplace identifier (kebab-case, no spaces). This is public-facing: users see it when installing plugins (for example, /plugin install my-tool@your-marketplace). |
"acme-tools" |
owner |
object | Marketplace maintainer information (see fields below) | |
plugins |
array | List of available plugins | See below |
Note
Reserved names: The following marketplace names are reserved for official Anthropic use and cannot be used by third-party marketplaces: claude-code-marketplace, claude-code-plugins, claude-plugins-official, anthropic-marketplace, anthropic-plugins, agent-skills, knowledge-work-plugins, life-sciences. Names that impersonate official marketplaces (like official-claude-plugins or anthropic-tools-v2) are also blocked.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Name of the maintainer or team |
email |
string | No | Contact email for the maintainer |
| Field | Type | Description |
|---|---|---|
metadata.description |
string | Brief marketplace description |
metadata.version |
string | Marketplace version |
metadata.pluginRoot |
string | Base directory prepended to relative plugin source paths (for example, "./plugins" lets you write "source": "formatter" instead of "source": "./plugins/formatter") |
Each plugin entry in the plugins array describes a plugin and where to find it. You can include any field from the plugin manifest schema (like description, version, author, commands, hooks, etc.), plus these marketplace-specific fields: source, category, tags, and strict.
| Field | Type | Description |
|---|---|---|
name |
string | Plugin identifier (kebab-case, no spaces). This is public-facing: users see it when installing (for example, /plugin install my-plugin@marketplace). |
source |
string|object | Where to fetch the plugin from (see Plugin sources below) |
Standard metadata fields:
| Field | Type | Description |
|---|---|---|
description |
string | Brief plugin description |
version |
string | Plugin version |
author |
object | Plugin author information (name required, email optional) |
homepage |
string | Plugin homepage or documentation URL |
repository |
string | Source code repository URL |
license |
string | SPDX license identifier (for example, MIT, Apache-2.0) |
keywords |
array | Tags for plugin discovery and categorization |
category |
string | Plugin category for organization |
tags |
array | Tags for searchability |
strict |
boolean | Controls whether plugin.json is the authority for component definitions (default: true). See Strict mode below. |
Component configuration fields:
| Field | Type | Description |
|---|---|---|
skills |
string|array | Custom paths to skill directories containing <name>/SKILL.md |
commands |
string|array | Custom paths to flat .md skill files or directories |
agents |
string|array | Custom paths to agent files |
hooks |
string|object | Custom hooks configuration or path to hooks file |
mcpServers |
string|object | MCP server configurations or path to MCP config |
lspServers |
string|object | LSP server configurations or path to LSP config |
Plugin sources tell Claude Code where to fetch each individual plugin listed in your marketplace. These are set in the source field of each plugin entry in marketplace.json.
Once a plugin is cloned or copied into the local machine, it is copied into the local versioned plugin cache at ~/.claude/plugins/cache.
| Source | Type | Fields | Notes |
|---|---|---|---|
| Relative path | string (e.g. "./my-plugin") |
none | Local directory within the marketplace repo. Must start with ./. Resolved relative to the marketplace root, not the .claude-plugin/ directory |
github |
object | repo, ref?, sha? |
|
url |
object | url, ref?, sha? |
Git URL source |
git-subdir |
object | url, path, ref?, sha? |
Subdirectory within a git repo. Clones sparsely to minimize bandwidth for monorepos |
npm |
object | package, version?, registry? |
Installed via npm install |
Note
Marketplace sources vs plugin sources: These are different concepts that control different things.
marketplace.json catalog itself. Set when users run /plugin marketplace add or in extraKnownMarketplaces settings. Supports ref (branch/tag) but not sha.source field of each plugin entry inside marketplace.json. Supports both ref (branch/tag) and sha (exact commit).For example, a marketplace hosted at acme-corp/plugin-catalog (marketplace source) can list a plugin fetched from acme-corp/code-formatter (plugin source). The marketplace source and plugin source point to different repositories and are pinned independently.
For plugins in the same repository, use a path starting with ./:
{
"name": "my-plugin",
"source": "./plugins/my-plugin"
}
Paths resolve relative to the marketplace root, which is the directory containing .claude-plugin/. In the example above, ./plugins/my-plugin points to <repo>/plugins/my-plugin, even though marketplace.json lives at <repo>/.claude-plugin/marketplace.json. Do not use ../ to reference paths outside the marketplace root.
Note
Relative paths only work when users add your marketplace via Git (GitHub, GitLab, or git URL). If users add your marketplace via a direct URL to the marketplace.json file, relative paths will not resolve correctly. For URL-based distribution, use GitHub, npm, or git URL sources instead. See Troubleshooting for details.
{
"name": "github-plugin",
"source": {
"source": "github",
"repo": "owner/plugin-repo"
}
}
You can pin to a specific branch, tag, or commit:
{
"name": "github-plugin",
"source": {
"source": "github",
"repo": "owner/plugin-repo",
"ref": "v2.0.0",
"sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
}
| Field | Type | Description |
|---|---|---|
repo |
string | Required. GitHub repository in owner/repo format |
ref |
string | Optional. Git branch or tag (defaults to repository default branch) |
sha |
string | Optional. Full 40-character git commit SHA to pin to an exact version |
{
"name": "git-plugin",
"source": {
"source": "url",
"url": "https://gitlab.com/team/plugin.git"
}
}
You can pin to a specific branch, tag, or commit:
{
"name": "git-plugin",
"source": {
"source": "url",
"url": "https://gitlab.com/team/plugin.git",
"ref": "main",
"sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
}
| Field | Type | Description |
|---|---|---|
url |
string | Required. Full git repository URL (https:// or git@). The .git suffix is optional, so Azure DevOps and AWS CodeCommit URLs without the suffix work |
ref |
string | Optional. Git branch or tag (defaults to repository default branch) |
sha |
string | Optional. Full 40-character git commit SHA to pin to an exact version |
Use git-subdir to point to a plugin that lives inside a subdirectory of a git repository. Claude Code uses a sparse, partial clone to fetch only the subdirectory, minimizing bandwidth for large monorepos.
{
"name": "my-plugin",
"source": {
"source": "git-subdir",
"url": "https://github.com/acme-corp/monorepo.git",
"path": "tools/claude-plugin"
}
}
You can pin to a specific branch, tag, or commit:
{
"name": "my-plugin",
"source": {
"source": "git-subdir",
"url": "https://github.com/acme-corp/monorepo.git",
"path": "tools/claude-plugin",
"ref": "v2.0.0",
"sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
}
The url field also accepts a GitHub shorthand (owner/repo) or SSH URLs ([email protected]:owner/repo.git).
| Field | Type | Description |
|---|---|---|
url |
string | Required. Git repository URL, GitHub owner/repo shorthand, or SSH URL |
path |
string | Required. Subdirectory path within the repo containing the plugin (for example, "tools/claude-plugin") |
ref |
string | Optional. Git branch or tag (defaults to repository default branch) |
sha |
string | Optional. Full 40-character git commit SHA to pin to an exact version |
Plugins distributed as npm packages are installed using npm install. This works with any package on the public npm registry or a private registry your team hosts.
{
"name": "my-npm-plugin",
"source": {
"source": "npm",
"package": "@acme/claude-plugin"
}
}
To pin to a specific version, add the version field:
{
"name": "my-npm-plugin",
"source": {
"source": "npm",
"package": "@acme/claude-plugin",
"version": "2.1.0"
}
}
To install from a private or internal registry, add the registry field:
{
"name": "my-npm-plugin",
"source": {
"source": "npm",
"package": "@acme/claude-plugin",
"version": "^2.0.0",
"registry": "https://npm.example.com"
}
}
| Field | Type | Description |
|---|---|---|
package |
string | Required. Package name or scoped package (for example, @org/plugin) |
version |
string | Optional. Version or version range (for example, 2.1.0, ^2.0.0, ~1.5.0) |
registry |
string | Optional. Custom npm registry URL. Defaults to the system npm registry (typically npmjs.org) |
This example shows a plugin entry using many of the optional fields, including custom paths for commands, agents, hooks, and MCP servers:
{
"name": "enterprise-tools",
"source": {
"source": "github",
"repo": "company/enterprise-plugin"
},
"description": "Enterprise workflow automation tools",
"version": "2.1.0",
"author": {
"name": "Enterprise Team",
"email": "[email protected]"
},
"homepage": "https://docs.example.com/plugins/enterprise-tools",
"repository": "https://github.com/company/enterprise-plugin",
"license": "MIT",
"keywords": ["enterprise", "workflow", "automation"],
"category": "productivity",
"commands": [
"./commands/core/",
"./commands/enterprise/",
"./commands/experimental/preview.md"
],
"agents": ["./agents/security-reviewer.md", "./agents/compliance-checker.md"],
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh"
}
]
}
]
},
"mcpServers": {
"enterprise-db": {
"command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"]
}
},
"strict": false
}
Key things to notice:
commands and agents: You can specify multiple directories or individual files. Paths are relative to the plugin root.${CLAUDE_PLUGIN_ROOT}: use this variable in hooks and MCP server configs to reference files within the plugin's installation directory. This is necessary because plugins are copied to a cache location when installed. For dependencies or state that should survive plugin updates, use ${CLAUDE_PLUGIN_DATA} instead.strict: false: Since this is set to false, the plugin doesn't need its own plugin.json. The marketplace entry defines everything. See Strict mode below.The strict field controls whether plugin.json is the authority for component definitions (skills, agents, hooks, MCP servers, output styles).
| Value | Behavior |
|---|---|
true (default) |
plugin.json is the authority. The marketplace entry can supplement it with additional components, and both sources are merged. |
false |
The marketplace entry is the entire definition. If the plugin also has a plugin.json that declares components, that's a conflict and the plugin fails to load. |
When to use each mode:
strict: true: the plugin has its own plugin.json and manages its own components. The marketplace entry can add extra skills or hooks on top. This is the default and works for most plugins.strict: false: the marketplace operator wants full control. The plugin repo provides raw files, and the marketplace entry defines which of those files are exposed as skills, agents, hooks, etc. Useful when the marketplace restructures or curates a plugin's components differently than the plugin author intended.GitHub provides the easiest distribution method:
.claude-plugin/marketplace.json with your plugin definitions/plugin marketplace add owner/repoBenefits: Built-in version control, issue tracking, and team collaboration features.
Any git hosting service works, such as GitLab, Bitbucket, and self-hosted servers. Users add with the full repository URL:
/plugin marketplace add https://gitlab.com/company/plugins.git
Claude Code supports installing plugins from private repositories. For manual installation and updates, Claude Code uses your existing git credential helpers. If git clone works for a private repository in your terminal, it works in Claude Code too. Common credential helpers include gh auth login for GitHub, macOS Keychain, and git-credential-store.
Background auto-updates run at startup without credential helpers, since interactive prompts would block Claude Code from starting. To enable auto-updates for private marketplaces, set the appropriate authentication token in your environment:
| Provider | Environment variables | Notes |
|---|---|---|
| GitHub | GITHUB_TOKEN or GH_TOKEN |
Personal access token or GitHub App token |
| GitLab | GITLAB_TOKEN or GL_TOKEN |
Personal access token or project token |
| Bitbucket | BITBUCKET_TOKEN |
App password or repository access token |
Set the token in your shell configuration (for example, .bashrc, .zshrc) or pass it when running Claude Code:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
Note
For CI/CD environments, configure the token as a secret environment variable. GitHub Actions automatically provides GITHUB_TOKEN for repositories in the same organization.
Test your marketplace locally before sharing:
/plugin marketplace add ./my-local-marketplace
/plugin install test-plugin@my-local-marketplace
For the full range of add commands (GitHub, Git URLs, local paths, remote URLs), see Add marketplaces.
You can configure your repository so team members are automatically prompted to install your marketplace when they trust the project folder. Add your marketplace to .claude/settings.json:
{
"extraKnownMarketplaces": {
"company-tools": {
"source": {
"source": "github",
"repo": "your-org/claude-plugins"
}
}
}
}
You can also specify which plugins should be enabled by default:
{
"enabledPlugins": {
"code-formatter@company-tools": true,
"deployment-tools@company-tools": true
}
}
For full configuration options, see Plugin settings.
Note
If you use a local directory or file source with a relative path, the path resolves against your repository's main checkout. When you run Claude Code from a git worktree, the path still points at the main checkout, so all worktrees share the same marketplace location. Marketplace state is stored once per user in ~/.claude/plugins/known_marketplaces.json, not per project.
For container images and CI environments, you can pre-populate a plugins directory at build time so Claude Code starts with marketplaces and plugins already available, without cloning anything at runtime. Set the CLAUDE_CODE_PLUGIN_SEED_DIR environment variable to point at this directory.
To layer multiple seed directories, separate paths with : on Unix or ; on Windows. Claude Code searches each directory in order, and the first seed that contains a given marketplace or plugin cache wins.
The seed directory mirrors the structure of ~/.claude/plugins:
$CLAUDE_CODE_PLUGIN_SEED_DIR/
known_marketplaces.json
marketplaces/<name>/...
cache/<marketplace>/<plugin>/<version>/...
To build a seed directory, run Claude Code once during image build, install the plugins you need, then copy the resulting ~/.claude/plugins directory into your image and point CLAUDE_CODE_PLUGIN_SEED_DIR at it.
To skip the copy step, set CLAUDE_CODE_PLUGIN_CACHE_DIR to your target seed path during the build so plugins install directly there:
CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin marketplace add your-org/plugins
CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin install my-tool@your-plugins
Then set CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/claude-seed in your container's runtime environment so Claude Code reads from the seed on startup.
At startup, Claude Code registers marketplaces found in the seed's known_marketplaces.json into the primary configuration, and uses plugin caches found under cache/ in place without re-cloning. This works in both interactive mode and non-interactive mode with the -p flag.
Behavior details:
/plugin disable rather than removing the marketplace.$CLAUDE_CODE_PLUGIN_SEED_DIR/marketplaces/<name>/ at runtime, not by trusting paths stored inside the seed's JSON. This means the seed works correctly even when mounted at a different path than where it was built./plugin marketplace remove or /plugin marketplace update against a seed-managed marketplace fails with guidance to ask your administrator to update the seed image.extraKnownMarketplaces or enabledPlugins declare a marketplace that already exists in the seed, Claude Code uses the seed copy instead of cloning.For organizations requiring strict control over plugin sources, administrators can restrict which plugin marketplaces users are allowed to add using the strictKnownMarketplaces setting in managed settings.
When strictKnownMarketplaces is configured in managed settings, the restriction behavior depends on the value:
| Value | Behavior |
|---|---|
| Undefined (default) | No restrictions. Users can add any marketplace |
Empty array [] |
Complete lockdown. Users cannot add any new marketplaces |
| List of sources | Users can only add marketplaces that match the allowlist exactly |
Disable all marketplace additions:
{
"strictKnownMarketplaces": []
}
Allow specific marketplaces only:
{
"strictKnownMarketplaces": [
{
"source": "github",
"repo": "acme-corp/approved-plugins"
},
{
"source": "github",
"repo": "acme-corp/security-tools",
"ref": "v2.0"
},
{
"source": "url",
"url": "https://plugins.example.com/marketplace.json"
}
]
}
Allow all marketplaces from an internal git server using regex pattern matching on the host. This is the recommended approach for GitHub Enterprise Server or self-hosted GitLab instances:
{
"strictKnownMarketplaces": [
{
"source": "hostPattern",
"hostPattern": "^github\\.example\\.com$"
}
]
}
Allow filesystem-based marketplaces from a specific directory using regex pattern matching on the path:
{
"strictKnownMarketplaces": [
{
"source": "pathPattern",
"pathPattern": "^/opt/approved/"
}
]
}
Use ".*" as the pathPattern to allow any filesystem path while still controlling network sources with hostPattern.
Note
strictKnownMarketplaces restricts what users can add, but does not register marketplaces on its own. To make allowed marketplaces available automatically without users running /plugin marketplace add, pair it with extraKnownMarketplaces in the same managed-settings.json. See Using both together.
Restrictions are validated early in the plugin installation process, before any network requests or filesystem operations occur. This prevents unauthorized marketplace access attempts.
The allowlist uses exact matching for most source types. For a marketplace to be allowed, all specified fields must match exactly:
repo is required, and ref or path must also match if specified in the allowlisthostPattern sources: the marketplace host is matched against the regex patternpathPattern sources: the marketplace's filesystem path is matched against the regex patternBecause strictKnownMarketplaces is set in managed settings, individual users and project configurations cannot override these restrictions.
For complete configuration details including all supported source types and comparison with extraKnownMarketplaces, see the strictKnownMarketplaces reference.
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).
Warning
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.
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.
Warning
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.
{
"name": "stable-tools",
"plugins": [
{
"name": "code-formatter",
"source": {
"source": "github",
"repo": "acme-corp/code-formatter",
"ref": "stable"
}
}
]
}
{
"name": "latest-tools",
"plugins": [
{
"name": "code-formatter",
"source": {
"source": "github",
"repo": "acme-corp/code-formatter",
"ref": "latest"
}
}
]
}
Assign each marketplace to the appropriate user group through managed settings. For example, the stable group receives:
{
"extraKnownMarketplaces": {
"stable-tools": {
"source": {
"source": "github",
"repo": "acme-corp/stable-tools"
}
}
}
}
The early-access group receives latest-tools instead:
{
"extraKnownMarketplaces": {
"latest-tools": {
"source": {
"source": "github",
"repo": "acme-corp/latest-tools"
}
}
}
}
Test your marketplace before sharing.
Validate your marketplace JSON syntax:
claude plugin validate .
Or from within Claude Code:
/plugin validate .
Add the marketplace for testing:
/plugin marketplace add ./path/to/marketplace
Install a test plugin to verify everything works:
/plugin install test-plugin@marketplace-name
For complete plugin testing workflows, see Test your plugins locally. For technical troubleshooting, see Plugins reference.
Claude Code provides non-interactive claude plugin marketplace subcommands for scripting and automation. These are equivalent to the /plugin marketplace commands available inside an interactive session.
Add a marketplace from a GitHub repository, git URL, remote URL, or local path.
claude plugin marketplace add <source> [options]
Arguments:
<source>: GitHub owner/repo shorthand, git URL, remote URL to a marketplace.json file, or local directory path. To pin to a branch or tag, append @ref to the GitHub shorthand or #ref to a git URLOptions:
| Option | Description | Default |
|---|---|---|
--scope <scope> |
Where to declare the marketplace: user, project, or local. See Plugin installation scopes |
user |
--sparse <paths...> |
Limit checkout to specific directories via git sparse-checkout. Useful for monorepos |
Add a marketplace from GitHub using owner/repo shorthand:
claude plugin marketplace add acme-corp/claude-plugins
Pin to a specific branch or tag with @ref:
claude plugin marketplace add acme-corp/[email protected]
Add from a git URL on a non-GitHub host:
claude plugin marketplace add https://gitlab.example.com/team/plugins.git
Add from a remote URL that serves the marketplace.json file directly:
claude plugin marketplace add https://example.com/marketplace.json
Add from a local directory for testing:
claude plugin marketplace add ./my-marketplace
Declare the marketplace at project scope so it is shared with your team via .claude/settings.json:
claude plugin marketplace add acme-corp/claude-plugins --scope project
For a monorepo, limit the checkout to the directories that contain plugin content:
claude plugin marketplace add acme-corp/monorepo --sparse .claude-plugin plugins
List all configured marketplaces.
claude plugin marketplace list [options]
Options:
| Option | Description |
|---|---|
--json |
Output as JSON |
Remove a configured marketplace. The alias rm is also accepted.
claude plugin marketplace remove <name>
Arguments:
<name>: marketplace name to remove, as shown by claude plugin marketplace list. This is the name from marketplace.json, not the source you passed to addWarning
Removing a marketplace also uninstalls any plugins you installed from it. To refresh a marketplace without losing installed plugins, use claude plugin marketplace update instead.
Refresh marketplaces from their sources to retrieve new plugins and version changes.
claude plugin marketplace update [name]
Arguments:
[name]: marketplace name to update, as shown by claude plugin marketplace list. Updates all marketplaces if omittedBoth remove and update fail when run against a seed-managed marketplace, which is read-only. When updating all marketplaces, seed-managed entries are skipped and other marketplaces still update. To change seed-provided plugins, ask your administrator to update the seed image. See Pre-populate plugins for containers.
Symptoms: Can't add marketplace or see plugins from it
Solutions:
.claude-plugin/marketplace.json exists at the specified pathclaude plugin validate or /plugin validateRun claude plugin validate . or /plugin validate . from your marketplace directory to check for issues. The validator checks plugin.json, skill/agent/command frontmatter, and hooks/hooks.json for syntax and schema errors. Common errors:
| Error | Cause | Solution |
|---|---|---|
File not found: .claude-plugin/marketplace.json |
Missing manifest | Create .claude-plugin/marketplace.json with required fields |
Invalid JSON syntax: Unexpected token... |
JSON syntax error in marketplace.json | Check for missing commas, extra commas, or unquoted strings |
Duplicate plugin name "x" found in marketplace |
Two plugins share the same name | Give each plugin a unique name value |
plugins[0].source: Path contains ".." |
Source path contains .. |
Use paths relative to the marketplace root without ... See Relative paths |
YAML frontmatter failed to parse: ... |
Invalid YAML in a skill, agent, or command file | Fix the YAML syntax in the frontmatter block. At runtime this file loads with no metadata. |
Invalid JSON syntax: ... (hooks.json) |
Malformed hooks/hooks.json |
Fix JSON syntax. A malformed hooks/hooks.json prevents the entire plugin from loading. |
Warnings (non-blocking):
Marketplace has no plugins defined: add at least one plugin to the plugins arrayNo marketplace description provided: add metadata.description to help users understand your marketplacePlugin name "x" is not kebab-case: the plugin name contains uppercase letters, spaces, or special characters. Rename to lowercase letters, digits, and hyphens only (for example, my-plugin). Claude Code accepts other forms, but the Claude.ai marketplace sync rejects them.Symptoms: Marketplace appears but plugin installation fails
Solutions:
Symptoms: Authentication errors when installing plugins from private repositories
Solutions:
For manual installation and updates:
gh auth status for GitHub)git config --global credential.helperFor background auto-updates:
echo $GITHUB_TOKENrepo scope for private repositoriesread_repository scopeSymptoms: Marketplace git pull fails and Claude Code wipes the existing cache, causing plugins to become unavailable.
Cause: By default, when a git pull fails, Claude Code removes the stale clone and attempts to re-clone. In offline or airgapped environments, re-cloning fails the same way, leaving the marketplace directory empty.
Solution: Set CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1 to keep the existing cache when the pull fails instead of wiping it:
export CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1
With this variable set, Claude Code retains the stale marketplace clone on git pull failure and continues using the last-known-good state. For fully offline deployments where the repository will never be reachable, use CLAUDE_CODE_PLUGIN_SEED_DIR to pre-populate the plugins directory at build time instead.
Symptoms: Plugin installation or marketplace updates fail with a timeout error like "Git clone timed out after 120s" or "Git pull timed out after 120s".
Cause: Claude Code uses a 120-second timeout for all git operations, including cloning plugin repositories and pulling marketplace updates. Large repositories or slow network connections may exceed this limit.
Solution: Increase the timeout using the CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS environment variable. The value is in milliseconds:
export CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS=300000 # 5 minutes
Symptoms: Added a marketplace via URL (such as https://example.com/marketplace.json), but plugins with relative path sources like "./plugins/my-plugin" fail to install with "path not found" errors.
Cause: URL-based marketplaces only download the marketplace.json file itself. They do not download plugin files from the server. Relative paths in the marketplace entry reference files on the remote server that were not downloaded.
Solutions:
{ "name": "my-plugin", "source": { "source": "github", "repo": "owner/repo" } }
Symptoms: Plugin installs but references to files fail, especially files outside the plugin directory
Cause: Plugins are copied to a cache directory rather than used in-place. Paths that reference files outside the plugin's directory (such as ../shared-utils) won't work because those files aren't copied.
Solutions: See Plugin caching and file resolution for workarounds including symlinks and directory restructuring.
For additional debugging tools and common issues, see Debugging and development tools.