Claude Code · September 2026
Claude Code settings, file by file
Where each settings.json lives, which one wins, the keys worth knowing, and examples you can copy — checked against the current settings reference.
The files and who they affect.
Claude Code reads settings from JSON files at four scopes, plus a managed source an organization can deploy. Precedence, highest first: managed, then --settings on the command line, then project local, then shared project, then user.
| Scope | Path | Applies to |
|---|---|---|
| Managed | /Library/Application Support/ClaudeCode/managed-settings.json on macOS, /etc/claude-code/managed-settings.json on Linux and WSL, C:\Program Files\ClaudeCode\managed-settings.json on Windows — or an MDM profile, or server-managed settings from the claude.ai console | Everyone the organization deploys it to; nothing below overrides it |
| Command line | claude --settings <file-or-json> | That session only; overrides the files below, never managed |
| Project local | .claude/settings.local.json | You, in this project; kept out of version control |
| Shared project | .claude/settings.json | Everyone working in the repository, once you commit it |
| User | ~/.claude/settings.json | You, in every project on this machine |
Claude Code also keeps ~/.claude.json for itself: sign-in state, MCP server configuration, and per-project trust decisions. You do not edit it. Full detail on the official settings page.
How precedence really works.
A key set at a higher level replaces the same key set lower down, with two exceptions worth knowing. Lists merge rather than override: permissions.allow from your user file and your team’s project file are combined, and a deny rule wins over an allow rule wherever either comes from. And environment variables are not a level in the stack; each variable-and-key pair has its own rule, so ANTHROPIC_MODEL exported in your shell beats the model key from any file, while an env block inside a settings file is an ordinary key that follows the levels above.
Two values are scope-limited: permissions.defaultMode of auto or bypassPermissions only takes effect from user settings, managed settings, or --settings, never from the project files a repository could commit. Files are strict JSON — a comment or a trailing comma is reported as a settings error at the next start. Claude Code watches the files and applies most edits, including permissions and hooks, to a running session. /status lists which files loaded; claude doctor lists entries it rejected.
The keys worth knowing.
The settings reference lists every key with its type, default, and scope. These are the ones people actually set.
| Key | What it does | Example |
|---|---|---|
permissions.allow | Tool uses that run without a prompt | ["Bash(npm run *)", "Read(~/.zshrc)"] |
permissions.ask | Always prompt before these | ["Bash(git push *)"] |
permissions.deny | Block these, including reads of files that hold secrets; beats allow | ["Read(./.env)", "Read(./secrets/**)"] |
permissions.defaultMode | Mode new sessions start in: default (Manual), acceptEdits, plan, auto, dontAsk, bypassPermissions | "plan" |
permissions.additionalDirectories | Directories outside the working one that Claude may read and edit | ["~/projects/shared"] |
permissions.disableBypassPermissionsMode | Remove bypass mode from every session; usually managed | "disable" |
env | Environment variables for every session and its subprocesses — provider routing, proxies, telemetry | {"CLAUDE_CODE_USE_BEDROCK": "1"} |
hooks | Your own commands at lifecycle events: PreToolUse, PostToolUse, SessionStart, Stop, and others | See the team example below |
model | Model new sessions start on; --model and ANTHROPIC_MODEL override it | "claude-sonnet-5" |
availableModels | Restrict what /model and --model may pick | ["opus", "sonnet"] |
effortLevel | Default reasoning effort for models without a saved level of their own | "xhigh" |
apiKeyHelper | A script that returns the API credential, re-run every five minutes by default | "~/.config/claude/get-key.sh" |
cleanupPeriodDays | Days to keep session transcripts before deleting them; 30 by default | 20 |
attribution | Change or hide the attribution added to commits and PRs; replaces the deprecated includeCoAuthoredBy | {"commit": "Claude Code"} |
enableAllProjectMcpServers | Approve every server in a project’s .mcp.json without prompting | true |
forceLoginMethod, forceLoginOrgUUID | Pin the login method and organization; enforced from managed settings | "claudeai" |
statusLine | A command whose output renders below the prompt | {"type": "command", "command": "..."} |
outputStyle, language | Change Claude’s role and tone, or have it answer in another language | "Spanish" |
autoUpdatesChannel | latest (the default) or stable, about a week behind | "stable" |
sandbox | Isolate Bash commands from the filesystem and network on macOS, Linux, and WSL2 | {"enabled": true} |
autoMemoryEnabled | Turn Claude’s own cross-session notes off | false |
claudeMdExcludes | Skip ancestor CLAUDE.md files by glob; useful in monorepos | ["**/monorepo/CLAUDE.md"] |
Permission rules, the syntax.
A rule is a tool name, optionally with a pattern in parentheses. Bash(npm run *) matches any npm script; Bash(git push *) matches pushes; Read(./.env) names one file relative to the project; Edit(docs/**) matches a tree; WebFetch(domain:example.com) scopes a domain; mcp__server__tool names one MCP tool. A bare tool name such as Read matches every use. Rules from every scope are merged, deny beats allow, and an ask rule from a project or managed file outranks an allow you saved locally with “don’t ask again” — which is the usual reason a prompt keeps coming back. The syntax in full is under permission rule syntax.
A personal file is small. The $schema line gives you autocomplete and validation in any editor that understands JSON schema; the rest is preference. This one starts every session on Sonnet in plan mode, follows the stable release channel, keeps transcripts for twenty days, and lets Claude Code run git diff and read your shell config without asking.
A team file, with a hook.
The shared project file is the one to commit. It carries the permissions everyone should share, the environment the project needs, and hooks — shell commands Claude Code runs at fixed points, which, unlike CLAUDE.md instructions, are enforced regardless of what the model decides. The example below approves npm scripts, always confirms pushes, refuses to read secrets, and runs a script from the repository before every Bash command. Hooks nest three deep: the event, a matcher, and the handlers. Allow rules in a committed file take effect only after each person trusts the folder; deny and ask rules apply regardless.
Settings, CLAUDE.md, and flags.
Three things shape a session and they are easy to conflate. Settings are enforced configuration: permission rules, hooks, and the sandbox apply whatever the model intends. CLAUDE.md is instruction: loaded as context at the start of every session, followed well when it is specific, but not a hard boundary — the docs say so plainly and point you to a PreToolUse hook when something must never happen. Flags are one session’s overrides: --permission-mode beats defaultMode, --model beats model, --allowedTools and --disallowedTools add rules for the run, --add-dir grants directories without persisting them, and --settings layers a file or a JSON string above your files for the session. /config writes a few personal options to the user file, /permissions edits rules, and /hooks shows what is configured.
One practical consequence: all of this lives on the host. The user file, the project files, the transcripts, the remembered approvals — they are on the machine where claude runs, not on the device you are looking at it from. Set a machine up once and every device that reaches it gets the same sessions, the same rules, the same history. That is the shape spawnd is built around: the host does the work and keeps the state, and a browser or a phone is only ever the console.
Start
Set up the host once; every console inherits it.
curl -fsSL https://spawnd.dev/install.sh | shQuestions
- Where is the Claude Code settings file?
- Personal settings are in ~/.claude/settings.json. Project settings are .claude/settings.json (shared, commit it) and .claude/settings.local.json (yours). Organizations deploy managed-settings.json in a system directory or push settings from the claude.ai console.
- Why isn’t my setting taking effect?
- Usually a higher scope sets the same key, or the key cannot apply from that file: auto and bypassPermissions in defaultMode only work from user or managed settings. Run /status to see which files loaded and claude doctor to see rejected entries.
- Do settings sync between machines?
- No. Settings and transcripts are files on each host. Committing .claude/settings.json shares project rules through git; personal settings stay per machine unless you copy them. Reaching one configured host from several devices is what spawnd is for.