Settings reference
Every settings.json key Claude Code reads, grouped by job, with the file each one belongs in, its accepted values, its default and worked examples.
This is the lookup page. When you already know roughly what you want to change and need the exact key, the values it accepts and where it is allowed to live, find the group below and scan the table. If you are still deciding which file to edit, or why a value is being ignored, start with Settings instead, which explains the file hierarchy and precedence.
I have grouped the keys by the job they do rather than alphabetically, because in practice you rarely touch one key in isolation: tightening permissions usually means touching three or four permission keys together, and turning on the sandbox means a whole sandbox block.
How to read the tables
Each table has a Where column that says which settings files are allowed to set the key. Claude Code silently ignores (or ignores with a warning) a key placed somewhere it does not accept.
| Label | Files that can set the key |
|---|---|
| Any | User ~/.claude/settings.json, project .claude/settings.json, local .claude/settings.local.json, and managed settings |
| User/managed | User settings, managed settings, and usually a file passed with --settings. Project and local files are ignored so a cloned repository cannot change it for you |
| User/local/managed | As above, plus .claude/settings.local.json |
| Managed | Only settings your organisation deploys (see Managed settings) |
| Global config | ~/.claude.json, not a settings file at all |
A few conventions apply throughout:
- Unset means the key is absent. Many Boolean keys behave identically when unset and when set to their "on" value, so the only meaningful thing to write is
false. - Where a flag or environment variable can override a key for one session, I note it in the Notes column. The full list of variables lives on Environment variables and the flags on CLI reference.
- Several "kill switch" keys are one-way: once any file turns the feature off, no other file can turn it back on. I call these out where they apply.
- Version numbers such as "v2.1.267+" mean the key needs at least that Claude Code release.
Model and responses
These choose which model runs, how hard it thinks, and how the conversation is cached. For the bigger picture of aliases, effort and the /model picker, see Model configuration.
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
model | Any | Alias (opus, sonnet, haiku, fable and so on) or full model ID | Account default | --model and ANTHROPIC_MODEL both beat it for one session, even a managed value. An availableModels list still applies |
fallbackModel | Any | Array of aliases or IDs; "default" expands to the default model | Unset (no fallback) | Tried in order when the primary is overloaded. Does not merge across files: the highest-precedence file supplies the whole chain. At most three distinct models are used. --fallback-model overrides |
availableModels | Any | Array of aliases or IDs | Unset (all models) | Limits what /model, --model, subagents, skills and the advisor can pick. A model ID entry also permits later versions that extend it. Enforce it from managed settings |
availableModelsMatch | Managed | "prefix" or "exact" | "prefix" | "exact" makes "claude-opus-5" permit Opus 5 only, not Opus 5.5. Family aliases still cover the whole family. v2.1.283+ |
deniedModels | Managed | Array of aliases or IDs | Unset | Blocks models even if availableModels allows them. "opus" blocks the family; "claude-opus-5" also blocks 5.x minors; write "claude-opus-5-0" for 5.0 alone. best, opusplan and default entries are ignored. v2.1.283+ |
enforceAvailableModels | Any (managed value wins when present) | Boolean | false | With true, the Default picker option resolves to the first allowed model when it would otherwise fall outside availableModels. v2.1.175+ |
modelOverrides | Any | Object: Anthropic model ID to provider model ID | Unset | Routes a model version to a Bedrock inference profile ARN, a Vertex version or a Foundry deployment |
modelPicker | User/managed | Object with options array and optional replaceBuiltInOptions | Built-in lineup | Relabel and reorder the /model list. One source supplies the whole lineup; never combined. v2.1.242+ |
modelPricing | Managed | Object with optional multiplier and overrides | List price | Makes /usage, the status line, SDK cost fields, --max-budget-usd and OpenTelemetry cost figures use your contracted rates. v2.1.242+ |
modelSettings | Any | Object keyed by model name | Unset | Per-model effortLevel, maxEffortLevel and autoCompactWindow. /effort writes here. v2.1.251+ |
effortLevel | Any | "low", "medium", "high", "xhigh" | Unset | Fallback effort for models with no saved level. --effort beats it, CLAUDE_CODE_EFFORT_LEVEL beats both. In user settings, Opus 5.5 and newer ignore it |
maxEffortLevel | Any | "low" to "xhigh", or "max" for no cap | Unset | Caps effort from every source, on every provider. The lowest cap across scopes wins. v2.1.267+ |
alwaysThinkingEnabled | Any | Boolean | Unset (thinking on) | Only false does anything. No effect on models that always think. MAX_THINKING_TOKENS overrides for a session |
showThinkingSummaries | Any | Boolean | false | true shows full thinking summaries when you expand with Ctrl+O; otherwise a collapsed stub |
fastMode | Any | Boolean | Unset (off) | /fast writes and removes this. Fast mode runs on Opus 5.5, Opus 5 and Opus 4.8 only. CLAUDE_CODE_DISABLE_FAST_MODE wins |
fastModePerSessionOptIn | Any | Boolean | false | true stops a saved fastMode: true from switching fast mode on at startup, so people opt in per session |
advisorModel | Any | "fable", "opus", "sonnet" or a full ID | Unset (advisor off) | /advisor writes this. --advisor overrides; CLAUDE_CODE_DISABLE_ADVISOR_TOOL turns it off regardless. Not available on Bedrock or Claude Platform on AWS |
outputStyle | Any | Name of a built-in or custom style | Default style | See Output styles |
language | Any | Any language name, unvalidated | Unset | Claude replies in that language; also sets the voice dictation language and session title language |
promptCacheTtl | Any | "5m" or "1h" | Per-request default | Main conversation cache lifetime. Order of precedence: FORCE_PROMPT_CACHING_5M, then CLAUDE_CODE_PROMPT_CACHE_TTL, then this key, then ENABLE_PROMPT_CACHING_1H |
subagentPromptCacheTtl | Any | "5m" or "1h" | Per-request default | Same idea for subagents and side requests; CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL sits above it |
switchModelsOnFlag | Any | Boolean | true | When a safety classifier flags a request: true switches to the fallback model and carries on; false pauses so you choose (or errors in -p runs) |
ultracode | Any | Boolean | Unset (off) | Start sessions with ultracode on, where workflows are enabled and the model supports xhigh. /effort ultracode toggles per session |
Effort per model
effortLevel is the blunt instrument; modelSettings lets each model keep its own level, and maxEffortLevel caps what any source can ask for. Here I let Opus run at xhigh for design work, keep Sonnet cheap, and cap everything else at high:
{
"maxEffortLevel": "high",
"modelSettings": {
"claude-opus-5-5": { "effortLevel": "xhigh", "maxEffortLevel": "max" },
"claude-sonnet-5": { "effortLevel": "medium", "autoCompactWindow": 400000 }
}
}
Rules worth remembering:
- Inside one file, a model's own
effortLevelbeats the top-level one. Across files, the highest-precedence file that sets either form for that model decides. - A per-model
maxEffortLevelonly replaces the top-level cap from the same source. Setting"max"exempts the model from that source's cap, not from caps in other files. autoCompactWindowinsidemodelSettingstakes100000to1000000or"auto", and needs v2.1.288+./effort autoclears the saved level for the current model.
modelPicker fields
| Field | Type | Behaviour |
|---|---|---|
options | Array of rows, each with required model and optional label, description, behavesAs | Shown in your order. model is passed through verbatim, so provider-format IDs work. behavesAs (v2.1.257+) names a model your version knows so a newer model inherits its capabilities |
replaceBuiltInOptions | Boolean, default false | true shows only your rows plus Default and the current model. false appends them after the built-in lineup |
Rows the session cannot serve are dropped; rows not yet selectable are greyed out and moved to the bottom; if nothing survives you get the built-in list back.
modelPricing fields
| Field | Type | Behaviour |
|---|---|---|
multiplier | Number above 0, up to 10 | Scales every computed cost. Below 1 is a discount; above 1 is a markup (markups need v2.1.271+) |
overrides | Map of model ID to { input, output, cacheRead, cacheWrite } in USD per million tokens, each 0 to 10000 | All four rates are required. cacheWrite covers both cache lifetimes. Rates are used as written, without fast-mode or regional surcharges |
A row keyed by a built-in model ID also covers that model's dated and provider-specific IDs. Any other key (a gateway alias, say) matches that exact ID only.
Permissions
These keys decide what Claude can do unprompted. The concepts are covered in Permissions and Permission modes; this is the key list.
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
permissions | Any | Object | Unset | Container for every permissions.* key below |
permissions.allow | Any | Array of rule strings | Unset | Approved without a prompt. Project-file rules apply only after you accept workspace trust. --allowedTools adds more for a session |
permissions.ask | Any | Array of rule strings | Unset | Always prompts |
permissions.deny | Any | Array of rule strings | Unset | Blocked outright. --disallowedTools adds more for a session |
permissions.additionalDirectories | Any | Array of directory paths | Unset | Extra working directories. --add-dir and /add-dir add per session. Most .claude/ config is not discovered from these |
permissions.defaultMode | Any (see notes) | Mode name, see below | Unset | auto and bypassPermissions are ignored from project and local files. --permission-mode overrides |
permissions.disableBypassPermissionsMode | Any | "disable" | Unset | Blocks bypass mode; --dangerously-skip-permissions is then rejected |
permissions.disableAutoMode / disableAutoMode | Any | "disable" | Unset | Removes auto mode from the Shift+Tab cycle; sessions that would start in auto start in default |
permissions.blockReadsOutsideWorkingDirectories | Any | Boolean | Unset | true from any file wins, so a repo can switch it on but not off. File tools refuse reads outside working directories in every mode. v2.1.257+ |
allowManagedPermissionRulesOnly | Managed | Boolean | Unset | Only managed allow/ask/deny rules apply; --allowedTools is ignored and "always allow" choices disappear. Also ignores allowed-tools frontmatter in user and repo skills (v2.1.282+) |
autoMode | User/managed | Object with environment, allow, soft_deny, hard_deny arrays and classifyAllShell | Built-in rules only | Prose rules for the auto mode classifier. Include "$defaults" in an array to keep the built-ins at that position. Arrays concatenate across files. See Auto mode configuration |
autoMode.classifyAllShell | User/managed | Boolean | false | true routes every Bash and PowerShell command through the classifier in auto mode, suspending shell allow rules. v2.1.193+ |
useAutoModeDuringPlan | User/local/managed | Boolean | true | false brings back prompts for non-read-only commands in plan mode |
skipAutoPermissionPrompt | User/managed | Boolean | Unset | Skip the one-time notice on first entering auto mode yourself |
skipDangerousModePermissionPrompt | User/local/managed | Boolean | Unset | Skip the confirmation before entering bypassPermissions |
permissions.defaultMode values
| Value | What Claude may do without asking |
|---|---|
"default" (alias "manual") | Reads only |
"acceptEdits" | Reads, file edits, and routine filesystem commands such as mkdir and mv |
"plan" | Reads and plans; edits wait for plan approval |
"auto" | Most actions, with a background classifier checking risky ones |
"dontAsk" | Anything pre-approved; everything that would prompt is denied instead |
"bypassPermissions" | Everything |
Rule syntax in one minute
Rules are Tool or Tool(specifier). Deny is checked first, then ask, then allow, and the first match wins regardless of specificity. A small, realistic block for a Next.js repo:
{
"permissions": {
"allow": ["Bash(pnpm lint)", "Bash(pnpm test *)", "WebFetch(domain:nextjs.org)"],
"ask": ["Bash(git push *)", "Bash(vercel *)"],
"deny": ["Read(./.env.local)", "Read(./secrets/**)"],
"defaultMode": "acceptEdits"
}
}
In MCP rules, * may appear only in the tool part after mcp__<server>__, for example mcp__linear__list_*. The full grammar, including path anchors for Read and Edit, is on Permissions.
Sandbox
The sandbox object isolates Bash commands from your filesystem and network on macOS, Linux and WSL2. Read Sandboxing first; this section lists every key. Many keys carry extra limits when set from project or local files under an admin-required sandbox, which the sandboxing page explains.
Core switches
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
sandbox.enabled | Any | Boolean | false | Turns sandboxing on |
sandbox.failIfUnavailable | Any | Boolean | false | true exits at startup if the sandbox cannot start, instead of running unsandboxed |
sandbox.autoAllowBashIfSandboxed | Any | Boolean | true | Sandboxed commands skip the permission prompt (deny and content-scoped ask rules still apply) |
sandbox.allowUnsandboxedCommands | Any | Boolean | true | false ignores Claude's dangerouslyDisableSandbox retry, so commands stay sandboxed unless excluded |
sandbox.excludedCommands | Any | Array of command patterns | Unset | Commands that always run outside the sandbox |
sandbox.ignoreViolations | Any | Object: command substring to array of violation substrings | Unset | Silences expected violation reports |
sandbox.enableWeakerNestedSandbox | Any | Boolean | false | Reuse the container's /proc; needed inside unprivileged Docker |
sandbox.enableWeakerNetworkIsolation | Any | Boolean | false | macOS: lets sandboxed tools reach com.apple.trustd.agent, fixing TLS checks in Go CLIs behind a proxy |
sandbox.allowAppleEvents | User/managed | Boolean | false | macOS: permits Apple Events, so open and osascript work |
sandbox.ripgrep | User/managed | Object with command and optional args | Claude Code's ripgrep | Swap in your own rg binary |
sandbox.bwrapPath | Managed | Absolute path | bwrap on PATH | Relative paths are dropped |
sandbox.socatPath | Managed | Absolute path | socat on PATH | Relative paths are dropped |
Filesystem
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
sandbox.filesystem.allowWrite | Any | Array of paths | Working dir, temp dir, added dirs | Extra writable paths |
sandbox.filesystem.denyWrite | Any | Array of paths | Unset | Blocks writes even inside allowed areas |
sandbox.filesystem.denyRead | Any | Array of paths | Unset | Default reads include files like ~/.aws/credentials, so this is where you hide them |
sandbox.filesystem.allowRead | Any | Array of paths | Unset | Re-opens part of a denyRead region |
sandbox.filesystem.allowManagedReadPathsOnly | Managed | Boolean | false | Only managed allowRead entries count |
sandbox.filesystem.disabled | User/managed | Boolean | false | Drop filesystem isolation but keep network isolation. Managed-only once managed settings configure sandbox.filesystem or a deny credential file |
Path prefixes in these lists follow normal Unix conventions, which is the opposite of permission rules:
| Prefix | Resolves to |
|---|---|
/tmp/cache | Absolute path (so does //tmp/cache) |
~/.kube | Under your home directory |
./dist or dist | Project root for project settings, ~/.claude for user settings |
Trailing / and /** are stripped. Wildcards work in denyRead and allowRead on every platform, but in allowWrite and denyWrite they work only on macOS: on Linux and WSL2 an entry containing *, ? or [ is skipped.
Network
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
sandbox.network.allowedDomains | Any | Domains, wildcards or IPs, optional :port | Unset | Pre-approved hosts. Managed-only when allowManagedDomainsOnly is on |
sandbox.network.deniedDomains | Any | Same format | Unset | Wins even inside an allowed wildcard |
sandbox.network.strictAllowlist | User/managed | Boolean | false | Deny unknown hosts instead of letting your permission mode decide |
sandbox.network.allowManagedDomainsOnly | Managed | Boolean | false | Only managed allowedDomains and WebFetch(domain:...) rules count; others are blocked without a prompt |
sandbox.network.allowUnixSockets | Any | Array of socket paths | Unset | macOS allow list for Unix sockets |
sandbox.network.allowAllUnixSockets | Any | Boolean | false | Allow every Unix socket |
sandbox.network.allowLocalBinding | Any | Boolean | false | macOS: listen on ports and connect to localhost |
sandbox.network.allowMachLookup | Any | Array of XPC service names; trailing * prefix match | Unset | macOS: for the iOS Simulator, Playwright and similar |
sandbox.network.httpProxyPort | Any | Local TCP port | Built-in proxy | Use your own HTTP proxy |
sandbox.network.socksProxyPort | Any | Local TCP port | Built-in proxy | Use your own SOCKS proxy |
sandbox.network.tlsTerminate | User/managed | Object with optional caCertPath, caKeyPath | Unset | Proxy terminates TLS so it can inspect HTTPS (needed for credential masking) |
Credentials
sandbox.credentials hides or masks secrets that sandboxed commands would otherwise see. mask entries, allowPlaintextInject, awsPairs and sigv4 are honoured only from user settings, managed settings and --settings; mask entries in project or local files are dropped.
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
sandbox.credentials.files | Any | Array of { path, mode } where mode is "deny" or "mask" | Unset | Block or mask a credential file |
sandbox.credentials.envVars | Any | Array of { name, mode } | Unset | Unset or mask an environment variable |
sandbox.credentials.allowPlaintextInject | User/managed | Boolean | false | Allow masked values to be substituted on plain HTTP, for trusted test networks |
sandbox.credentials.awsPairs | User/managed | Array of { accessKeyIdVar, secretAccessKeyVar, sessionTokenVar? } | Standard AWS trio only | Pair custom-named AWS variables for request re-signing |
sandbox.credentials.sigv4 | User/managed | Object with streaming, presigned, sigv4a, each "deny" or "passthrough" | All "deny" | What the proxy does with AWS request forms it cannot re-sign |
Optional fields on a mask entry:
| Field | Files | Env vars | Purpose |
|---|---|---|---|
extract | Yes | Yes | Regex; only capture group 1 is masked, so the rest stays parseable |
onExtractNoMatch | Yes | Yes | "warn" (default), "deny" or "error" when nothing matched |
decode | Yes | Yes | "jwt": replace verified JWTs with valid-looking fakes |
maskClaims | Yes | Yes | With decode, mask only named payload claims |
maskDuplicates | Yes | No | Also replace verbatim copies of a masked value elsewhere in the file |
injectHosts | Yes | Yes | Narrow which allowed hosts receive the real value on egress |
An example I use for a Postgres connection string and a Stripe key, where the real values are only substituted on the way out to the right hosts:
{
"sandbox": {
"enabled": true,
"network": { "allowedDomains": ["api.stripe.com", "db.internal.example"] },
"credentials": {
"envVars": [
{ "name": "DATABASE_URL", "mode": "mask", "extract": ":([^:@/]+)@", "onExtractNoMatch": "deny" },
{ "name": "STRIPE_SECRET_KEY", "mode": "mask", "injectHosts": ["api.stripe.com"] }
],
"files": [{ "path": "~/.npmrc", "mode": "deny" }]
}
}
}
If a managed credential entry fails validation but still has a valid path or name, Claude Code degrades it to deny with a warning rather than dropping it.
Memory, context and environment
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
autoCompactEnabled | Any | Boolean | true | DISABLE_AUTO_COMPACT can also turn it off; neither can undo the other's "off" |
autoCompactWindow | Any | Tokens, 100000 to 1000000 | Tuned per model | Capped at the model's window. --autocompact beats it, CLAUDE_CODE_AUTO_COMPACT_WINDOW beats both |
autoMemoryEnabled | Any | Boolean | true | false stops reading and writing auto memory. CLAUDE_CODE_DISABLE_AUTO_MEMORY overrides either way |
autoMemoryDirectory | Any | Absolute or ~/ path | ~/.claude/projects/<project>/memory/ | See Memory |
claudeMd | Managed | String of CLAUDE.md content (\n for line breaks) | Unset | Organisation-wide instructions |
claudeMdExcludes | Any | Array of globs or absolute paths | Unset | Skip specific CLAUDE.md files |
fileCheckpointingEnabled | Any | Boolean | true | false means /rewind cannot restore files. CLAUDE_CODE_DISABLE_FILE_CHECKPOINTING also turns it off |
plansDirectory | Any | Path relative to project root | ~/.claude/plans | Where plan mode writes plans |
bashOutputMaxChars | Any | Positive integer, clamped to 4000 to 128000 | 30,000 characters | Inline output size for successful commands |
skillListingBudgetFraction | Any | Number above 0 and at most 1 | 0.01 (1% of context) | Space reserved for the skill list |
skillListingMaxDescChars | Any | Positive integer | 1536 | Per-skill description cap in the listing |
env | Any | Object of variable name to string | Unset | Variables for every session and subprocess |
How env behaves
env looks simple but has sharp edges:
- A value here overrides the same variable exported in your shell. To cancel a shell export, set it to
"". - When the desktop app or a self-hosted environment runner launches the session, its launch environment wins over every
envvalue. NO_COLORandFORCE_COLORset here reach subprocesses only, not Claude Code's own interface.- User, managed and
--settingsvalues apply at startup; project and local values apply once you trust the workspace (or immediately in-pmode). A saved change to the mergedenvis picked up mid-session. - Values are plain text in a file and reach every subprocess. Use
apiKeyHelperorotelHeadersHelperfor secrets instead.
Project and local files cannot set variables a cloned repository should not control. Claude Code drops these (logging a warning visible with claude --debug):
- Location variables:
CLAUDE_CONFIG_DIR,CLAUDE_CODE_TMPDIR,HOME,TMPDIR,TMP,TEMPand theXDG_*family. - Windows program and machine paths such as
SystemRoot,ComSpec,ProgramData,LOCALAPPDATA,PATHEXT,PSModulePathand theProgramFilesfamily. - Variables that export session content, such as
OTEL_LOG_RAW_API_BODIES,ENABLE_BETA_TRACING_DETAILEDandBETA_TRACING_ENDPOINT. - OpenTelemetry switches and destinations:
CLAUDE_CODE_ENABLE_TELEMETRY, the enhanced telemetry beta pair, theOTEL_*_EXPORTERselectors, theOTEL_LOG_*content variables,OTEL_EXPORTER_OTLP_*endpoint, header, protocol and certificate variables, and the Prometheus host and port (v2.1.282+). Values that switch telemetry off, such asnonefor an exporter, still apply. - Startup and sync variables such as
CLAUDE_CODE_PROCESS_WRAPPER,CLAUDE_CODE_SYNC_SKILLS,CLAUDE_CODE_SYNC_PLUGINS,CLAUDE_CODE_PLUGIN_CACHE_DIRandCLAUDE_CODE_PLUGIN_SEED_DIR.
A handful are ignored from every settings file because only the launch environment may set them: hosting identity variables such as CLAUDE_CODE_REMOTE and CLAUDE_CODE_ACCOUNT_UUID, CLAUDE_CODE_MESSAGING_SOCKET, CLAUDE_CODE_MESSAGING_TOKEN, CLAUDE_CODE_PROJECT_DIR_NAME, CLAUDE_CODE_RESTRICTED, and the rm safety toggles (CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY, CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT, CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT, CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT).
Interface and terminal
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
theme | Any | "auto", "dark", "light", "dark-daltonized", "light-daltonized", "dark-ansi", "light-ansi", "custom:<slug>", "custom:<plugin>:<slug>" | "dark" | Custom themes live in ~/.claude/themes/ or a plugin |
tui | Any | "default" (classic) or "fullscreen" | Chosen for you | CLAUDE_CODE_NO_FLICKER and CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN override. See Fullscreen |
viewMode | Any | "default", "verbose", "focus" | Unset | Focus view needs the fullscreen renderer. Takes precedence over verbose |
verbose | Any | Boolean | false | Full tool output. --verbose overrides |
editorMode | Any | "normal" or "vim" | "normal" | Vim-style prompt editing |
vimInsertModeRemaps | User/managed | Object: two-character sequence to "<Esc>" | Unset | For example { "jk": "<Esc>" } |
axScreenReader | Any | Boolean | Unset | Flat, screen-reader-friendly output. --ax-screen-reader and CLAUDE_AX_SCREEN_READER override. See Accessibility |
prefersReducedMotion | Any | Boolean | false | Tones down spinner, shimmer and flash animations |
maxProseWidth | Any | Whole number of columns, minimum 40 | Terminal width | Keeps prose readable on wide screens |
syntaxHighlightingDisabled | Any | Boolean | false | Turns off highlighting in diffs and code |
autoScrollEnabled | Any | Boolean | true | Fullscreen: follow new output |
wheelScrollAccelerationEnabled | Any | Boolean | true | Fullscreen: accelerate fast wheel scrolling |
statusLine | Any | { type: "command", command, padding?, refreshInterval?, hideVimModeIndicator? } | None | refreshInterval is seconds, minimum 1. See Status line |
subagentStatusLine | Any | { type: "command", command } | Default rows | Rewrites subagent rows in the task display |
fileSuggestion | Any | { type: "command", command } | Built-in search | Custom @ autocomplete, see below |
footerLinksRegexes | User/managed | Array of { type: "regex", pattern, url, label? } | Unset | Turns IDs in output into clickable footer badges |
respectGitignore | Any | Boolean | true | Keep ignored files out of the @ picker |
emojiCompletionEnabled | Any | Boolean | true | :shortcode: suggestions and replacement |
promptSuggestionEnabled | Any | Boolean | true | Greyed-out suggested prompts. CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION overrides |
spellcheck | User/managed | Object with enabled, checker ("aspell", "hunspell", "ispell", "auto"), language, color | Off | Needs a checker installed; the highest tier's block applies whole |
spinnerTipsEnabled | Any | Boolean | true | false hides all tips, including custom ones |
spinnerTipsOverride | Any | Object with tips, tipsFile, label, excludeDefault | Built-in tips | Custom tips, see below |
spinnerVerbs | Any | { mode: "append" or "replace", verbs: [...] } | Built-in verbs | Words shown while a turn runs |
showTurnDuration | Any | Boolean | true | The "Cooked for" line after each reply |
showClearContextOnPlanAccept | Any | Boolean | false | Adds a "clear context" option when approving a plan |
terminalProgressBarEnabled | Any | Boolean | true | Progress bar in terminals that support it |
terminalTitleFromRename | Any | Boolean | true | /rename and --name set the tab title |
timeFormat | Any | "auto", "12-hour", "24-hour", "24-hour-utc" | "auto" | The UTC preset ignores timeZone |
timeZone | Any | IANA name such as "Europe/London" | System zone | Unknown names fall back to the system zone |
defaultShell | Any | "bash" or "powershell" | "bash" (PowerShell on Windows without Bash) | Shell for ! commands |
respondToBashCommands | Any | Boolean | true | false adds ! output to context without Claude replying |
companyAnnouncements | Any | Array of strings | None | Shown at startup |
askUserQuestionTimeout | User/managed | "60s", "5m", "10m", "never" | "never" | Unanswered questions auto-continue. CLAUDE_AFK_TIMEOUT_MS overrides |
dialogExpiry | User/managed | "60s", "5m", "10m", "never" | "5m" | How long a dialog forwarded to Remote Control or an SDK host waits. CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS overrides |
autoContinueAtUsageLimit | User/managed | Boolean | true | Wait and resume after a claude.ai usage limit resets. A project or local value can only turn it off |
bashEditDiffEnabled | User/managed (false from any file) | Boolean | Unset | Records files changed by Bash in every mode; by default only in auto and bypass modes. CLAUDE_CODE_BASH_EDIT_DIFF overrides |
voice | Any | { enabled, mode: "hold" or "tap", autoSubmit } | Off | mode defaults to "hold"; autoSubmit applies to hold mode. See Voice dictation |
voiceEnabled | Any | Boolean | Unset | Older single-key form; voice.enabled wins when set |
Custom @ file suggestions
The command receives {"query": "..."} on stdin, gets the same environment as hooks (including CLAUDE_PROJECT_DIR), must answer within five seconds, and prints one path per line. Only the first 15 are shown. For a big monorepo I point it at git ls-files, which is faster than a filesystem walk:
#!/usr/bin/env bash
q=$(jq -r '.query')
git -C "$CLAUDE_PROJECT_DIR" ls-files | grep -i -- "$q" | head -15
{ "fileSuggestion": { "type": "command", "command": "~/.claude/bin/suggest-files.sh" } }
Footer link badges
Each footerLinksRegexes entry matches a regex against the finished turn's output and builds a link from named capture groups. Limits: the built URL must keep the template's literal origin, at most 2,048 characters; schemes are https, http or a known editor or app scheme (vscode, vscode-insiders, cursor, windsurf, zed, jetbrains, idea, slack, linear, notion, figma); labels are cut to 28 columns; at most five badges show, and /clear removes them. Keep patterns linear, because they run on the main thread.
{
"footerLinksRegexes": [
{ "type": "regex", "pattern": "\\b(?<key>ENG-\\d+)\\b", "url": "https://linear.app/acme/issue/{key}", "label": "{key}" }
]
}
Custom spinner tips
Each tips entry is either a plain string or an object with id (required, up to 64 characters of letters, digits, ., _, -), text (required, one line, up to 500 characters), cooldownSessions (0 to 1000, default 0) and priority (-10 to 10, default 0). tipsFile points at a local JSON file of the same entries (up to 256 KB, read once per process, not deliverable through server-managed settings). label replaces the Tip prefix (up to 40 characters) and excludeDefault: true hides the built-in tips. Up to 200 tips are read. Project and local files may contribute plain strings only; the richer fields need v2.1.247+.
Git and attribution
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
attribution | Any | Object with commit, pr, sessionUrl; or false to hide everything | Standard attribution | The false form needs v2.1.281+; older versions reject the whole file |
attribution.commit | Any | String (empty hides it) | Co-Authored-By: trailer naming the model in use | A subagent's commit names the subagent's model |
attribution.pr | Any | String (empty hides it) | A "Generated with Claude Code" line | Appended to PR descriptions |
attribution.sessionUrl | Any | Boolean | true | Adds the claude.ai session link to commits and PRs from cloud and Remote Control sessions |
includeCoAuthoredBy | Any | Boolean | true | Deprecated; use attribution |
includeGitInstructions | Any | Boolean | true | false drops the built-in commit and PR instructions and the git status snapshot. CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS overrides |
prUrlTemplate | Any | URL using {host}, {owner}, {repo}, {number}, {url} | Unset | Points rendered PR links at an internal review tool; GitLab merge request links are left alone |
Hooks and workflows
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
hooks | Any | Object keyed by event; each value an array of { matcher, hooks } groups. Hook type is "command", "prompt", "agent", "http" or "mcp_tool" | None | Merges across files; managed hooks cannot be removed. See Hooks |
disableAllHooks | Any | Boolean | Unset | Turns off hooks, the custom status line and the custom file suggestion together. Only managed settings can disable managed hooks |
allowManagedHooksOnly | Managed | Boolean | Unset | Only managed hooks, SDK hooks and hooks from force-enabled plugins run |
allowedHttpHookUrls | Any | Array of URL patterns with * | Any URL | Arrays merge across files |
httpHookAllowedEnvVars | Any | Array of variable names | Each hook's own list | Which variables HTTP hooks may put in headers; arrays merge |
enableWorkflows | Any | Boolean | On, except Pro plan | Your personal on/off for workflows |
disableWorkflows | Any | Boolean | false | Organisation-wide off switch. CLAUDE_CODE_DISABLE_WORKFLOWS also turns them off |
workflowKeywordTriggerEnabled | Any | Boolean | true | false lets you type "ultracode" without starting a workflow |
workflowSizeGuideline | Any | "unrestricted", "small" (under 5 agents), "medium" (under 10), "large" (under 50) | "medium" ("small" on Pro, v2.1.271+) | Overrides the /config choice and hides that row |
When allowManagedHooksOnly is on, or disableAllHooks is set outside managed settings, only a managed statusLine, subagentStatusLine or fileSuggestion runs; yours is skipped without warning.
Plugins, skills and marketplaces
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
enabledPlugins | Any | Object: "plugin@marketplace" to Boolean | Each plugin's defaultEnabled | Per-scope on/off |
extraKnownMarketplaces | Any | Object: name to { source, autoUpdate? } | Unset | Repo entries need workspace trust. Alias additionalMarketplaces (v2.1.232+) |
pluginConfigs | User/managed | Object: plugin ID to { options, mcpServers? } | Unset | Stored answers to a plugin's configuration dialog |
prependPlugins | User/managed | Array of "plugin@marketplace" | Unset | Organisation mods that run before user mods. User value only read with no managed settings and no Team or Enterprise sign-in |
appendPlugins | User/managed | Same | Unset | Mods that run after user mods; same read rules |
strictKnownMarketplaces | Managed | Array of source objects | Unset (anything allowed) | Allowlist of marketplace sources. An empty array blocks everything, including the official marketplace. Alias allowedMarketplaces |
blockedMarketplaces | Managed | Array of source objects | Unset | Blocklist |
pluginSuggestionMarketplaces | Managed | Array of marketplace names | Unset | Which marketplaces can surface install suggestions in /plugin |
pluginTrustMessage | Managed | String | Standard warning | Extra text on the trust warning |
disableCommandPluginSources | Managed | Boolean | Follows allowManagedHooksOnly | Blocks plugins installed by running a marketplace-declared command |
strictPluginOnlyCustomization | Managed | true, or an array of "skills", "agents", "hooks", "mcp" | Unset | Locks those kinds to plugin and managed sources |
syncClaudeAiPlugins | User/local/managed | Boolean | Sync on | false stops loading plugins enabled on your claude.ai account; in user or managed settings it also moves them to ~/.claude/plugins/.trash/ |
syncClaudeAiSkills | User/local/managed | Boolean | Sync on | Same for skills, under ~/.claude/skills/synced/ |
skillOverrides | Any | Object: skill name to "on", "name-only", "user-invocable-only", "off" | All "on" | The /skills menu writes to .claude/settings.local.json |
disableBundledSkills | Any | Boolean | Unset | Removes bundled skills and workflows and hides built-in commands such as /init from the model |
disableSkillShellExecution | Any | Boolean | Unset | Replaces inline shell in skills and commands with a "disabled by policy" placeholder |
channelsEnabled | Managed | Boolean | Blocked on Team, Enterprise and managed Console; allowed otherwise | Allows channels |
allowedChannelPlugins | Managed | Array of { marketplace, plugin } or "plugin@marketplace" strings | Anthropic default list | Which channel plugins may push messages. String form v2.1.267+ |
Marketplace sources
Allowlists, blocklists and extraKnownMarketplaces describe marketplaces with a source object:
source | Fields | Where it is valid |
|---|---|---|
github | repo, optional ref, path | Everywhere. "owner/*" wildcards only in the allow and block lists (v2.1.223+) |
git | url, optional ref, path | Everywhere; uses your normal git credentials |
url | url, optional headers, headersHelper | Everywhere; plugins must not use relative paths |
file | path to a marketplace.json | Everywhere |
directory | path to a folder containing .claude-plugin/marketplace.json | Everywhere |
settings | name, plugins (inline marketplace) | extraKnownMarketplaces |
hostPattern | Regex matched against the host | Allow and block lists |
pathPattern | Regex matched against file and directory paths | Allow and block lists |
skills-dir | None | Allow and block lists; opts the ~/.claude/skills/ plugin scan back in, which any allowlist otherwise stops |
Allowlist matching is exact for github and git, including ref and path, so { "repo": "acme/plugins" } and { "repo": "acme/plugins", "ref": "main" } are different entries. Blocklists are looser: an entry without ref or path blocks all of them, and owner names compare case-insensitively.
MCP servers
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
enableAllProjectMcpServers | Any | Boolean | Unset (prompt per server) | Approve every server in .mcp.json. In untrusted folders, the project file's value is ignored |
enabledMcpjsonServers | Any | Array of .mcp.json server names | Unset | Approve named servers |
disabledMcpjsonServers | Any | Array of server names | Unset | Reject named servers |
allowedMcpServers | Any | Array of objects with exactly one of serverName, serverCommand (exact argv), serverUrl (* wildcards) | Unset (all allowed) | Merges across files unless allowManagedMcpServersOnly is set. Empty array blocks every user-added server |
deniedMcpServers | Any | Same shape; serverName can be a connector's display name such as "claude.ai Linear" | Unset | Always merges across files |
allowManagedMcpServersOnly | Managed | Boolean | false | Only the managed allowlist counts |
managedMcpServers | Managed | Object of server name to an http or sse server entry with an https:// URL | Unset | Pushes remote servers to everyone. See Managed MCP |
disableClaudeAiConnectors | Any | Boolean | false | Stop fetching claude.ai connectors. ENABLE_CLAUDEAI_MCP_SERVERS=false also does this |
allowAllClaudeAiMcps | Managed | Boolean | false | Keep claude.ai connectors alongside a deployed managed-mcp.json |
allowClaudeInChromeWithManagedMcp | Managed (device sources only) | Boolean | false | Let Claude in Chrome run alongside managed-mcp.json. Ignored from server-managed settings and HKCU |
Agents, sessions and worktrees
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
agent | Any | Built-in or custom agent name | Default agent | Start the main thread as that subagent. --agent overrides |
teammateMode | Any | "in-process", "auto", "tmux", "iterm2" | "in-process" | How agent team members display. --teammate-mode overrides |
disableAgentView | Any | Boolean | Unset | Turns off claude agents, --bg, /background and the supervisor. CLAUDE_CODE_DISABLE_AGENT_VIEW also does |
crossSessionInbound | Any | "accept", "hold", "refuse" | Decided per message | Project and local values apply only when stricter. See Cross-session messaging |
isolatePeerMachines | Any | Boolean | Unset | Ask before Claude messages your sessions on other machines. true from any file wins |
processWrapper | User/managed | Launcher command as an argv prefix | Unset | Runs background processes through a corporate launcher. CLAUDE_CODE_PROCESS_WRAPPER overrides |
worktree.baseRef | Any | "fresh" (from origin/<default>) or "head" (local HEAD) | "fresh" | Where new worktrees branch from |
worktree.symlinkDirectories | Any | Array of repo-relative directories | Unset | Symlink heavy folders such as node_modules instead of copying |
worktree.sparsePaths | Any | Array of repo-relative directories | Whole tree | Sparse checkout per worktree |
worktree.bgIsolation | Any | "worktree" or "none" | "worktree" | "worktree" blocks edits to the main checkout from background sessions until they enter a worktree |
For a pnpm monorepo this saves me gigabytes of disk:
{
"worktree": {
"baseRef": "head",
"symlinkDirectories": ["node_modules", ".turbo"],
"sparsePaths": ["apps/web", "packages/ui", "packages/config"]
}
}
Remote, desktop and notifications
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
remoteControlAtStartup | Any | Boolean | Auto-connect default | Connect Remote Control at startup. --remote-control forces it on |
disableRemoteControl | Any | Boolean | false | Refuses every way of starting Remote Control |
remote.defaultEnvironmentId | Any (self-hosted ccpool_ IDs: user, managed, --settings only) | env_... or ccpool_... ID | Anthropic-hosted, else first non-bridge environment | Default for claude --cloud. --environment overrides. See Cloud environments |
agentPushNotifEnabled | Any | Boolean | false | Claude may push a phone notification when it judges one worthwhile |
inputNeededNotifEnabled | Any | Boolean | false | Push notification when a prompt is waiting, while Remote Control is connected |
preferredNotifChannel | Any | "auto", "terminal_bell", "iterm2", "iterm2_with_bell", "kitty", "ghostty", "notifications_disabled" | "auto" | Task-complete alerts. See Terminal configuration |
awaySummaryEnabled | Any | Boolean | On | The recap shown when you return. CLAUDE_CODE_ENABLE_AWAY_SUMMARY overrides |
enableArtifact | Any | Boolean | Account availability | Only false matters, and no file can undo it. See Artifacts |
disableArtifact | Any | Boolean | Unset | Deprecated; true turns the tool off, false is ignored |
disableDeepLinkRegistration | Any | "disable" | Unset | Stops registering the claude-cli:// handler |
disableDesktopLocalSessions | Managed | true | Unset | Desktop app offers only SSH and cloud sessions |
sshConfigs | User/managed | Array of { id, name, sshHost, sshPort?, sshIdentityFile? } | Unset | Pre-filled SSH connections in the desktop app |
sshHostAllowlist | Managed | Array of hostname patterns | Any host | Limits desktop SSH targets |
Authentication and providers
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
apiKeyHelper | Any | Shell command | Unset | Prints the API credential. See Authentication |
awsAuthRefresh | Any | Shell command | Unset | Refreshes Bedrock credentials in .aws |
awsCredentialExport | Any | Shell command printing JSON credentials | Ambient AWS chain | For Bedrock |
gcpAuthRefresh | Any | Shell command | Unset | Refreshes Google Cloud credentials |
otelHeadersHelper | Any | Executable or shell command | Unset | Rotating OpenTelemetry headers |
forceLoginMethod | Any ("gateway" from device managed sources only) | "claudeai", "console", "gateway" | User chooses | Restrict sign-in route |
forceLoginOrgUUID | Any (enforced only when managed) | One UUID or an array | Any organisation | Elsewhere it only pre-selects the organisation |
forceLoginGatewayUrl | Managed (device sources) | Full URL | Unset | Gateway the login screen uses. See Claude apps gateway |
gatewayInternalNetworks | Managed (device sources) | Up to four non-overlapping public IPv4 CIDRs, /8 to /32 | Private ranges only | Lets /login reach a gateway on public address space you use internally |
allowedProviders | Managed | Array of "anthropic", "bedrock", "vertex", "foundry", "anthropicAws", "mantle", "customEndpoint", "gateway" | Any provider | A server-managed list can narrow, never widen, a device list |
Updates and versions
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
autoUpdatesChannel | Any | "latest" or "stable" (about a week old, skips regressions) | "latest" | See Setup |
minimumVersion | Any | Version string such as "2.1.200" | Unset | Auto-update never installs below this. A managed value cannot be lowered |
requiredMinimumVersion | Managed | Version string | Unset | Refuse to start on older builds |
requiredMaximumVersion | Managed | Version string | Unset | Refuse to start on newer builds |
Desktop tools
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
browserExternalPageTools | Managed | "disabled" (desktop also accepts "disable") | Tools allowed | Keeps Claude's tools off external pages in the desktop Browser pane |
disableBrowserExternalNavigation | Managed | true | Unset | Browser pane limited to localhost |
disableMobileSimulatorTools | Managed | true | Per-user toggle | Blocks Claude's iOS Simulator tools |
Privacy and retention
| Key | Where | Accepts | Default | Notes |
|---|---|---|---|---|
cleanupPeriodDays | Any | Whole number, minimum 1 | 30 | Transcript retention. See Data usage |
desktopSessionCleanupPeriodDays | User/managed | Whole number, minimum 0 | 0 (no limit) | Desktop and Cowork transcripts |
feedbackDrafts | User/managed | "notify", "quiet", "off" | "notify" | "off" removes the feedback drafting tool. CLAUDE_CODE_SEND_FEEDBACK=0 overrides |
feedbackSurveyRate | Any | Number from 0 to 1 | Remote rate (0.005 on Bedrock, Vertex, Foundry) | CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 turns it off |
skipWebFetchPreflight | Any | Boolean | Unset (check runs) | Skip the WebFetch hostname safety check, for networks that cannot reach Anthropic |
Managed-only control keys
These shape how managed policy itself is delivered and combined. They only make sense in managed settings or server-managed settings.
| Key | Accepts | Default | Notes |
|---|---|---|---|
managedSourcesBehavior | "first-wins" or "merge" | "first-wins" | Whether to use only the highest-priority admin source or combine them all |
parentSettingsBehavior | "first-wins" or "merge" | "first-wins" | Whether restrictions passed by an SDK or IDE host are dropped or applied (restrictively) under your managed tier |
forceRemoteSettingsRefresh | Boolean | false | Block startup until server-managed settings are freshly fetched; exit on failure |
disableSideloadFlags | Boolean | false | Reject --plugin-dir, --plugin-url, --agents and --mcp-config |
policyHelper | Object with path, timeoutMs, refreshIntervalMs | Unset | Executable that computes policy at startup. Read from plist, HKLM or the managed file only |
policyHelper.path | Absolute, normalised path (.exe on Windows) | Required | |
policyHelper.timeoutMs | Integer, minimum 1000 | 10000 | |
policyHelper.refreshIntervalMs | 0, or at least 60000 | Run once | Background refresh |
wslInheritsWindowsSettings | Boolean | false | WSL reads the Windows policy chain, falling back to /etc/claude-code |
Under "merge", keys combine by kind:
| Kind | Rule | Examples |
|---|---|---|
| Lists | Entries from every source are combined | permissions.allow, sandbox.network.allowedDomains |
| Locks | Strictest value from any source wins | allowManagedPermissionRulesOnly, permissions.disableBypassPermissionsMode |
| Restriction allowlists | Taken whole from the highest source that sets one | availableModels, allowedMcpServers, allowedProviders, strictKnownMarketplaces, allowedChannelPlugins, fallbackModel |
| Whole values | Taken whole from the highest source that sets them | sandbox.credentials.awsPairs, sandbox.ripgrep |
| Provided MCP servers | Names combined; on a clash the higher source's entry wins | managedMcpServers |
| Helpers and login pins | Highest policy-carrying source only | apiKeyHelper, awsAuthRefresh, gcpAuthRefresh, otelHeadersHelper, forceLoginOrgUUID |
env | Merged per variable under both modes | env |
| Everything else | Highest source that sets it | model, cleanupPeriodDays |
Only use "merge" when every lower-ranked source is also under admin control, because lower sources can then add allow rules. Run /status and check the "Setting sources" line to see what combined.
Global config keys (~/.claude.json)
These live in ~/.claude.json and are ignored in any settings file. /config writes most of them.
| Key | Accepts | Default | Notes |
|---|---|---|---|
autoConnectIde | Boolean | false | Connect to a running VS Code or JetBrains IDE from an external terminal. CLAUDE_CODE_AUTO_CONNECT_IDE overrides |
autoInstallIdeExtension | Boolean | true | Install the IDE extension when run from a VS Code terminal. CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL=1 skips |
claudeInChromeDefaultEnabled | Boolean | Unset (off, setup offered) | Start interactive sessions with Chrome integration. --chrome and --no-chrome override |
copyFullResponse | Boolean | false | /copy skips the code-block picker |
copyOnSelect | Boolean | true | Mouse selection copies to the clipboard in fullscreen and agent view |
defaultToAgentsView | Boolean | false | Bare claude opens agent view |
leftArrowOpensAgents | Boolean | true | ← on an empty prompt backgrounds the session and opens agent view |
diffTool | "auto" or "terminal" | "auto" | Show proposed diffs in the connected IDE or keep them in the terminal |
externalEditorContext | Boolean | false | Ctrl+G editor buffer starts with Claude's last reply as # comments |
prStatusFooterEnabled | Boolean | true | PR review status badge in the footer |
Older versions also kept theme, verbose, showTurnDuration, terminalProgressBarEnabled, teammateMode, preferredNotifChannel, remoteControlAtStartup, agentPushNotifEnabled, inputNeededNotifEnabled and respectGitignore here. Claude Code still reads those old values when no settings file sets the key.
Deprecated and removed keys
| Key | Status |
|---|---|
includeCoAuthoredBy | Deprecated; use attribution |
disableArtifact | Deprecated; use enableArtifact: false |
keybindingFlavor | Deprecated, no effect; word editing always follows readline conventions |
taskOutputMaxChars | Removed in v2.1.277 with the TaskOutput tool |
permissionExplainerEnabled | Removed in v2.1.257 with the Ctrl+E command explanation |
teammateDefaultModel | Removed in v2.1.234 |
Related
- Settings: which file to edit and how precedence works
- Example settings files: complete personal, team and organisation files
- Permissions: rule syntax and evaluation order
- Sandboxing: what the sandbox keys actually enforce
- Environment variables: the per-session overrides mentioned throughout