One read of Claude Code CLIclaude-code-20260821T230701Z
90 pages moved out of 189 read.
What this read moved
26-50 of 90, page 2 of 4This capture is too large to show at once. Changes 26-50 of 90 are below, significant first; the rest are on the following screens.
llm-gateway-rollout Changed · +5 / -4 lines
managed-mcp Changed · +17 / -17 lines
managed-settings New page · 295 lines, new page
# Deploy managed settings ## Deploy a managed settings file ## Choose a delivery mechanism ### Where and when a policy applies ### Where each mechanism stores the policy ### Split a file-based policy across teams ## Which managed source Claude Code uses ### Keys read from every admin source ### Compute the policy with a helper program ### Let an embedding host add policy ### What a developer can change ## Check that a policy is in force ### Read the source in /status ### Find entries Claude Code dropped #### Keys that fail closed ## Keys only a managed source can set ## See also
A whole new page. There's nothing to diff it against, so here is what it says.
# Deploy managed settings
> Deploy managed settings to every developer's machine: delivery mechanisms per OS, which managed source Claude Code uses, and how to verify enforcement.
Managed settings are the settings your organization deploys to every developer's machine. Claude Code applies them above every other level, so no user, project, local, or `--settings` value overrides them, apart from a few [security-sensitive exceptions](/docs/en/settings#exceptions-to-managed-settings-precedence) where a stricter value from a lower level still counts.
This page is for the administrator who deploys managed settings or debugs why one isn't applying. To decide what to enforce, start with the [Decide what to enforce](/docs/en/admin-setup#decide-what-to-enforce) table. For the claude.ai console path, see [Server-managed settings](/docs/en/server-managed-settings). For which file a developer's own values go in, see [Settings](/docs/en/settings).
## Deploy a managed settings file
This is the quickest way to put a policy on each machine: a `managed-settings.json` file. If you haven't picked how to deliver managed settings yet, or your devices are under MDM or developers run cloud sessions, read [Choose a delivery mechanism](#choose-a-delivery-mechanism) first.
<Steps>
<Step title="Write managed-settings.json">
Write a `managed-settings.json` that holds the keys you've decided to enforce, in the same JSON shape as `settings.json`. The [Decide what to enforce](/docs/en/admin-setup#decide-what-to-enforce) table lists the keys behind each control, and each entry in the [settings reference](/docs/en/settings-reference) says whether a managed source can set it. This file blocks two file reads, turns off bypass mode, and makes Claude Code ignore permission rules from user, project, and local files and from `--allowedTools`:
```json managed-settings.json theme={null}
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./secrets/**)"
],
"disableBypassPermissionsMode": "disable"
},
"allowManagedPermissionRulesOnly": true
}
```
For a fuller example that shows the shape of more managed keys, including the login method, models, MCP servers, and marketplaces, see [An organization's managed settings](/docs/en/settings-example#an-organizations-managed-settings).
</Step>
<Step title="Place the file on each machine">
Save the file as `managed-settings.json` in the system directory for the operating system, using whatever tooling already places files on your fleet:
* **macOS**: `/Library/Application Support/ClaudeCode/managed-settings.json`
* **Linux and WSL**: `/etc/claude-code/managed-settings.json`
* **Windows**: `C:\Program Files\ClaudeCode\managed-settings.json`
</Step>
<Step title="Confirm the policy applied">
On one machine, run `/status` inside Claude Code. The `Setting sources` line shows `Enterprise managed settings (file)`. Roll out to the rest of the fleet after that; [Check that a policy is in force](#check-that-a-policy-is-in-force) covers what to look at when the line is missing.
</Step>
</Steps>
<span id="managed-settings-delivery" />
<span id="delivery-mechanisms" />
## Choose a delivery mechanism
The file in the steps above is one of four ways to get managed settings onto a machine. Every mechanism carries the same policy keys as a `settings.json` file, so the [settings reference](/docs/en/settings-reference) applies to all of them. A few keys are tied to particular sources, and each entry's Scope line says which:
* **Delivery controls**: [`policyHelper`](/docs/en/settings-reference#policyhelper) and [`wslInheritsWindowsSettings`](/docs/en/settings-reference#wslinheritswindowssettings)
* **Gateway login keys**: [`forceLoginGatewayUrl`](/docs/en/settings-reference#forcelogingatewayurl) and the `"gateway"` value of [`forceLoginMethod`](/docs/en/settings-reference#forceloginmethod)
A managed settings file, an MDM profile, or the claude.ai console applies one policy to everyone it reaches. To give one group of developers a different policy, deploy a different file or profile to that group; the claude.ai console [can't target a group yet](/docs/en/server-managed-settings#current-limitations), while a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) delivers managed settings per IdP group.
When more than one mechanism delivers a policy to the same machine, Claude Code uses one and ignores the others; [Which managed source Claude Code uses](#which-managed-source-claude-code-uses) gives the order.
The MDM and file rows are together called endpoint-managed settings, because the policy is stored on the developer's device, as opposed to the server-managed row, where Claude Code fetches it.
Pick a mechanism by how you already manage devices, using the table below.
| Mechanism | How you deliver it | When Claude Code reads it | Use it when |
| :----------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------- |
| [Server-managed settings](/docs/en/server-managed-settings) | In the claude.ai admin console, or on a self-hosted [Claude apps gateway](/docs/en/claude-apps-gateway) | Fetched at startup and polled hourly; see [changes that need approval](#where-and-when-a-policy-applies) | You want one place to change policy for a claude.ai organization without touching each machine |
| MDM or OS-level policy | As a macOS configuration profile or a Windows `HKLM` registry value, through Jamf, Intune, Group Policy, or a similar tool; see [where each mechanism stores the policy](#where-each-mechanism-stores-the-policy) | Read at startup and checked for changes every 30 minutes | You already manage devices with MDM or Group Policy |
| File-based | As `managed-settings.json` in a system directory on each machine; see [where each mechanism stores the policy](#where-each-mechanism-stores-the-policy) | Read at startup and reloaded when a file changes | Machines without MDM, Linux hosts, or images you build yourself |
| HKCU registry, Windows and WSL | As a Windows `HKCU` registry value; see [where each mechanism stores the policy](#where-each-mechanism-stores-the-policy) | Read at startup and checked for changes every 30 minutes; Claude Code uses it only when no other managed source delivers a policy key and no [host-supplied parent settings](#let-an-embedding-host-add-policy) supply a restrictive key | You can't write the machine-level `HKLM` key |
Starter templates for Jamf, Iru, Intune, and Group Policy are in the [MDM examples repository](https://github.com/anthropics/claude-code/tree/main/examples/mdm).
For managed MCP servers, which you deploy alongside any of these through `managed-mcp.json`, see [Managed MCP configuration](/docs/en/managed-mcp).
### Where and when a policy applies
A deployed policy reaches the developer's sessions as follows:
* **Surfaces**: every surface that runs Claude Code on the machine reads these sources: the terminal, the VS Code and JetBrains extensions, the desktop app, and [Agent SDK](/docs/en/agent-sdk/typescript) sessions, which load managed settings even when `settingSources` excludes the user, project, and local files.
* **Cloud sessions**: a session in an Anthropic-hosted environment doesn't read a device's MDM profile or file, so policy for it has to come from server-managed settings. A session in a [self-hosted environment](/docs/en/self-hosted-environments) reads the managed settings file in its runner image only when server-managed settings deliver no keys.
* **Running sessions**: a session picks up most changes on the schedule in the table without a restart. Claude Code reads [`forceRemoteSettingsRefresh`](/docs/en/settings-reference#forceremotesettingsrefresh) and [`requiredMinimumVersion`](/docs/en/settings-reference#requiredminimumversion) only at session start, arms a new or changed [`policyHelper`](/docs/en/settings-reference#policyhelper) entry at the next launch, and reads [some user-editable keys once at session start](/docs/en/settings#when-edits-take-effect).
* **Changes that need approval**: a server-managed change to a setting that [needs approval](/docs/en/server-managed-settings#security-approval-dialogs), such as a hook or an `env` variable, waits for the developer to accept the dialog in an interactive session, and applies for the current run in a session an IDE extension or the Agent SDK hosts. Other server-managed changes apply on the next poll.
* **Long-lived sessions**: a session left open for weeks can still lag a rollout. [`requiredMinimumVersion`](/docs/en/settings-reference#requiredminimumversion) blocks an outdated binary from starting and doesn't end a session that's already running.
<span id="format-the-policy-for-each-platform" />
### Where each mechanism stores the policy
The keys are the same everywhere, but each mechanism stores them in a different place and shape:
* **Server-managed**: Anthropic's servers, or your gateway, hold the policy. Claude Code keeps a local cache that it applies at startup and [replaces on each successful fetch](/docs/en/server-managed-settings#security-considerations).
* **macOS configuration profile**: the `com.anthropic.claudecode` managed preferences domain. Use the same top-level keys as `managed-settings.json`, with nested settings as dictionaries and lists as plist arrays.
* **Windows HKLM registry**: the JSON as a `REG_SZ` or `REG_EXPAND_SZ` value named `Settings` under `HKLM\SOFTWARE\Policies\ClaudeCode`.
* **File-based**: `managed-settings.json`, an optional `managed-settings.d/` directory, and `managed-mcp.json` in the system directory: `/Library/Application Support/ClaudeCode/` on macOS, `/etc/claude-code/` on Linux and WSL, and `C:\Program Files\ClaudeCode\` on Windows. Claude Code doesn't read the legacy Windows path `C:\ProgramData\ClaudeCode\managed-settings.json`.
* **Windows HKCU registry**: the same `Settings` value under `HKCU\SOFTWARE\Policies\ClaudeCode`.
### Split a file-based policy across teams
If several teams own parts of one policy, put each part in its own file in `managed-settings.d/`, next to `managed-settings.json` in the same system directory, instead of editing one shared file.
Claude Code merges `managed-settings.json` first, then every `*.json` file in the directory in alphabetical order. Name the files with numeric prefixes to control the order, such as `10-telemetry.json` and `20-security.json`. Claude Code ignores hidden files and files that don't end in `.json`.
When two files set the same key, Claude Code combines them by these rules:
* **Single values**, such as `"model": "opus"` or `"cleanupPeriodDays": 7`: the later file's value replaces the earlier one
* **Lists**, such as `permissions.deny` or `sandbox.network.allowedDomains`: the two lists combine, with duplicates removed
* **Nested blocks**, such as `env` or `sandbox`: the two blocks merge key by key, and each key inside follows these same rules
* **`fallbackModel`**: the later chain replaces the earlier one whole
* **[`extraKnownMarketplaces`](/docs/en/settings-reference#extraknownmarketplaces)**: a later entry with the same name replaces the earlier one whole
<span id="precedence-within-the-managed-tier" />
## Which managed source Claude Code uses
When your organization delivers more than one managed source, Claude Code uses the first of these sources that delivers at least one policy key and ignores the rest rather than merging them, apart from the few cross-source keys covered in [Keys read from every admin source](#keys-read-from-every-admin-source).
Claude Code shows no warning for the sources it skips. To see which source it used, run `/status`.
Two terms recur in this section:
* **Policy key**: any settings key other than the control key [`wslInheritsWindowsSettings`](/docs/en/settings-reference#wslinheritswindowssettings). A managed settings file or MDM policy that contains only that key doesn't count, and Claude Code moves on to the next source.
* **Admin source**: one of the first three sources below. The HKCU registry is user-writable and isn't one.
Claude Code checks the sources in this order, highest priority first:
1. Remote settings, delivered from claude.ai as [server-managed settings](/docs/en/server-managed-settings) or by a [Claude apps gateway](/docs/en/claude-apps-gateway). Claude Code fetches this source only when the session authenticates to Anthropic's API directly with an [eligible login or key](/docs/en/server-managed-settings#platform-availability), or signs in to a gateway with `/login`. On other providers, or when `ANTHROPIC_BASE_URL` points somewhere other than Anthropic's API, it starts at the next source
2. MDM or OS-level policies: the macOS plist or the HKLM registry key
3. Managed settings files, `managed-settings.d/*.json` and `managed-settings.json` merged together
4. The HKCU registry, on Windows, and on WSL once the HKLM registry or the Windows managed settings file turns [`wslInheritsWindowsSettings`](/docs/en/settings-reference#wslinheritswindowssettings) on and the HKCU value also sets it. Claude Code reads it only when no source above it delivers a policy key and no [host-supplied parent settings](#let-an-embedding-host-add-policy) supply a restrictive key
This diagram shows the ranking, with examples of the cross-source keys Claude Code reads from the first three sources:
<img src="https://mintcdn.com/claude-code/Omul3urhGAnblS-5/images/managed-source-precedence.svg?fit=max&auto=format&n=Omul3urhGAnblS-5&q=85&s=5e9f989651e0399b25e8d15eb5da1429" className="dark:hidden" alt="Diagram showing the four managed settings sources ranked from remote settings at the top through MDM, managed settings files, and the HKCU registry at the bottom. The first source with a policy key supplies the policy and the rest are skipped. A side panel shows that cross-source keys such as the sandbox locks, forceRemoteSettingsRefresh, and the per-variable env merge are read from every admin source, which excludes the HKCU registry." width="680" height="330" data-path="images/managed-source-precedence.svg" />
<img src="https://mintcdn.com/claude-code/Omul3urhGAnblS-5/images/managed-source-precedence-dark.svg?fit=max&auto=format&n=Omul3urhGAnblS-5&q=85&s=51f8d96a369202d7e3479d374dec60ca" className="hidden dark:block" alt="Diagram showing the four managed settings sources ranked from remote settings at the top through MDM, managed settings files, and the HKCU registry at the bottom. The first source with a policy key supplies the policy and the rest are skipped. A side panel shows that cross-source keys such as the sandbox locks, forceRemoteSettingsRefresh, and the per-variable env merge are read from every admin source, which excludes the HKCU registry." width="680" height="330" data-path="images/managed-source-precedence-dark.svg" />
### Keys read from every admin source
For most keys, Claude Code reads only the [source it selected](#which-managed-source-claude-code-uses). A value in a lower-ranked source is ignored even when the selected source leaves that key unset.
A few keys work differently. Claude Code reads them from every admin source, so a lower-ranked MDM policy or managed settings file can still set them when the selected source doesn't. Claude Code leaves the user-writable HKCU registry out of that scan; when HKCU is the only source and no host supplies parent settings, HKCU applies like any selected source.
The cross-source keys include:
* `sandbox.network.allowManagedDomainsOnly` and `sandbox.filesystem.allowManagedReadPathsOnly`: a `true` in any admin source turns the lock on. While a lock is on, Claude Code unions the allowlist it locks, `sandbox.network.allowedDomains` together with `WebFetch(domain:...)` allow rules, or `sandbox.filesystem.allowRead`, across every admin source. Without the lock, an unselected admin source's allowlist is ignored like any other key from an unselected source
* `allowAllClaudeAiMcps`
* The sandbox binary paths `sandbox.bwrapPath` and `sandbox.socatPath`
* The sandbox `ripgrep` binary, [`sandbox.ripgrep`](/docs/en/settings-reference#sandbox-ripgrep)
* `sandbox.filesystem.disabled` and `sandbox.network.strictAllowlist`
* [`useAutoModeDuringPlan`](/docs/en/settings-reference#useautomodeduringplan) and [`syncClaudeAiSkills`](/docs/en/settings-reference#syncclaudeaiskills), where a `false` from any admin source turns the behavior off. A `false` in the developer's user or local settings turns it off too; each key can only deny
* A commit-trailer opt-out in `attribution`, or in the deprecated `includeCoAuthoredBy`, from any tier
* [`forceRemoteSettingsRefresh`](/docs/en/server-managed-settings)
* `env`, merged per variable across the admin sources: each variable comes from the highest-priority source that defines it, so lower sources fill in variables the higher ones leave unset. A few variables follow their own rules; [Per-key exceptions across managed sources](/docs/en/server-managed-settings#per-key-exceptions-across-managed-sources) names each one. Requires Claude Code v2.1.223 or later. Before v2.1.223, Claude Code applied the selected source's whole `env` block only
### Compute the policy with a helper program
A [`policyHelper`](/docs/en/settings-reference#policyhelper) is an executable your MDM policy or managed settings file names, and Claude Code runs it to compute managed settings at startup. When the selected source configures one and the helper emits a `managedSettings` object, that output changes what Claude Code reads:
* **The emitted `managedSettings` object is the only managed settings for the session**, including for the [keys it otherwise reads from every admin source](#keys-read-from-every-admin-source), apart from `forceRemoteSettingsRefresh`, which Claude Code checks in every admin source at startup before the helper runs. A helper that exits 0 without emitting one contributes nothing, and the sources apply as usual; a helper that fails stops Claude Code from starting, as the [`policyHelper`](/docs/en/settings-reference#policyhelper) entry describes
Claude Code selects the source at startup, and that selection decides whether a helper runs. The [`policyHelper`](/docs/en/settings-reference#policyhelper) entry says which sources can configure a helper.
<span id="parent-settings-from-embedding-hosts" />
<span id="control-policy-from-an-embedding-host" />
<span id="merge-policy-from-an-embedding-host" />
### Let an embedding host add policy
When another application launches Claude Code, such as Claude Desktop, an IDE extension, or an Agent SDK app, that host can pass its own managed settings through the SDK `managedSettings` option. Claude Code calls these parent settings.
By default, Claude Code ignores parent settings whenever an admin source is present: server-managed settings, an MDM or OS-level policy, or a managed settings file.
To have Claude Code merge parent settings alongside an admin source, set [`parentSettingsBehavior`](/docs/en/settings-reference#parentsettingsbehavior) to `"merge"` in the highest-priority managed source; Claude Code reads the key from that source only.
Claude Code then keeps only the host's values that restrict what Claude can do, with one gap to know about: unless you also set the `allowManaged*Only` locks, the host's permission allow rules and sandbox allowlists still apply. See [Restrict parent settings](/docs/en/claude-apps-gateway#restrict-parent-settings) for the locks.
A [`policyHelper`](/docs/en/settings-reference#policyhelper) can turn parent merging off regardless of this key; its entry says when.
Claude Code also applies these checks to parent-supplied values on their own:
* When any admin source sets `allowManagedPermissionRulesOnly`, Claude Code drops [parent-supplied](/docs/en/claude-apps-gateway#restrict-parent-settings) permission allow rules and `additionalDirectories` as it reads them, even when a higher-priority source leaves the key unset. The key's effect on your own permission rules still comes only from the selected source, or from parent settings you've chosen to merge
* A `forceLoginOrgUUID` or `allowedMcpServers` value in the highest-priority admin source blocks a parent-supplied one, and Claude Code enforces the admin value. A value in an admin source that isn't the highest-priority one neither applies nor blocks the parent's. Before v2.1.223, a value in any admin source blocked the parent's
* An `availableModels` value follows the same rule as `forceLoginOrgUUID` and `allowedMcpServers`
### What a developer can change
A developer's own settings files, `--settings` values, and project files never override a managed value; the [exceptions](/docs/en/settings#exceptions-to-managed-settings-precedence) only let a stricter lower-level value count. Four things sit outside that rule:
* **The model for a session**: a managed `model` is a default, not a lock. `--model` and `ANTHROPIC_MODEL` still pick the model for that session, so deploy [`availableModels`](/docs/en/settings-reference#availablemodels) to restrict the choice.
* **Local admin rights**: a developer who is an administrator on the machine can edit the managed source itself, which is why MDM tooling can redeploy the profile or file on a schedule and why the HKLM registry and the macOS managed preferences domain exist.
* **The server-managed cache**: server-managed settings come from Anthropic's servers, and an edit to the local cache [lasts only until the next successful fetch](/docs/en/server-managed-settings#security-considerations).
* **Other tools**: managed settings bind Claude Code only. A developer who calls the API from another tool isn't under them.
<span id="verify-enforcement" />
<span id="verify-that-a-policy-is-in-force" />
## Check that a policy is in force
A developer reports that a policy isn't applying, or you want to confirm a rollout landed before pushing it to the fleet. Two commands on that machine answer it: `/status` shows which managed source Claude Code selected, and `claude doctor` lists what it dropped.
### Read the source in /status
On the developer's machine, run `/status` inside Claude Code and read the `Setting sources` line. When a managed source is in effect, the line lists `Enterprise managed settings` with the source Claude Code selected in parentheses:
* `(remote)`: server-managed settings from claude.ai or a gateway
* `(plist)` or `(HKLM)`: an MDM or OS policy
* `(file)`, `(drop-ins)`, or `(file + drop-ins)`: `managed-settings.json`, the drop-in directory, or both
* `(HKCU)`: the user-writable registry fallback
* `(parent process)`: an [embedding host](#let-an-embedding-host-add-policy) supplied restrictive settings
* `(helper)`: a [`policyHelper`](/docs/en/settings-reference#policyhelper) configured by the selected MDM or file source
When the policy isn't applying, the line tells you which of two problems you have:
* **The line is missing**: Claude Code found no managed source that delivers a policy key. Check that the file sits at the path for the OS, that it's valid JSON, and that it contains a key other than `wslInheritsWindowsSettings`.
* **The line names a source other than the one you deployed**: a higher-priority source is present and Claude Code ignored yours. [Which managed source Claude Code uses](#which-managed-source-claude-code-uses) gives the order.
<span id="invalid-entries-in-managed-settings" />
### Find entries Claude Code dropped
When a managed settings file, MDM profile, registry value, or server-managed payload fails schema validation, Claude Code first skips the individual entries it can repair, such as one invalid permission rule, with a warning for each, then drops any top-level key whose value still fails and keeps enforcing every remaining valid key. Claude Code is stricter with the `managedSettings` a [`policyHelper`](/docs/en/settings-reference#policyhelper) emits: it makes the same entry repairs, but any schema violation that survives fails the whole helper run, and at startup Claude Code refuses to start, the same as for a helper that exits non-zero. A managed settings file or drop-in file that isn't valid JSON contributes no settings at all; Claude Code reports it with the other validation errors and reads the remaining sources as usual.
To find a dropped entry, look in one of three places:
* Interactive sessions show a dialog at startup listing the invalid entries.
* Non-interactive runs with `-p` print a summary to stderr.
* [`claude doctor`](/docs/en/debug-your-config) lists each invalid entry with its source and field.
#### Keys that fail closed
A few enforcement keys aren't dropped when invalid. Claude Code enforces a stricter fallback until the value is fixed; the table shows what it enforces for each key:
| Field | Behavior when present but invalid |
| :---------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowedMcpServers` | Enforced as an empty allowlist, so no MCP servers are admitted until the value is fixed. An individual invalid entry is stripped and the valid subset is enforced. |
| `allowManagedHooksOnly` | Treated as `true` until fixed: the [hook restrictions](/docs/en/settings-reference#allowmanagedhooksonly) apply and, unless `disableCommandPluginSources` is explicitly `false`, command-sourced plugins are disabled. |
| `allowManagedMcpServersOnly` | Treated as `true`. |
| `disableCommandPluginSources` | Treated as `true`, so command-sourced plugins stay disabled until the value is fixed. |
| `availableModels` | Enforced as an empty allowlist until fixed, so only the Default model is available; a non-string entry is stripped and the valid subset enforced. |
| `enforceAvailableModels` | Treated as `true`. |
| `forceLoginOrgUUID` | No organization is permitted to log in until the value is fixed. |
| `deniedMcpServers` | An individual invalid entry is stripped and the valid subset is enforced. A wholly invalid value is dropped with a warning, since denying every server would block servers the policy never named. |
| `sandbox.credentials` | A recoverable invalid entry is degraded to `mode: "deny"` with a warning; an unrecoverable one is stripped; valid entries stay enforced. See [invalid credential entries](/docs/en/settings-reference#invalid-credential-entries-in-managed-settings) |
`requiredMinimumVersion` and `requiredMaximumVersion` fail open by design: an invalid value is dropped rather than enforced, so a bad policy push can't prevent Claude Code from starting.
This tolerance applies only to managed settings. User, project, and local settings files remain strict: a file whose JSON or top-level shape fails validation is rejected as a whole and reported, and an individual entry that fails, such as a malformed permission rule, is skipped with a warning while the rest of the file applies.
<span id="managed-only-settings" />
## Keys only a managed source can set
Claude Code reads the following keys only from a managed source; placing them in user or project settings files has no effect.
Most of them are locks: the value a lock governs, such as permission rules or `sandbox.network.allowedDomains`, is an ordinary key that any level can set, and the lock tells Claude Code to honor only the managed value.
The table covers the permission, plugin, and delivery controls. For any key not listed here, the Scope column of the [settings reference](/docs/en/settings-reference#all-settings) index says whether it's managed-only; the remaining managed-only keys there include the gateway login URL, version, browser, mobile-simulator, SSH host, sandbox binary path, and CLAUDE.md controls.
| Setting | Description |
| :-------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`allowAllClaudeAiMcps`](/docs/en/settings-reference#allowallclaudeaimcps) | Load the claude.ai connectors alongside a deployed `managed-mcp.json` instead of suppressing them |
| [`allowedChannelPlugins`](/docs/en/settings-reference#allowedchannelplugins) | Allowlist of channel plugins that may push messages. Replaces the default Anthropic allowlist when set. Requires `channelsEnabled: true`. See [Restrict which channel plugins can run](/docs/en/channels#restrict-which-channel-plugins-can-run) |
| [`allowManagedHooksOnly`](/docs/en/settings-reference#allowmanagedhooksonly) | When `true`, restricts which hooks run; see [what runs under `allowManagedHooksOnly`](/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly) for the full effect list |
| [`allowManagedMcpServersOnly`](/docs/en/settings-reference#allowmanagedmcpserversonly) | When `true`, only `allowedMcpServers` from managed settings are respected. `deniedMcpServers` still merges from all sources. See [Managed MCP configuration](/docs/en/managed-mcp) |
| [`allowManagedPermissionRulesOnly`](/docs/en/settings-reference#allowmanagedpermissionrulesonly) | Only managed permission rules apply; the entry lists every source it ignores |
| [`blockedMarketplaces`](/docs/en/settings-reference#blockedmarketplaces) | Blocklist of marketplace sources. Blocked sources are checked before downloading, so they never touch the filesystem. See [managed marketplace restrictions](/docs/en/plugin-marketplaces#managed-marketplace-restrictions) |
| [`channelsEnabled`](/docs/en/settings-reference#channelsenabled) | Allow [channels](/docs/en/channels) for the organization. See [enterprise controls](/docs/en/channels#enterprise-controls) for the default on each plan |
| [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources) | When `true`, blocks [`command` plugin sources](/docs/en/plugin-marketplaces#command-sources) entirely, so the marketplace-declared command never runs. When unset, follows `allowManagedHooksOnly`. Requires Claude Code v2.1.229 or later |
| [`disableSideloadFlags`](/docs/en/settings-reference#disablesideloadflags) | Reject the `--plugin-dir`, `--plugin-url`, `--agents`, and `--mcp-config` flags at startup. Requires Claude Code v2.1.193 or later |
| [`forceRemoteSettingsRefresh`](/docs/en/settings-reference#forceremotesettingsrefresh) | When `true`, blocks CLI startup until remote managed settings are freshly fetched and exits if the fetch fails. See [fail-closed enforcement](/docs/en/server-managed-settings#enforce-fail-closed-startup) |
| [`parentSettingsBehavior`](/docs/en/settings-reference#parentsettingsbehavior) | Whether host-supplied parent settings merge under the managed policy |
| [`pluginSuggestionMarketplaces`](/docs/en/settings-reference#pluginsuggestionmarketplaces) | Marketplaces whose plugins Claude Code may suggest to users |
| [`pluginTrustMessage`](/docs/en/settings-reference#plugintrustmessage) | Custom message appended to the plugin trust warning shown before installation |
| [`policyHelper`](/docs/en/settings-reference#policyhelper) | Executable that computes managed settings at startup; see [Compute managed settings with a policy helper](/docs/en/settings-reference#policyhelper) |
| [`sandbox.filesystem.allowManagedReadPathsOnly`](/docs/en/settings-reference#sandbox-filesystem-allowmanagedreadpathsonly) | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |
| [`sandbox.network.allowManagedDomainsOnly`](/docs/en/settings-reference#sandbox-network-allowmanageddomainsonly) | Honor only managed `allowedDomains` and `WebFetch(domain:...)` allow rules; block other domains without prompting |
| [`strictKnownMarketplaces`](/docs/en/settings-reference#strictknownmarketplaces) | Controls which plugin marketplace sources users can add and install plugins from. See [managed marketplace restrictions](/docs/en/plugin-marketplaces#managed-marketplace-restrictions) |
| [`strictPluginOnlyCustomization`](/docs/en/settings-reference#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources; `true` locks all four, an array names which |
| [`wslInheritsWindowsSettings`](/docs/en/settings-reference#wslinheritswindowssettings) | When set in the HKLM registry or a file under `C:\Program Files\ClaudeCode`, have WSL read the Windows policy chain in addition to `/etc/claude-code`; the entry gives the order |
<Note>
On Team and Enterprise plans, an Owner enables or disables [Remote Control](/docs/en/remote-control) and [web sessions](/docs/en/claude-code-on-the-web) organization-wide in [Claude Code admin settings](https://claude.ai/admin-settings/claude-code). Remote Control can additionally be disabled per device with the [`disableRemoteControl`](/docs/en/settings-reference#disableremotecontrol) setting. Web sessions have no per-device managed settings key.
</Note>
## See also
* [Set up Claude Code for your organization](/docs/en/admin-setup): decide what to enforce and how
* [Server-managed settings](/docs/en/server-managed-settings): deliver policy from the claude.ai console or a gateway
* [Managed MCP configuration](/docs/en/managed-mcp): control which MCP servers developers can use
* [Settings reference](/docs/en/settings-reference): every key, with whether a managed source can set it
* [Example settings files](/docs/en/settings-example#an-organizations-managed-settings): a complete `managed-settings.json` showing the shape of the managed keys
mcp Changed · +7 / -7 lines
memory Changed · +4 / -4 lines
model-config Changed · +29 / -29 lines
monitoring-usage Changed · +3 / -3 lines
network-config Changed · +20 / -20 lines
overview Changed · +5 / -5 lines
permission-modes Changed · +26 / -26 lines
permissions Changed · +23 / -48 lines
### Managed-only settings
plugin-marketplaces Changed · +19 / -19 lines
plugin-relevance Changed · +3 / -3 lines
plugins-reference Changed · +10 / -10 lines
quickstart Changed · +5 / -5 lines
remote-control Changed · +8 / -8 lines
sandboxing Changed · +39 / -39 lines
server-managed-settings Changed · +40 / -40 lines
sessions Changed · +8 / -8 lines
settings-example New page · 389 lines, new page
# Example settings files ## Your own settings
A whole new page. There's nothing to diff it against, so here is what it says.
# Example settings files
> Realistic settings.json files for a developer, a team, and an organization: copy one, keep the keys you want, and change the values.
This page holds three example `settings.json` files, one for each place you save a setting:
* A developer's `~/.claude/settings.json`
* A team's `.claude/settings.json`, committed to the repository
* An organization's `managed-settings.json`
Each one is a plausible file for that reader, so you can see the shape and copy the parts you want. None of them is a recommended baseline. Every value comes from the key's entry on the [settings reference](/docs/en/settings-reference), which has its type, default, and where it can be set.
Each example has two tabs. **Copyable settings file** is the file as you'd save it. **What each key does** is the same file with a comment above each key; Claude Code doesn't accept comments in a settings file, so copy from the first tab.
## Your own settings
One developer's personal settings. It picks a model and effort, adjusts the terminal, and pre-approves a read-only command and one file read. Everything not listed keeps its default. A file like this goes in `~/.claude/settings.json`, where it applies to every project you open.
<Tabs>
<Tab title="Copyable settings file">
Save this as `~/.claude/settings.json`. It's valid JSON with no comments, so you can paste it as is and delete the keys you don't want.
```json ~/.claude/settings.json theme={null}
{
"model": "claude-sonnet-5",
"effortLevel": "xhigh",
"editorMode": "vim",
"theme": "light-daltonized",
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'",
"padding": 2
},
"spinnerTipsEnabled": false,
"preferredNotifChannel": "terminal_bell",
"permissions": {
"allow": [
"Bash(git diff *)",
"Read(~/.zshrc)"
]
},
"autoUpdatesChannel": "stable",
"cleanupPeriodDays": 20
}
```
</Tab>
<Tab title="What each key does">
The same file with a comment above each key. Read it here; copy from the other tab, because Claude Code doesn't accept comments in a settings file.
```jsonc ~/.claude/settings.json theme={null}
{
// Start every session on Sonnet 5
"model": "claude-sonnet-5",
// Reason more deeply than the default high level; /effort saves a new level, and --effort overrides it for one session
"effortLevel": "xhigh",
// Vim keybindings in the prompt
"editorMode": "vim",
// The colorblind-friendly light theme
"theme": "light-daltonized",
// A status line below the prompt: model name and context used
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'",
"padding": 2
},
// Hide the tips that rotate under the spinner
"spinnerTipsEnabled": false,
// Ring the terminal bell for notifications, such as a finished task or a waiting permission prompt
"preferredNotifChannel": "terminal_bell",
// Let Claude Code run git diff and read your .zshrc without asking
"permissions": {
"allow": [
"Bash(git diff *)",
"Read(~/.zshrc)"
]
},
// Take updates from the stable channel
"autoUpdatesChannel": "stable",
// Delete session transcripts and other local session data older than 20 days
"cleanupPeriodDays": 20
}
```
</Tab>
</Tabs>
<h2 id="a-teams-shared-settings">
A team's shared settings
</h2>
One team's shared settings, committed to the repository so everyone who clones it gets the same permissions, hooks, telemetry, and plugin marketplace. Save a file like this at `.claude/settings.json` at the top of the repository. Three things to know before you commit one:
* **Cloud sessions read it too.** A [cloud session](/docs/en/settings#settings-in-cloud-sessions) on Claude Code on the web starts from a clone of the repository, so the committed file applies there as well.
* **Allow rules wait for trust.** Allow rules and `extraKnownMarketplaces` entries take effect after each person [trusts this folder itself](/docs/en/permissions#project-allow-rules-and-workspace-trust), not only a parent folder; deny and ask rules apply in every session, trusted or not.
* **The hook is a script in the repo.** This file's hook runs `.claude/hooks/block-rm.sh`; [How a hook resolves](/docs/en/hooks#how-a-hook-resolves) walks through writing it.
<Tabs>
<Tab title="Copyable settings file">
Save this as `.claude/settings.json` at the top of the repository and commit it. It's valid JSON with no comments, so you can paste it as is and delete the keys you don't want.
```json .claude/settings.json theme={null}
{
"permissions": {
"allow": [
"Bash(npm run *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
},
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317"
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
}
]
}
]
},
"extraKnownMarketplaces": {
"acme-tools": {
"source": {
"source": "github",
"repo": "acme-corp/claude-plugins"
}
}
},
"enabledPlugins": {
"code-formatter@acme-tools": true
},
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": [
"/tmp/build"
]
},
"network": {
"allowedDomains": [
"registry.npmjs.org",
"*.example.com"
]
}
},
"plansDirectory": "./plans"
}
```
</Tab>
<Tab title="What each key does">
The same file with a comment above each key. Read it here; copy from the other tab, because Claude Code doesn't accept comments in a settings file.
```jsonc .claude/settings.json theme={null}
{
"permissions": {
// Run npm scripts without asking
"allow": [
"Bash(npm run *)"
],
// Always confirm before pushing
"ask": [
"Bash(git push *)"
],
// Never read env files or the secrets folder
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
},
// Send OpenTelemetry metrics to the team's collector over gRPC; replace the endpoint with your collector's URL
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317"
},
// Before every Bash command, run a script in the repo that can block it
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
}
]
}
]
},
// Register the team's plugin marketplace on every clone
"extraKnownMarketplaces": {
"acme-tools": {
"source": {
"source": "github",
"repo": "acme-corp/claude-plugins"
}
}
},
// Enable one plugin from that marketplace; a plugin from an external source such as a GitHub repository still needs each person to install it once
"enabledPlugins": {
"code-formatter@acme-tools": true
},
// Sandbox commands: writable build dir; npm and example.com pre-allowed, other hosts still prompt
"sandbox": {
"enabled": true,
"filesystem": {
"allowWrite": [
"/tmp/build"
]
},
"network": {
"allowedDomains": [
"registry.npmjs.org",
"*.example.com"
]
}
},
// Keep plan files inside the repo
"plansDirectory": "./plans"
}
```
</Tab>
</Tabs>
<h2 id="an-organizations-managed-settings">
An organization's managed settings
</h2>
A `managed-settings.json` file that shows the shape of the managed keys, with one plausible value for each. It isn't a recommended policy: pick the keys that match your own requirements and set your own values. The example sets these keys:
* `forceLoginMethod` and `forceLoginOrgUUID` pin the login method and organization
* `availableModels` and `enforceAvailableModels` restrict which models sessions can use
* `permissions.deny` blocks two file reads and `curl`, and `disableBypassPermissionsMode` removes the bypass permission mode
* `allowManagedPermissionRulesOnly` and `allowManagedMcpServersOnly` make the managed permission and MCP allowlists the only ones that apply
* `allowedMcpServers` pins the MCP server by URL
* `strictKnownMarketplaces` allows one plugin marketplace
* `sandbox` sandboxes commands with a fixed network allowlist and no unsandboxed retry
* `requiredMinimumVersion` sets a minimum Claude Code version
* `cleanupPeriodDays` shortens retention of session transcripts and other local data to seven days
* `companyAnnouncements` shows a message at startup
Administrators deploy a file like this as `managed-settings.json`, or the same JSON through MDM or [server-managed settings](/docs/en/server-managed-settings). One deployed file applies to every machine or account it reaches. To give a group different values, deploy a different file or profile to that group, since [server-managed settings don't support per-group policy yet](/docs/en/server-managed-settings#current-limitations).
<Tabs>
<Tab title="Copyable settings file">
Deploy this as `managed-settings.json`, or the same JSON through MDM or the claude.ai console. It's valid JSON with no comments; replace the example organization UUID, server URL, and marketplace with your own and delete the keys you don't want.
```json managed-settings.json theme={null}
{
"forceLoginMethod": "claudeai",
"forceLoginOrgUUID": [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
],
"availableModels": [
"opus",
"sonnet"
],
"enforceAvailableModels": true,
"permissions": {
"deny": [
"Bash(curl *)",
"Read(./.env)",
"Read(./secrets/**)"
],
"disableBypassPermissionsMode": "disable"
},
"allowManagedPermissionRulesOnly": true,
"allowedMcpServers": [
{
"serverUrl": "https://api.githubcopilot.com/*"
}
],
"allowManagedMcpServersOnly": true,
"strictKnownMarketplaces": [
{
"source": "github",
"repo": "acme-corp/approved-plugins"
}
],
"sandbox": {
"enabled": true,
"failIfUnavailable": true,
"allowUnsandboxedCommands": false,
Cut at 300 lines. The page has the rest.
settings-reference New page · 5350 lines, new page
# Claude Code settings reference ## Scopes ## All settings ## Model and responses ### `advisorModel` ### `alwaysThinkingEnabled` ### `availableModels` ### `effortLevel` ### `enforceAvailableModels` ### `fallbackModel` ### `fastMode` ### `fastModePerSessionOptIn` ### `language` ### `model` ### `modelOverrides` ### `outputStyle` ### `showThinkingSummaries` ### `switchModelsOnFlag` ### `ultracode` ## Permission settings ### `allowManagedPermissionRulesOnly` ### `autoMode` ### `autoMode.classifyAllShell` ### `disableAutoMode` ### `permissions` ### `useAutoModeDuringPlan` ### `permissions.allow` #### Permission rule syntax ### `permissions.ask` ### `permissions.deny` ### `permissions.additionalDirectories` ### `permissions.defaultMode` ### `permissions.disableBypassPermissionsMode` ### `skipAutoPermissionPrompt` ### `skipDangerousModePermissionPrompt` ## Sandbox settings ### `sandbox` ### `sandbox.enabled` ### `sandbox.failIfUnavailable` ### `sandbox.autoAllowBashIfSandboxed` ### `sandbox.excludedCommands` ### `sandbox.allowUnsandboxedCommands` ### `sandbox.filesystem` #### Sandbox path prefixes ### `sandbox.filesystem.allowWrite` ### `sandbox.filesystem.denyWrite` ### `sandbox.filesystem.denyRead` ### `sandbox.filesystem.allowRead` ### `sandbox.filesystem.allowManagedReadPathsOnly` ### `sandbox.filesystem.disabled` ### `sandbox.ignoreViolations` ### `sandbox.enableWeakerNestedSandbox` ### `sandbox.enableWeakerNetworkIsolation` ### `sandbox.allowAppleEvents` ### `sandbox.ripgrep` ### `sandbox.bwrapPath` ### `sandbox.socatPath` ### `sandbox.credentials` #### Invalid credential entries in managed settings ### `sandbox.credentials.files` #### Mask fields for files ### `sandbox.credentials.envVars` #### Mask fields for environment variables ### `sandbox.credentials.allowPlaintextInject` ### `sandbox.credentials.awsPairs` ### `sandbox.credentials.sigv4` ### `sandbox.network` ### `sandbox.network.allowUnixSockets` ### `sandbox.network.allowAllUnixSockets` ### `sandbox.network.allowLocalBinding` ### `sandbox.network.allowMachLookup` ### `sandbox.network.allowedDomains` ### `sandbox.network.deniedDomains` ### `sandbox.network.strictAllowlist` ### `sandbox.network.allowManagedDomainsOnly` ### `sandbox.network.httpProxyPort` ### `sandbox.network.socksProxyPort` ### `sandbox.network.tlsTerminate` ## Memory and context ### `autoCompactEnabled` ### `autoCompactWindow` ### `autoMemoryDirectory` ### `autoMemoryEnabled` ### `claudeMd` ### `claudeMdExcludes` ### `env` #### How `env` values interact with your shell #### When Claude Code applies `env` values #### Variables Claude Code ignores in `env` ### `fileCheckpointingEnabled` ### `plansDirectory` ### `skillListingBudgetFraction` ### `skillListingMaxDescChars` ## Interface and terminal ### `askUserQuestionTimeout` ### `autoScrollEnabled` ### `axScreenReader` ### `companyAnnouncements` ### `defaultShell` ### `dialogExpiry` ### `editorMode` ### `emojiCompletionEnabled` ### `fileSuggestion` #### Command input and output ### `footerLinksRegexes` #### Badge constraints ### `keybindingFlavor` ### `prefersReducedMotion` ### `promptSuggestionEnabled` ### `respectGitignore` ### `respondToBashCommands` ### `showClearContextOnPlanAccept` ### `showTurnDuration` ### `spellcheck` ### `spinnerTipsEnabled` ### `spinnerTipsOverride` ### `spinnerVerbs` ### `statusLine` ### `subagentStatusLine` ### `syntaxHighlightingDisabled` ### `terminalProgressBarEnabled` ### `terminalTitleFromRename` ### `theme` ### `tui` ### `verbose` ### `viewMode` ### `vimInsertModeRemaps` ### `voice` ### `voiceEnabled` ### `wheelScrollAccelerationEnabled` ## Git and attribution ### `attribution` ### `includeCoAuthoredBy` ### `includeGitInstructions` ### `prUrlTemplate` ### `attribution.commit` ### `attribution.pr` ### `attribution.sessionUrl` ## Hooks and automation ### `allowedHttpHookUrls` ### `allowManagedHooksOnly` #### What runs under `allowManagedHooksOnly` ### `disableAllHooks` #### Status line and file suggestion gates ### `disableWorkflows` ### `enableWorkflows` ### `hooks` ### `httpHookAllowedEnvVars` ### `workflowKeywordTriggerEnabled` ### `workflowSizeGuideline` ## Plugins and skills ### `disableBundledSkills` ### `disableSkillShellExecution` ### `skillOverrides` ### `syncClaudeAiSkills` ### `allowedChannelPlugins` ### `blockedMarketplaces` ### `channelsEnabled` ### `disableCommandPluginSources` ### `pluginSuggestionMarketplaces` ### `pluginTrustMessage` ### `strictKnownMarketplaces` #### Allowed source types #### Owner wildcards #### Exact matching #### Allow only the official marketplace #### Combine with `extraKnownMarketplaces` ### `strictPluginOnlyCustomization` ### `strictPluginOnlyCustomization.skills` ### `strictPluginOnlyCustomization.agents` ### `strictPluginOnlyCustomization.hooks` ### `strictPluginOnlyCustomization.mcp` ### `enabledPlugins` ### `extraKnownMarketplaces` #### Marketplace source types #### Marketplace key aliases ### `pluginConfigs` ## MCP ### `allowAllClaudeAiMcps` ### `allowedMcpServers` ### `allowManagedMcpServersOnly` ### `deniedMcpServers` ### `disableClaudeAiConnectors` ### `disabledMcpjsonServers` ### `enableAllProjectMcpServers` ### `enabledMcpjsonServers` ## Agents, sessions, and worktrees ### `agent` ### `crossSessionInbound` ### `disableAgentView` ### `isolatePeerMachines` ### `processWrapper` ### `teammateMode` ### `worktree` ### `worktree.baseRef` ### `worktree.symlinkDirectories` ### `worktree.sparsePaths` ### `worktree.bgIsolation` ## Remote, desktop, and notifications ### `agentPushNotifEnabled` ### `awaySummaryEnabled` ### `disableArtifact` ### `disableDeepLinkRegistration` ### `disableRemoteControl` ### `enableArtifact` ### `inputNeededNotifEnabled` ### `preferredNotifChannel` ### `remote.defaultEnvironmentId` ### `remoteControlAtStartup` ### `sshConfigs` ### `sshHostAllowlist` ## Authentication and providers ### `apiKeyHelper` ### `awsAuthRefresh` ### `awsCredentialExport` ### `forceLoginMethod` ### `forceLoginGatewayUrl` ### `forceLoginOrgUUID` ### `gcpAuthRefresh` ### `otelHeadersHelper` ## Updates and versioning ### `autoUpdatesChannel` ### `minimumVersion` ### `requiredMaximumVersion` ### `requiredMinimumVersion` ## Tools ### `browserExternalPageTools` ### `disableBrowserExternalNavigation` ### `disableMobileSimulatorTools` ## Privacy and telemetry ### `cleanupPeriodDays` ### `feedbackSurveyRate` ### `skipWebFetchPreflight` ## Enterprise and managed settings ### `disableSideloadFlags` ### `forceRemoteSettingsRefresh` ### `parentSettingsBehavior` ### `policyHelper` #### Write the helper output ### `policyHelper.path` ### `policyHelper.timeoutMs` ### `policyHelper.refreshIntervalMs` ### `wslInheritsWindowsSettings` ## Global config settings ### `autoConnectIde` ### `autoInstallIdeExtension` ### `diffTool` ### `externalEditorContext` ### `permissionExplainerEnabled` ### `teammateDefaultModel` ## See also
This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.
A whole new page. There's nothing to diff it against, so here is what it says.
# Claude Code settings reference
> Complete reference for every Claude Code settings.json key: where each one goes, its type and default, and a paste-ready example, with an index of every key.
export const BackToIndex = ({href = '#all-settings', label = 'Back to index'}) => {
const [show, setShow] = useState(false);
useEffect(() => {
const onScroll = () => setShow(window.scrollY > window.innerHeight);
onScroll();
window.addEventListener('scroll', onScroll, {
passive: true
});
return () => window.removeEventListener('scroll', onScroll);
}, []);
return <div className="not-prose">
<style>{`
.bti-btn {
position: fixed; right: 20px; bottom: 20px; z-index: 40;
display: inline-flex; align-items: center; gap: 6px;
padding: 8px 12px; border-radius: 999px;
font-size: 13px; font-weight: 500; line-height: 1; text-decoration: none;
color: #1f1f1f; background: #ffffff; border: 1px solid #d9d9d9;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
opacity: 0; pointer-events: none; transform: translateY(6px);
transition: opacity 160ms ease, transform 160ms ease;
}
.bti-btn.bti-show { opacity: 1; pointer-events: auto; transform: translateY(0); }
.bti-btn:hover { border-color: #b3b3b3; }
.dark .bti-btn { color: #ececec; background: #1e1e1e; border-color: #3a3a3a; box-shadow: 0 2px 8px rgba(0,0,0,0.5); }
.dark .bti-btn:hover { border-color: #5a5a5a; }
@media print { .bti-btn { display: none; } }
`}</style>
<a className={'bti-btn' + (show ? ' bti-show' : '')} href={href} aria-hidden={!show} tabIndex={show ? 0 : -1}>
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M8 13V3M3.5 7.5 8 3l4.5 4.5" /></svg>
{label}
</a>
</div>;
};
export const ReferenceFilter = ({placeholder, noun, facets, facetOrder, columnHelp, children}) => {
const useLive = init => {
const [v, setV] = useState(init);
const ref = useRef(init);
return [v, ref, x => {
ref.current = x;
setV(x);
}];
};
const cap = s => s.charAt(0).toUpperCase() + s.slice(1);
const plural = s => s.endsWith('y') ? s.slice(0, -1) + 'ies' : s + 's';
const facetNames = facets || ['category', 'topic', 'scope', 'where'];
const orderOf = {};
Object.keys(facetOrder || ({})).forEach(k => {
orderOf[k] = facetOrder[k].map(x => String(x).toLowerCase());
});
const rankIn = (col, v) => {
const list = orderOf[col];
if (!list) return -1;
const i = list.indexOf(String(v).toLowerCase());
return i < 0 ? list.length : i;
};
const cmpValues = col => (a, b) => {
const ra = rankIn(col, a);
const rb = rankIn(col, b);
if (ra !== rb) return ra - rb;
return a < b ? -1 : a > b ? 1 : 0;
};
const help = columnHelp || ({});
const FIRST_COL_HELP = 'Click an entry to open it.';
const optionLabel = (f, c) => c === 'All' ? 'All ' + plural(f.label.toLowerCase()) : c;
const nounText = noun || 'entries';
const placeholderText = placeholder || 'Filter this reference';
const rootRef = useRef(null);
const tablesRef = useRef(null);
const searchRef = useRef(null);
const menuRef = useRef({});
const [q, qRef, setQ] = useLive('');
const [sel, selRef, setSel] = useLive({});
const [sortBy, sortRef, setSortBy] = useLive(null);
const [menuOpen, menuOpenRef, setMenu] = useLive(null);
const [facetList, setFacetList] = useState([]);
const [firstHead, setFirstHead] = useState('');
const [counts, setCounts] = useState({
shown: 0,
total: 0
});
const [disabled, setDisabled] = useState(false);
const menuBtn = name => menuRef.current[name] ? menuRef.current[name].querySelector(':scope > button') : null;
const menuList = name => menuRef.current[name] ? menuRef.current[name].querySelector('[role="listbox"]') : null;
const closeMenu = name => {
setMenu(null);
const btn = menuBtn(name);
if (btn) btn.focus();
};
const focusSelected = name => {
const list = menuList(name);
if (!list) return;
const btn = list.querySelector('button[aria-selected="true"]') || list.querySelector('button');
if (btn) btn.focus();
};
const setFacet = (name, value) => {
setSel(Object.assign({}, selRef.current, {
[name]: value
}));
apply(qRef.current);
closeMenu(name);
};
const sortTables = by => {
(tablesRef.current || []).forEach(tab => {
const t = tab.el;
const idx = tab.heads.indexOf(by);
const body = t.querySelector('tbody');
if (idx < 0 || !body) return;
const rows = [...body.querySelectorAll('tr')];
const keyOf = r => r.children[idx] ? r.children[idx].textContent.trim().toLowerCase() : '';
const cmp = cmpValues(by);
rows.map((r, i) => ({
r,
i: Number(r.dataset.sfIndex !== undefined ? r.dataset.sfIndex : i),
k: keyOf(r)
})).sort((a, b) => cmp(a.k, b.k) || a.i - b.i).forEach(x => body.appendChild(x.r));
[...t.querySelectorAll('thead th')].forEach((h, i) => {
const sortable = tab.heads[i] === tab.heads[0] || facetNames.indexOf(tab.heads[i]) > -1;
if (sortable) h.setAttribute('aria-sort', i === idx ? 'ascending' : 'none'); else h.removeAttribute('aria-sort');
});
});
};
const scan = () => {
const tables = [];
let el = rootRef.current ? rootRef.current.nextElementSibling : null;
while (el) {
if (el.tagName === 'H2' || el.querySelector(':scope > h2')) break;
const found = el.tagName === 'TABLE' ? [el] : [...el.querySelectorAll('table')];
found.forEach(t => {
const headCells = [...t.querySelectorAll('thead th, thead td')];
const heads = headCells.map(h => h.textContent.trim().toLowerCase());
if (heads.length === 0) return;
const facetIdx = {};
heads.forEach((h, i) => {
if (facetNames.indexOf(h) > -1) facetIdx[h] = i;
});
if (!t.dataset.sfDecorated) {
t.dataset.sfDecorated = '1';
headCells.forEach((h, i) => {
const text = i === 0 ? help[heads[0]] || FIRST_COL_HELP : help[heads[i]];
if (text) h.title = text;
});
}
const rows = [...t.querySelectorAll('tbody tr')].map((r, i) => {
if (r.dataset.sfIndex === undefined) r.dataset.sfIndex = String(i);
const cells = r.querySelectorAll('td');
const fv = {};
Object.keys(facetIdx).forEach(h => {
fv[h] = cells[facetIdx[h]] ? cells[facetIdx[h]].textContent.trim() : '';
});
return {
el: r,
text: [...cells].map(c => c.textContent).join(' ').toLowerCase(),
facets: fv,
anchors: [...r.querySelectorAll('a[href^="#"]')].map(a => a.getAttribute('href').slice(1)),
ids: [...r.querySelectorAll('[id]')].map(n => n.id)
};
});
tables.push({
el: t,
box: t.closest('[data-table-wrapper]') || t,
rows,
heads
});
});
el = el.nextElementSibling;
}
tablesRef.current = tables;
if (sortRef.current) sortTables(sortRef.current);
return tables;
};
const apply = query => {
let tables = tablesRef.current || scan();
if (tables.some(t => !t.el.isConnected)) tables = scan();
const needle = query.trim().toLowerCase();
const sel = selRef.current;
const activeFacets = Object.keys(sel).filter(h => sel[h] && sel[h] !== 'All');
const show = (el, on) => {
const want = on ? '' : 'none';
if (el.style.display !== want) el.style.display = want;
};
let total = 0;
let shown = 0;
const visibleTargets = new Set();
tables.forEach(t => {
let tableVisible = 0;
t.rows.forEach(row => {
total += 1;
const catOk = activeFacets.every(h => {
const v = row.facets[h];
return v === sel[h] || v === '' || v === undefined;
});
const match = catOk && (needle === '' || row.text.includes(needle));
show(row.el, match);
if (match) {
tableVisible += 1;
row.anchors.forEach(a => visibleTargets.add(a));
}
});
show(t.box, !(t.rows.length > 0 && tableVisible === 0));
shown += tableVisible;
});
if (shown < total && visibleTargets.size > 0) {
tables.forEach(t => {
t.rows.forEach(row => {
if (row.el.style.display === 'none' && row.ids.some(id => visibleTargets.has(id))) {
show(row.el, true);
show(t.box, true);
shown += 1;
}
});
});
}
setCounts({
shown,
total
});
return total;
};
const deriveFacets = tables => {
const seen = {};
tables.forEach(t => t.rows.forEach(r => {
Object.keys(r.facets).forEach(h => {
if (!seen[h]) seen[h] = [];
if (r.facets[h] && seen[h].indexOf(r.facets[h]) === -1) seen[h].push(r.facets[h]);
});
}));
const list = facetNames.filter(h => seen[h] && seen[h].length > 0).map(h => ({
name: h,
label: cap(h),
values: seen[h].sort(cmpValues(h))
}));
setFacetList(list);
const first = tables[0] ? tables[0].heads[0] : '';
setFirstHead(first);
if (!sortRef.current && first) {
setSortBy(first);
sortTables(first);
}
const init = {};
list.forEach(f => {
init[f.name] = selRef.current[f.name] || 'All';
});
setSel(init);
};
const onChange = value => {
setQ(value);
apply(value);
};
const clearAll = () => {
const next = {};
Object.keys(selRef.current).forEach(k => {
next[k] = 'All';
});
setSel(next);
setQ('');
apply('');
if (searchRef.current) searchRef.current.focus();
};
useEffect(() => {
const tables = scan();
deriveFacets(tables);
const total = apply('');
let retryTimer;
if (total === 0) {
retryTimer = setTimeout(() => {
tablesRef.current = null;
if (apply(qRef.current) > 0) deriveFacets(tablesRef.current); else setDisabled(true);
}, 500);
}
const onKey = e => {
if (e.key === 'Escape' && menuOpenRef.current !== null) closeMenu(menuOpenRef.current);
if (!searchRef.current) return;
if (e.metaKey || e.ctrlKey || e.altKey) return;
const active = document.activeElement;
const tag = active && active.tagName;
const editable = active && active.isContentEditable;
const interactive = tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || tag === 'BUTTON' || tag === 'A' || editable || active && active.getAttribute && active.getAttribute('role');
if (e.key === '/' && !interactive) {
const r = rootRef.current ? rootRef.current.getBoundingClientRect() : null;
if (r && r.bottom > 0 && r.top < (window.innerHeight || 0)) {
e.preventDefault();
setMenu(null);
searchRef.current.focus();
}
}
if (e.key === 'Escape' && menuOpenRef.current === null && active === searchRef.current) {
onChange('');
searchRef.current.blur();
}
};
const onDocClick = e => {
const open = menuOpenRef.current;
if (open !== null && menuRef.current[open] && !menuRef.current[open].contains(e.target)) setMenu(null);
};
Cut at 300 lines. The page has the rest.