.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
_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.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:
managed-settings.jsonmust be a regular file (not a symlink), owned by root, and not group- or world-writable./etc/claude-desktopitself must be a directory (not a symlink), owned by root, and not group- or world-writable.
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
inferenceCustomHeaders details
inferenceCustomHeaders details
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).inferenceCredentialHelper details
inferenceCredentialHelper details
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)
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.inferenceProvider details
inferenceProvider details
Anthropic
Bedrock
inferenceBedrockServiceTier details
inferenceBedrockServiceTier details
Foundry
inferenceFoundryAuthFlow details
inferenceFoundryAuthFlow details
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 includehttp://127.0.0.1/callbackunder 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 URIsms-appx-web://Microsoft.AAD.BrokerPlugin/{client-id}(Windows) andmsauth.com.anthropic.claudefordesktop://auth(macOS) under the Mobile and desktop applications platform. Not supported on Linux.
broker as unset and use device code.Gateway
inferenceGatewayOidc details
inferenceGatewayOidc details
<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: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
modelDiscoveryEnabled details
modelDiscoveryEnabled details
inferenceModels details
inferenceModels details
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: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: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: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
inferenceVertexWorkforceOidc details
inferenceVertexWorkforceOidc details
Workspace restrictions
Authentication
Chat surface
chatAdvancedFileAnalysisEnabled details
chatAdvancedFileAnalysisEnabled details
Code surface
Cowork surface
Workspace
builtinToolPolicy details
builtinToolPolicy details
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.autoModeEnabled details
autoModeEnabled details
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.toolSearchEnabled details
toolSearchEnabled details
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.allowedWorkspaceFolders details
allowedWorkspaceFolders details
~ 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.coworkEgressAllowedHosts details
coworkEgressAllowedHosts details
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
isDesktopExtensionEnabled details
isDesktopExtensionEnabled details
MCP
managedMcpServers details
managedMcpServers details
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.mcpPersistentAlwaysAllowEnabled details
mcpPersistentAlwaysAllowEnabled details
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
deploymentOrganizationUuid details
deploymentOrganizationUuid details
disableEssentialTelemetry details
disableEssentialTelemetry details
disableNonessentialTelemetry details
disableNonessentialTelemetry details
claude.ai. Already listed under Egress Requirements → Nonessential telemetry.Auto update
OTLP
otlpResourceAttributes details
otlpResourceAttributes details
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.otlpContentCapture details
otlpContentCapture details
userPrompts— user-typed prompt textassistantResponses— assistant message texttoolDetails— tool input arguments, e.g. the web-search query stringtoolContent— tool output content, e.g. fetched page text or command stdoutrawApiBodies— full inference API request and response bodies
OTEL_LOG_* env vars; see the Claude Code monitoring docs.otlpTracesEnabled details
otlpTracesEnabled details
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
inferenceMaxTokensPerWindow details
inferenceMaxTokensPerWindow details
inferenceTokenWindowHours to also be set — without a window length the cap is inert and no limit is enforced.inferenceTokenWindowHours details
inferenceTokenWindowHours details
inferenceMaxTokensPerWindow is set — the cap only takes effect once both are configured.Appearance
deploymentDisplayName details
deploymentDisplayName details
deploymentDisplaySubtitle details
deploymentDisplaySubtitle details
enduserAttribution details
enduserAttribution details
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
disableFeatureDiscovery details
disableFeatureDiscovery details
disableAutoUpdates and autoUpdaterEnforcementHours.Plugins & skills
orgPluginSettings details
orgPluginSettings details
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:toolPolicy (if any) applies; the entry here for that name is ignored.allowedPluginMarketplaces details
allowedPluginMarketplaces details
Source
claudeAiImport details
claudeAiImport details
Bootstrap
bootstrapOidc details
bootstrapOidc details
bootstrapOidc.clientId. Writing the sub-fields as separate registry values causes the app to silently fall through to device-code mode.Guides
Recommended security profiles
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.- Standard
- Restricted
- Locked down
Tool permissions for managed MCP servers
EachmanagedMcpServers 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.
"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.