Configure Claude Code: settings, permissions, and models
Claude Code configuration is a stack of JSON settings files (managed, command line, project local, shared project, user) that decides which tools run without asking, which permission mode a session starts in, and which model and effort level it uses. Permission rules are evaluated deny, then ask, then allow, and the highest settings level wins for every other key.
This page is for developers setting up Claude Code on a real repository, and for tech leads who own the file the whole team commits. The situation it fixes: the agent asks before every npm test, a teammate’s settings silently allow git push, and nobody can say which of four files set the model everyone is running.
What you’ll walk away with from Claude Code configuration
Section titled “What you’ll walk away with from Claude Code configuration”- A committed
.claude/settings.jsonwith allow, ask, and deny rules that match how your project builds and tests. - A clear answer to “which file wins?” for every key, and the two commands that show the effective result.
- A permission mode and sandbox setup that cuts prompts without handing the agent your credentials.
- A model and effort choice that follows the vendor default, plus the keys a team uses to pin it.
- Three copy-paste prompts: generate the permission set, audit the effective configuration, and compare effort levels on your own code.
Commands and keys on this page were checked against the installed CLI, Claude Code 2.1.283 (claude --help), and the official settings, permissions, and model configuration documentation on 2026-09-26.
Where do Claude Code settings live, and which file wins?
Section titled “Where do Claude Code settings live, and which file wins?”Claude Code merges five levels. For any single key, the highest level that sets it wins; array keys such as permissions.allow are concatenated across levels.
| Precedence | Level | Location | Who it affects | Use it for |
|---|---|---|---|---|
| 1 (highest) | Managed | managed-settings.json (macOS /Library/Application Support/ClaudeCode/, Linux and WSL /etc/claude-code/, Windows C:\Program Files\ClaudeCode\), MDM, or server-managed settings from the claude.ai admin console | Everyone the organization deploys it to | Security policy nobody can override |
| 2 | Command line | --settings, --model, --permission-mode, --allowedTools, and similar flags | This session only | One-off experiments and CI jobs |
| 3 | Project local | .claude/settings.local.json | You, in this repository | Personal exceptions; standing approvals land here |
| 4 | Shared project | .claude/settings.json (committed) | Everyone who clones the repository | The team’s rules, hooks, and plugins |
| 5 (lowest) | User | ~/.claude/settings.json | You, in every project | Personal defaults such as theme and default mode |
Three details decide most “why is my setting ignored?” questions:
- Environment variables are not a level.
ANTHROPIC_MODELexported in your shell overrides themodelkey from any file. Anenvblock inside a settings file is an ordinary key and follows the table. - Some values are refused at some levels.
permissions.defaultModeset toautoorbypassPermissionshas no effect from project or local settings (since v2.1.257 forbypassPermissions); put it in user or managed settings, or pass--permission-mode. - Project allow rules wait for workspace trust.
permissions.allowandpermissions.additionalDirectoriesin a committed file apply only after each teammate accepts the trust dialog for that folder.denyandaskrules apply at once, because they only restrict.
When you choose “Yes, and don’t ask again” on a prompt, Claude Code writes an allow rule to .claude/settings.local.json at the repository root. The first time it writes that file, it adds the file to your global git excludes, so it stays out of commits. If you create the file by hand, add it to .gitignore yourself.
Which permission mode should you start in?
Section titled “Which permission mode should you start in?”The permission mode sets the baseline; rules then adjust individual tools. Press Shift+Tab in the CLI to cycle modes, or pass --permission-mode at launch.
| Mode (config value) | What it does | Reach for it when |
|---|---|---|
Auto (auto) | A classifier model reviews each action instead of prompting you | Everyday interactive work on a supported model |
Manual (default) | Reads run freely; state-changing actions prompt | You want to approve every change, or auto mode is unavailable |
Accept edits (acceptEdits) | Auto-approves in-scope file edits and common filesystem commands (mkdir, touch, rm, mv, cp, sed); other Bash still prompts | Guided refactors where you review the diff at the end |
Plan (plan) | Read-only exploration; edits wait until you approve a plan | Unfamiliar code or a change that spans modules |
Don’t ask (dontAsk) | Denies everything that is not pre-approved by an allow rule | Scripted runs where an unexpected tool call must fail, not hang |
Bypass permissions (bypassPermissions) | Skips prompts and safety checks | Disposable, network-restricted containers only |
With Claude Code v2.1.283 or later (the latest release channel on 2026-09-26), auto mode is the starting mode for interactive terminal and VS Code sessions on every plan and provider. Sessions still start in Manual when you run claude -p or the Agent SDK, when a settings file sets permissions.disableAutoMode, or when the model does not support auto mode. That last case includes Haiku on every provider, and a default Microsoft Foundry session, which runs Claude Sonnet 4.5. The stable channel (v2.1.274 on 2026-09-26) starts in auto mode only on Pro, Max, and Team plans.
To start in a different mode every time, set it in your user settings:
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "permissions": { "defaultMode": "acceptEdits" }}The $schema line gives you autocomplete and validation in VS Code, Cursor, and other editors that read JSON Schema. The schema can lag the newest CLI release, so a warning on a recently added key does not by itself mean the key is wrong.
Write permission rules for your project
Section titled “Write permission rules for your project”Rules turn repeated prompts into standing decisions. Write them once in the shared project file, where the whole team gets them and code review sees every change.
-
Create
.claude/settings.jsonat the repository root with the commands your project runs every day, and deny the ones it must never run unattended:.claude/settings.json {"$schema": "https://json.schemastore.org/claude-code-settings.json","permissions": {"allow": ["Bash(npm run lint)","Bash(npm run test *)","Bash(npm run build)","Bash(npx tsc --noEmit)","Bash(git diff *)","Bash(git log *)","Bash(git status)"],"ask": ["Bash(git push *)","Bash(npm publish *)"],"deny": ["Bash(curl *)","Bash(wget *)","Read(.env)","Read(.env.*)","Read(./secrets/**)"]}} -
Commit the file through a pull request. Put personal exceptions in
.claude/settings.local.json, never in the shared file. -
Restart Claude Code in the repository and accept the workspace trust dialog, which lists the allow rules the folder grants.
-
Run
/permissions. The dialog lists every rule together with the settings file it came from, so you can confirm your rules loaded from the file you meant.
How permission rule syntax works
Section titled “How permission rule syntax works”A rule is Tool or Tool(specifier). Claude Code checks deny rules first, then ask, then allow; the first match in that order decides, and a more specific allow rule cannot carve an exception out of a broader deny rule.
| Rule | Matches |
|---|---|
Bash | Every shell command |
Bash(npm run test *) | npm run test and anything after it; a trailing * also matches the bare command |
Bash(git log:*) | The same as Bash(git log *); the :* form is recognized only at the end of a pattern |
Read(.env) | Any .env file at any depth under the current directory; a bare filename follows gitignore semantics. Read(./.env) would match only the one in the current directory |
Read(secrets/**) | As a deny rule, any secrets directory at any depth |
Read(//etc/**) | An absolute path. A single leading / anchors at the settings source instead: the project root for project and local settings, ~/.claude/ for user settings |
Edit(docs/**) | Edits under docs/; path rules for Write are accepted but never consulted, so use Edit |
WebFetch(domain:github.com) | Fetches to that domain |
mcp__github__* | Every tool from the MCP server named github |
Claude Code splits compound commands on &&, ||, ;, and |, and every part must match an allow rule. Put the * after the subcommand: Bash(git log *) allows only git log, while Bash(git *) allows every git command.
In auto mode, Claude Code drops allow rules broad enough to run arbitrary code (for example Bash(*), wildcarded interpreters such as Bash(python*), and package-manager run commands such as Bash(npm run *)) and restores them when you leave auto mode; narrow rules such as Bash(npm test) stay (Claude Code permission-modes docs, checked 2026-09-26).
Match the strictness of the file to the risk of the repository rather than copying one file everywhere:
| Repository | Allow | Ask | Deny |
|---|---|---|---|
| Prototype or spike | Bash(npm run *), Bash(git *) | Bash(git push *) | Secrets, network tools |
| Product service | Named lint, test, build, and read-only git commands | Push, publish, migrations | Secrets, network tools, deploy scripts |
| Infrastructure or production-adjacent | Read-only commands only | Every edit and plan command | terraform apply, kubectl delete, deploys, secrets |
Turn on the sandbox for fewer prompts with a real boundary
Section titled “Turn on the sandbox for fewer prompts with a real boundary”Rules decide what Claude may try; the sandbox decides what a Bash command can reach. It isolates the filesystem and network with Seatbelt on macOS and bubblewrap on Linux and WSL2; native Windows is not supported (sandboxing documentation, checked 2026-09-26).
Run /sandbox in a session to turn it on and see whether any dependency is missing, or set it in a settings file:
{ "sandbox": { "enabled": true, "allowUnsandboxedCommands": false, "network": { "allowedDomains": ["github.com", "*.npmjs.org"] } }}autoAllowBashIfSandboxed defaults to true, so sandboxed commands run without prompts; deny rules and ask rules that name a command still apply. allowUnsandboxedCommands: false removes the escape hatch that lets a failing command retry outside the sandbox. Manual mode plus the auto-allow sandbox is the vendor’s suggested setup when you want fewer prompts without a classifier.
By default, a command that reaches a host outside allowedDomains prompts you; set "strictAllowlist": true under sandbox.network in user or managed settings to deny it instead.
When is bypass permissions acceptable?
Section titled “When is bypass permissions acceptable?”Only inside a disposable container or VM with restricted network access, running as a non-root user, and never with production credentials in the environment. --dangerously-skip-permissions disables prompts and safety checks, offers no protection against prompt injection; deny rules, explicit ask rules, and rm of critical paths still stop it.
# Inside a throwaway, network-restricted container onlyclaude -p "Run the test suite and fix the failing snapshot tests" --dangerously-skip-permissions--allow-dangerously-skip-permissions adds bypass to the Shift+Tab cycle without starting in it. For isolation, use the devcontainer setup. Organisations turn bypass off in managed settings, where users cannot override it:
{ "permissions": { "disableBypassPermissionsMode": "disable" }}For most interactive work, auto mode or the sandbox gives you the reduced prompting without giving up the checks.
Choose the model and effort level
Section titled “Choose the model and effort level”Start on the default model, tune effort before you switch model, and switch model only when your own evaluations say so.
On the latest channel from v2.1.280, Claude Code defaults to Claude Opus 5.5 on every paid plan, the Anthropic API, Amazon Bedrock, Google Cloud’s Agent Platform, and Claude Platform on AWS. Microsoft Foundry defaults to Claude Sonnet 4.5. The stable channel had not reached v2.1.280 on 2026-09-26 and still runs the older defaults. Prices, context windows, and the full per-plan table live on the models hub.
| Alias | Resolves to (Anthropic API) | Use it for |
|---|---|---|
default | Your account’s default, or your organization’s | Clearing an override |
opus | Claude Opus 5.5 | The default for hard agentic coding |
sonnet | Claude Sonnet 5 | Routine work when cost matters |
fable | Claude Fable 5.1 | Deliberately chosen long-horizon work; never a default, and may bill to usage credits |
best | Fable where available, otherwise opus | Maximum capability |
haiku | Claude Haiku 4.5 | Cheap, high-volume subagent work |
opusplan | Opus in plan mode, Sonnet for execution | Planning quality at execution cost |
Switch with /model <alias> in a session, claude --model <alias> at launch, or the model key in a settings file. A model in project or managed settings reapplies at every launch, and the startup header names the file that set it.
Effort controls how much the model reasons per step. Opus 5.5 starts at medium; other models that support effort start at high. Change it with /effort, claude --effort <level>, or CLAUDE_CODE_EFFORT_LEVEL. The effortLevel key accepts low, medium, high, or xhigh; max applies to one session unless set through the environment variable, and ultracode (xhigh plus automatic workflow orchestration) has its own ultracode key. Thinking cannot be turned off on Opus 5.5 or the Fable models. For when deeper reasoning pays off, see deep reasoning and effort levels.
Fast mode is a separate axis: /fast runs Opus 5.5, Opus 5, or Opus 4.8 up to 2.5 times faster at a higher per-token price (Anthropic fast-mode docs, checked 2026-09-26). On subscription plans it draws on usage credits, not your plan’s limits, and it is not available on Bedrock, Google Cloud’s Agent Platform, Microsoft Foundry, or Claude Platform on AWS.
Teams that must pin models use managed settings: availableModels restricts what users can pick, enforceAvailableModels extends that list to the Default option, maxEffortLevel caps effort, and from v2.1.283 deniedModels and availableModelsMatch: "exact" hold back a newly released model until you have evaluated it. Managed policy for AI agents covers rolling these out.
Other settings worth adding on day one
Section titled “Other settings worth adding on day one”-
Formatting after every edit. A
PostToolUsehook runs your formatter on each file Claude writes, so style never reaches review.hooksis an object keyed by event name, and the hook reads the tool call as JSON on stdin:.claude/settings.json {"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | { read -r f; npx prettier --write --ignore-unknown \"$f\"; }" }]}]}}Hooks automation covers blocking hooks and test gates.
-
Extra directories.
claude --add-dir ../apior/add-dir ../apigrants file access for one session;permissions.additionalDirectoriespersists it. Most.claude/configuration in the added directory is not loaded. -
Environment for every Bash command. An
envblock, for example"env": { "NODE_ENV": "development" }, is injected into the commands Claude runs. Never put secrets in a committed file. -
Quick edits without the menu.
/config model=sonnetor/config theme=darksets a key directly, also inclaude -p;/config --helplists the keys it accepts. Skipthinking=falseon Opus 5.5 and the Fable models, where thinking cannot be turned off. -
Multiline input.
/terminal-setupinstalls a Shift+Enter binding for newlines in terminals that need it.
MCP servers are configured in .mcp.json, not in settings.json; see MCP setup. Editor integration lives on the IDE integration page.
How do you prove the configuration does what you think?
Section titled “How do you prove the configuration does what you think?”Do not trust a settings file because it looks right. Check the effective result, and make changes to the shared file reviewable.
/statusshows the version, model, and account, and itsSetting sourcesline lists every settings file the session loaded, including the managed source that applies to you. It does not show which file supplied each key./permissionslists every rule with the file it came from, and the recent auto-mode denials.claude doctor, from the shell, prints installation diagnostics and reads the settings files in the current directory./doctorin a session also flags unparseable settings and offers fixes.- CI gate. Add
jq empty .claude/settings.jsonto CI so invalid JSON fails the build. This matters becauseclaude -psilently skips a settings file that fails validation. - Owner sign-off. Add
/.claude/ @your-org/tech-leadstoCODEOWNERS, so a tech lead approves every change to the rules the whole team and every CI run inherit.
When Claude Code configuration breaks
Section titled “When Claude Code configuration breaks”A command you allowed still prompts, or is denied. A deny or ask rule elsewhere matches first; Bash(npm *) in deny blocks npm run test whatever the allow list says. Run /permissions, find the shadowing rule and its file, and narrow it.
“Yes, and don’t ask again” keeps asking. That choice writes an allow rule to your local file, which never outranks an ask rule from project or managed settings. Change the ask rule at its source or accept the prompt.
Teammates still see prompts for rules in the committed file. Project allow rules apply only after the workspace trust dialog is accepted. Ask them to restart Claude Code in the repository and accept it.
defaultMode: "auto" in .claude/settings.json does nothing. Project and local files cannot set auto or bypassPermissions. Move it to ~/.claude/settings.json.
The model key is ignored. An exported ANTHROPIC_MODEL, a model in managed settings, or an organization default outranks it. Run /status, then unset ANTHROPIC_MODEL or change the file the startup header names.
Your saved effort level does not apply to Opus 5.5. A top-level effortLevel in user settings applies to older models only. Choose a level with /effort while Opus 5.5 is active; Claude Code saves it for that model.
A Read deny rule in user settings protects nothing. Read(/secrets/**) in ~/.claude/settings.json anchors at ~/.claude/. Use Read(//path/…) or Read(~/…) for rules that must apply in every project.
Settings silently vanish in a script. claude -p skips invalid settings without an error dialog. Run claude doctor to see what it dropped, and keep the jq empty gate in CI.
MCP servers or hooks are skipped. The .mcp.json top-level key is mcpServers, and hooks must be an object keyed by event, not an array. Fix the key, then restart.
Bypass became the default without anyone deciding it. A shell alias such as alias ccc="claude --dangerously-skip-permissions", copied from an old setup guide, makes every session that uses it a bypass session. Delete the alias, use auto mode or the sandbox instead, and set disableBypassPermissionsMode in managed settings when the organization must enforce it.
A broken configuration stops Claude Code from working at all. Start with claude --safe-mode, which disables CLAUDE.md, hooks, MCP servers, plugins, and other customizations while managed settings still apply, then remove the faulty entry.
Where to go next after configuring Claude Code
Section titled “Where to go next after configuring Claude Code”Configuration follows Claude Code authentication. Next, connect your editor, then give the agent project context.
Using another tool as well? The equivalent pages are Codex configuration and Cursor essential configuration.