Settings: the Control Panel

Settings: the Control Panel

Part 2 — Context Engineering Chapter 1 of 5
Listen to this article
Read aloud in your browser

Overview

This chapter covers:

  • Four settings files, what each one reaches, and which of them your teammates get
  • The precedence stack — and the three kinds of key that do not obey it
  • Why environment variables are not a level, and are decided pair by pair
  • Which edits reach a running session and which wait for a restart
  • The checklist for “I set this and nothing happened”

Four files

ScopeFileReaches
User~/.claude/settings.jsonYou, every project on this machine
Shared project.claude/settings.jsonEveryone working in that folder — commit it
Project local.claude/settings.local.jsonYou, that one project
Managedmanaged-settings.json, MDM, or the claude.ai consoleEveryone your organisation deploys it to

Installing Claude Code creates none of them. The user file appears the first time you change something in /config; the local file appears the first time you answer “Yes, and don’t ask again” on a permission prompt.

Two properties of the local file are worth knowing before you go looking for it:

  • Claude Code writes it, and keeps it out of git for you. The first time it writes the file in a repository that does not already ignore it, it adds **/.claude/settings.local.json to your global git excludes. Create the file by hand and that never happens — gitignore it yourself.
  • In a repository, it lives at the root. Start a session in a subdirectory and Claude Code still reads and writes the root file, so an approval you give in packages/api applies repository-wide. Before v2.1.211 it stayed in the starting directory.

There is a fifth file, ~/.claude.json, that Claude Code maintains for itself — sign-in, MCP servers, per-project trust decisions. You don’t edit it.

Settings files are strict JSON. A // comment or a trailing comma is a syntax error, and the file is reported as a Settings Error at the next start. Add "$schema": "https://json.schemastore.org/claude-code-settings.json" at the top for autocomplete and validation in your editor.

Precedence

When the same key appears in more than one file, the highest level that sets it wins.

flowchart TB
    M["Managed settings — your organisation"] --> C["Command line — claude --settings"]
    C --> L["Project local — .claude/settings.local.json"]
    L --> P["Shared project — .claude/settings.json"]
    P --> U["User — ~/.claude/settings.json"]

Read it top-down: managed beats the command line, which beats project local, which beats shared project, which beats user. The two that catch people out are next to each other in that list — your team’s committed .claude/settings.json outranks your personal ~/.claude/settings.json, and the way to get your own value back is .claude/settings.local.json, not the user file.

Managed is absolute. --settings does not override a managed key, and --model picks only from the models your organisation allows.

Lists merge instead of overriding

permissions.allow set in three files does not resolve to one file’s list — the entries combine. This is what makes shared and personal permission rules coexist: your team’s file adds rules, yours adds more, and neither erases the other.

Model keys are the exception, because position carries meaning. fallbackModel is an ordered chain, so the highest file that defines it supplies the whole value. availableModels in managed settings replaces your entries rather than merging with them — that is the key an administrator uses to actually constrain model choice, not model.

Resolve a key

Environment variables are not a level

They sit outside the stack entirely, and each variable–key pair has its own rule:

  • ANTHROPIC_MODEL exported in your shell applies over the model key from any file.
  • ANTHROPIC_DEFAULT_MODEL applies only when no file sets model.

Same subject, opposite behaviour. There is no general rule to memorise here; check the variable’s row in the environment variables reference for the pair you are setting.

An env block inside a settings file is an ordinary key and follows the normal stack. It is also the right place for variables background agents need — a shell export does not reach them.

{
  "env": {
    "API_TIMEOUT_MS": "1200000",
    "HTTPS_PROXY": "http://proxy.corp.example.com:8080"
  }
}

Changing a setting

Three routes, for three different intentions:

IntentionRoute
Change a personal option/config, or /config verbose=true for one key
Set anything, durablyEdit the file for the scope you want
Try a value without savingclaude --settings '{"model": "claude-opus-4-8"}'

/config lists a short set of personal options — theme, editor mode, verbose — not every key. It is not a view of your settings.json.

Which edits reach a running session

Claude Code watches the settings files and reloads them, so most edits — permissions, hooks, credential helpers — apply without a restart. A few keys are read once at session start:

KeyChange it with
model/model
effortLevel, modelSettings/effort
outputStyle/clear or a restart — it is part of the system prompt

Managed settings delivered by MDM or the console arrive on a schedule rather than on save, so restart before concluding a policy has not shipped.

The debugger

Two commands, and they answer different questions:

  • /status — the Setting sources line lists every file loaded for this session. It confirms which files were read. It does not say which file supplied a given key.
  • claude doctor — lists the entries Claude Code rejected: malformed permission rules, unknown hook events, values the schema refused.

A broken file is not silent, but it degrades in three different ways worth telling apart. Settings Error: invalid JSON or a rejected value, and an interactive session offers to fix it. Settings Warning: individual entries failed and were skipped; the rest of the file is live. Configuration error: ~/.claude.json cannot be parsed — Claude Code backs it up to ~/.claude/backups/ and offers a reset.

claude -p shows no dialog. It skips the broken file or values and continues, so a -p run that ignored your setting needs claude doctor to explain itself.

When a setting doesn’t apply

The checklist, in the order worth trying:

  1. A higher level sets it. /status first, then the stack above.
  2. A variable or flag overrides it independently, decided per pair.
  3. The file cannot set that value. permissions.defaultMode values auto and bypassPermissions do not take effect from .claude/settings.json or .claude/settings.local.json — both live in the repository, so honouring them would let a checked-in file escalate its own permissions. User or managed settings, or --permission-mode for one session.
  4. A security key keeps its strict value. For a short list — disableClaudeAiConnectors, isolatePeerMachines, enableArtifact, crossSessionInbound, useAutoModeDuringPlan, syncClaudeAiSkills — Claude Code honours the restrictive value from a lower scope, over managed. This is the one place the stack runs backwards, and it runs backwards on purpose.
  5. The key waits for trust. permissions.allow, additionalDirectories, extraKnownMarketplaces and most env values from a committed file apply only after each teammate trusts the folder. deny and ask rules apply immediately.
  6. The file is broken. claude doctor.

There is a related failure that looks like precedence and isn’t: a change you made inside Claude Code vanishes in new sessions. /model and /config write to ~/.claude/settings.json; if that file is read-only or generated by another tool, the change applies now and is gone next time. Set it in whatever generates the file.

Cloud sessions read a different set

A session on Claude Code on the web or claude --cloud runs on a fresh clone, not your machine:

SourceReaches a cloud session
.claude/settings.jsonYes — it is in the clone
~/.claude/settings.jsonNo
.claude/settings.local.jsonNo
ManagedServer-managed only, not a local managed-settings.json or MDM profile

If a setting must hold in a cloud session, it belongs in the committed project file.

Model configuration

The model is a setting like any other, with the usual four routes — /model, --model, the model key, ANTHROPIC_MODEL — plus aliases that track the current release rather than pinning a version:

AliasResolves to
defaultYour account’s default — Opus 5 on Max and Enterprise, Sonnet 5 on Pro
opus, sonnet, haikuThe latest of each
fable, bestThe latest Fable, for the hardest and longest tasks
opusplanOpus while planning, Sonnet while executing
opus[1m], sonnet[1m]The same model with a 1M-token context window

Effort is the separate dial — how much the model reasons per step — set with /effort or --effort, from low through high (the default) to xhigh, max and ultracode. max applies to the current session only unless you set it through the environment. Per-model defaults live in modelSettings:

{
  "modelSettings": {
    "claude-opus-5":   { "effortLevel": "xhigh" },
    "claude-sonnet-5": { "effortLevel": "medium" }
  }
}

One behaviour that reads as a bug and isn’t: claude --resume keeps the model saved in the transcript, ignoring your current default. Details and the rest of the model surface are in the model configuration docs.

Summary

  • Four files. Precedence, highest first: managed → command line → project local → shared project → user.
  • Your team’s committed file outranks your user file. .claude/settings.local.json is how you get your own value back.
  • Lists like permissions.allow merge across files rather than overriding. fallbackModel and a managed availableModels do not.
  • Environment variables are not a level; each variable–key pair has its own rule. ANTHROPIC_MODEL beats any file, ANTHROPIC_DEFAULT_MODEL yields to one.
  • Most edits reload into a running session; model, effortLevel and outputStyle do not.
  • /status says which files loaded, claude doctor says what was rejected. Neither says which file supplied a key.
  • A short list of security keys honours the stricter value from a lower scope, over managed.
  • Cloud sessions read the committed project file and server-managed settings — nothing else from your machine.
  • Full reference: settings, every key, example files.

Chapter 6 is CLAUDE.md — the file that tells Claude how your project works, where it can live, and what never belongs in it.