Claude Code reads settings from settings.json (project or global) at startup. All keys are optional. Unknown keys are ignored.
{
// Model to use by default. Overridden by --model flag.
"model": "claude-opus-4-8",
// Permission controls
"permissions": {
// Mode: "default" (prompt per tool), "auto" (no prompts), or "plan" (plan only)
"mode": "default",
// Tools (or tool+pattern) to allow without prompting in default mode
"allow": [
"Read",
"Bash(npm test)",
"Bash(npm run *)"
],
// Tools (or tool+pattern) to block in all modes
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Write(migrations/**)"
]
},
// Hooks: shell scripts invoked at agent lifecycle events
"hooks": [
{
"event": "PreToolUse",
"matcher": { "tool_name": "Bash" },
"command": "/usr/local/bin/bash-guard.sh"
},
{
"event": "PostToolUse",
"command": "/usr/local/bin/audit-logger.sh"
}
],
// MCP server configurations
"mcp": {
"servers": [
{
"name": "my-db",
"transport": "stdio",
"command": "/usr/local/bin/mcp-db",
"args": ["--config", "/etc/mcp/db.json"],
"env": { "DB_URL": "postgres://localhost/mydb" }
}
]
},
// Environment variables injected into every Claude Code session
"env": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug"
}
}
Never put ANTHROPIC_API_KEY or other secrets in settings.json. It is committed to the repo and visible to all contributors. Use settings.local.json or your shell profile instead.
{
"model": "claude-sonnet-4-6",
"permissions": {
"mode": "default",
"allow": [
"Read",
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(npm run build)"
],
"deny": [
"Bash(git push --force*)",
"Bash(DROP TABLE*)",
"Write(migrations/**)"
]
},
"hooks": [
{
"event": "PreToolUse",
"matcher": { "tool_name": "Write", "tool_input.file_path": "migrations/**" },
"command": "/usr/local/bin/migration-guard.sh"
},
{
"event": "Stop",
"command": "/usr/local/bin/session-audit.sh"
}
],
"mcp": {
"servers": [
{
"name": "internal-docs",
"transport": "http",
"url": "https://mcp.internal.example.com/v1",
"headers": { "Authorization": "Bearer ${INTERNAL_MCP_TOKEN}" }
}
]
},
"env": {
"NODE_ENV": "development"
}
}
Pair settings.json with a settings.local.json.example file committed to the repo. The example shows which env vars to set (with placeholder values) so teammates know what to configure locally without exposing real credentials.