Settings files and precedence
Where Claude Code reads its settings from, which file a key belongs in, how to check a change landed, and which value wins when files disagree.
Almost everything about how Claude Code behaves on your machine is controlled by a handful of JSON keys: the model it starts on, which commands it may run unattended, which files it must never open, how the terminal looks and what your employer insists on. This page is about the files those keys live in. If you already know the key you want, jump to the settings reference; if you want to write permission rules, see permissions.
The terminal, the VS Code and JetBrains extensions and the desktop app all read the same files, so everything here applies to all of them. Cloud sessions are different and get their own section at the end.
The four files and who they affect
Each settings file has a scope: the people and projects a key saved in it reaches.
| Scope | Path | Reaches | Typical contents |
|---|---|---|---|
| User | ~/.claude/settings.json | You, in every project on this machine | Theme, editor mode, preferred model, your personal allow rules |
| Shared project | .claude/settings.json (inside the repo) | Anyone who opens that folder; commit it and the whole team gets it | Team permission rules, hooks, plugins, project env |
| Project local | .claude/settings.local.json (inside the repo) | Only you, only in this project | Personal overrides, experiments before you share a change |
| Managed | managed-settings.json, MDM profiles, or the claude.ai admin console | Every machine or account your organisation targets | Security and compliance policy |
On Windows, ~/.claude means %USERPROFILE%\.claude. If you want your home-level files somewhere else, set CLAUDE_CONFIG_DIR (see environment variables); Claude Code then keeps settings, history and plugins under that folder.
A worked example of scope
Say I have three projects checked out: portfolio/, billing-api/ and client-portal/. A colleague also has a clone of client-portal/, and I sometimes kick off a cloud session against it.
- A key in
~/.claude/settings.jsonapplies in all three of my folders, and nowhere on my colleague's laptop or in the cloud session. - A key in
client-portal/.claude/settings.jsonapplies in myclient-portal/straight away. It only reaches my colleague and the cloud session once I commit and push it. - A key in
client-portal/.claude/settings.local.jsonapplies to my copy ofclient-portal/and nothing else. - Managed settings reach every machine and account the organisation targets. Of the managed sources, only server-managed settings from the console reach cloud sessions.
Where the files come from
Installing Claude Code creates none of them. If one exists, it got there in one of these ways:
- Managed: your organisation put it there. You do not edit it.
- Shared project: someone committed it, or you create
.claude/settings.jsonyourself. - User: Claude Code writes
~/.claude/settings.jsonthe first time you change an option in/configthat lives in user settings, such as the theme. - Project local: Claude Code writes
.claude/settings.local.jsonthe first time you pick a standing approval such as "Yes, and don't ask again" on a Bash prompt. A few/configoptions, including Show tips, also save here.
There is also a fifth file, ~/.claude.json, which Claude Code manages for itself. It stores your login, MCP server definitions, per-project state such as trust decisions, and the global config options that /config writes. You rarely need to touch it. The .claude directory guide maps every file Claude Code reads.
Sharing settings with a team
Commit .claude/settings.json and everyone who clones the repository picks up the same permissions, hooks and plugins. Anyone who needs to differ puts the exception in their own .claude/settings.local.json, so personal tweaks never need a commit. Example settings files has a full team file to start from.
Two things can stop a committed key reaching teammates. Some keys wait until each person trusts the folder, and some keys are ignored entirely in a repository file. Both are covered under troubleshooting.
Keeping personal settings out of git
.claude/settings.local.json is the place for "just me, just here". If the team file pins "model": "claude-sonnet-5" and you would rather use Opus in this repo, put "model": "claude-opus-5-5" in your local file and only your sessions change.
Three behaviours make this file different from the shared one:
- Claude Code writes to it. Every "Yes, and don't ask again" approval for a Bash command or a fetch domain lands here as an
allowrule. - It is git-ignored for you. The first time Claude Code writes the file inside a git repository that does not already ignore it, it adds
**/.claude/settings.local.jsonto your global git excludes file. That iscore.excludesFileif your global git config sets it to an absolute or~path, otherwise$XDG_CONFIG_HOME/git/ignore, falling back to~/.config/git/ignore. If you made the file by hand before Claude Code ever wrote it, add it to.gitignoreyourself. - Its allow rules skip the trust step while the file is untracked. The committed project file has to wait for workspace trust; your local file does not, unless git is tracking it.
Which directory holds the local file
Since v2.1.211, if you start Claude Code in a subfolder of a git repository, it reads and writes .claude/settings.local.json at the repository root, so an approval you grant in packages/web/ applies across the whole repo. In a worktree it uses the main checkout's root.
It falls back to keeping the file beside .claude/settings.json in the starting directory when you are outside a git repository, when the repository root is your home folder, on Windows, or when the root, its .git or its .claude entry is not owned by your user. A local file left in a subfolder by an older version is still read; where both set a key, the root copy wins and permission rules from both apply.
Path anchors inside the file do not move to the root. A permission rule starting with /, or a relative sandbox path, still anchors at the session's primary working directory.
The shared .claude/settings.json, by contrast, is read from the directory you started in. If your team commits it at the repo root, start Claude Code there. After /cd (v2.1.246 or later), both project files are read from the new directory.
What your organisation enforces
If you work somewhere that manages Claude Code, some keys are fixed and nothing in your own files will move them. Run /status: the Setting sources line names the managed source in force. Managed settings can arrive as:
- server-managed settings fetched from the claude.ai admin console or a self-hosted Claude apps gateway
- an MDM or OS-level policy, or a
managed-settings.jsonfile in a system directory - an embedding host such as Claude Desktop, via the SDK
managedSettingsoption
The administrator's side of this is in managed settings and admin setup.
Changing a setting
You have three routes: the /config menu, editing a file, or a one-off override at launch.
There is no published system prompt to edit. If you want standing instructions for Claude, put them in CLAUDE.md or pass --append-system-prompt.
The /config menu
Run /config and open the Config tab. It shows a short list of personal options (theme, editor mode, verbose output and so on), not every key. Changing one saves it for you: most go to ~/.claude/settings.json, a few such as Show tips go to .claude/settings.local.json, and the global config options go to ~/.claude.json.
You can set an option directly with key=value:
/config verbose=true
/config is a terminal feature. The VS Code chat panel and the desktop app do not open it, so edit the files or use those apps' own settings screens.
Editing a file
Open the file for the scope you want and add the key. The files are strict JSON: no comments and no trailing commas. A syntax slip shows up as a Settings Error the next time you start.
Here is a user-level file I might use on a Python project: it lets Claude run the formatter and test suite without asking, and stops it reading anything under a local credentials/ folder.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(ruff format *)",
"Bash(pytest *)"
],
"deny": [
"Read(./credentials/**)"
]
}
}
The $schema line is optional but worth having. Editors that understand JSON Schema (VS Code, Cursor and others) will autocomplete keys and flag typos. The schema occasionally lags a fresh release, so a warning on a brand-new key does not necessarily mean it is wrong.
Save, then run /status to confirm the file loaded. For complete personal, team and organisation files, see example settings files.
Overriding for one session
To try something without saving it, set it at launch:
--settingstakes JSON inline or a path to a JSON file. It sits above your user, project and local files and below managed settings, and accepts any key your user file accepts. It cannot set managed-only or global config keys.- A dedicated flag, where one exists:
--modelformodel,--effortforeffortLevelandmodelSettings. - An environment variable paired with the key, such as
ANTHROPIC_MODELformodel.
For example, to run one session on Opus with spinner tips off, leaving your files untouched:
claude --settings '{"model": "claude-opus-5-5", "spinnerTipsEnabled": false}'
Commands inside a session usually do save. /model stores your choice as the default for new sessions, unless you press s in the picker, which switches for this session only. Model configuration explains which /effort choices persist.
When edits take effect
Claude Code watches its settings files and reloads them on change, so most edits apply to a running session, including permissions, hooks and credential helpers such as apiKeyHelper. It also notices a new settings file created mid-session, as long as its folder existed at start (the project .claude/ folder is picked up even if you create it during the session). Each detected file change fires the ConfigChange hook.
Managed settings from MDM or the console arrive on a polling schedule rather than on save, and do not fire ConfigChange.
A few keys are read only at startup. The ones you are most likely to trip over:
model: use/modelto switch mid-session. Switching model starts a fresh prompt cache, so the next request costs more (see prompt caching).effortLevelandmodelSettings: use/effort.
Confirming what loaded
/status opens a dialog whose Status tab includes a Setting sources line: one entry per file read this session, such as User settings or Project local settings. If managed settings apply, the entry says in brackets how they reached you.
That line tells you which files were read, not which file supplied a particular key. For rejected entries, run claude doctor (see debug your config). When project or managed settings choose the model, the startup header names the file. Note that /status and /config are the same dialog on different tabs, and the Config tab is not a view of your JSON.
When a file is broken
What you see depends on how bad the damage is:
| Situation | What happens |
|---|---|
| A user, project or local file is invalid JSON or fails the schema | Settings Error dialog at interactive start: fix it with Claude's help, exit, or carry on without that file |
| Only individual entries are bad (a malformed rule, an unknown hook event) | Settings Warning: those entries are skipped, the rest of the file applies |
| A managed file has bad entries | The valid parts are still enforced; some keys fall back to a stricter value until fixed |
~/.claude.json cannot be parsed | Configuration error: the broken file is copied to ~/.claude/backups/.claude.json.corrupted.<timestamp> and you choose to exit or reset |
Claude Code keeps the five most recent ~/.claude/backups/.claude.json.backup.<timestamp> copies, so you can restore an earlier state by copying one back.
A -p (headless) run never shows a dialog. It skips whatever is broken and carries on, so if a scripted run seems to ignore a setting, run claude doctor afterwards. The one exception is a managed settings document that cannot be parsed at all; see errors.
Settings precedence
When a key appears in several places, the highest level that sets it wins. From top to bottom:
- Managed settings. Nothing you set overrides these, and flags such as
--modelcan only pick from models the organisation allows. A managedmodelis a starting default rather than a lock; the locks areavailableModelsanddeniedModels. - Command line
--settings. Applies for that session. Keys you leave out keep their file values. Single-purpose flags like--modelare not part of this stack; each key's reference entry says which flags override it. - Project local (
.claude/settings.local.json). - Shared project (
.claude/settings.json). - User (
~/.claude/settings.json).
Environment variables are not a level in this list. Where a key has a paired variable, the pairing decides: an exported ANTHROPIC_MODEL beats model from any file, whereas ANTHROPIC_DEFAULT_MODEL only applies when no file sets model. The environment variables page lists the pairs. An env block inside a settings file is just another key and follows the levels above.
Arrays merge
List-valued keys such as permissions.allow are combined across files rather than replaced, so each scope can add entries without wiping out another's. Four model-related keys have their own rules:
fallbackModelis an ordered chain, so the whole value comes from the highest file that defines it.modelPickeris never merged. The whole value comes from the highest of managed,--settingsand user settings; project and local copies are ignored. Needs v2.1.242 or later.availableModelsfrom managed settings is applied exactly as written, and entries from user, project or local files are ignored (unless an embedding app supplies its own list). Outside the managed tier it merges normally.modelSettingsis resolved one model at a time together witheffortLevel.
Four scenarios
Suppose I have turned off the tips under the spinner by setting spinnerTipsEnabled to false in my user file. Here is how each level can turn them back on.
- The team file sets it to
true. Shared project beats user, so I see tips in that repo only. Fix: add"spinnerTipsEnabled": falseto that repo's.claude/settings.local.json; local beats shared, and teammates are unaffected. - Managed settings set it to
true. I cannot override this from any file or--settings./statustells me which source to raise with my administrator. - I launched with
claude --settings '{"spinnerTipsEnabled": true}'. That session shows tips; the next one does not, because nothing was saved. - A flag or variable overrides a key directly. This is per key. For
model,ANTHROPIC_MODELbeats the file value and--modelbeats both. Remove the flag or unset the variable.
Troubleshoot a setting that does not apply
Start with /status, then match your symptom. The debug your config page covers deeper checks, including a clean-configuration test.
A value I set is ignored. Usual causes:
- Something higher sets the same key: another file,
--settings, a managed source, or a paired flag or variable. - A security key is holding its strict value (see the exceptions table below).
- The file is not allowed to set that value.
permissions.defaultModeofautoorbypassPermissionshas no effect from project or local files; set it in user or managed settings, or pass--permission-mode. (Before v2.1.257,bypassPermissionsworked from any file.) Telemetry exporter variables in a project or localenvblock are also ignored, apart from a few values that switch telemetry off. - The file is broken and was skipped.
A change made inside Claude Code is gone next session. Choices such as a default model are written to ~/.claude/settings.json. If that file is generated by another tool or symlinked to a read-only copy, the write fails silently and the change lives only in the current session. Set it at the source, or replace the file with a writable one.
A managed change has not arrived. Restart first; managed sources poll on a schedule. If /status then shows a different source from the one your administrator edited, a higher-priority managed source is in play. Managed settings gives the order.
A committed key does not reach teammates. Either the key is not honoured in a repository file at all (in the settings reference, look for a scope of User, local, or managed, User or managed, Managed or Global config), or it is waiting for trust. permissions.allow, permissions.additionalDirectories, extraKnownMarketplaces and most env values only apply once each person trusts the folder. deny and ask rules apply immediately.
Permission rules combine oddly. Choosing "Yes, and don't ask again" writes an allow to your local file, and an allow never outranks an ask from a project or managed file, so you can still be prompted. In VS Code the approval card lets you choose which file to save to, including the shared one; the CLI always writes to the local file. Organisation allow rules also merge with yours unless allowManagedPermissionRulesOnly is set.
Exceptions to managed precedence
For a handful of keys that restrict what a session can do, Claude Code honours the stricter value even from a scope that normally cannot beat managed settings.
| Key | Stricter value honoured | From where |
|---|---|---|
disableClaudeAiConnectors | true | Any scope |
enableArtifact / disableArtifact | false / true | Any scope (v2.1.242+); nothing re-enables the Artifact tool |
isolatePeerMachines | true | Any scope |
permissions.blockReadsOutsideWorkingDirectories | true | Any scope (v2.1.257+) |
autoMode.classifyAllShell | true | User file or --settings |
remoteControlAtStartup | false | Shared project or local file; a true there is ignored |
crossSessionInbound | Stricter on the ladder accept < hold < refuse | Shared project or local file |
useAutoModeDuringPlan | false | Managed, --settings, user or local (not the shared project file) |
syncClaudeAiSkills | false | Managed, --settings, user or local (not the shared project file) |
syncClaudeAiPlugins | false | Managed, --settings, user or local (not the shared project file) |
maxEffortLevel | The lowest cap | Any scope including --settings (v2.1.267+) |
One more exception: an app that embeds Claude Code and sets CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST takes its own model configuration over managed model, fallbackModel, modelPicker, modelOverrides and the model-selection variables in a managed env block. A managed availableModels list still applies unless the app supplies its own.
Settings in cloud sessions
A cloud session runs on a fresh clone in a cloud environment, so your laptop's files mostly do not come along.
| Source | Read in the cloud? |
|---|---|
.claude/settings.json | Yes, in a single-repository session, because it is part of the clone. In a multi-repository session only enabledPlugins and extraKnownMarketplaces are read from each repo, and those plugins still do not load in the cloud |
~/.claude/settings.json and .claude/settings.local.json | No; they stay on your machine |
| Managed file or MDM profile on your device | No |
| Server-managed settings | Yes. A self-hosted environment also reads the managed file baked into its runner image |
In the browser at claude.ai/code, /config opens the Claude Code section of your claude.ai settings rather than changing a key. To change behaviour in the cloud, set an environment variable on the environment, or commit the key to the repo's .claude/settings.json for single-repo sessions.