Claude Code's behavior is shaped by settings.json. Understanding the config is the fastest path to making the harness fit your work.
~/.claude/settings.json, global. Applies to every session everywhere.~/.claude/settings.local.json, machine-specific, typically gitignored. Good for per-machine permission lists.You can also put .claude/settings.json in a project, that settings file applies when you run Claude Code from that directory.
permissionsControls what the agent can do without asking. Sub-fields:
defaultMode. "manual" (ask every time), "auto" (auto-approve known-safe), or "plan" (plan-then-execute)allow, array of tool-call patterns to always approve (e.g., "Bash(ls:*)", "Edit", "mcp__notion__*")deny, array of patterns to always reject (e.g., "Bash(sudo:*)", "Bash(rm -rf:*)")See Permissions for detailed design patterns.
skipAutoPermissionPromptBoolean. If true, Claude doesn't pop an approval dialog when the model wants to run something outside the allow/deny list, it proceeds based on its own judgment. Use only in auto mode with a strict deny list.
enabledPluginsMap of plugin IDs → enabled (true/false). Installed plugins not listed here default to enabled.
envEnvironment variables to set for every Claude Code session. Useful for tokens, paths, feature flags.
hooksArray of hook definitions. See Hooks.
mcpServersMap of MCP server name → config (command, args, env, url, etc.). Each server shows up as a set of tools in the agent session.
autoUpdaterStatusControls whether Claude Code auto-updates. Usually fine to leave on default.
{
"permissions": {
"defaultMode": "auto",
"allow": [
"Read", "Write", "Edit", "Glob", "Grep",
"Bash(ls:*)", "Bash(cat:*)", "Bash(git status)",
"mcp__notion__*"
],
"deny": [
"Bash(sudo:*)",
"Bash(rm -rf:*)",
"Bash(git push:*)",
"mcp__*__delete_*"
]
},
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp"],
"env": { "NOTION_API_KEY": "${NOTION_API_KEY}" }
}
}
}
Bash(*:*). That's total shell access with no deny guardrails. Reserve for dev environments only.${VAR} substitution.Project-level .claude/settings.json can be checked into git so the whole team works with the same permission baseline. Keep settings.local.json out of version control.