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 through OS-native managed preferences: a .mobileconfig profile on macOS, registry policy on Windows, or a root-owned JSON file on Linux (organizations in the admin console beta can instead deliver these settings from Organization settings on claude.ai). 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 app-behavior keys (the update keys disableAutoUpdates, autoUpdaterEnforcementHours, and updateViaUpdatesHost, the lifecycle keys relaunchEnforcementHours and configRecheckIntervalMinutes, or the network proxy keys): those keys are enforced from the managed source, but the rest of the configuration stays local and user-editable. Configuration takes effect at launch, so fully quit and reopen the app after any change. From version 1.46388.1 a running app also notices a changed managed configuration at its next re-check (configRecheckIntervalMinutes, 10 minutes by default), prompts the user to restart, and requires the restart after relaunchEnforcementHours (24 hours by default). 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.
Claude Desktop on 3P reads the same managed-configuration sources as standard Claude Desktop but ignores keys scoped to standard deployments. Keys such as forceLoginOrgUUID have no effect in a 3P deployment.

Value types

Write every value as a string in the OS preference store, even booleans and arrays.
Array- and object-typed keys such as inferenceModels, inferenceGatewayOidc, managedMcpServers, coworkEgressAllowedHosts, and otlpHeaders are single keys whose value is a whole JSON document. The portable encoding is a JSON string, which works on every platform. In a .mobileconfig that is a single <string> element containing [...] or {...}, and on Windows a REG_SZ value. A macOS profile may instead carry the value as a native <array> or <dict>, which the app reads as the equivalent JSON. Separate keys with dotted names, such as inferenceGatewayOidc.clientId, are never read.
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, non-secret constants. Do not put API keys, bearer tokens or other credentials here — this map is stored and distributed as plain configuration. For tokens, and 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)
The helper receives CLAUDE_HELPER_CONTEXT in its environment (interactive, mid-session-refresh, background, scheduled-task, setup-test) so it can decide whether to prompt the user — see the credential-helper docs for the full contract.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 to both Cowork and Code.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.
Pins the app (sign-in, the connection test, model discovery, MCP servers, plugins), the Claude Code engine behind Chat, Cowork, and Code, and on macOS and Windows the Cowork workspace VM (the agent’s shell, package-install, git, and plugin commands, and the whole engine under requireCoworkFullVmSandbox) to one HTTP proxy. Use it when your gateway or the internet is reachable only through a corporate proxy and you cannot rely on the system proxy. It is a reachability setting, not an egress control.The value is an http:// or https:// URL, usually with a port. SOCKS proxies and embedded credentials (user:pass@) are rejected. Give a local forwarding proxy on the device as http://127.0.0.1:port; an https:// loopback address cannot be verified from inside the Cowork workspace VM. Requests to localhost, 127.0.0.1, [::1], and *.local names bypass the proxy so local MCP servers keep working; everything else goes through it, and if the proxy is unreachable requests fail rather than connect directly. The engine receives it as HTTPS_PROXY and HTTP_PROXY with a matching NO_PROXY; if Claude Code managed settings on the device set those variables, they win for the engine on the host. Traffic that never uses this proxy: the Cowork workspace VM on Linux, credential and header helper scripts, the update download, the Windows sign-in broker, and pages opened in the system browser.Read once at launch from device management (MDM) or the local configuration file only; a configuration server cannot deliver it, because the app may need the proxy to reach that server. A profile that sets only this key (or only the other app-behavior keys, such as disableAutoUpdates) does not take over a connection users set up in the app, but those keys are read from one source as a group, so put the proxy in the same profile as your update settings. Changes apply at the next app start. When egressProxyPacUrl is also set, the PAC file wins and this key is ignored.
At launch the app downloads the PAC script and asks it which proxy to use for each request, as a browser would, instead of following the operating system’s proxy settings. Same value rules, coverage, exclusions, and delivery as egressProxyUrl, except that bypassing is the script’s decision: localhost, 127.0.0.1, and [::1] still never use a proxy, but *.local names and everything else follow whatever it returns. If the PAC file cannot be downloaded, the app connects directly rather than failing.On macOS and Windows the Cowork workspace VM is handed a copy of the script when it starts and evaluates it for each request itself; there myIpAddress() returns the VM’s internal address rather than the device’s, so a script that chooses by client subnet gives the VM its off-network answer (if that download fails, the VM connects directly). The Claude Code engine behind Chat, Cowork, and Code cannot evaluate a PAC file, so the app hands it one proxy (whichever the script returns for your inference endpoint) plus a bypass for loopback and *.local names. If the script answers DIRECT or only SOCKS for that endpoint, the engine uses no proxy at all, so have it return an HTTP PROXY host:port entry there; if the engine needs different rules, set HTTPS_PROXY and NO_PROXY in Claude Code managed settings, which win for the engine on the host.
When set to true, the Cowork workspace VM on macOS and Windows gets a static IPv6 address (a unique local fd… address) and an IPv6 default route on its virtual network next to its IPv4 address, and the VM’s gateway forwards that traffic over the device’s own IPv6 connectivity, as it already does for IPv4. Use it when the tools the agent runs in the VM (shell commands, package installs, git, plugin commands, and the whole engine under requireCoworkFullVmSandbox) must reach IPv6-only destinations. The VM’s resolver then also returns IPv6 (AAAA) answers. A connection the VM makes over IPv6 succeeds only where the device’s own IPv6 does; on a device without working IPv6, destinations that have both keep working over IPv4 and IPv6-only destinations stay unreachable. Because the VM’s address is unique-local, most tools in it keep preferring IPv4 for destinations that have both, so IPv6 mostly carries traffic to IPv6-only destinations.This is a reachability setting, not an egress control: coworkEgressAllowedHosts keeps deciding which hostnames the agent’s tools may reach, by name, over either protocol, and IPv6 literals are still not accepted there. Hosts your policies allow must also be reachable, and filtered the way you intend, over IPv6 on your network.Unset (default): the VM is IPv4-only and its resolver returns no IPv6 answers. A change takes effect the next time the workspace VM starts, typically at the next app launch. Does not apply to the Cowork workspace VM on Linux or to Code sessions, which use the device’s own network stack.
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

Raises how long Cowork, Chat and Code sessions wait for the next model event on an open streaming response (Claude Code’s CLAUDE_STREAM_IDLE_TIMEOUT_MS). It only helps when the gateway writes SSE keep-alive ping events (or : comment lines) into the response while the upstream model is silent — for example a LiteLLM proxy with keep-alive pings enabled in front of Amazon Bedrock. With pings arriving, Claude Code accepts at least about five minutes of keep-alives and then waits this many seconds more for real model output before abandoning the request. Gateway provider only; the other providers keep Claude Code’s defaults.A response on which nothing at all arrives — no pings — still fails after about 5 minutes regardless of this key, because at the device a silent connection cannot be told apart from a dead one. If long generations fail behind a gateway that does not send pings, configure the gateway to send them rather than raising this value. While this key is set, the app’s value takes precedence over CLAUDE_STREAM_IDLE_TIMEOUT_MS in Claude Code’s own managed settings for sessions the app starts; when it is unset, that setting still applies. Values outside 300–1800 are rejected at parse time (the error is listed in the diagnostics report) and the default applies.
  • browser (default) — opens the system browser for an authorization-code (PKCE) sign-in on a loopback redirect URI. See the IdP setup notes on inferenceGatewayOidc for redirect-URI registration.
  • broker — signs in through the OS identity broker (Web Account Manager on Windows, Company Portal on macOS). Requires the IdP to be Microsoft Entra ID — the issuer on inferenceGatewayOidc must be https://login.microsoftonline.com/{tenant-id}/v2.0. The broker satisfies Conditional Access policies that require a compliant/managed device or token protection, and needs no 127.0.0.1/callback loopback redirect. The Entra 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.
Broker mode mints a token in the customer’s own Entra tenant with the customer-configured scopes, and forwards it to the customer’s own gateway; both endpoints of that trust relationship are inside the customer’s control.
External IdP mode. The app discovers <issuer>/.well-known/openid-configuration, runs an OIDC authorization-code-with-PKCE sign-in in the system browser with clientId, and sends the resulting token as Authorization: Bearer on every inference request. Leave this unset for a gateway that hosts its own RFC 8414 metadata at <baseUrl>/.well-known/oauth-authorization-server.Bearer token type. id_token (the default) sends the OIDC ID token; the gateway validates signature, iss, and aud (the clientId configured here). access_token sends the OAuth access token, for gateways that validate as a resource server (Portkey, Kong, Envoy JWT filter, AWS API Gateway authorizers); scopes must then name the gateway’s registered API scope. Either way the gateway must check aud, not just signature and issuer, or it accepts any token from your tenant.IdP setup. The app’s loopback callback is http://127.0.0.1:<port>/callback; register 127.0.0.1 (not localhost) and include /callback. Entra: a public-client app with a Mobile and desktop applications redirect URI of http://127.0.0.1/callback (any port; omitting the path fails with AADSTS50011); in access_token mode also grant the gateway API’s delegated permission, or sign-in fails with AADSTS65001. Okta: a Native app with the exact URI http://127.0.0.1:<port>/callback and that port in redirectPort.Refresh. With offline_access the app renews the token silently and prompts a browser sign-in only when refresh fails. Google never returns an id_token on refresh, so a Google Workspace-backed gateway in id_token mode re-prompts about hourly; access_token mode is unaffected.

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).
When a user has no saved selection, start the picker on the 1M-context variant of the default model (the first listed model, or the first model your endpoint returns under discovery) if it offers one. A saved selection is always kept; users who picked a model before this version need to pick the 1M row once, after which it persists. Equivalent to setting prefer1m on the default entry of inferenceModels, but also applies under dynamic 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. 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:
"claude-sonnet-5[1m]" is shorthand for the same entry. When an ID is listed both bare and with [1m] (as a gateway lists it), the picker shows one model with a 1M variant; put labelOverride on the bare entry (a label on the [1m] spelling is ignored there); tier-tagged entries are not folded. prefer1m: true (no effect without supports1m) makes the 1M variant the default picker selection when this entry is the default model; users can still switch, and an explicit pick is kept. Under dynamic discovery (no explicit list), set modelPrefer1mContext instead.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 Code sessions) resolve to your model. isFamilyDefault: true picks the winner when several entries share a tier:
Off unless set: the Usage page shows token counts only, since the app cannot know your negotiated provider rates. true turns on a USD estimate priced at Anthropic’s published list price and is the only switch that does: inferenceModelPricingMultiplier and inferenceModelPricing refine the estimate while this is on and are ignored otherwise; turning this off hides them in the config editors without clearing them. Claude Code performs the calculation, so the same figures appear in its own cost reporting for Code sessions. Model IDs Claude Code cannot map to a Claude model (an opaque gateway alias, an inference-profile ARN it cannot resolve) are left out of the estimate until inferenceModelPricing gives them a rate. A machine-level Claude Code managed modelPricing (MDM / managed-settings.json / server-managed) takes precedence over all three keys.
Mirrors Claude Code’s managed modelPricing.multiplier: a number in (0, 1] applied to every computed cost, whether the model was priced at Anthropic list price or by an inferenceModelPricing row; use it for a flat contracted discount. Applies only while inferenceModelPricingEnabled is true; on its own it does not turn the estimate on. Ignored when a machine-level Claude Code managed modelPricing is present.
Each row replaces Anthropic list price for one model in the Usage page’s estimate, in USD per million tokens (inputPerMtok, outputPerMtok, cacheReadPerMtok, cacheWritePerMtok, all four required; cacheWritePerMtok prices both 5-minute and 1-hour cache writes); rows apply only while inferenceModelPricingEnabled is true and do not turn the estimate on by themselves. Mirrors Claude Code’s managed modelPricing.overrides, and name is matched the same way: a built-in Claude model ID (e.g. claude-sonnet-4-6, or its Bedrock, Vertex, or Foundry ID) covers every dated and provider spelling of that model; any other value (a gateway alias, an inference-profile ARN) matches that exact ID only (case-insensitive) and wins over a built-in row. An ID Claude Code cannot map to a Claude model at all gets no estimate until a row here prices it. inferenceModelPricingMultiplier still applies on top of a row.
These are estimates for visibility, not an invoice; your provider bills at its own rates. A machine-level Claude Code managed modelPricing (MDM / managed-settings.json / server-managed) takes precedence over this table.

Vertex

  • browser (default) — opens the system browser for an authorization-code (PKCE) sign-in on a loopback redirect URI. See the IdP setup notes on inferenceGatewayOidc for redirect-URI registration; the same rules apply here.
  • broker — signs in through the OS identity broker (Web Account Manager on Windows, Company Portal on macOS). Requires the workforce-pool IdP to be Microsoft Entra ID — the issuer on inferenceVertexWorkforceOidc must be https://login.microsoftonline.com/{tenant-id}/v2.0. The broker satisfies Conditional Access policies that require a compliant/managed device or token protection, and needs no 127.0.0.1/callback loopback redirect. The Entra 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.
The GCP STS token-exchange step is unchanged in either flow; only how the Entra id_token is acquired differs.

Workspace

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

When off, the SSH option is hidden and any connection attempt is refused.Entries are exact hostnames (build01.corp.example.com) or *. wildcards (*.corp.example.com matches the apex and subdomains at any depth); matching is case-insensitive and ignores a user@ prefix. Both the host the user entered and the HostName their ~/.ssh/config resolves it to must match, so an alias cannot reach a host outside the list. ProxyCommand is permitted when the resolved host matches (this key governs which hosts the app offers, not network egress); ProxyJump is refused with a message suggesting ProxyCommand.This is opt-in because a remote session runs Claude Code on the SSH host and the app forwards the session’s inference credential to it, plus your OTLP collector endpoint and auth headers when otlpEndpoint is set. List only hosts you trust with those. Token-based credentials are forwarded; file-based kinds (Bedrock IAM Identity Center sign-in or AWS profile, Vertex Google sign-in or a credentials file) are refused at session start.If this key is unset, an sshHostAllowlist in Claude Code’s own managed-settings file on the device still applies; when both are set, this key wins where the app’s configuration is admin-managed (MDM, the admin console, or a device-managed bootstrap URL) and otherwise applies only while that file sets none. allowedWorkspaceFolders still applies on the remote host.
Pins which OpenSSH client the app runs wherever it starts ssh: evaluating the user’s SSH configuration (ssh -G), making the SSH connection and its channels, and the Code tab’s terminal. ssh-keygen and ssh-add are taken from the same directory when they exist there, otherwise from PATH. The program must be OpenSSH 7.6 or newer (on Windows, Win32-OpenSSH 9.4 or newer to carry the connection); on macOS and Linux a wrapper script that ends in one is accepted, on Windows it must be a native .exe (not a .cmd, .bat or .ps1 script). When this key is set and the program is missing, cannot be run, or is too old, SSH sessions fail with an error telling the user to ask their IT administrator (the configured path is in its details) — the app never falls back to another ssh. The connection itself runs through this program on the system-OpenSSH engine, which the SSH connection engine setting’s system-openssh value selects on every platform, including Windows; when the app’s built-in SSH library makes the connection instead, this key still governs configuration evaluation (ssh -G), host-key lookups (ssh-keygen) and the terminal.
system-openssh: the app makes every SSH connection by running an OpenSSH ssh program — the one sshClientPath names, otherwise the first ssh on the user’s PATH (on Windows, a Win32-OpenSSH ssh.exe: the PATH one, else the in-box or Microsoft-installed client) — so the organization’s own OpenSSH build, with its Kerberos/GSSAPI, certificate and ssh_config support, is what authenticates. The program must be OpenSSH 7.6 or newer (Windows: Win32-OpenSSH 9.4 or newer). When sshClientPath is set and that program cannot be used, sessions fail with an error telling the user to ask their IT administrator rather than falling back; when it is unset and Windows has no usable client, the built-in library is used.builtin: the app’s built-in SSH library makes the connection, whatever the build’s default.auto or unset: the build’s default engine.An explicit value applies to new connections (sessions already connected keep their engine) and overrides the build’s default in both directions, including any remote switch-off Anthropic ships for the OpenSSH engine — so with system-openssh set, switching back is done here, by setting builtin.

Cowork surface

Workspace

When on (default), users can add plugin marketplaces from the plugin browser. Set to false to block user marketplace adds: the add-marketplace surfaces are hidden, and the app refuses adds that still reach it (deep links, stale UI).This is a feature-availability control enforced in the app, not a data boundary: marketplaces already registered on the user’s machine (or registered outside the app, for example by the Claude Code CLI or by editing Claude Code’s plugin files) are not removed or blocked by this key. Marketplaces provisioned by your organization (allowedPluginMarketplaces) are unaffected.This key applies only while the app runs in third-party mode. If users could otherwise sign in to Claude.ai on the device, also set disableDeploymentModeChooser so the app stays in third-party mode.
When on (default), users can upload plugin files and create plugins with Claude. Set to false to stop users adding plugins of their own: every in-app option for doing so is hidden, and the app refuses uploads that still reach it.This is a feature-availability control enforced in the app, not a data boundary: plugins already installed (or placed on disk outside the app) are not removed or blocked by this key. Plugins from organization-provisioned marketplaces and the organization plugins directory are unaffected.This key applies only while the app runs in third-party mode. If users could otherwise sign in to Claude.ai on the device, also set disableDeploymentModeChooser so the app stays in third-party mode.
Each entry is a Claude Code tool name (Bash, Read, Write, Edit, Glob, Grep, NotebookEdit, WebFetch, WebSearch, Task, TodoWrite, TaskCreate, TaskUpdate, TaskGet, TaskList, TaskStop, Skill, REPL, JavaScript, AskUserQuestion, ToolSearch, SendUserMessage) or an argument-scoped permission rule such as Bash(curl *) or Edit(**/*.env). A bare name covers every call; a scoped rule covers matching calls in every permission mode, including Auto and bypass. Scopes are matched for Bash(…) (a command pattern) and for file paths written as Read(…) (covers Read, Grep, Glob) or Edit(…) (covers Edit, Write, NotebookEdit); other tools take Tool(<field>:<pattern>). WebSearch and WebFetch are bare-name only: per-host web access is coworkEgressAllowedHosts.Scoped Bash(…) rules apply in Code sessions and in VM-sandboxed Cowork sessions (requireCoworkFullVmSandbox); Cowork’s own sandboxed shell honors bare names only. Anchor file patterns with **/ (Read(**/secrets/**)), because in the VM sandbox a host absolute path does not match. Scoped rules need a build that supports them across the whole fleet (disableAutoUpdates pins builds): an older build passes a scoped entry to Claude Code unchecked. An entry whose pattern contains ) followed by a space or comma is enforced only through Claude Code’s managed-settings channel, so another Claude Code managed-settings source replaces it unless that source sets parentSettingsBehavior to "merge"; every other entry is enforced either way.An unusable entry (a lowercase tool name, an unbalanced parenthesis, a scoped WebSearch(…) or WebFetch(…)) is kept, because the deny list is served exactly as written, and raises a configuration warning.
When on (default), users can create new skills and upload skill files in the app. Set to false to block user skill creation: the skill-creation and upload surfaces are hidden (the skill_creation feature is served as blocked by the organization), and the agent’s skill-creation tools (saving skills from a conversation, skill proposals) are not offered in sessions — the same effect as turning off the User-created skills organization setting available to claude.ai enterprise admins.This is a feature-availability control enforced in the app’s UI, not a data boundary: skills are files on the user’s machine, and files already present there (or placed there outside the app) are not removed or blocked by this key. Skills themselves remain usable; organization-distributed plugins and bundled skills are unaffected (to disable bundled skills, use disableBundledSkills).
Keys use the same tool names and argument-scoped rule syntax as Disabled built-in tools (disabledBuiltinTools), and scopes apply in the same sessions. Scoped ask rules reach sessions only through Claude Code’s managed-settings channel, so another Claude Code managed-settings source replaces them unless it sets parentSettingsBehavior to "merge" (bare names hold either way). They need the same fleet-wide build support, and an older build drops a scoped ask entry as a configuration error (which also blocks WSL sessions on Windows until that client updates), so the tool runs unprompted.An ask entry, bare or scoped, also turns off the app’s remembered “always allow” choices for that tool, so each prompted call is confirmed individually. In Code side chats, and in Cowork sessions that run tools on the host, ask on a file tool (Read, Write, Edit, Glob, Grep) blocks matching calls instead of prompting; Code sessions and VM-sandboxed Cowork sessions show the prompt. An unusable entry is dropped and recorded as a configuration error; a value other than allow or ask is treated as ask and reported. To remove a tool or deny a rule outright, use Disabled built-in tools instead.
When enabled, users can select Auto mode (Code) / Automatically approve (Cowork). 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 Code sessions, a separately deployed Claude Code managed-settings file that sets disableAutoMode to "disable" overrides this key and keeps Auto mode hidden.
When set to true, sessions cannot run in bypass permissions mode: the app stops offering the mode in Code and Cowork, and a session that requests it anyway is downgraded. This is the disableBypassPermissionsMode setting from the permissions section of Claude Code’s managed settings; a separately deployed Claude Code managed-settings file that sets it to "disable" also removes the mode, whichever source sets it.Unset (default): users the deployment otherwise allows can choose bypass permissions mode.
When enabled, Cowork, Code, and Chat sessions place only tool names 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. If your endpoint does not accept the request shape it then receives, requests fail with HTTP 400.
  • Claude API, Vertex AI, Bedrock, or Bedrock Mantle with no custom base URL: not needed. The app leaves Claude Code’s experimental betas on there, as terminal Claude Code does, so tool search is on by default (on Vertex AI, for Claude 4.5 and newer models). To turn it off in Code, Cowork, and Chat, set ENABLE_TOOL_SEARCH to false in the env block of OS-level Claude Code managed settings (with parentSettingsBehavior: "merge"). Earlier app versions treat these like the last case.
  • Gateway provider, app versions bundling Claude Code 2.1.247 or later: requests add only the tool-search shape (the tool-search-tool-2025-10-19 anthropic-beta value, deferred tool loading, tool_reference content blocks); every other experimental Claude Code beta stays suppressed. OS-level Claude Code managed settings that keep that suppression or turn ENABLE_TOOL_SEARCH off still win; set ENABLE_TOOL_SEARCH to force there instead (with parentSettingsBehavior: "merge"). Sessions in Claude Code’s own gateway mode (CLAUDE_CODE_USE_GATEWAY) get its gateway-safe tool-search shape regardless.
  • Foundry, a custom base URL, and earlier app versions: the app suppresses Claude Code’s experimental betas for the session and the key lifts that, so requests carry the tool-search shape together with Claude Code’s other experimental betas for that provider. On Vertex with app versions bundling Claude Code older than 2.1.221, leave this unset while any model older than Claude 4.5 is in use; those engines send the header regardless of model and Vertex’s pre-4.5 stacks reject it.
Before fetching a page, Claude Code’s WebFetch tool asks api.anthropic.com whether the domain is on Anthropic’s content blocklist, and refuses the fetch if that lookup cannot complete. Third-party deployments route inference elsewhere and often block api.anthropic.com at the firewall; with the lookup on, every WebFetch in Code sessions then fails with “Unable to verify if domain … is safe to fetch”, and where the host is reachable, every fetched hostname is sent to Anthropic. (Cowork sessions fetch through the app’s own allowlisted fetch and never run this lookup.)Off (default): the lookup runs as it does today, so api.anthropic.com must be reachable from users’ machines for Code-session WebFetch to work (listed under Egress Requirements). Set to true when users’ machines cannot reach api.anthropic.com (corporate firewall, government network) or you do not want fetched hostnames sent there: Code sessions then fetch without the lookup and never contact that host for it. This is the same skipWebFetchPreflight setting Claude Code reads from its own managed-settings file; the app passes it to every session it starts. To restrict which domains Claude may fetch, use coworkEgressAllowedHosts or builtinToolPolicy instead.
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.
When set to true, Code sessions refuse reads outside their working directories (the session folder plus any allowedWorkspaceFolders). The file tools (Read, Grep, Glob) refuse them in every permission mode; where Claude Code’s sandbox runs (macOS, or Linux and SSH hosts with bubblewrap, once allowedWorkspaceFolders or an egress allowlist is also configured) shell commands cannot see the home directory and other user folders (/Users, /home, mounted volumes) and a read there is refused with no prompt; elsewhere (Windows, Linux without bubblewrap, or neither folders nor an egress allowlist configured) such shell reads prompt for approval. The app keeps the user’s git configuration files (which may themselves embed credentials such as URL tokens; a symlinked one stays hidden), its own Claude Code installation, and the session’s plugin and attachment folders readable (not on a Windows SSH host, where plugin files and attachments stay out of the file tools’ reach under the block). An allowed folder that is or contains the home directory leaves it readable.Users can re-open folders (even their whole home) in their own Claude Code settings with sandbox.filesystem.allowRead or permissions.additionalDirectories; settings files tracked in a git repository cannot. The key travels on Claude Code’s managed-settings channel: another Claude Code managed-settings source replaces it unless that source sets parentSettingsBehavior to "merge", and one that sets sandbox.filesystem.allowManagedReadPathsOnly reduces it to approval prompts. This is permissions.blockReadsOutsideWorkingDirectories in Claude Code’s managed settings.Unset (default): nothing changes.
Applies to both Cowork and Code, and only to tool calls. In Cowork it governs the sandbox’s web fetch, shell commands, and package installs; in Code sessions it is translated into Claude Code’s network sandbox allowlist, where a separately deployed Claude Code managed-settings file takes precedence by default. It does not cover Web Search (which runs at your inference provider), inference, or MCP traffic. When unset, only the inference endpoint is reachable from the sandbox, so the agent’s package installs and web fetches fail with a 403.Entries are exact hostnames (api.github.com), wildcards (*.corp.com matches subdomains at any depth, not corp.com itself), or * to allow all. IP addresses match only when listed exactly. localhost and private-network addresses are always blocked for web fetch; shell commands and package installs run in a network sandbox that reaches only the listed hosts plus your inference provider. With *, that sandbox is disabled and web fetch still blocks private addresses.Any entry except bare * may carry a :port suffix (internal.corp.com:8443, *.corp.com:8443) restricting it to that port. IPv6 literals are not supported. An invalid entry is dropped (with a warning in the app log) and the rest keep working; an unreadable value counts as an empty list. Ports are enforced for the Cowork sandbox’s web fetch, shell, and package-install egress; plugin CLIs ignore port-scoped entries for now, and the Code translation treats them as the bare host. Deploy port-scoped entries only once your whole fleet is on a build that supports them (disableAutoUpdates pins builds): on an older build one such entry invalidates the sandbox’s whole shell and package-install allowlist for the session.Listed hosts also need to be open on your network firewall.
Free-text instructions from your organization that Claude Desktop appends, in a clearly delimited block, after its own system prompt in Chat, Cowork, and Code (every chat, task, and Code session, including the sub-agents they spawn): for example house style, data-handling rules, or topics to decline. The model is told these instructions come from the organization’s administrator and take priority over a user’s personal preferences.This is guidance the model follows, not an enforced control: like any system-prompt text it steers the model’s behavior and is usually honored, but it does not guarantee an outcome and is not a substitute for the restriction keys (tool policy, egress allowlist, folder allowlist). The app’s own system prompt is never replaced or shortened by this key; in Code sessions it is added after Claude Code’s own prompt and any CLAUDE.md instructions still apply.Read from the app’s loaded configuration when a session starts; a changed value generally takes effect for sessions started after the next app launch. Leading and trailing whitespace is trimmed; an empty string is treated as unset. Maximum 3,000 characters; a longer value is rejected (the key is ignored with a configuration error) rather than truncated. Line breaks are preserved when the value is delivered as JSON, a bootstrap response, a .mobileconfig profile, or a .reg file; the Group Policy (ADMX) and Intune text box for this setting is single-line.

Connectors

Authentication

auto (default): use the OS sign-in broker where available (WAM on Windows, the Company Portal SSO extension on macOS) and fall back to a browser sign-in otherwise. disabled: always use the browser sign-in. required: fail sign-in when the broker is unavailable rather than falling back to the browser, so the refresh token stays broker-held. Linux has no broker, so required is not supported there. Desktop builds older than the version that introduced required treat it as disabled (browser-only sign-in) — the opposite posture — so gate rollout on client version.

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.toolPolicy locks the per-tool approval state, keyed by tool name: "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), "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 show a session-scoped Allow for this task alongside Allow for all tasks with a malicious-instruction warning. In Code sessions, blocked and ask are forwarded as Claude Code permission rules; allow is not.Keys may contain * wildcards ("read_*" matches every tool whose name starts with read_; anchored, and * is the only wildcard). When several wildcard keys match, the strictest applies (blocked > ask > allow). An exact-name key wins over matching wildcards, with two exceptions in the stricter direction: in Code sessions a wildcard ask, or a wildcard blocked other than the bare "*", beats a less strict exact key (so "*": "blocked" plus exact "allow" entries still works as deny-by-default there); and in chat approval prompts and always-allow persistence a wildcard ask keeps every matching tool behind a per-call prompt even when a more permissive exact key matches, while direct tool invocations such as artifact or widget calls follow the exact key.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, and allow behave exactly as documented there whether this key is enabled or not.This key governs the chat and Cowork surfaces. Code sessions use a separate permission path this key does not cover — govern Code tool approvals with per-tool toolPolicy entries, whose blocked and ask values are forwarded there.
Sets the per-call timeout the agent applies to every MCP tool call; a call that runs longer fails with a timeout error the model can see. Cowork and chat sessions default to 180 seconds. Code sessions have no desktop-imposed MCP tool timeout today, so setting this key introduces one there as well. The desktop’s own request deadlines toward MCP servers — the managed servers above and, where isLocalDevMcpEnabled permits them, user-added local servers — follow this value so they never cut a call short first; while the key is unset, calls to user-added local servers are additionally limited to 60 seconds by the desktop. Values outside 60–3600 are rejected at parse time (the error is listed in the diagnostics report) and the defaults apply.The timeout is global (there is no per-server or per-tool form), so size it for the slowest tool you need to complete: long-running tools on one server extend the window during which a stuck call on any server holds its turn. Cowork’s built-in shell tool runs under the same cap: a single command’s timeout_ms (itself limited to 600 seconds) cannot exceed this value.

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 Claude Desktop 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.Destinations are listed under Egress Requirements → Nonessential telemetry.
“Nonessential services” covers three outbound fetches the app runs without: connector favicons (the icon proxy), the artifact-preview iframe origin, and the MCP Apps widget iframe origin (*.claudemcpcontent.com). Turning this on blocks all three.What you lose when this is on: connectors show without icons, artifacts do not render in conversations, and connectors that return MCP Apps show the text tool result instead of the widget.Destinations are listed under Egress Requirements → Nonessential services.

Auto update

Has no effect when disableAutoUpdates is in place at launch: the updater never starts, so nothing is downloaded and this timer never arms. If the policy reaches an already-running app after an update has downloaded, that one staged update still installs on this timer; no further updates are fetched.Leaving it blank uses the 72-hour default and then waits for the machine to be idle (10+ minutes without input) before restarting; setting any explicit value (including 72) restarts once the window elapses regardless of user activity. In both cases the restart holds off while Claude is mid-task.
By default the app asks api.anthropic.com which version to install. That host also serves the model APIs, so organizations that block un-approved LLM endpoints at the network edge end up blocking updates too.Turn this on to read the same feed from releases.claude.com, a hostname that carries no model API. api.anthropic.com can then stay blocked without breaking auto-update. Rollout behavior is unchanged; the installer download still comes from downloads.claude.ai as before.

Configuration updates

Set it via MDM (plist, registry, or file) or serve it from your configuration endpoint (remote bootstrap configuration). When the running app observes a managed-configuration change it cannot apply without restarting, it shows the sidebar relaunch card and starts this window. The window starts at the running app’s next configuration re-check (the re-check interval beside it), so allow up to one re-check interval on top of this value between saving a change and the restart dialog. When the window ends the app blocks with a restart dialog and restarts on its own after 2 minutes with no activity (no running Claude task and no keyboard or pointer input); the user can also restart right away. Defaults to 24 hours. Set a larger value (up to 336 = 14 days) to give users longer; 0 shows the dialog at the first observation.A served value is read from the newest served configuration, so tightening or loosening the window takes effect at the next poll without a restart, and a change to this key alone never asks for one. Like the update keys beside it, a value from a device-management profile that sets only app-behavior keys applies without making the rest of the configuration device-managed, and takes precedence over a served one. Because the key is grouped with the other app-behavior keys, a profile that sets any of them claims the whole group: set this key in the same profile as the update keys you deploy, or a served value is ignored on those devices and the 24-hour default applies.
How often the running app re-checks its managed configuration for changes: it re-polls your configuration endpoint with a conditional request, so an unchanged configuration costs one 304 round-trip. A detected change shows the sidebar relaunch card and starts the relaunchEnforcementHours window, so a saved change reaches a running app within roughly one interval. Defaults to 10 minutes; each wait is jittered by ±10% so a fleet does not poll in lockstep. Values outside 2–30 are rejected with a parse error and the default applies.Applied without a restart: a new served value re-arms the timer at the check that delivers it, and a change to this key alone never asks for a relaunch. Set it via MDM or serve it from your configuration endpoint; like the update keys beside it, a value from a device-management profile that sets only app-behavior keys applies without making the rest of the configuration device-managed, and takes precedence over a served one. Because the key is grouped with the other app-behavior keys, a profile that sets any of them claims the whole group, and every key in it is then read from that profile alone: deploy this key in the same profile as the update keys (disableAutoUpdates, autoUpdaterEnforcementHours, …). A profile that sets the update keys without it ignores a served interval and the default applies; a profile that sets only this key ignores served update settings, so a served disableAutoUpdates no longer holds on those devices. A profile that also manages the connection itself (sets bootstrapUrl or the provider keys) follows the normal tier order instead: once a served configuration is in hand it, not the profile, supplies this key.

OTLP

Code sessions export over the protocol set here. Chats and Cowork tasks export over http/protobuf instead of grpc on Windows, and on other platforms whenever the Claude Code engine is given an HTTP proxy (the operating system’s proxy, egressProxyUrl or egressProxyPacUrl, or HTTPS_PROXY / HTTP_PROXY in a Claude Code settings file); the application log notes the substitution. The desktop application’s own events always go over http/json to <endpoint>/v1/logs. None of this changes the endpoint, so choose grpc only for a collector that also serves OTLP/HTTP at the same address; otherwise keep http/protobuf and point otlpEndpoint at the collector’s OTLP/HTTP receiver (conventionally port 4318).
inference-credential adds Authorization: Bearer <token> to every export, using the token the app currently holds for the inference provider, with no helper script to deploy. The collector must accept that token as issued: a gateway OIDC token carries the gateway’s audience, Microsoft Entra on Foundry issues the Foundry resource’s token, and Vertex workforce identity forwards a Google Cloud access token; static gateway and Bedrock keys are forwarded as-is. Because the token can also call inference as the user, use this only for a collector you operate; for anything else, use the headers helper script with an ingest-scoped credential. Kinds that never produce a bearer (AWS SigV4 kinds on Bedrock, Google ADC / OAuth files on Vertex, API-key kinds) export without it — use the helper script instead. Cowork tasks pick up the current token each time they start; a Code session keeps the token it started with for as long as it stays open; the desktop’s own event exporter uses the current token on every flush. Before sign-in, exports go out unauthenticated. An Authorization header printed by the headers helper script wins over this.
Absolute path to an executable that prints a single JSON object of HTTP headers on stdout, e.g. {"Authorization": "Bearer …"}. The desktop runs it (no arguments; output cached for a few minutes, and a failure is not retried for 30 seconds) whenever it needs collector headers and merges the result over OpenTelemetry exporter headers and the Collector authentication header (the helper wins on conflict). Cowork tasks get the current output when they start; Code sessions and host-run Cowork sessions are also given the script as Claude Code’s own otelHeadersHelper, so an open session re-runs it as tokens rotate (on Windows this applies to .exe, .cmd and .bat helpers; a .ps1 helper applies at session start only); the desktop’s own event exporter re-runs it per flush. Session start waits at most two seconds for a slow helper and otherwise proceeds without its headers until it finishes. Use this when the collector needs a credential the inference sign-in cannot provide, when the collector token rotates, or when the config comes from a hosted admin console, which cannot store header values. If the helper fails, telemetry is sent without its headers — check the app log.
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 (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. When otlpEndpoint is set, this key alone decides whether those sessions export traces: leaving it unset or false keeps traces off even if Claude Code’s own settings or managed settings (for example a managed-settings.json on the device) turn tracing on. Without otlpEndpoint it has no effect. The span structure may evolve between Claude Code releases; see the Claude Code monitoring docs.

Limits

Session retention

The app deletes whole sessions in the background shortly after it fetches this configuration (at launch and on each re-poll), or some minutes after launch and then daily when the configuration comes from device management alone. Idle time runs from the session’s last activity; viewing an old Code session counts as activity, viewing an old chat or Cowork task without continuing it does not durably. A session that is running or open on screen is skipped and checked again on the next pass, as is a chat or Cowork task whose folder changed on disk within the period. Pinned sessions are not exempt. Minimum 1 day; a value that cannot be read as a whole number of days deletes nothing. Set through the served configuration or in the device-management profile that carries the rest of the configuration. What it does not reach: another account’s sessions on the device (evaluated when that account signs in), Code sessions on a remote machine (SSH/WSL), Cowork background (dispatch) tasks the sidebar does not list, a chat or Cowork task whose folder cannot be located, and Claude Code files not named by a session id (prompt history, plans, shell snapshots), which keep Claude Code’s own retention. Honored only by Claude Desktop configured for a third-party model provider.
The app deletes whole sessions in the background shortly after it fetches this configuration (at launch and on each re-poll), or some minutes after launch and then daily when the configuration comes from device management alone. Idle time runs from the session’s last activity; viewing an old Code session counts as activity, viewing an old chat or Cowork task without continuing it does not durably. A session that is running or open on screen is skipped and checked again on the next pass, as is a chat or Cowork task whose folder changed on disk within the period. Pinned sessions are not exempt. Minimum 1 day; a value that cannot be read as a whole number of days deletes nothing. Set through the served configuration or in the device-management profile that carries the rest of the configuration. What it does not reach: another account’s sessions on the device (evaluated when that account signs in), Code sessions on a remote machine (SSH/WSL), Cowork background (dispatch) tasks the sidebar does not list, a chat or Cowork task whose folder cannot be located, and Claude Code files not named by a session id (prompt history, plans, shell snapshots), which keep Claude Code’s own retention. Honored only by Claude Desktop configured for a third-party model provider.
The app deletes whole sessions in the background shortly after it fetches this configuration (at launch and on each re-poll), or some minutes after launch and then daily when the configuration comes from device management alone. Idle time runs from the session’s last activity; viewing an old Code session counts as activity, viewing an old chat or Cowork task without continuing it does not durably. A session that is running or open on screen is skipped and checked again on the next pass, as is a chat or Cowork task whose folder changed on disk within the period. Pinned sessions are not exempt. Minimum 1 day; a value that cannot be read as a whole number of days deletes nothing. Set through the served configuration or in the device-management profile that carries the rest of the configuration. What it does not reach: another account’s sessions on the device (evaluated when that account signs in), Code sessions on a remote machine (SSH/WSL), Cowork background (dispatch) tasks the sidebar does not list, a chat or Cowork task whose folder cannot be located, and Claude Code files not named by a session id (prompt history, plans, shell snapshots), which keep Claude Code’s own retention. Honored only by Claude Desktop configured for a third-party model provider.
Meant to be set per user or group, through the served configuration’s group overrides or in the same device-management profile that carries the rest of the configuration (a profile carrying only this key makes the device profile-managed, like any policy key); a hold in the device’s profile also counts when the served configuration does not restate it. Deletion stops at the first configuration fetch that carries this value, before it takes effect as configuration at the next relaunch; a device that cannot reach its configuration server deletes nothing.

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

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 session 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.
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. 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. Maximum 60 characters.
When the organization’s configuration uses a field that is deprecated — a renamed key, or a legacy value or entry form — the app shows every user a dismissable warning naming the field, what to use instead, and the date support ends (each field’s cut-off is listed in the configuration changelog and takes effect at 12:00 PM Pacific Time on that date). The warning shows from the field’s announced warning date until dismissed, and once more in the 24 hours before the cut-off. Set this to true to suppress the first showing for your users while you migrate; the final 24-hour reminder is always shown, and the deprecation stays listed in the diagnostic report (Help → Troubleshooting) and the hosted configuration editor regardless.

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

Locks per-tool permissions on MCP servers that arrive via the org-plugins directory — one entry per server name:
The older record form ({"mcpServers": {"internal-search": {"toolPolicy": {"delete_document": "blocked"}}}}) is deprecated and accepted only until October 7, 2026. Desktop versions before 1.15200.0 parse only the record form: on those builds an array value is ignored and plugin tool locks are not enforced, so update the fleet past 1.15200.0 before deploying the 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.
Static headers sent on every request to the bootstrap config URL — for a service-account credential (Authorization: Basic …, an API key header) or a routing/tenant header. When either this or the headers helper script is set and no separate bootstrapOidc provider is configured, the app treats the headers as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. These headers (and the helper script’s below) also accompany requests to a plugin marketplace this server hosts on its own origin (allowedPluginMarketplaces with credentialKind: "inferenceCredential"). Header values are masked in diagnostics and telemetry. For a rotating token, use the headers helper script instead.
Absolute path to an executable that prints a single JSON object of HTTP headers on stdout, e.g. {"Authorization": "Bearer …"}. The app runs it (no arguments; output cached for a few minutes) before each bootstrap config fetch and merges the result over Bootstrap request headers (the helper wins on conflict). Use this instead of embedding user:pass@ in the bootstrap URL, or when the bootstrap server needs a rotating token from a secrets manager. When either this or the static headers are set and no separate bootstrapOidc provider is configured, the app treats them as sufficient auth and does not require a per-user sign-in for the bootstrap fetch. If a per-user sign-in also runs (bootstrapOidc or the server’s own device-code flow), that Bearer token wins on Authorization.

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 session-scoped or 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, approve for the rest of the task (offered for tools that can modify data), or grant a standing approval unless mcpPersistentAlwaysAllowEnabled is false. Full prompt options require version 1.22209.0 or later; earlier third-party builds offered only per-call approval. The reference above also lists an "ask-session" value, which behaves exactly as "ask" and is accepted until October 7, 2026. After that date the app rejects an entry that uses it, so write "ask". 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 — is supported, including in Code sessions (where an allowed tool still gets Claude Code’s own approval prompt). See the managedMcpServers reference for wildcard matching, precedence rules, and built-in connector defaults.