Growth Kit 2.0 is here! CRO, Paid Ads & more! Code Kit v4.6 released for CC's new Task System.
Claude FastClaude Fast

Claude Code Settings Reference: Every Config Option Explained

Complete reference for Claude Code settings.json, environment variables, and the 5-scope hierarchy. Every setting key, permission rule, and sandbox option documented.

Most Claude Code frustrations trace back to one root cause: configuration that doesn't match how you actually work. You're either approving every command manually, missing team-shared defaults, or wondering why a setting you changed has no effect.

The fix is understanding Claude Code's settings system. Not just the keys and values, but the hierarchy that decides which setting wins when multiple scopes conflict.

Quick Win: Add a $schema line to your settings.json and get instant autocomplete for every option:

{
  "$schema": "https://json-schema.org/claude-code-settings.json",
  "permissions": {
    "allow": ["Bash(npm run lint)", "Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

That schema enables autocompletion and inline validation in VS Code, Cursor, and any editor with JSON schema support.

The 5-Scope Hierarchy

Claude Code settings follow a strict precedence system. Understanding this hierarchy is the difference between "my setting isn't working" and "I put it in the wrong scope."

Scope Precedence (Highest to Lowest)

PriorityScopeLocationWho It AffectsShared?
1ManagedSystem directoriesAll users on machineYes (IT-deployed)
2Command lineCLI flagsCurrent session onlyNo
3Local.claude/settings.local.jsonYou, this projectNo (gitignored)
4Project.claude/settings.jsonAll collaboratorsYes (in git)
5User~/.claude/settings.jsonYou, all projectsNo

The rule is straightforward: higher-scoped settings always override lower ones. If your IT team sets a managed policy that denies Bash(curl *), no user or project setting can override it. Period.

When to Use Each Scope

Managed is for organizations that need enforcement without exceptions:

  • Security policies (deny access to credentials, block destructive commands)
  • Compliance rules that apply across every developer and every project
  • Standardized hooks or MCP server configurations deployed by IT

Command line is for one-off session overrides:

  • Testing with a different model: claude --model claude-sonnet-4-5-20250929
  • Running with extra permissions for a specific task
  • Debugging with --debug flag

Local is your personal playground for a specific repo:

  • Override a project setting that doesn't fit your machine
  • Test a hook before proposing it to the team
  • Machine-specific paths (your SSH key location, local proxy port)

Project is for team alignment:

  • Permission rules everyone should follow
  • Shared hooks for auto-formatting or linting
  • MCP server configurations the whole team uses
  • CLAUDE.md instructions for project context

User is your personal defaults:

  • Preferred language, theme, and output style
  • Plugins you use across every project
  • Global permission rules (like always denying access to ~/.ssh)

Managed Settings Paths by OS

Managed settings require administrator privileges and live outside user home directories:

Operating SystemPath
macOS/Library/Application Support/ClaudeCode/
Linux / WSL/etc/claude-code/
WindowsC:\Program Files\ClaudeCode\

Two files go here: managed-settings.json for settings and managed-mcp.json for MCP servers.

Complete Settings File Locations

Every configuration surface in Claude Code maps to a specific file at each scope:

FeatureUserProject (shared)Local (personal)
Settings~/.claude/settings.json.claude/settings.json.claude/settings.local.json
Subagents~/.claude/agents/.claude/agents/N/A
MCP servers~/.claude.json.mcp.json~/.claude.json (per-project)
Plugins~/.claude/settings.json.claude/settings.json.claude/settings.local.json
CLAUDE.md~/.claude/CLAUDE.mdCLAUDE.md or .claude/CLAUDE.mdCLAUDE.local.md

Claude Code automatically creates timestamped backups of configuration files and retains the five most recent. So if you break something, your last working config is recoverable.

All Settings Keys by Category

Here is every available key you can put in settings.json, organized by what it controls.

General Settings

KeyDescriptionDefaultExample
modelOverride the default model(system default)"claude-sonnet-4-5-20250929"
languageClaude's preferred response languageEnglish"japanese"
outputStyleAdjust system prompt style(none)"Explanatory"
cleanupPeriodDaysDays before inactive sessions are deleted3020
autoUpdatesChannelRelease channel: "stable" or "latest""latest""stable"
showTurnDurationShow response timing ("Cooked for 1m 6s")truefalse
spinnerVerbsCustomize spinner text(defaults){"mode": "append", "verbs": ["Pondering"]}
spinnerTipsEnabledShow tips while Claude workstruefalse
terminalProgressBarEnabledTerminal progress bar (iTerm2, Windows Terminal)truefalse
alwaysThinkingEnabledEnable extended thinking by defaultfalsetrue
plansDirectoryWhere plan files are stored~/.claude/plans"./plans"
respectGitignore@ file picker respects .gitignoretruefalse
companyAnnouncementsMessages shown at startup (random cycle)(none)["Review guidelines at docs.acme.com"]

Permission Settings

These live inside the "permissions" object. For a deep dive into how permissions work in practice, see the permission management guide.

KeyDescriptionExample
allowRules to auto-allow tool use["Bash(npm run lint)", "Read(~/.zshrc)"]
askRules that require confirmation["Bash(git push *)"]
denyRules to block tool use entirely["WebFetch", "Bash(curl *)", "Read(./.env)"]
additionalDirectoriesExtra directories Claude can access["../docs/", "../shared/"]
defaultModeDefault permission mode at launch"acceptEdits"
disableBypassPermissionsModeBlock --dangerously-skip-permissions"disable"

Permission rule evaluation order: Deny rules are checked first, then ask, then allow. First match wins.

Rule syntax examples:

RuleWhat It Matches
BashAll Bash commands
Bash(npm run *)Commands starting with npm run
Read(./.env)Reading the .env file
Read(./secrets/**)Reading anything in secrets/
WebFetch(domain:example.com)Fetch requests to example.com

Sandbox Settings

These live inside the "sandbox" object and control bash command isolation. Filesystem and network restrictions use permission rules (Read, Edit, WebFetch), not sandbox settings.

KeyDescriptionDefaultExample
enabledEnable bash sandboxingfalsetrue
autoAllowBashIfSandboxedAuto-approve commands when sandboxedtruetrue
excludedCommandsCommands that run outside sandbox(none)["git", "docker"]
allowUnsandboxedCommandsAllow dangerouslyDisableSandbox escapetruefalse
enableWeakerNestedSandboxWeaker sandbox for Docker (Linux/WSL2)falsetrue
network.allowedDomainsOutbound domains whitelist(none)["github.com", "*.npmjs.org"]
network.allowUnixSocketsUnix socket paths accessible in sandbox(none)["~/.ssh/agent-socket"]
network.allowAllUnixSocketsAllow all Unix socket connectionsfalsetrue
network.allowLocalBindingAllow binding to localhost (macOS only)falsetrue
network.httpProxyPortCustom HTTP proxy port(auto)8080
network.socksProxyPortCustom SOCKS5 proxy port(auto)8081

Attribution Settings

These live inside the "attribution" object and control how Claude marks its contributions in git.

KeyDescriptionDefault
commitText appended to git commit messages"Generated with Claude Code..." + Co-Authored-By trailer
prText appended to pull request descriptions"Generated with Claude Code..."

Set either to an empty string "" to hide that attribution. The older includeCoAuthoredBy key still works but is deprecated.

{
  "attribution": {
    "commit": "Generated with AI\n\nCo-Authored-By: AI <[email protected]>",
    "pr": ""
  }
}

Plugin Settings

KeyDescriptionExample
enabledPluginsToggle plugins on/off{"formatter@acme-tools": true}
extraKnownMarketplacesAdditional plugin sourcesSee example below
strictKnownMarketplaces(Managed only) Restrict marketplace sources[{"source": "github", "repo": "acme/plugins"}]
{
  "enabledPlugins": {
    "formatter@acme-tools": true,
    "deployer@acme-tools": true,
    "analyzer@security-plugins": false
  },
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": "github",
      "repo": "acme-corp/claude-plugins"
    }
  }
}

Marketplace source types include github (repo), git (any URL), directory (local path for development), and hostPattern (regex matching).

MCP Server Settings

KeyDescriptionExample
enableAllProjectMcpServersAuto-approve all project MCP serverstrue
enabledMcpjsonServersSpecific MCP servers to approve["memory", "github"]
disabledMcpjsonServersSpecific MCP servers to reject["filesystem"]
allowedMcpServers(Managed only) MCP server allowlist[{"serverName": "github"}]
deniedMcpServers(Managed only) MCP server denylist[{"serverName": "filesystem"}]

For a full walkthrough of MCP configuration, see the MCP basics guide.

Authentication and Provider Settings

KeyDescriptionExample
apiKeyHelperScript to generate auth value"/bin/generate_temp_api_key.sh"
forceLoginMethodRestrict to claudeai or console"claudeai"
forceLoginOrgUUIDAuto-select organization during login"xxxxxxxx-xxxx-..."
awsAuthRefreshScript to refresh AWS credentials"aws sso login --profile myprofile"
awsCredentialExportScript outputting AWS credential JSON"/bin/generate_aws_grant.sh"
otelHeadersHelperScript generating OpenTelemetry headers"/bin/generate_otel_headers.sh"

Hook and Advanced Settings

KeyDescriptionExample
hooksLifecycle event hook configurationSee hooks guide
disableAllHooksDisable all hookstrue
allowManagedHooksOnly(Managed only) Block user/project hookstrue
allowManagedPermissionRulesOnly(Managed only) Block user/project permission rulestrue
fileSuggestionCustom @ file autocomplete script{"type": "command", "command": "~/.claude/file-suggestion.sh"}
statusLineCustom status line display{"type": "command", "command": "~/.claude/statusline.sh"}
envEnvironment variables for every session{"FOO": "bar"}

File Suggestion Configuration

If your project is a large monorepo where the default file picker is slow, you can replace it with a custom command:

{
  "fileSuggestion": {
    "type": "command",
    "command": "~/.claude/file-suggestion.sh"
  }
}

The command receives JSON via stdin with a query field ({"query": "src/comp"}) and outputs newline-separated file paths to stdout (limited to 15 results). The same environment variables available to hooks are accessible here, including CLAUDE_PROJECT_DIR.

Essential Environment Variables

Claude Code recognizes roughly 70 environment variables. Most are niche, but about 20 of them show up regularly in real workflows. Here are the ones worth knowing, organized by what you're trying to do.

Model and Provider

VariablePurpose
ANTHROPIC_API_KEYAPI key for direct API access
ANTHROPIC_MODELOverride the default model
ANTHROPIC_DEFAULT_SONNET_MODELModel name for Sonnet alias
CLAUDE_CODE_SUBAGENT_MODELModel for subagents (separate from main model)
CLAUDE_CODE_USE_BEDROCKRoute through AWS Bedrock
CLAUDE_CODE_USE_VERTEXRoute through Google Vertex

The model aliases (ANTHROPIC_DEFAULT_SONNET_MODEL, ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_HAIKU_MODEL) are useful when your organization runs custom fine-tuned models behind the standard aliases. Set the alias once and every session picks it up.

Performance Tuning

VariablePurpose
CLAUDE_CODE_MAX_OUTPUT_TOKENSMax output tokens (default: 32K, max: 64K)
MAX_THINKING_TOKENSExtended thinking budget (default: 31,999, set 0 to disable)
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE% of context capacity (1-100) triggering auto-compaction
BASH_DEFAULT_TIMEOUT_MSDefault bash command timeout
BASH_MAX_TIMEOUT_MSMaximum bash timeout Claude can set
BASH_MAX_OUTPUT_LENGTHMax bash output chars before truncation

CLAUDE_AUTOCOMPACT_PCT_OVERRIDE is particularly worth knowing about. By default, auto-compaction triggers when context fills to a certain threshold. If you're working on a task that needs deep context and you'd rather compact later (or earlier), this variable gives you control. For more on managing your context window effectively, see the context management guide.

Privacy and Telemetry

VariablePurpose
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICDisable updates, telemetry, error reporting all at once
DISABLE_TELEMETRYOpt out of Statsig telemetry
DISABLE_ERROR_REPORTINGOpt out of Sentry error reporting
CLAUDE_CODE_HIDE_ACCOUNT_INFOHide email and org name from UI
DISABLE_AUTOUPDATERDisable automatic version updates

CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is the all-in-one toggle. It bundles DISABLE_AUTOUPDATER, DISABLE_BUG_COMMAND, DISABLE_ERROR_REPORTING, and DISABLE_TELEMETRY into a single switch. Useful for air-gapped or privacy-sensitive environments where you want to minimize outbound connections.

Session Control

VariablePurpose
CLAUDE_CODE_TASK_LIST_IDShare a task list across multiple sessions
CLAUDE_CODE_ENABLE_TASKSSet false to revert to old TODO list
CLAUDE_CODE_SHELLOverride automatic shell detection
CLAUDE_CONFIG_DIRCustom config/data directory location
MCP_TIMEOUTTimeout in ms for MCP server startup
MCP_TOOL_TIMEOUTTimeout in ms for MCP tool execution

The MCP timeout variables are worth setting if you run resource-heavy MCP servers (database connections, browser automation). The defaults work for lightweight tools, but anything that needs initialization time benefits from explicit timeouts.

You can set environment variables in two ways: export them in your shell profile, or add them to the "env" object in settings.json for persistence across sessions without modifying shell configs.

Practical Configuration Examples

Starter Config (Personal Use)

A minimal ~/.claude/settings.json for individual developers:

{
  "$schema": "https://json-schema.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)"
    ],
    "deny": ["Read(./.env)", "Read(./.env.*)", "Read(~/.ssh/**)"]
  },
  "showTurnDuration": true,
  "autoUpdatesChannel": "stable"
}

Team Config (Project Scope)

A .claude/settings.json committed to your repo:

{
  "$schema": "https://json-schema.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(npx prettier --write *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(rm -rf *)",
      "Bash(git push --force *)"
    ]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\""
          }
        ]
      }
    ]
  },
  "attribution": {
    "commit": "Generated with Claude Code\n\nCo-Authored-By: Claude <[email protected]>",
    "pr": "Generated with Claude Code"
  }
}

Enterprise Config (Managed Scope)

A managed-settings.json deployed to system directories:

{
  "$schema": "https://json-schema.org/claude-code-settings.json",
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/credentials.*)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": [
        "github.com",
        "*.npmjs.org",
        "registry.yarnpkg.com",
        "*.internal.acme.com"
      ]
    }
  },
  "allowManagedHooksOnly": true,
  "allowManagedPermissionRulesOnly": true,
  "forceLoginMethod": "console",
  "strictKnownMarketplaces": [
    {
      "source": "github",
      "repo": "acme-corp/approved-plugins"
    }
  ],
  "companyAnnouncements": [
    "All code requires review before merge. See docs.acme.com/security",
    "Report AI-related security concerns to [email protected]"
  ]
}

This locks down network access, forces sandbox mode, restricts plugins to approved sources, and prevents users from bypassing permissions.

Settings Precedence in Practice

Understanding precedence prevents the most common configuration headaches. Here are the scenarios that trip people up, with clear answers.

Scenario 1: Permission conflict across scopes

Your user settings allow Bash(curl *), but the project settings deny it. Which wins? The project scope (priority 4) beats the user scope (priority 5). So the deny applies. But if you really need curl for your machine, add the allow rule to .claude/settings.local.json instead. Local scope (priority 3) beats project scope (priority 4), so your local allow overrides the project deny.

Scenario 2: Managed override

Your team's project settings.json allows Bash(rm -rf *). IT deploys a managed setting that denies it. The managed setting wins. Always. No user, local, or project setting can override managed scope. This is by design for security compliance.

Scenario 3: Local experimentation

You want to test a hook before proposing it to the team. Add it to .claude/settings.local.json. It takes priority over the shared .claude/settings.json but only applies to you. Claude Code automatically configures git to ignore .local. files, so there's no risk of accidentally committing personal settings.

Scenario 4: Settings merging

Settings don't simply replace each other. They merge. If your user settings allow Bash(git status) and your project settings allow Bash(npm run lint), both rules apply. The merge combines permission arrays. But if the same key has different values at different scopes, the higher-priority scope wins for that specific key.

Scenario 5: Environment variables in settings vs shell

If you set ANTHROPIC_MODEL both as a shell export and inside settings.json's env object, the shell environment variable takes precedence. The env object in settings applies at Claude Code startup, but pre-existing shell variables aren't overwritten.

How Settings Relate to Other Configuration

Settings files don't exist in isolation. They work alongside several other configuration surfaces.

CLAUDE.md files contain instructions and context that Claude reads at startup. Think of settings as "what Claude can do" and CLAUDE.md as "what Claude should know." Settings control permissions, tools, and behavior. CLAUDE.md controls knowledge, conventions, and project context.

MCP servers extend Claude with additional tools. Their configurations live in separate files (.mcp.json for project, ~/.claude.json for user), but settings control which MCP servers get approved and which get blocked.

Hooks are configured inside settings.json under the hooks key. They execute shell commands or LLM prompts at lifecycle events. The disableAllHooks and allowManagedHooksOnly settings provide top-level control.

Plugins are also managed through settings.json via enabledPlugins and marketplace configuration. The strictKnownMarketplaces managed setting gives administrators control over which plugin sources are allowed.

Subagents live as Markdown files in ~/.claude/agents/ (user) or .claude/agents/ (project). They aren't configured through settings.json directly, but the same scope hierarchy applies to where they're stored.

Config Backup Behavior

Claude Code automatically creates timestamped backups when configuration files change. It keeps the five most recent backups per file. If an update breaks your setup, the previous working version is recoverable without git archaeology.

This applies to settings.json, .claude.json, and other core config files. Combined with the local scope for experimentation, you have a solid safety net for trying new configurations.

What to Configure First

If you're just getting started with Claude Code settings, tackle these in order:

  1. Permission rules in project settings. Deny access to .env files and secrets. Allow your common build/test commands
  2. A PostToolUse hook for auto-formatting. This eliminates the single biggest source of approval fatigue
  3. Attribution settings if you want to customize (or hide) the co-authored-by trailer
  4. User-level defaults for preferences that apply across all your projects

For a broader overview of the three configuration surfaces (CLAUDE.md, MCP, settings), start with the configuration basics guide.

Next Steps

Last updated on