Skip to content

Example settings files

Three realistic settings.json files, one personal, one for a team repository and one managed policy, with a note on every key so you can copy what you need.

Reading a list of keys only gets you so far. It is usually quicker to look at a complete file, delete what you do not want and change the values. This page gives three, one for each place a setting can live:

  • a personal ~/.claude/settings.json
  • a team's .claude/settings.json, committed to the repository
  • an organisation's managed-settings.json

None of them is a recommended baseline. They are plausible files for the person who would own them. Each is shown first as valid JSON you can paste, followed by a key-by-key explanation. Claude Code rejects comments in settings files, so always copy the JSON block, not the notes. Types, defaults and allowed scopes for every key are in the settings reference, and settings files and precedence explains how the three files combine.

Your own settings

This is close to what I run on my own laptop. It picks a default model and effort, tweaks the terminal, adds a status line and pre-approves a couple of harmless actions. Anything not listed keeps its default, and because it lives in ~/.claude/settings.json it applies in every project.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "claude-opus-5-5",
  "modelSettings": {
    "claude-opus-5-5": { "effortLevel": "medium" }
  },
  "editorMode": "vim",
  "theme": "dark",
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"\\(.model.display_name) | ctx \\(.context_window.used_percentage // 0)%\"'"
  },
  "spinnerTipsEnabled": false,
  "preferredNotifChannel": "terminal_bell",
  "permissions": {
    "allow": [
      "Bash(git status)",
      "Bash(git log *)",
      "Read(~/.gitconfig)"
    ]
  },
  "autoUpdatesChannel": "stable",
  "cleanupPeriodDays": 30
}

What each key is doing:

KeyEffect here
$schemaGives editors autocomplete and validation. Optional, ignored by Claude Code
modelEvery new session starts on Opus 5.5
modelSettingsPer-model options. Here Opus runs at medium effort to keep everyday turns quick. /effort also saves a level per model, and --effort overrides it for one session
editorModeVim-style editing in the prompt box
themeThe dark colour theme. The daltonised themes (such as light-daltonized) are there if you need colour-blind-friendly palettes
statusLineRuns a command after each turn and prints its output under the prompt. This one shows the model name and context used; see status line
spinnerTipsEnabledHides the rotating tips under the spinner
preferredNotifChannelRings the terminal bell when a task finishes or a prompt is waiting
permissions.allowLets Claude run git status, any git log, and read ~/.gitconfig without asking
autoUpdatesChannelTakes updates from the stable channel rather than the newest build
cleanupPeriodDaysDeletes transcripts and other local session data older than 30 days

A team's shared settings

This file sits at .claude/settings.json at the top of a repository and is committed, so everyone who clones it gets the same guardrails, the same pre-commit-style hook and the same plugin marketplace. It is modelled on a TypeScript monorepo I look after.

Before you commit something like it, know these five things:

  • Cloud sessions use it too. A cloud session starts from a clone, so the committed file applies there.
  • Telemetry does not belong here. Claude Code ignores the OpenTelemetry exporter variables in a repository's settings files, apart from values that switch telemetry off. Put them in managed settings or each person's user file (see monitoring usage).
  • Allow rules wait for trust. allow rules and extraKnownMarketplaces only take effect once each person has trusted this exact folder, not merely a parent. deny and ask rules apply straight away, trusted or not.
  • The hook is a script in the repo. Commit .claude/hooks/guard-migrations.sh alongside this file. The hooks guide shows how to write one.
  • Rules match what Claude actually types. Bash(git push *) does not catch git -C . push. Read(./.env) stops the file tools and commands that name the file, such as cat .env, but not grep -r over the directory. Enabling the sandbox closes that gap, because your Read deny paths are added to what sandboxed commands cannot read. See permissions.
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(pnpm run *)",
      "Bash(pnpm test *)",
      "Bash(pnpm tsc *)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(pnpm publish *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./infra/secrets/**)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
          }
        ]
      }
    ]
  },
  "extraKnownMarketplaces": {
    "northwind-tools": {
      "source": {
        "source": "github",
        "repo": "northwind-dev/claude-plugins"
      }
    }
  },
  "enabledPlugins": {
    "changelog-writer@northwind-tools": true
  },
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["/tmp/northwind-build"]
    },
    "network": {
      "allowedDomains": [
        "registry.npmjs.org",
        "*.northwind.dev"
      ]
    }
  },
  "plansDirectory": "./docs/plans"
}

What each key is doing:

KeyEffect here
permissions.allowAny pnpm run, pnpm test or pnpm tsc command runs without a prompt
permissions.askPushing and publishing always need a human to confirm, even if someone has a broader allow rule
permissions.denyThe file tools and file-reading commands cannot open .env files or anything under infra/secrets/
hooks.PreToolUseBefore every edit or write, a repo script runs and can block changes to applied database migrations. ${CLAUDE_PROJECT_DIR} keeps the path working from any subfolder
extraKnownMarketplacesRegisters the team's plugin marketplace on every clone
enabledPluginsSwitches on one plugin from that marketplace. A plugin from an external source still needs each person to install it once
sandbox.enabledRuns Bash commands inside the OS sandbox
sandbox.filesystem.allowWriteAdds a scratch build directory to the paths sandboxed commands may write
sandbox.network.allowedDomainsPre-approves npm and the company's own domains for sandboxed network access
plansDirectorySaves plan-mode plan files inside the repo so they can be reviewed in pull requests

Read more in sandboxing and plugins.

An organisation's managed settings

A managed-settings.json that shows the shape of most of the managed-only keys, each with one plausible value. Treat it as a menu, not a policy: choose the keys that match your own requirements. Administrators deploy the same JSON as a file, through MDM, or as server-managed settings from the claude.ai console. One document applies to everyone it reaches; for different groups, deploy different files or profiles, because server-managed settings do not yet support per-group policy.

{
  "forceLoginMethod": "claudeai",
  "forceLoginOrgUUID": [
    "00000000-0000-0000-0000-000000000000"
  ],
  "availableModels": ["opus", "sonnet"],
  "enforceAvailableModels": true,
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)",
      "Read(./.env)",
      "Read(~/.aws/**)"
    ],
    "disableBypassPermissionsMode": "disable"
  },
  "allowManagedPermissionRulesOnly": true,
  "allowedMcpServers": [
    { "serverUrl": "https://mcp.linear.app/*" }
  ],
  "allowManagedMcpServersOnly": true,
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "northwind-dev/approved-plugins" }
  ],
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": ["registry.npmjs.org", "pypi.org", "github.com"],
      "allowManagedDomainsOnly": true
    }
  },
  "requiredMinimumVersion": "2.1.200",
  "cleanupPeriodDays": 14,
  "companyAnnouncements": [
    "Claude Code is approved for client work. Read the AI usage policy on the intranet before your first session."
  ]
}

What each key is doing:

KeyEffect here
forceLoginMethodOnly claude.ai logins are allowed (no API key login)
forceLoginOrgUUIDAnd only into this organisation. Replace the placeholder with your organisation's UUID
availableModelsSessions can use Opus and Sonnet only
enforceAvailableModelsMakes the Default model option obey that list as well
permissions.denyBlocks curl and wget as Claude would normally write them, the project .env, and the user's AWS credentials folder, on every machine
permissions.disableBypassPermissionsModeRemoves bypass-permissions mode entirely
allowManagedPermissionRulesOnlyIgnores permission rules from user, project and local files, so only this file's rules apply
allowedMcpServersOnly an MCP server at this URL may load. Matching by URL rather than name matters, because anyone can name a server anything. With only URL entries, every stdio server is blocked
allowManagedMcpServersOnlyMakes this managed list the only MCP allowlist that counts
strictKnownMarketplacesPlugins can come from this one marketplace only
sandbox.enabledEvery shell command runs sandboxed
sandbox.failIfUnavailableClaude Code refuses to start where the sandbox cannot be set up
sandbox.allowUnsandboxedCommandsA command blocked by the sandbox cannot be retried outside it
sandbox.network.allowManagedDomainsOnlyUsers cannot add their own allowed domains on top of npm, PyPI and GitHub
requiredMinimumVersionClaude Code will not start on versions older than 2.1.200
cleanupPeriodDaysLocal transcripts and session data are kept for two weeks
companyAnnouncementsA message every user sees at startup

Remember that a Bash(curl *) deny is not a hard boundary: /usr/bin/curl or sh -c 'curl ...' would slip past the rule. The sandbox's network allowlist is what actually enforces it, which is why this file pairs the two. Managed settings covers delivery, and admin setup walks through choosing what to enforce.