AI NewsletterSubscribe →
Resource HubReference

Settings.json — Full Reference

Every top-level key in .claude/settings.json — permissions, hooks, env, model, sandbox, statusLine, and the rest. Schema, precedence order, worked examples.

Larry Maguire

Larry Maguire

GenAI Skills Academy

.claude/settings.json is the configuration file that controls how Claude Code behaves in a workspace. It governs permissions, hooks, environment variables, the default model, sandbox boundaries, and a long tail of operational toggles. This article is the full reference: every top-level key, what it accepts, the precedence order between user / workspace / managed scopes, and worked examples for the patterns you will actually use.

If you have never opened settings.json before, start with Your First Claude Code Workspace for the basics. This article assumes you know what the file is and want to know what every field does.

Where settings.json lives — three scopes

Claude Code reads settings from several locations and merges them, with later sources overriding earlier ones. The full precedence order, lowest to highest:

  1. User settings~/.claude/settings.json — applies to every workspace on this machine
  2. Shared workspace settings.claude/settings.json — committed to the repo, applies to anyone using this workspace
  3. Local workspace settings.claude/settings.local.json — gitignored by convention, your personal overrides for this workspace
  4. Command-line arguments--model, --permission-mode — override everything for that one session
  5. Managed settings — pushed by IT in enterprise deployments — cannot be overridden

Practical implication: put team conventions in the shared settings.json (committed), put your personal preferences in settings.local.json (gitignored), and let your global ~/.claude/settings.json hold defaults that apply everywhere.

Top-level keys

Key Type Purpose
permissionsobjectallow / deny / ask rules and the default permission mode
hooksobjectevent-driven shell scripts (PreToolUse, PostToolUse, etc.)
envobjectenvironment variables exposed to Bash and shell tools during the session
modelstringdefault model alias or full model ID
sandboxobjectfilesystem and network isolation rules
statusLinestring / objectcustom status bar format
enabledPluginsarraywhich Claude Code plugins to load
extraKnownMarketplacesarrayadditional plugin sources beyond defaults
contextCompactionThresholdnumber% of context window before auto-compaction triggers
effortLevelstringadaptive reasoning budget (e.g. low / medium / high)
cleanupPeriodDaysnumberhow long session history is retained locally (default 30)
apiKeyHelperstringcommand that returns an API key (for non-OAuth auth)
enabledMcpjsonServers / disabledMcpjsonServersarrayselectively enable / disable MCP servers from .mcp.json
remoteControlAtStartupbooleanauto-enable Remote Control on session start
voiceEnabledbooleanenable voice input
agentPushNotifEnabledbooleanpush notifications when sub-agents complete
disableAllHooksbooleankill switch for all hooks (debug or trust scenarios)
skipDangerousModePermissionPromptbooleansuppress the bypassPermissions warning (containers only)

Several keys are managed-only — they only take effect when set in a managed (enterprise-pushed) settings file: disableBypassPermissionsMode, disableAutoMode, allowManagedHooksOnly, allowManagedPermissionRulesOnly, allowManagedMcpServersOnly, availableModels, modelOverrides. Setting them in user or workspace settings has no effect.

permissions — the rule set

The permissions object is where you pre-approve, pre-deny, or pre-flag specific tool calls. It contains four fields:

{
  "permissions": {
    "defaultMode": "default",
    "allow": [],
    "deny": [],
    "ask": []
  }
}

defaultMode sets the starting permission mode for new sessions. Valid values: default, acceptEdits, plan, auto, dontAsk, bypassPermissions. See Permission Modes Deep Dive for what each does.

allow, deny, and ask take arrays of permission rule strings. Format: ToolName(matcher). Examples:

{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(git status:*)",
      "Bash(npm test:*)",
      "Bash(npm run build:*)",
      "Read(~/Documents/**)",
      "WebFetch(domain:github.com)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(curl:*)",
      "Edit(/etc/**)",
      "WebFetch(domain:*.suspicious-site.com)"
    ],
    "ask": [
      "Bash(git push:*)",
      "Bash(npm publish:*)"
    ]
  }
}

Evaluation order: deny rules win first (a denied call is blocked even if also allowed), then ask rules (force a prompt even in non-prompting modes), then allow rules. Anything matching no rule falls through to the current permission mode's default behaviour.

Matcher patterns:

  • :* — wildcard suffix (matches any continuation of the command)
  • ** — recursive directory glob
  • domain:example.com — domain match for WebFetch
  • mcp__servername__* — pattern match for MCP tools (servername is the MCP key)

hooks — event-driven scripts

The hooks object maps event names to arrays of hook definitions. Each event can have multiple hook entries; each entry can have one or more matchers and one or more commands to run.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/bash-audit.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "PreCompact": [
      {
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/save-checkpoint.sh"
          }
        ]
      }
    ]
  }
}

For the full event list, payload schemas, and return contracts, see Hooks — Complete Event Reference.

env — session environment variables

Variables in env are exposed to the Bash tool and any shell command Claude runs during the session. They do not leak into your shell after the session ends.

{
  "env": {
    "NODE_ENV": "development",
    "DEBUG": "true",
    "ANTHROPIC_BASE_URL": "https://api.anthropic.com"
  }
}

Do not put secrets here

settings.json is often committed to git. Anything you put in env is committed with it. Use apiKeyHelper or a gitignored .env file (loaded via a hook) for actual credentials. settings.json is for non-secret defaults only.

model — default model selection

Set the default model for new sessions in this workspace. Use an alias (recommended) or a full model ID:

{
  "model": "sonnet"
}

// or pin a specific version
{
  "model": "claude-sonnet-4-6"
}

// or use the 1M-context variant
{
  "model": "sonnet[1m]"
}

Override per-session with --model on the command line.

sandbox — filesystem and network isolation

Sandbox rules constrain which paths and network destinations Claude Code can touch, regardless of permission rules. Use to enforce a hard boundary even in auto or bypassPermissions mode.

{
  "sandbox": {
    "filesystem": {
      "readPaths": ["~/projects/myapp/**"],
      "writePaths": ["~/projects/myapp/**"],
      "denyPaths": ["~/projects/myapp/secrets/**"]
    },
    "network": {
      "allowedDomains": ["github.com", "registry.npmjs.org"]
    }
  }
}

statusLine — custom status bar

Override the status bar shown at the bottom of the Claude Code panel. Useful when you want to surface workspace identity, current git branch, or context usage.

{
  "statusLine": {
    "type": "command",
    "command": ".claude/scripts/status-line.sh"
  }
}

The command's stdout becomes the status line. Refreshes periodically.

contextCompactionThreshold

The percentage of the context window at which auto-compaction kicks in. Default is around 80%. Lower it if you have a PreCompact hook that needs more headroom; raise it if you want to push compaction later.

{
  "contextCompactionThreshold": 75
}

See Context Window Management for the full picture.

cleanupPeriodDays — local history retention

Claude Code stores conversation history locally as .jsonl files. After this many days, old session files are cleaned up. Default is 30; raise it if you use PRIMA Memory or another tool that depends on long history.

{
  "cleanupPeriodDays": 90
}

apiKeyHelper — non-OAuth authentication

Path to an executable that prints an API key on stdout. Used when Claude Code should authenticate with a key from your password manager, secret store, or vault rather than OAuth.

{
  "apiKeyHelper": "/usr/local/bin/get-anthropic-key"
}

The command runs each time Claude Code needs to authenticate. Useful for shared machines, CI environments, and key-rotation workflows.

enabledMcpjsonServers / disabledMcpjsonServers

By default Claude Code loads every server defined in .mcp.json in the workspace. These two arrays let you selectively enable or disable specific servers without editing .mcp.json itself — handy when one workspace's MCP config is shared across people who want different active servers.

{
  "enabledMcpjsonServers": ["filesystem", "github"],
  "disabledMcpjsonServers": ["expensive-api-server"]
}

Worked example — a typical workspace settings.json

{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(npm test:*)",
      "Bash(npm run build:*)",
      "Bash(npm run lint:*)",
      "Read(./**)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)",
      "Edit(.env)",
      "Edit(.env.local)"
    ],
    "ask": [
      "Bash(git push:*)",
      "Bash(npm publish:*)"
    ]
  },
  "hooks": {
    "PreCompact": [
      {
        "hooks": [
          { "type": "command", "command": ".claude/hooks/save-checkpoint.sh" }
        ]
      }
    ]
  },
  "env": {
    "NODE_ENV": "development"
  },
  "model": "sonnet",
  "contextCompactionThreshold": 75
}

Validation and debugging

If Claude Code starts behaving unexpectedly after a settings change, validate the JSON syntax first — a missing comma silently breaks the entire file. Paste contents into jsonlint.com, or use cat .claude/settings.json | jq . in a terminal. Either tells you the exact line of any error.

To see what settings are actually in effect (the merged result of all scopes), run /config in a session. This shows the resolved values rather than what's in any single file.

What lives outside settings.json

Two things you might expect to be in settings.json but are not:

  • MCP server definitions — these go in .mcp.json at the workspace root, or ~/.claude.json globally. settings.json only enables / disables them.
  • CLAUDE.md and rules files — these are loaded as instruction context, not configuration. They live in .claude/CLAUDE.md and .claude/rules/*.md.

settings.json is for behavioural and operational configuration. Instructions to Claude itself go in CLAUDE.md.

GenAI Skills Academy

Achieve Productivity Gains With AI Today

Send me your details and let’s book a 15 min no-obligation call to discuss your needs and concerns around AI.