Support OAuth Client ID Metadata Documents (CIMD)#5
Merged
Conversation
Clients can use an HTTPS URL as their client_id; the server fetches and validates the metadata document from that URL per draft-ietf-oauth-client-id-metadata-document-00. Opt-in via the clientIdMetadataDocuments option. Documents are cached through the OAuthServerModel (saveClientIdMetadataDocument / getClientIdMetadataDocument) respecting Cache-Control headers. The draft MCP Authorization spec recommends CIMD and deprecates Dynamic Client Registration in its favor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements OAuth Client ID Metadata Documents: clients use an HTTPS URL as their
client_id, and the authorization server fetches and validates a JSON metadata document from that URL instead of requiring registration.The draft MCP Authorization spec says authorization servers SHOULD support CIMD and deprecates Dynamic Client Registration in its favor. Claude clients (Web, Desktop, Code, Cowork) now use CIMD exclusively for user-initiated MCP OAuth flows, and ChatGPT prefers it when advertised - both select CIMD when the metadata advertises
client_id_metadata_document_supported: truealongsidenoneintoken_endpoint_auth_methods_supported, which this server does. The upstream MCP SDK only implements the client side, so this is original AS-side work following the spec.Usage
Opt-in on
OAuthServer(off by default since it makes the server fetch client-supplied URLs):Implementation
isClientIdMetadataDocumentUrl()detects URL-formatted client ids (HTTPS, path component, no fragment/credentials);OAuthServer.getClient()resolves them via the newClientIdMetadataDocumentFetcher, so the authorize, token, refresh, revoke, and device flows work with URL client ids unchanged.client_idequals the URL exactly; valid JSON with requiredclient_id,client_name,redirect_uris; redirect URIs validated against the document by the existing handlers.token_endpoint_auth_methodother thannoneare rejected (private_key_jwtnot supported), andgrant_typesmust be enabled on the server.OAuthServerModelvia new optionalsaveClientIdMetadataDocument/getClientIdMetadataDocumentmethods (implemented byMemoryOAuthServerModel), honoringCache-Control(max-ageclamped to a configurable ceiling,no-store/no-cacheuncached) - instances sharing a model share the cache. Enabling CIMD on a model lacking these methods fails at construction, matching the device-grant capability check.validateClientIdUrltrust-policy hook (e.g. domain allowlists) and injectablefetch. DNS-rebinding protection is explicitly out of scope and documented.client_id_metadata_document_supported: trueonly when enabled.Docs
README gained a CIMD section (usage, trust policy, security notes including the localhost-redirect impersonation caveat for consent screens), DCR is marked as deprecated by the MCP spec in favor of CIMD (kept for backwards compatibility), and the spec-compliance list was refreshed to name everything implemented (PKCE/RFC 7636, RFC 6750, RFC 8707).
Tests
28 new tests: URL detection, document validation failures (mismatched
client_id, missing fields, invalid JSON, HTTP errors, oversized), SSRF and trust-hook rejections, model-backed caching (cache hit,no-store,max-ageexpiry, cache shared across server instances), server-config validation, metadata advertisement, and an authorize-flow round trip with a URL client id - all with injected mockfetch, no network.