Every flag you pass to claude on the command line disappears when the session ends. The .claude/settings.json file is where you make things permanent. It is the single source of truth for Claude Code's behavior—controlling which model runs, which shell commands are allowed, which MCP servers connect, which hooks fire on file edits, and what environment variables are injected into every bash call Claude makes.
This guide covers every key in the file, shows you exactly where to put it, and walks through the four most common patterns that teams use to automate their Claude Code workflow.
Two File Locations (and One Local Override)
Claude Code reads settings from two locations and merges them in a defined priority order. Understanding this layering is the key to sharing sensible defaults with your team while keeping personal preferences out of the repository.
User-Level: ~/.claude/settings.json
This file lives in your home directory and applies to every Claude Code session on your machine, regardless of which project you are in. Put your personal preferences here: the model you like to use by default, personal agent definitions, and your own quality-of-life hooks.
Project-Level: .claude/settings.json
This file lives in the root of your project—the same directory that contains your package.json or pyproject.toml. It applies only when you are working in that project. Because it lives in the repo, you can commit it to Git and every developer on your team gets the same MCP servers, permission rules, and automation hooks automatically when they clone the project.
Local Override: .claude/settings.local.json
A third file, .claude/settings.local.json, sits next to the project settings file. It has the same structure and follows the same merge rules, but it is specifically designed to be added to .gitignore. This is where you put secrets—API keys, personal tokens, private environment variables—that should never be committed.
Priority order (highest to lowest): settings.local.json → .claude/settings.json (project) → ~/.claude/settings.json (user).
The Full settings.json Structure
Here is the complete skeleton of every key Claude Code supports, with inline comments:
{
"model": "claude-opus-4-7",
"permissions": {
"allow": [
"Bash(git *)",
"Bash(npm *)",
"Bash(npx *)",
"Edit",
"Write",
"Read"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Bash(wget *)"
]
},
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_..."
}
}
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
]
},
"additionalDirectories": ["../packages/shared"],
"agents": {
"reviewer": {
"description": "Reviews code for bugs",
"prompt": "You are a senior code reviewer. Focus on correctness and security."
}
},
"env": {
"NODE_ENV": "development"
}
}
Key-by-Key Reference
model
Sets the default Claude model for every session started in the scope of this settings file.
{
"model": "claude-opus-4-7"
}
Valid values are any model identifier supported by the Anthropic API (for example claude-opus-4-7, claude-sonnet-4-5, claude-haiku-4-5). If you omit this key, Claude Code falls back to its built-in default. Setting a cheaper model in the project settings file is a fast way to control per-project costs without changing your global preference.
permissions.allow and permissions.deny
Permission rules are how you tell Claude Code which tool calls require human confirmation and which do not. Each entry is a string that matches against ToolName(arguments) using shell-style glob patterns.
{
"permissions": {
"allow": [
"Bash(git *)",
"Bash(npm run *)",
"Bash(npx *)",
"Edit",
"Write",
"Read"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Bash(wget *)"
]
}
}
Rules on the allow list are executed without prompting you each time. Rules on the deny list are always rejected—they cannot be overridden by the allow list or by a user confirming in the terminal. This makes deny the right place for commands that should never run automatically under any circumstances.
Tool names you can use in patterns: Bash, Edit, Write, Read, WebSearch, WebFetch, and any MCP tool name.
mcpServers
MCP (Model Context Protocol) server definitions connect Claude to external tools—databases, GitHub, Slack, browser automation, and more. This key accepts the exact same object format as the --mcp-config CLI flag.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_your_token_here"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/mydb"
}
}
}
}
Each key under mcpServers is the server's display name. The command and args fields define how to start the server process. The env field passes environment variables to that server process only—it is separate from the top-level env key, which applies to Claude's bash calls.
Because MCP servers often need credentials, define the mcpServers key in the project .claude/settings.json (so the team gets the server definitions) but put the actual tokens in .claude/settings.local.json (so secrets stay out of Git).
Complete AI Builder Bootcamp
Claude, Python automation & full-stack — 12 live sessions with Yash Thakker.
The Complete AI Builder Bootcamp is the best AI development course for learning Claude AI, prompt engineering, Python automation, and full-stack web development. This intensive 6-week live bootcamp teaches you how to build AI-powered applications using Claude Projects, Claude Artifacts, Claude Code, and the complete Claude ecosystem. You'll master prompt engineering techniques, learn to create custom Claude connectors and MCP integrations, build Python automation workflows, develop full-stack websites with AI assistance, and create AI marketing agents.
The bootcamp includes 12 live Zoom sessions with Yash Thakker, founder of AISOLO Technologies and instructor to 350,000+ students. You'll build 8+ portfolio projects including AI playbooks, full-stack note-taking applications, Python automation scripts, marketing agents, and personal portfolio websites. The curriculum covers AI fundamentals, Claude Projects and Artifacts, Claude Co-work, Claude plugins and skills, Claude Code for Python development, full-stack development, AI marketing, and capstone projects.
Students receive 1-year access to all recordings, permanent Discord community access, a certificate of completion, and personalized career guidance. All enrollments include a 7-day money-back guarantee. This is the most comprehensive Claude AI bootcamp available, taking students from zero AI knowledge to expert AI builder in 6 weeks.
hooks
Hooks run shell commands automatically before or after Claude uses a tool. They are the foundation of project-specific automation—auto-formatting, linting, test running, audit logging—without requiring Claude to explicitly decide to run those commands.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"Running: $CLAUDE_TOOL_INPUT\" >> ~/.claude/audit.log"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
},
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
]
}
}
Hook types: PreToolUse fires before the tool call; if the hook exits with a non-zero status it blocks the call. PostToolUse fires after the call succeeds.
Environment variables available inside hook commands:
$CLAUDE_FILE_PATH— the path of the file being edited or written$CLAUDE_TOOL_INPUT— the full input passed to the tool (JSON string)$CLAUDE_TOOL_NAME— the name of the tool that triggered the hook
The matcher field supports glob patterns. "Edit" matches all Edit calls; "Bash(npm *)" matches only npm bash calls.
additionalDirectories
By default, Claude Code only has read/write access to files within the project root. additionalDirectories grants access to paths outside that root—useful for monorepos where a service shares code with sibling packages.
{
"additionalDirectories": [
"../packages/shared",
"../packages/ui",
"/home/user/global-configs"
]
}
Paths can be relative (resolved from the project root) or absolute. This is equivalent to passing --add-dir on the CLI, but persisted across all sessions in this project.
agents
Custom agents let you define specialized Claude personas that can be invoked by name. Each agent gets its own system prompt that shapes how it responds, making it easy to codify your team's review standards, documentation style, or security posture.
{
"agents": {
"reviewer": {
"description": "Reviews code for bugs and security issues",
"prompt": "You are a senior software engineer specializing in security. When reviewing code, focus on correctness, injection risks, and edge cases. Be direct and specific."
},
"docs-writer": {
"description": "Writes technical documentation",
"prompt": "You write clear, concise technical documentation for developers. Use active voice, short sentences, and code examples for every non-trivial concept."
}
}
}
Agents defined in the user-level settings file are available in every project. Agents defined in the project settings file are only available in that project.
env
Environment variables listed under env are injected into every shell command Claude runs via the Bash tool. This is the right place to set NODE_ENV, point to a local service, or define variables that scripts in your project expect to exist.
{
"env": {
"NODE_ENV": "development",
"API_BASE_URL": "http://localhost:3000",
"LOG_LEVEL": "debug"
}
}
Do not put secrets here if this file will be committed to Git. Instead, put sensitive values in .claude/settings.local.json, which has identical structure and identical precedence behavior, but should be listed in .gitignore.
Project vs. User vs. Local: Best Practices
| What to configure | Where to put it |
|---|---|
permissions (team-wide tool rules) | .claude/settings.json (project, commit to Git) |
mcpServers (server definitions without credentials) | .claude/settings.json (project, commit to Git) |
hooks (auto-format, lint, audit) | .claude/settings.json (project, commit to Git) |
additionalDirectories | .claude/settings.json (project, commit to Git) |
model (your personal default) | ~/.claude/settings.json (user) |
Personal agents | ~/.claude/settings.json (user) |
API keys, tokens, passwords in env or mcpServers.env | .claude/settings.local.json (gitignored) |
How to Edit settings.json
Interactive editor: Type /config inside any Claude Code session. Claude Code opens an interactive menu where you can toggle permissions, add MCP servers, and set the model without touching JSON directly. Changes are written back to the appropriate settings file immediately.
Direct JSON editing: Open the file in any text editor. Claude Code reads the file fresh at the start of each session, so changes take effect next time you start a session. There is no reload command required.
Validating Your Settings
Run Claude Code with the --debug flag to see exactly which settings files were loaded and what values were applied after merging:
claude --debug
The debug output will show:
- The full path of each settings file Claude found
- The merged result after all layers are applied
- Any keys that were overridden at a higher layer
- MCP servers that were registered and whether they started successfully
This is the fastest way to diagnose a setting that is not taking effect, a typo in a key name, or a permission rule that is not matching the way you expect.
Four Common Settings Patterns
1. Auto-Format Every File Claude Edits
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{ "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATH" }]
},
{
"matcher": "Write",
"hooks": [{ "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATH" }]
}
]
}
}
Put this in the project .claude/settings.json and every file Claude creates or modifies will be formatted according to your Prettier config, automatically, without Claude having to think about it.
2. Restrict Claude to Only Git and npm Commands
{
"permissions": {
"allow": [
"Bash(git *)",
"Bash(npm *)",
"Bash(npx *)",
"Read",
"Edit",
"Write"
],
"deny": [
"Bash(rm *)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(ssh *)"
]
}
}
This pattern is common for onboarding new team members or for projects where the codebase is sensitive. Claude can still read, edit, and write files and run standard build commands, but cannot make network requests or delete files without explicit human confirmation.
3. Connect to Your Database via MCP
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/myapp_dev"
}
}
}
}
Add this to the project settings (without the actual connection string) and put the real DATABASE_URL value in .claude/settings.local.json. Claude will be able to query your database schema, generate migrations, and validate queries against real data.
4. Set a Cheaper Model to Control Project Costs
{
"model": "claude-haiku-4-5"
}
Add this to a project's .claude/settings.json when the work is primarily repetitive—bulk refactoring, documentation generation, or test writing—where a faster, cheaper model performs just as well. Your global ~/.claude/settings.json can keep the more capable model as your default for exploratory or complex work, and the project setting will override it automatically when you work in that repo.
Summary
The .claude/settings.json file is the control plane for Claude Code. Flags typed on the CLI are session-only; this file makes configuration permanent and shareable. The three-tier layering—user, project, local—gives you a clean separation between what the whole team shares (project settings), what you personally prefer (user settings), and what must never leave your machine (local settings). Use /config for interactive editing, and claude --debug any time something is not behaving as expected.