AI how-to notes · 2026-09-17 · last run 2026-09-17 · 한국어 원문
Claude Code settings.json locations and precedence — documented rules and a Windows MCP approval test
The short version
Claude Code settings live in four scopes — user, shared project, project local, and managed — and when the same key shows up in more than one of them, the value comes from the highest level that sets it: managed, then command line, then local, then shared, then user (per the official docs). On Windows, ~/.claude means %USERPROFILE%\.claude.
That order is the documented general rule, not a result we verified by giving the same key competing values. Our measurements cover the MCP approval key enableAllProjectMcpServers and the deny list disabledMcpjsonServers in an untrusted folder. The comparison below concerns those MCP-specific rules.
2026-09-28 documentation review and reorganization: we reread the settings docs and MCP docs, and moved the basic approval instructions into the MCP setup article. The measurement date and command output below remain from 2026-09-17; we added no Windows rerun results.
Who this is for
You edited settings.json and nothing seems to have changed. Or you share a repo with your team and want your own settings kept separate. Or you can never remember whether a given key belongs in settings.json or settings.local.json.
What we tested on
| Item | Value |
|---|---|
| OS | Windows 11 Home (10.0.26200) |
| Shells | Git Bash, PowerShell 7 |
| Claude Code | version 2.1.274, native install (confirmed with claude doctor) |
| Test folder | C:\Users\User\AppData\Local\Temp\longtail_C\proj (not a git repo, never opened as a chat session) |
| User settings | read only (we printed file stats and top-level key names, nothing more) |
The four files, per the official docs
Source: official settings docs (checked 2026-09-17, rechecked 2026-09-28). This is the scope comparison table retained from the original article.
| Scope | File | Who it affects |
|---|---|---|
| User | ~/.claude/settings.json | You, in every project on this machine |
| Shared project | .claude/settings.json | Everyone working in the folder that contains it. In a git repository, commit it so teammates get it |
| Project local | .claude/settings.local.json | You, in this one project only. Claude Code keeps it out of git when it creates the file; if you create it by hand, add it to .gitignore yourself |
| Managed | managed-settings.json and other managed sources | Everyone your organization deploys it to; nothing you set overrides it, apart from a few security-sensitive exceptions |
If you are on Windows, one sentence from the same page is worth memorizing.
On Windows, `~/.claude` means `%USERPROFILE%\.claude`.The local file can appear without you creating it. According to the docs, answering "Yes, and don't ask again" to a permission prompt makes Claude Code write that allow rule into .claude/settings.local.json. Launched from a subfolder of a git repository, it writes the file at the repository root — but the docs call out Windows (on Windows) as an exception to that rule, where the local file sits in the same place as .claude/settings.json. Exactly where that is, we cannot state from the excerpt alone, and we did not measure it.
Precedence, quoted from the docs
From the Settings precedence section of the same page.
When the same key appears in more than one place, Claude Code uses the value from the highest level that sets it.
1. Managed settings
2. Command line arguments
3. Project local settings (`.claude/settings.local.json`)
4. Shared project settings (`.claude/settings.json`)
5. User settings (`~/.claude/settings.json`)Two riders attached to that list trip people up in practice. First, list-shaped keys such as permissions.allow are merged rather than overridden by the higher level (Lists merge instead of overriding). Second, environment variables are not a layer in this table at all — the docs state that ANTHROPIC_MODEL takes precedence over model in any file.
User settings on our machine
We read and parsed the user settings.json, and kept only file stats and top-level key names in the output.
-rw-r--r-- 1 User 197121 18746 Sep 16 18:34 /c/Users/User/.claude/settings.json
-rw-r--r-- 1 User 197121 93011 Aug 15 09:14 /c/Users/User/.claude/settings.local.json
['agentPushNotifEnabled', 'autoMode', 'autoUpdatesChannel', 'enabledPlugins', 'env', 'extraKnownMarketplaces', 'hooks', 'model', 'permissions', 'skipWorkflowUsageWarning', 'statusLine', 'theme']There was a settings.local.json in the home .claude folder too. We did not check when or by what action it got there.
Is there a command that tells you which file wins?
The command list in claude --help has no settings-inspection command such as config (it has agents, auth, auto-mode, doctor, mcp, plugin, project, update, and others). claude auto-mode config is described as "Print the effective auto mode config as JSON: your settings where set, defaults otherwise", so it does show merged values — but it covers only the auto mode keys, and since our user file has an autoMode key, running it would print personal settings. We left it alone.
The check the docs recommend is /status inside a session (the Setting sources line), which requires opening a chat session, so we skipped it this time. That line names the files Claude Code loaded; it does not identify the source of each effective key (documentation rechecked 2026-09-28).
We therefore chose enableAllProjectMcpServers, which approves servers in a project .mcp.json, and the deny list disabledMcpjsonServers. We left one server named tempfs in the test folder and varied only the settings files and the --settings argument. The basic steps for adding the server and clearing Pending approval through interactive approval or a single invocation with --settings are in Adding an MCP server to Claude Code on Windows.
MCP approval and rejection results — separate from general precedence
| Run | Where the setting was | claude mcp list / get result |
|---|---|---|
| 0 | no settings file | ⏸ Pending approval |
| 1 | "enableAllProjectMcpServers": true in .claude/settings.json | ⏸ Pending approval |
| 2 | same value in .claude/settings.local.json only | ⏸ Pending approval |
| 4 | no file + --settings '{"enableAllProjectMcpServers": true}' | ✔ Connected |
| 5 | "disabledMcpjsonServers": ["tempfs"] in .claude/settings.json + the --settings from run 4 | get: ✘ Rejected (see disabledMcpjsonServers in settings) |
| 6 | same as run 5 | the tempfs line disappears from list entirely |
Run 3 (approving via --settings while the local file from run 2 was still there) was also ✔ Connected. To isolate the local file's contribution we deleted it and re-ran as run 4.
Runs 1 and 2 failing to apply the file's MCP approval appears to be down to this folder never having been "trusted". The MCP docs (checked 2026-09-17, rechecked 2026-09-28) say that in an untrusted folder the approval in a committed .claude/settings.json is ignored, that an approval in settings.local.json "waits for the trust dialog", and that the three places that do apply before trust are the user ~/.claude/settings.json, managed settings, and --settings. Our results are consistent with that description.
Run 5 matches another line from the same page: "A disabledMcpjsonServers entry in any settings file still rejects the server." Approving from the command line (rank 2) lost to the rejection in the shared project file (rank 4), so this pair of keys follows a separate rule that the precedence table above does not describe. It also showed that a rejection in the shared file is read even in an untrusted folder.
Checking whether a settings file is broken
The help text for claude doctor says it "Reads settings files in the current directory without a trust prompt". We deliberately broke both files in the test folder and ran it: a string "yes" instead of true in settings.json, and a trailing comma in settings.local.json.
Invalid settings
- C:\Users\User\AppData\Local\Temp\longtail_C\proj\.claude\settings.json › enableAllProjectMcpServers: Expected boolean, but received undefined
Suggested fix: Use true or false without quotes. Example: "includeCoAuthoredBy": true
- C:\Users\User\AppData\Local\Temp\longtail_C\proj\.claude\settings.local.json: Expected object, but received undefinedBoth files were caught, and the exit code was 0. Note that the wording says "received undefined", which does not match what we actually put in the file. After fixing the files, run claude doctor again and check that the list comes back empty.
What didn't work
We never managed to test levels 2 through 5 head to head with the same key set to different values. Under the constraint of not opening a chat session (/status, the startup header), we found no read-only command that reveals where a value came from. And in an untrusted folder both the local and shared approvals are ignored, so there was no way to stage a scenario where local beats shared.
What we did not check
- Managed settings.
claude doctorprintedManaged settings (remote): not fetched — requires an Enterprise or Team subscription. That output alone does not tell us whether other managed sources exist, and we ran no managed-settings experiment. - Behavior in a trusted folder (one where the trust dialog was accepted in a chat session).
- Whether
settings.local.jsonlands at the root inside a git repository, and whether it gets registered in global git excludes. - The
--setting-sourcesoption (it is in the help text) for switching layers off one at a time. - macOS and Linux.