Claude Code settings.json: Every Option Explained
By Tyler Cyert
Claude Code settings.json is the configuration file that controls how Claude Code behaves in your project. It manages tool permissions, lifecycle hooks, environment variables, and model preferences — everything that does not belong in prose instructions like CLAUDE.md.
If CLAUDE.md is what you tell the agent, settings.json is what you enforce. Instructions can be ignored under pressure. Permissions cannot.
Where settings.json Lives
Claude Code loads settings from multiple locations, evaluated in order:
| File | Location | Purpose | Git? |
|---|---|---|---|
.claude/settings.json | Project root | Team-wide project settings | Yes |
.claude/settings.local.json | Project root | Personal project overrides | No |
~/.claude/settings.json | Home directory | Global defaults | No |
~/.claude/settings.local.json | Home directory | Global personal overrides | No |
Project-level settings take precedence over global. Local files override their non-local counterparts. This layering means your team shares one committed config while each developer can adjust locally.
The Permissions Object
The most important section. Permissions control which tools Claude Code can use without asking.
A basic permissions block includes an allow array for safe operations like Read, Glob, Grep, and specific Bash commands like npm run build and npm run test. It also includes a deny array for dangerous operations like rm -rf * and git push --force.
How Rules Are Evaluated
Rules evaluate in order: deny > ask > allow. The first matching rule wins. If no rule matches, Claude Code prompts you for approval.
- allow — Claude runs the tool without asking. Use for safe, read-only operations and specific commands you trust.
- deny — Claude cannot use the tool at all. Use for destructive operations you never want automated.
- ask — Claude prompts before each use. This is the default for unmatched tools.
For a deeper dive into permission patterns, see our Claude Code permissions guide.
Permission Patterns
Permissions support prefix matching. Bash(npm run) matches npm run build, npm run test, and any other npm run command. Be specific to avoid over-permitting.
Environment Variables
Set environment variables that apply to every Claude Code session in your project using the env key in settings.json. Common examples include NODE_ENV, DATABASE_URL, and feature flags like CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS.
Environment variables in settings.json are visible to your team when committed. Never put secrets here — use .claude/settings.local.json or your shell environment for API keys and credentials.
Hooks Configuration
Hooks are shell commands triggered by lifecycle events. They go in settings.json under the hooks key.
Each hook specifies an event (like PostToolUse or PreToolUse), an optional matcher to filter by tool name (like Edit|Write or Bash), a command to run, and a description. For example, a PostToolUse hook matching Edit|Write can run prettier --write $CLAUDE_FILE_PATH to auto-format after every file change.
Exit code 0 means proceed. Exit code 2 means block the action. For a complete guide to events and patterns, see our Claude Code hooks guide.
Model Configuration
Override the default model for your project with the model key. Claude Code supports opus, sonnet, and haiku. The main model handles primary tasks. Set smallFastModel to haiku for background operations like file search and summarization.
MCP Server Configuration
Connect external tools via the Model Context Protocol using the mcpServers key. Each MCP server entry specifies a command, args, and optional env variables. MCP servers extend Claude Code with custom tools — database access, API integrations, or internal services. See our MCP servers guide for setup details.
Default Permission Mode
Control the baseline permission behavior with defaultMode:
| Mode | Behavior |
|---|---|
normal | Prompts for unmatched tools (default) |
auto | Auto-approves most tools, still respects deny rules |
plan | Read-only mode, no modifications allowed |
bypassPermissions | Skips all checks — use only in sandboxed environments |
A Production-Ready Example
A complete settings.json for a TypeScript web project includes three sections. The permissions object allows read-only tools (Read, Glob, Grep) plus specific build commands (npm run build, npm run test, npm run lint, npx tsc --noEmit), while denying destructive operations (rm -rf, git push --force, git reset --hard, npx prisma migrate reset). The hooks object runs prettier --write via PostToolUse on every Edit or Write. The env object sets NODE_ENV to development.
Debugging Your Configuration
Run /status inside Claude Code to see which settings files are loaded and their source. If a file has syntax errors, /status reports the issue.
Add a $schema property pointing to the official JSON schema to get autocomplete and validation in VS Code or Cursor.
Scaffolding settings.json with DotBox
Writing permissions, hooks, and environment variables by hand means remembering the exact JSON schema, valid event names, and matcher syntax. DotBox generates your settings.json through a visual interface — configure permissions with checkboxes, add hooks from a dropdown of lifecycle events, and export a validated config file as part of your complete .claude/ directory structure.