On this page
Claude Code settings are JSON files. Put personal settings in
~/.claude/settings.json, team settings in .claude/settings.json (commit
it), and your own per-project overrides in .claude/settings.local.json.
Managed settings from your organization beat all three. Permissions,
environment variables, hooks and the default model all go in these files.
This is the whole Claude Code configuration model in one place. The part most
people trip on is not the file format. It's which file a key
belongs in, and why a rule you added doesn't seem to apply. This guide covers
both, then shows where your MCP servers, skills and subagents are configured,
because those mostly live outside settings.json.
Everything here comes from the official Claude Code docs: settings, permissions and the .claude directory reference, checked on 8 November 2026.
Where Claude Code settings files live
Claude Code reads four settings files. The file you pick decides who the setting applies to.
| Scope | File | Applies to | Use it for |
|---|---|---|---|
| User | ~/.claude/settings.json |
You, in every project on this machine | Your theme, default model, personal permission rules |
| Shared project | .claude/settings.json |
Everyone in the project, once you commit it | Team permissions, hooks, plugins, project env vars |
| Project local | .claude/settings.local.json |
You, in this project only | Personal overrides, trying a rule before you share it |
| Managed | managed-settings.json (or MDM / the claude.ai admin console) |
Everyone your organization deploys it to | Security policy you can't override |
On Windows, ~/.claude means %USERPROFILE%\.claude. Installing Claude Code
doesn't create any of these files. Claude Code writes the user file the first
time you change an option in /config, and the local file the first time you
pick "Yes, and don't ask again" on a permission prompt.
When Claude Code creates .claude/settings.local.json in a git repo, it adds
it to your global git excludes so it stays out of commits. If you create the
file by hand, add it to .gitignore yourself.
The managed file sits in a system folder:
- macOS:
/Library/Application Support/ClaudeCode/managed-settings.json - Linux and WSL:
/etc/claude-code/managed-settings.json - Windows:
C:\Program Files\ClaudeCode\managed-settings.json
There is also a fifth file, ~/.claude.json. Claude Code writes it for
itself: your account details, per-project trust decisions, a few global
options, and your personal MCP servers. You normally don't edit it by hand.
Which settings file wins: precedence
When the same key is set in more than one place, the higher level wins. From highest to lowest:
- Managed settings. Nothing you set overrides them.
- Command line. JSON passed with
--settingsfor one session. - Project local (
.claude/settings.local.json). - Shared project (
.claude/settings.json). - User (
~/.claude/settings.json).
So if your team's file sets a model you don't want, put your own model in
.claude/settings.local.json. It beats the shared file and only changes your
sessions.
Two exceptions catch people out:
- Lists merge. If
permissions.allowappears in three files, Claude Code combines all three lists. A file can add rules, not remove another file's. - Some keys only work from certain files. For example,
permissions.defaultModeset toautoorbypassPermissionsdoesn't take effect from a project or local file. Set those in your user file or pass--permission-modefor one session.
Environment variables aren't a level in this stack. Some override their
matching key (an exported ANTHROPIC_MODEL beats the model key), and the
docs list which ones per variable.
How to configure Claude Code: change a setting
You have three ways in.
The /config menu. Run /config in the terminal and open the Config tab.
It shows a short list of personal options (theme, editor mode, verbose
output), not every key. You can also set one directly: /config verbose=true.
The VS Code panel and the desktop app don't open /config; edit the file
instead.
Edit the file. Settings files are strict JSON. A // comment or a
trailing comma is an error, and Claude Code shows a Settings Error dialog at
the next start. Add the $schema line to get autocomplete and validation in
your editor.
One session only. Pass a key on the command line. Nothing is saved:
claude --settings '{"model": "claude-sonnet-5"}'
Claude Code watches the files and reloads most edits (including
permissions and hooks) without a restart. model and effort are read at
session start, so switch those with /model and /effort instead.
A starter settings.json
This user file lets Claude run your lint and test scripts without asking and
stops it reading .env files. It's the example from the official docs:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)"
]
}
}
Other keys you'll likely want at some point:
| Key | What it does |
|---|---|
model |
The model every new session starts with |
env |
Environment variables for every session and the commands it runs |
permissions |
allow, ask, deny, defaultMode, additionalDirectories |
hooks |
Your own commands that run at points in a session, such as before a tool call |
enabledPlugins |
Turn plugins on or off per scope |
skillOverrides |
Hide or collapse a skill without editing its SKILL.md |
statusLine |
A command that draws a status line under the prompt |
attribution |
Change or hide the attribution Claude adds to commits and PRs |
cleanupPeriodDays |
How many days transcripts are kept (default 30) |
The full list is in the settings reference.
Claude Code permissions: allow, ask and deny
Permissions are the most useful part of the settings file. Each rule names a tool, and optionally what it may do.
- allow: run without asking.
- ask: always prompt, even if something else allows it.
- deny: never run.
Order matters, specificity doesn't. Claude Code checks deny first, then
ask, then allow. The first match decides. So a broad deny like
Bash(aws *) blocks aws s3 ls even if you also allowed Bash(aws s3 ls).
You can't carve an exception out of a deny with an allow.
Deny beats everything, across files. If any file denies a tool, no other file can allow it. A user-level deny blocks a project-level allow, and the reverse.
Rule syntax in one table
| Rule | Matches |
|---|---|
Bash |
Every shell command |
Bash(npm run build) |
Exactly npm run build |
Bash(npm run *) |
Any npm run script |
Bash(git commit *) |
git commit with any options |
Read(./.env) |
Reading .env in the current folder |
Edit(./src/**) |
Edits anywhere under src/ |
WebFetch(domain:example.com) |
Fetches to example.com |
mcp__github |
Every tool from the github MCP server |
mcp__github__* |
Same, wildcard form |
mcp__github__create_issue |
One MCP tool |
Agent(Explore) |
The built-in Explore subagent |
Skill(deploy) |
The deploy skill |
Put the * after the subcommand. Bash(git log *) allows only git log;
Bash(git *) allows every git command, including git push. A space before
the * matters too: Bash(ls *) doesn't match lsof, but Bash(ls*) does.
Bash(ls:*) means the same as Bash(ls *), but only at the end of a rule.
Two things permissions don't do
- A deny on a pattern isn't a sandbox.
Read(./.env)blocks Claude's file tools and shell commands Claude Code recognizes, likecat .env. It doesn't stop a script that opens the file itself. For a hard OS-level block, use sandboxing. - Instructions in CLAUDE.md aren't permissions. "Never push to main" in a prompt shapes what Claude tries. Only rules, modes and hooks change what Claude Code allows.
A bare tool name in deny (like Bash or mcp__*) removes the tool from
Claude's context entirely, so Claude never sees it. A scoped rule like
Bash(rm *) leaves the tool there and blocks matching calls.
To see every rule and the file it came from, run /permissions.
Why a committed allow rule doesn't apply yet
allow rules and additionalDirectories in a project's .claude/settings.json
grant power, so Claude Code holds them until you accept the workspace trust
dialog for that folder. The dialog lists what the folder would grant. deny
and ask rules apply right away, because they only restrict. That's a good
reason to read a cloned repo's settings file before you trust it.
Permission modes and defaultMode
A mode decides what happens when no rule matches. Set the default for new
sessions with permissions.defaultMode:
| Mode | What it does |
|---|---|
default |
Asks the first time each tool is used (shown as Manual) |
acceptEdits |
Also accepts file edits and common file commands like mkdir and mv in your working folders |
plan |
Reads and explores, but doesn't edit your files until you approve a plan |
auto |
No routine prompts; a background classifier checks risky actions first |
dontAsk |
Denies anything that would prompt; pre-allowed tools still run |
bypassPermissions |
Skips prompts. Only for containers or VMs |
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
Deny rules still block in every mode, including bypassPermissions. To stop
anyone using bypass or auto mode, set permissions.disableBypassPermissionsMode
or permissions.disableAutoMode to "disable". It works from any file, but
it only sticks for a whole team from managed settings.
Where Claude Code MCP configuration lives
MCP servers are not set up in settings.json. They live here:
| Where | Holds |
|---|---|
~/.claude.json |
Your user-scope servers, and local-scope servers under each project's path |
.mcp.json (project root) |
Project-scope servers, shared through git |
managed-mcp.json (system folder) |
Servers your organization deploys |
The easy way to write these files is claude mcp add with --scope local,
project or user. The full walkthrough is in
Claude Code MCP setup.
What settings.json does control is which servers are allowed to load and
which tools they get:
| Key | What it does |
|---|---|
enableAllProjectMcpServers |
Approve every server in a project's .mcp.json without a prompt |
enabledMcpjsonServers |
Approve named servers from .mcp.json |
disabledMcpjsonServers |
Reject named servers from .mcp.json |
allowedMcpServers |
Allowlist of servers users can add |
deniedMcpServers |
Block servers by URL, command or name |
permissions with mcp__ rules |
Allow, ask or deny single MCP tools |
Leave enableAllProjectMcpServers off. It means any repo you clone can
start any server its .mcp.json names, without you seeing it first. A server
is code with your credentials, so approve servers one at a time and check them
first. Our directory grades each listed server on its code, its
permissions and its maintainers.
For a server you do keep, deny the tools you don't need. A deny rule is a hard block; limit MCP tools shows the rules for read-only setups.
Where skills, subagents and CLAUDE.md live
These are files in the .claude folder, not keys in settings.json. The
project version lives in your repo; the user version lives in ~/.claude/.
| What | Project | All your projects |
|---|---|---|
| Instructions | CLAUDE.md (project root) |
~/.claude/CLAUDE.md |
| Skills | .claude/skills/<name>/SKILL.md |
~/.claude/skills/<name>/SKILL.md |
| Commands | .claude/commands/*.md |
~/.claude/commands/*.md |
| Subagents | .claude/agents/*.md |
~/.claude/agents/*.md |
| Rules | .claude/rules/*.md |
~/.claude/rules/*.md |
| Output styles | .claude/output-styles/*.md |
~/.claude/output-styles/*.md |
| Keyboard shortcuts | n/a | ~/.claude/keybindings.json |
Settings can still shape them. skillOverrides hides a skill from Claude or
from the / menu, and a Skill(name) deny rule blocks it. An Agent(name)
deny rule turns off a subagent. More in
Claude Code skills
and Claude Code subagents.
For private notes in one project, there's CLAUDE.local.md at the project
root. Add it to .gitignore yourself.
Check what loaded and fix a broken file
- Run
/status. The Setting sources line lists each settings file Claude Code loaded, plus any managed source. - Run
/permissionsto see each rule and which file it came from. - Run
claude doctorin your shell to list entries Claude Code rejected.
If a value still doesn't apply, it's usually one of these:
- A higher level sets the same key (check managed settings first).
- The key can't be set from that file (some keys are user or managed only).
- An allow rule in a committed file is waiting for workspace trust.
- An
askrule somewhere outranks your allow. - The file has a JSON error, so Claude Code skipped it or the bad entry.
A safe setup for a team, step by step
- Commit
.claude/settings.jsonwith the$schemaline. - Add
denyrules for secrets:Read(./.env),Read(./.env.*),Read(./secrets/**). - Add
allowrules only for the exact scripts you run all day, such asBash(npm run test *). AvoidBash(git *)and other wide rules. - Add an
askrule for anything that leaves the machine, likeBash(git push *). - Share MCP servers through
.mcp.json, with keys in environment variables. See keep API keys out of your MCP config. - Deny the MCP tools nobody needs, such as delete or admin tools.
- Let each person keep their own extras in
.claude/settings.local.json.
If your organization needs this enforced rather than suggested, put the deny
rules and disableBypassPermissionsMode in managed settings.
Setting up Claude Code with MCP for a whole team, or need a custom MCP server with permissions built in from the start? Tell us what you need.
Frequently asked questions
Where is the Claude Code settings.json file?
Your personal file is ~/.claude/settings.json (on Windows,
%USERPROFILE%\.claude\settings.json). A project's shared file is
.claude/settings.json in the project folder, and your private
per-project file is .claude/settings.local.json. None of them exist until
you or Claude Code create one.
What is the difference between settings.json and settings.local.json?
.claude/settings.json is shared: you commit it and the whole team gets it.
.claude/settings.local.json is yours alone, stays out of git, and beats the
shared file when both set the same key. Permission lists from both are merged.
Does a deny rule override an allow rule in Claude Code?
Yes, always. Claude Code checks deny, then ask, then allow, and the first match wins. A deny in any settings file blocks the tool even if another file, or a more specific rule, allows it.
Where does Claude Code store MCP server configuration?
Not in settings.json. Personal and local-scope servers are in
~/.claude.json; team servers are in .mcp.json at the project root. Settings
only decide which of those servers may load and which of their tools are
allowed.
How do I see which Claude Code settings are active?
Run /status and read the Setting sources line, then /permissions for the
rules. claude doctor lists any entries that were rejected.
Can I comment in Claude Code settings.json?
No. The files are strict JSON, so a // comment or trailing comma makes
Claude Code report a Settings Error. Keep notes in a README or in CLAUDE.md.
How do I configure Claude Code?
Run /config for the short list of personal options, or edit
~/.claude/settings.json for everything else. Use .claude/settings.json for
team settings and .claude/settings.local.json for your own overrides in one
project. MCP servers, skills and subagents are configured in other files, as
the sections above show.
How do I change Claude Code settings for one session only?
Pass them on the command line, for example
claude --settings '{"model": "claude-sonnet-5"}'. Nothing is saved, and the
setting ends with the session.