Skip to main content
Most settings on this page are easier to configure in the in-app configuration window. Use this reference when you’re scripting an MDM policy or bootstrap response by hand.
Claude Desktop on third-party (3P) is configured entirely through OS-native managed preferences: a .mobileconfig profile on macOS, registry policy on Windows, or a root-owned JSON file on Linux. This page documents every supported key. For the desktop release each key first appeared in, see the configuration changelog. The easiest way to author a configuration is the in-app configuration window (Developer → Configure Third-Party Inference…), which validates values, shows per-provider requirements, and exports directly to .mobileconfig or .reg. Use this reference when you need to author policy by hand, audit an existing profile, or understand exactly what a key does.

How keys are read

The local location is a directory: _meta.json records which saved configuration is applied, and each configuration is a <id>.json file alongside it. The in-app configuration window writes here. When a managed source is present, it wins and locally written values are ignored. The exception is a managed source that sets only the update keys (disableAutoUpdates and autoUpdaterEnforcementHours): those two keys are enforced from the managed source, but the rest of the configuration stays local and user-editable. Configuration is read once at launch, so fully quit and reopen the app after any change. On Windows, the two policy hives are not merged: when machine policy is present under HKLM\SOFTWARE\Policies\Claude, the app ignores HKCU\SOFTWARE\Policies\Claude entirely; Deploy the configuration has the exact rule. See Deploy with MDM for the full precedence rules.

Value types

Write every value as a string in the OS preference store, even booleans and arrays.
The most common configuration mistake is writing array- or object-typed keys as native plist/registry structures. Keys like inferenceModels, inferenceGatewayOidc, managedMcpServers, coworkEgressAllowedHosts, and otlpHeaders must be JSON strings. In a .mobileconfig, that means a single <string> element containing [...] or {...} — not an <array>, not a <dict>, and not separate keys with dotted names like inferenceGatewayOidc.clientId.
On Windows, write registry values as REG_SZ, directly under the policy key rather than nested in a subkey (the app never reads subkeys). REG_DWORD is also accepted for boolean and integer keys and is read as its decimal value. Avoid REG_EXPAND_SZ: the app counts it toward machine policy being present but cannot read its contents. The app cannot see REG_QWORD, REG_MULTI_SZ, or REG_BINARY values at all.

Linux

The managed source on Linux is a single JSON file, /etc/claude-desktop/managed-settings.json, with keys at the top level exactly as named in the reference — no wrapper object, no nesting:
Because the file is real JSON, array- and object-typed keys use native JSON values — the string-encoding rule above applies to plist and registry sources only. (String-encoded values are also accepted, so a profile generated for another platform can be reused.) The file is only honored when it can’t be edited by the user it configures:
  • managed-settings.json must be a regular file (not a symlink), owned by root, and not group- or world-writable.
  • /etc/claude-desktop itself must be a directory (not a symlink), owned by root, and not group- or world-writable.
A file that fails these checks is rejected: none of its settings are applied, the app treats the device as managed but unreadable, and local settings are also disabled until the file is fixed and the app is relaunched. The reason is logged to main.log in the app’s logs directory — ~/.config/Claude/logs/ (or ~/.config/Claude-3p/logs/ once the app is running in 3P mode); search for managed-settings.json. The same log names any key that fails schema validation. There is no per-user managed location on Linux; per-user configuration goes through the in-app configuration window, which writes to the local configLibrary directory above.

Reference

The reference below is generated from the configuration schema and grouped to match the sidebar of the in-app configuration window. The Availability column shows whether a key can be set in an MDM profile, returned from a bootstrap server, or both.

Connection

Sent on every inference and model-discovery request (joined into the CLI’s ANTHROPIC_CUSTOM_HEADERS).Use this for fleet-wide constants. For per-user or per-session values, have the credential helper script emit JSON with a headers field; those are merged over these static entries (helper wins on conflict).
Claude runs the executable with no arguments and reads stdout (trimmed). Exit code must be 0; any output on stderr is logged but ignored. Stdout must contain only one of the formats below (no banners, prompts, or log lines).Output format is either:
  • a single bare token (the API key / bearer token), or
  • a JSON object {"token": "...", "headers": {"Name": "Value", ...}} when per-request headers are needed (merged over Custom inference headers, helper wins on conflict)
Result is cached for the TTL below. On TTL expiry the helper is re-invoked transparently (no user prompt, no relaunch).Expiry and refresh: the app checks the active credential’s expiry before each turn and refreshes silently when possible (re-runs the helper, or uses the stored refresh token for interactive sign-in kinds). If the provider returns HTTP 401 mid-turn, the same silent refresh is attempted before surfacing an error. When silent refresh fails, a prompt appears with a provider-specific action (re-sign-in for interactive kinds; admin-contact for static credentials). Applies to all providers and both tabs.Typical use: a shell script that pulls from Keychain, 1Password CLI, or an internal secret broker. Example:security find-generic-password -s anthropic-api -wIf this field is set, static credential fields (API key, bearer token) are ignored. The helper always wins.
The app activates 3P mode only when this is set and the required credential keys for the selected provider are present and valid; otherwise it launches in standard mode. Keys for providers other than the selected one are ignored. Each provider’s required keys are documented on its dedicated page under Inference providers.

Anthropic

Bedrock

Tier availability varies by model and region. Reserved capacity uses a provisioned-throughput ARN as the model ID instead of this setting. Older bundled Claude Code CLI versions ignore this key.

Foundry

  • device-code (default) — shows a code to enter at microsoft.com/devicelogin. The app registration must have Allow public client flows enabled.
  • browser — opens the system browser for an authorization-code (PKCE) sign-in on a loopback redirect URI. The app registration must include http://127.0.0.1/callback under the Mobile and desktop applications platform (Entra ignores the loopback port, but not the path). Works with Allow public client flows disabled, and is unaffected by Conditional Access policies that block device-code authentication.
  • broker — signs in through the OS identity broker (Web Account Manager on Windows, Company Portal on macOS), so it can satisfy Conditional Access policies that require a compliant/managed device or token protection. The app registration must include the broker redirect URIs ms-appx-web://Microsoft.AAD.BrokerPlugin/{client-id} (Windows) and msauth.com.anthropic.claudefordesktop://auth (macOS) under the Mobile and desktop applications platform. Not supported on Linux.
App versions that predate this key always use device code; versions that predate the broker option treat broker as unset and use device code.

Gateway

External IdP mode. The app discovers <issuer>/.well-known/openid-configuration, runs an OIDC authorization-code-with-PKCE flow in the system browser with clientId, and sends the resulting token as Authorization: Bearer on every inference request — see Bearer token type below for how the gateway validates it.Bearer token type. id_token (the default) sends the OIDC ID token — the gateway validates signature + iss + aud, where aud is the clientId configured here. access_token sends the OAuth access token — the gateway validates as an OAuth resource server against the audience/scope the IdP issued the token for; set scopes to the gateway’s registered API scope (required in this mode). Use access_token for gateways that expect a resource-server token (Portkey, Kong, Envoy JWT filter, AWS API Gateway authorizers).The gateway MUST validate iss AND aud, not just the signature. Signature + issuer alone accepts any token from the same tenant, including tokens issued to unrelated apps. In id_token mode the audience is the clientId:
IdP setup. The app’s loopback callback binds http://127.0.0.1:<port>/callback (RFC 8252 §7.3). Register 127.0.0.1; most IdPs do not treat localhost and 127.0.0.1 as interchangeable. Entra: register a public-client app, add a Mobile and desktop applications redirect URI of http://127.0.0.1/callback. (Microsoft’s docs say the path is wildcarded for loopback; in practice it is not: http://127.0.0.1 without /callback fails with AADSTS50011. The port IS wildcarded.) Grant openid profile email offline_access (delegated, no admin consent); in access_token mode also add the gateway API’s delegated permission under API permissions (and ensure the gateway’s own app registration exposes that scope via Expose an API) — without it Entra rejects the sign-in with AADSTS65001. Okta: register a Native app with the exact redirect URI http://127.0.0.1:<port>/callback and set redirectPort here to that port (Okta requires an exact match).Refresh: offline_access returns a refresh token; the app refreshes the bearer silently before expiry. When refresh fails (revoked, idle past the IdP’s window), the user re-authenticates in the browser. Google Workspace caveat (id_token mode only): Google never returns id_token on a refresh-token grant, so a Google-backed gateway in id_token mode will prompt a browser sign-in roughly once per ID-token TTL (~1h). Entra and Okta return a fresh id_token and are unaffected; access_token mode is unaffected on all IdPs.Leave this unset for a gateway that hosts its own RFC 8414 metadata at <baseUrl>/.well-known/oauth-authorization-server (the original gateway-as-AS path).

Models

Auto-populate the model picker from the provider’s model-list endpoint at launch. For gateway and Anthropic providers, a config that doesn’t set this key skips discovery automatically when the model list below already makes it unnecessary; the toggle here only sets it explicitly on or off. Turn off if the endpoint isn’t reachable from your network, or to use a fixed list. When off, the model list below is required and must use full model IDs (aliases like sonnet/opus are resolved via discovery).
Use the provider’s exact model ID: Vertex publisher IDs (claude-sonnet-5), Bedrock inference-profile IDs (us.anthropic.claude-sonnet-5), or Foundry deployment names. The first entry is the default. Entries may be plain ID strings or objects.Gateway: the name must be the exact ID your gateway’s /v1/models endpoint returns. If you set supports1m on an alias (sonnet) but discovery returns the full ID, the variant won’t appear.Extended context (supports1m) is a capability assertion you make about your deployment; only set it for models you’ve confirmed support the 1M-token window:
Default to 1M context (prefer1m) makes the 1M-context variant the default picker selection when this entry is the default model (the first entry); users can still switch to the standard variant, and an explicit user pick is always kept. No effect without supports1m:
Display label (labelOverride) is for IDs the picker can’t derive a friendly name from (Bedrock ARNs, gateway routing aliases). Display-only; name is still what the app sends:
Tier mapping (anthropicFamilyTier) tells the app which Claude tier (haiku/sonnet/opus/fable/mythos) an entry stands in for, so bare tier aliases (e.g. in the Code tab) resolve to your model. isFamilyDefault: true picks the winner when several entries share a tier:

Vertex

Workspace restrictions

Authentication

Chat surface

Also enables inline data analysis. The sandbox can only read files attached to the conversation and has no network access.

Code surface

Cowork surface

Workspace

ask-session applies to connector tool policies only — written here it is treated as ask. To remove a tool entirely, use Disabled built-in tools instead.
When enabled, users can select Auto mode (Code tab) / Act without asking (Cowork tab). Claude runs a safety classifier on each action and only prompts for approval on actions it judges risky, instead of following the static per-tool policy.Requires a model that supports the safety classifier — which models qualify depends on the deployment’s provider and the app version. Models without support show the option greyed out. builtinToolPolicy and this key may both be set; Auto mode is a user-selectable option alongside the default policy, not a replacement for it.In the Code tab, a separately deployed Claude Code managed-settings file that sets disableAutoMode to "disable" overrides this key and keeps Auto mode hidden.
When enabled, Cowork and Code sessions load MCP tool schemas on demand (“tool search”): only tool names are placed in context up front, and Claude fetches a tool’s full schema the first time it needs it. Use this when many MCP tools are configured and their inlined schemas crowd out the context window (sessions that compact every turn or two). Equivalent to running terminal Claude Code with ENABLE_TOOL_SEARCH=true against the same endpoint.Enabling this key causes sessions to send experimental anthropic-beta request headers, and the beta request fields that ride with them, to your inference endpoint — tool search (advanced-tool-use, with tool_reference content blocks and deferred tool loading) and context management (a context_management request field on supported models) among them. Enable it only if your gateway forwards and accepts these; when it does not, requests fail with HTTP 400 on the beta header or fields. A practical preflight: run terminal Claude Code through the same gateway with ENABLE_TOOL_SEARCH=true — Claude Desktop then sends the same request surface, so if the terminal works, Desktop will too. Do not enable this on Vertex-provider deployments — Vertex rejects the tool-search beta header, and this key overrides the protection Claude Code applies to Vertex by default, turning working (inlined) MCP tools into failing requests.Claude Desktop otherwise suppresses all of Claude Code’s experimental beta features on 3P deployments (it pins CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 into session environments, because strict gateways reject unrecognized beta headers and fields). Enabling this key lifts that suppression, so other experimental betas — for example, on gateway- and Foundry-backed deployments, context_management request fields on models that support them — are re-enabled as well. This matches the request surface terminal Claude Code presents through the same gateway by default. Leave unset to keep the conservative default.
Paths can reference ~ and these environment variables, expanded per user: %OneDrive%, %OneDriveCommercial%, %OneDriveConsumer%, %APPDATA%, %LOCALAPPDATA%, %USERNAME%, %XDG_DOCUMENTS_DIR%. The set is fixed; an entry that references any other %VAR%, or one that is unset on the device, is ignored.Each folder is interpreted on the machine the session runs on. For a Code session on an SSH host, ~ means the remote user’s home, an entry that references a %VAR% is ignored there (environment variables belong to the machine that defines them), and the session’s working directory must fall inside one of the folders as they exist on that host. One list serves every machine: ["/Users", "~"] governs /Users on a managed Mac and the signed-in user’s home on a Linux host. A folder that names nothing real on a given machine simply allows nothing there.
Applies to both the Cowork and Code tabs. In the Cowork tab it governs the sandbox’s web fetch, shell commands, and package installs. In the Code tab it is translated into Claude Code’s network sandbox allowlist; a separately deployed Claude Code managed-settings file on the endpoint takes precedence by default.Does not apply to Web Search, which runs server-side at your inference provider rather than from the sandbox.Only affects tool calls. Inference and MCP traffic are covered by their own allowlists elsewhere. When unset, only the inference endpoint is reachable from the sandbox; the agent’s package installs (pip/npm) and web fetches will fail with a 403.Accepts exact hostnames (api.github.com), wildcards (*.corp.com matches one subdomain level), and * to allow all. *.corp.com matches docs.corp.com but not corp.com itself; add both if you need the apex. IP literals and localhost always resolve regardless of this list; this is a public-egress filter, not a sandbox.Hosts you add here also need to be open on your network firewall. See Egress Requirements for the full allowlist.

Connectors & extensions

Authentication

Extensions

1P builds default to enabled at runtime unless this is explicitly set. In 3P, enabling this allows loading extensions; local install additionally requires an org policy backend.

MCP

For OAuth-authenticated entries, the app builds the redirect URI as http://<callbackHost>:<callbackPort>/callback; register that exact value with the OAuth provider. Tokens refresh automatically during a session, so users aren’t interrupted when the initial access token expires.toolPolicy locks the per-tool approval state, keyed by tool name. Keys may contain * wildcards ("read_*" matches every tool whose name starts with read_; matching is anchored and * is the only wildcard, identical to Claude Code permission-rule globs). An exact-name key wins over matching wildcard keys, with two exceptions in the stricter direction: in the Code tab, forwarded blocked/ask wildcard rules take precedence over a less strict exact key, and in chat approval flows and always-allow persistence a wildcard ask key keeps every matching tool behind a per-call prompt (no persistent always-allow), and a wildcard ask-session key likewise keeps every matching tool on the ask-session clamp, even when a more permissive exact-name key matches — for direct (imperative) tool invocations such as artifact or widget tool calls, the exact-name key still decides. When several wildcard keys match a tool, the strictest applies (blocked > ask > ask-session > allow). "blocked" removes the tool from the session and labels it admin-blocked. "ask" requires approval on every call (Allow once / Deny only; no persistent always-allow). "ask-session" requires approval on the tool’s first use per session; a session-scoped Allow for this task covers the rest of that session, a new session re-prompts, and persistent always-allow stays unavailable. Scheduled tasks do not honor ask-session grants: every run prompts and blocks until attended, exactly as ask (use allow for tools that must run unattended). "allow" pre-approves. Tools not listed follow the user’s choice: the prompt offers a persistent Always allow, except for tools that can modify data, which instead show a session-scoped Allow for this task alongside Allow for all tasks with a malicious-instruction warning. In the Code tab, blocked/ask/ask-session are forwarded as Claude Code permission rules (ask-session as an ask rule, with the once-per-session behavior applied by the desktop); allow is not.For the bundled Microsoft 365 connector, the send tools (outlook_send_mail, outlook_send_draft, outlook_forward_mail, outlook_create_event, outlook_update_event, teams_send_chat_message, teams_send_channel_message, teams_reply_channel_message) cannot be loosened below ask — an allow setting resolves to ask.
When enabled (the default), approval prompts for tools without a toolPolicy entry offer a persistent grant — Always allow, or Allow for all tasks for tools that can modify data — the Tool permissions picker in Connector settings lets users pre-approve tools, and those grants persist across sessions with no expiry.When disabled, the persistent options are hidden from approval prompts and from the Connector settings picker, previously stored persistent grants stop being honored, and scheduled-task runs no longer record or replay cross-run tool approvals. Session-scoped approvals are unchanged: users can still approve each call, and tools that can modify data keep the session-scoped Allow for this task option.A per-tool toolPolicy entry on managedMcpServers always takes precedence over this key: blocked, ask, ask-session, and allow behave exactly as documented there whether this key is enabled or not.This key governs the chat and Cowork surfaces. The Code tab uses a separate permission path this key does not cover — govern Code tab tool approvals with per-tool toolPolicy entries, whose blocked and ask values are forwarded there.

Telemetry & updates

If unset, a shared placeholder UUID is used: telemetry can’t be distinguished from other unconfigured deployments, and local data is stored under the placeholder. Changing this value orphans data stored under the previous value (sessions, skills, plugins).
“Essential” means the signals Anthropic needs to keep your deployment working: crash stacks, startup failure reasons, and version/OS metadata. No prompts, completions, file contents, or identifiers beyond a random install ID.What you lose when this is on: when a Cowork build hits a bug that only reproduces on your OS version or locale, Anthropic can’t see it unless a user manually reports. Fixes ship slower.Why this is discouraged, not blocked: some air-gapped environments require zero outbound telemetry as a matter of policy. The switch exists for them. If you don’t have that constraint, leave it off.
“Nonessential” covers two things: product-usage analytics (which features get used, navigation patterns; no prompts or completions) and the Send action in Help → Generate Diagnostic Report. Turning this on stops both.Destination for both: claude.ai. Already listed under Egress Requirements → Nonessential telemetry.

Auto update

OTLP

Extra resource attributes to attach to every span, metric, and log sent to your collector. When End-user attribution is on and no enduser.id is set here, the desktop fills it with the signed-in user’s runtime identity; a value you set here always wins. process.owner (the OS login name) is always emitted; set it here to override.
Each category enables a class of raw content in OpenTelemetry events sent to your collector (this data never reaches Anthropic):
  • userPrompts — user-typed prompt text
  • assistantResponses — assistant message text
  • toolDetails — tool input arguments, e.g. the web-search query string
  • toolContent — tool output content, e.g. fetched page text or command stdout
  • rawApiBodies — full inference API request and response bodies
These mirror Claude Code’s OTEL_LOG_* env vars; see the Claude Code monitoring docs.
Enables Claude Code’s session-tracing beta (CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 + OTEL_TRACES_EXPORTER=otlp) in spawned Cowork tasks and Code sessions. Each user interaction exports a trace whose spans and events carry trace_id/span_id, enabling end-to-end correlation in your observability backend (metrics do not carry trace context; correlate those via session.id). Traces go to the collector endpoint and protocol configured above. While the Claude Code feature is in beta the span structure may evolve; see the Claude Code monitoring docs.

Usage limits

Token limits

Requires inferenceTokenWindowHours to also be set — without a window length the cap is inert and no limit is enforced.
Required when inferenceMaxTokensPerWindow is set — the cap only takes effect once both are configured.

Appearance

Set this to the name users should see for this deployment (for example, “Claude for Government”). When unset, the desktop shows the default provider label. Bootstrap-delivered only; maximum 60 characters.
Optional detail shown after the deployment display name in the account-menu header (for example, “Claude for Veterans Affairs · Claude for Government”). Shown only when the display name is also set. Bootstrap-delivered only; maximum 60 characters.
When on (default), the app resolves the signed-in user’s identity from the configured credential source (the identity provider claim, or the OS login name when no claim is available) and shows it in the sidebar footer, the account menu, and the Code-tab greeting. If an OpenTelemetry collector is configured, the same identity is also emitted as the enduser.id resource attribute on every span, metric, and log sent to your collector — unless you have set a static enduser.id under OpenTelemetry resource attributes, in which case your static value is kept and the runtime identity is not emitted. When off, no identity is shown in the app and no runtime enduser.id is emitted; a static enduser.id under OpenTelemetry resource attributes still passes through unchanged. This setting does not gate the process.owner resource attribute (the OS login name), which is standard OpenTelemetry process metadata and is always emitted — set a static process.owner under OpenTelemetry resource attributes to override it. Applies to both Cowork tasks and Code sessions.

Feature discovery

Covers the version-shipped announcement UI baked into each release: the What’s new button that appears on its own after an update, and the one-time New feature tips (coach-marks) that point out newly shipped capabilities. Useful when your organization gates feature availability and doesn’t want the app advertising capabilities you haven’t rolled out.User-initiated surfaces stay: the What’s-new menu item and header button still open the release notes on demand. Auto-update behavior is unaffected — that is governed by disableAutoUpdates and autoUpdaterEnforcementHours.

Plugins & skills

Applies toolPolicy locks to MCP servers that arrive via the org-plugins directory, keyed by server name. Either shape is accepted; when hand-authoring a profile, use the legacy record shape until your fleet floor parses the canonical array form:
If a Managed MCP servers entry and an org-plugin server share a name, the Managed MCP servers entry wins and its toolPolicy (if any) applies; the entry here for that name is ignored.

Source

Bootstrap

Set this to use a separate identity provider (Microsoft Entra ID, Okta, Ping, or any compliant OIDC provider) for the bootstrap sign-in. The app runs an authorization-code-with-PKCE flow in the system browser. Omit to use device-code mode against the bootstrap server’s own origin.This is an object-typed key — in an MDM profile it is a single JSON-string value, not separate keys with dotted names like bootstrapOidc.clientId. Writing the sub-fields as separate registry values causes the app to silently fall through to device-code mode.

Guides

The profiles below are illustrative examples rather than built-in presets, and the labels are descriptive only. Use them as starting points and adjust for your environment. Layer the inference-provider keys for your cloud on top of whichever profile you choose.
Recommended for most enterprise deployments. Telemetry and auto-updates stay on so Anthropic can diagnose issues and ship fixes; users can extend Claude Desktop with their own connectors.

Tool permissions for managed MCP servers

Each managedMcpServers entry can carry a toolPolicy that locks the approval state per tool:
  • "allow" — the tool runs without prompting.
  • "ask" — the user approves every call; no standing grants are offered.
  • "blocked" — the tool is removed from Claude’s session; connector settings show it as blocked by your organization.
Tools with no policy entry stay user-controlled (built-in connectors apply default policies to some tools — see the reference above): the user is prompted and can approve once or grant a standing approval, depending on the tool and your organization’s settings. Full prompt options require version 1.22209.0 or later; earlier third-party builds offered only per-call approval. The reference above also documents an "ask-session" value; its once-per-session behavior is not yet functional in shipped builds, so don’t rely on it yet. Managed policies take precedence over user grants, and enforcement happens in the desktop host process, not only in the prompt UI. A deny-by-default posture — "*": "blocked" plus exact "allow" entries for approved tools — works from an upcoming release, which also supersedes the Code-tab wildcard-precedence note in the reference above. See the managedMcpServers reference for wildcard matching, precedence rules, and built-in connector defaults.