settings.json Reference

Every field, every option, with practical examples. Official docs

File Locations hooks permissions env model projects Full Examples

File Locations

FileScopePriority
~/.claude/settings.jsonGlobal (all projects)Lowest
.claude/settings.jsonProject (in repo)Medium
.claude/settings.local.jsonProject local (gitignored)Highest
Project settings merge with global. Higher priority files override lower ones for the same key. For hooks, they are combined, not replaced.

hooks

hooks object
Shell scripts that run at lifecycle points. The core of safety configuration.

Structure

{
  "hooks": {
    "EVENT": [
      {
        "matcher": "REGEX",
        "hooks": [
          {
            "type": "command",
            "command": "bash path/to/hook.sh"
          }
        ]
      }
    ]
  }
}

Events

EventWhenstdin JSON
PreToolUseBefore tool executestool_name, tool_input
PostToolUseAfter tool completestool_name, tool_input, tool_result
StopClaude finishes respondingstop_reason
SubagentStopSubagent finishesSubagent context
UserPromptSubmitUser sends a messagePrompt content

Matcher

ValueMatches
""All tools
"Bash"Shell commands only
"Edit"File edits only
"Write"File writes only
"Read"File reads only
"Edit|Write"Any file modification
"Bash|Edit|Write"Multiple tools (regex OR)

Exit Codes

CodeEffect
0Allow (default)
2Block the action
1Hook error (ignored, action proceeds)

stdout Override

// Auto-approve
echo '{"decision":"approve","reason":"Safe command"}'

// Block with reason
echo '{"decision":"block","reason":"Too dangerous"}'

Practical Example

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {"type": "command", "command": "bash ~/.claude/hooks/destructive-guard.sh"},
          {"type": "command", "command": "bash ~/.claude/hooks/branch-guard.sh"},
          {"type": "command", "command": "bash ~/.claude/hooks/secret-guard.sh"}
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {"type": "command", "command": "bash ~/.claude/hooks/scope-guard.sh"}
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {"type": "command", "command": "bash ~/.claude/hooks/syntax-check.sh"}
        ]
      },
      {
        "matcher": "",
        "hooks": [
          {"type": "command", "command": "bash ~/.claude/hooks/context-monitor.sh"}
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {"type": "command", "command": "bash ~/.claude/hooks/api-error-alert.sh"}
        ]
      }
    ]
  }
}

permissions

permissions object
Allow/deny rules for tool usage without prompting.
{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(git status)",
      "Bash(git log *)",
      "Read(*)",
      "Bash(ls *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(git push * --force)"
    ]
  }
}
Gotcha: Permissions use glob patterns, not regex. * matches anything. Claude adds flags like -C /path that can break exact matches — use hooks for reliable blocking.

env

env object
Environment variables passed to Claude Code and hooks.
{
  "env": {
    "CC_TOKEN_BUDGET": "20",
    "CC_MAX_LINE_LENGTH": "120",
    "CC_DISK_WARN_PCT": "90",
    "CC_ALLOWLIST_FILE": "~/.claude/allowlist.txt"
  }
}

model

model string
Default model for Claude Code sessions.
{
  "model": "claude-sonnet-4-6"
}
ModelBest for
claude-opus-4-6Complex reasoning, architecture
claude-sonnet-4-6Fast daily coding (default)
claude-haiku-4-5Quick tasks, high volume

Project-Level Settings

// .claude/settings.json (commit to repo)
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "bash .claude/hooks/guard.sh"
      }]
    }]
  }
}

// .claude/settings.local.json (gitignored, personal)
{
  "permissions": {
    "allow": ["Bash(npm test)"]
  }
}
Use relative paths in project settings (.claude/hooks/guard.sh) so they work for all team members. Use npx cc-safe-setup --team to set this up automatically.

Full Working Examples

Minimal Safe Setup

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [
        {"type": "command", "command": "bash ~/.claude/hooks/destructive-guard.sh"},
        {"type": "command", "command": "bash ~/.claude/hooks/branch-guard.sh"},
        {"type": "command", "command": "bash ~/.claude/hooks/secret-guard.sh"}
      ]
    }]
  }
}

Node.js Project

{
  "hooks": {
    "PreToolUse": [
      {"matcher": "Bash", "hooks": [
        {"type": "command", "command": "bash ~/.claude/hooks/destructive-guard.sh"},
        {"type": "command", "command": "bash ~/.claude/hooks/branch-guard.sh"},
        {"type": "command", "command": "bash ~/.claude/hooks/secret-guard.sh"},
        {"type": "command", "command": "bash ~/.claude/hooks/auto-approve-build.sh"}
      ]},
      {"matcher": "Edit|Write", "hooks": [
        {"type": "command", "command": "bash ~/.claude/hooks/syntax-check.sh"}
      ]}
    ]
  },
  "permissions": {
    "allow": ["Bash(npm test)", "Bash(npm run lint)", "Read(*)"]
  }
}

Maximum Safety (Autonomous)

// Generated by: npx cc-safe-setup --profile strict
// 33 hooks for autonomous/production use
// Run: npx cc-safe-setup --shield