Repository navigation
chore(mcp): MCP packages 2.4.0 and Client ID Metadata Documents - #2744
Conversation
…ance baselines - DurableObjectOAuthClientProvider accepts clientMetadataUrl and exposes clientMetadataDocument; the client uses CIMD when the authorization server advertises it and falls back to dynamic client registration otherwise - conformance: auth/basic-cimd removed from both client baselines; fixture ported from @modelcontextprotocol/server@2.4.0; sep-2322 entry cites modelcontextprotocol/conformance#475; legacy handler baseline renamed - @modelcontextprotocol/client and /server 2.4.0, /sdk 1.32.2
🦋 Changeset detectedLatest commit: d0347fd The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| ); | ||
| } | ||
| validateClientMetadataUrl(options.clientMetadataUrl); | ||
| this.clientMetadataUrl = options.clientMetadataUrl || undefined; |
There was a problem hiding this comment.
🟡 Existing registrations block metadata URL adoption
When a server has a saved dynamic registration, adding clientMetadataUrl leaves client_id set to that registration. The SDK reuses stored client information before considering CIMD support. A server that retires that registration rejects authorization instead of using the configured URL.
Learn more
The MCP client manager restores each saved client_id into the provider during restoreConnectionsFromStorage. The provider then returns that client's saved registration from clientInformation. The SDK only selects clientMetadataUrl when it has no usable saved client information. Consequently, enabling CIMD on an existing Agent keeps using its previous dynamic registration even if the authorization server advertises CIMD.
Example: An Agent registered old-client with a server last week. After deploying clientMetadataUrl: "https://app.example/client.json", it restores old-client; OAuth still sends old-client, which fails if the server has retired that registration.
Recommended fix: Decide whether to migrate saved registrations when CIMD becomes configured. Preserve valid tokens where appropriate, but invalidate or replace the saved client information and matching persisted client_id before the SDK chooses its client ID when switching to CIMD. Add a test that starts with a saved DCR registration, enables CIMD, and verifies the next OAuth flow.
Was this helpful? React with 👍 or 👎 to provide feedback.
| } | ||
| ``` | ||
|
|
||
| Serve the document at that URL. `provider.clientMetadataDocument` returns its JSON: `client_id` is the URL and `redirect_uris` holds the callback URL. The authorization server checks every redirect URI against the document, so pass a fixed `callbackPath` to `addMcpServer` rather than relying on the per-instance default. |
There was a problem hiding this comment.
🔍 CIMD guide lacks a serving example
clientMetadataDocument produces JSON but installs no route. A Worker must serve it at the configured URL; otherwise authorization servers cannot fetch the document. A route example would make the integration reproducible.
Was this helpful? React with 👍 or 👎 to provide feedback.
🔴 agents import sizes: 2 entry points over threshold
Changed exports (21)
How this worksEach runtime export is bundled on its own, minified, and gzipped. Changes smaller than 100 B, or smaller than 1% and 1 KiB, are ignored. Growth over 10% or 5 KiB is marked 🔴. This report is informational and does not fail CI. The workflow artifact contains every measurement. Compared |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
The MCP client can now use an OAuth Client ID Metadata Document.
DurableObjectOAuthClientProvidertakes aclientMetadataUrloption and sends it as theclient_idwhen the authorization server advertisesclient_id_metadata_document_supported, and uses dynamic client registration with servers that don't. The MCP packages move to@modelcontextprotocol/clientand/server2.4.0 and/sdk1.32.2.The conformance referee stays at
@modelcontextprotocol/conformance@0.2.0-alpha.12. It is the newest release, and itsmainhas no commits since then. Every lane already ran every scenario alpha.12 has for its spec version, including all 40 server scenarios at 2026-07-28 againstcreateMcpHandler, so no lanes changed. Baseline changes:auth/basic-cimdis removed from both client baselines. The conformance worker now setsclientMetadataUrl.auth/scope-retry-limitstays until feat(mcp): limit step-up re-authorization rounds (MCP spec 2026-07-28) #2663 lands. I ran the client lanes on that stack, and with this change on top both client lanes have nothing left but the referee bug below.sep-2322-client-request-statestays because of a referee bug (sep-2322 absent-resultType probe is an invalid stimulus on the 2026-07-28 wire it negotiates modelcontextprotocol/conformance#475). The fixture leaves outresultTypeafter negotiating 2026-07-28, and the released spec says only servers on earlier revisions may do that.McpAgentand legacy-compat entries stay, each with a comment giving the reason. Those code paths are deprecated, andcreateMcpHandlerpasses the same scenarios at 2026-07-28.baseline-server-handler.ymlis renamed tobaseline-server-handler-legacy.ymlbecause the legacy lane is the only one that reads it.pnpm --filter agents run test:conformance, agents unit tests (including the newclient-metadata-document.test.ts) andpnpm run checkran.