Testing CIMD support across Anthropic’s Claude products | by Leduccc | May, 2026 | MediumSitemapOpen in appSign up<br>Sign in
Medium Logo
Get app<br>Write
Search
Sign up<br>Sign in
Testing CIMD support across Anthropic’s Claude products
Leduccc
8 min read·<br>May 15, 2026
Listen
Share
TL;DR: Claude Code, Claude Desktop and Claude Cowork all use CIMD on the user-initiated paths I observed. An MCP authorization server can ship CIMD-only and cover the current Anthropic client population.
Anthropic only documents Client ID Metadata Document (CIMD) support for one of their products: Claude Code. For Desktop, Web and Cowork the documentation says the surfaces share infrastructure but never names the client_id or the registration mechanism. If you are designing an OAuth 2.1 authorization server for MCP and want to know whether you can ship CIMD-only or have to support Dynamic Client Registration (DCR) as well, that gap matters.<br>A Reddit thread from May 2026 asks exactly the same question. The answers are not authoritative. A few third-party blogs claim hosted surfaces use a pre-registered UUID; those claims do not cite primary sources and turned out to be incorrect once tested. So I tested each product directly against an authorization server (AS) I control, logged every request and read the answer off the wire.<br>Why CIMD beats DCR<br>DCR is a permanent operational liability. It exposes an open registration endpoint, so anti-abuse becomes the AS operator’s problem. RFC 7591 leaves the gating policy entirely to the operator. Without software_statement validation or some other admission control, spammers can carve registration rows into the database until storage explodes or queries become slow scans.<br>Every registered client gets to claim its own client_name, client_uri and redirect_uris. Consent screens can lie unless registration is gated on a trust signal stronger than the request itself, such as pre-shared signing keys, manual review or an allowlist. Each registration also creates a long-lived row with its own garbage collection story and a question of what happens to issued tokens when the client is deleted. RFC 7592 adds an entire CRUD API on top.<br>CIMD avoids all of that. The client_id is a URL. The origin of the URL is the trust anchor; if the client_id is on claude.ai, the AS already knows whether it trusts claude.ai. The metadata document is fetched fresh each time, so there is no stored state. There is no open endpoint to abuse and no admission policy to write.<br>As such, given the choice between the two, the right call is to ship CIMD first. DCR can wait until a non-Anthropic MCP client that needs it shows up.<br>Why Cowork needs an extra step<br>Web, Desktop and Mobile all run the OAuth client in the user’s own browser or app process. Whatever client_id reaches my AS is, by construction, the one those products use. There is no service in between that could mint a different identity.<br>Cowork is different. Cowork runs on Anthropic’s servers. When a Cowork agent invokes an MCP tool, the request originates from Anthropic’s egress, not from the user’s machine. Even if the initial OAuth flow looks identical to Web (because the user kicks it off from a browser), nothing in the protocol rules out Cowork’s server side using a different OAuth client when it refreshes a token, picks up a scheduled task or runs autonomously. The shared-infrastructure claim in Anthropic’s docs is suggestive but not conclusive on its own.<br>As such, the Cowork test has to go past the initial authorize. I need to see Cowork actually invoke a tool and confirm the bearer it sends matches the one issued during the user-initiated CIMD flow. That covers the user-initiated happy path. Token refresh, scheduled tasks and autonomous runs are each separate observable events that would each require their own capture; this article only closes the user-initiated case directly.<br>Setup<br>Tested clients<br>- Claude Code CLI: 2.1.142<br>- Claude Desktop: v1.7196.0 (macOS)<br>- Claude.ai Web: personal account<br>- Claude Cowork: running inside Claude.app v1.7196.0, personal accountTest infrastructure<br>- Language: Python 3.14, FastAPI + uvicorn (~150 LOC)<br>- Public URL: cloudflared quick tunnel (https://.trycloudflare.com)<br>- Logging: every inbound HTTP request to JSONL, full headers + bodyThe AS advertised both registration_endpoint and client_id_metadata_document_supported: true so each client had every path available and picked the one it actually wanted to use. Per Anthropic's selection rule, Claude picks CIMD only when both client_id_metadata_document_supported: true and none in token_endpoint_auth_methods_supported are advertised. Both conditions were satisfied.<br>"issuer": "https://.trycloudflare.com",<br>"authorization_endpoint": "https://.trycloudflare.com/oauth/authorize",<br>"token_endpoint": "https://.trycloudflare.com/oauth/token",<br>"registration_endpoint": "https://.trycloudflare.com/oauth/register",<br>"client_id_metadata_document_supported": true,<br>"grant_types_supported":...