If you build a remote MCP client, the 2026-07-28 spec changes the one step you probably never thought about: how your client tells an authorization server who it is. The old answer — Dynamic Client Registration — is now deprecated. The new default is Client ID Metadata Documents (CIMD), and the difference is worth ten minutes because it moves a piece of work off your client and onto your infrastructure.
The short version: with CIMD, your client_id stops being an opaque string the server minted for you and becomes an HTTPS URL that you host. That URL resolves to a small JSON document describing your client. The authorization server fetches it and validates it on first use — no registration write, no stored record. For an ecosystem full of ephemeral agents, that deletes a real failure mode. It also hands you one new thing to secure.
What Dynamic Client Registration actually cost#
Dynamic Client Registration (RFC 7591) let a client POST its metadata to a registration endpoint and get back a freshly minted client_id. That solved the bootstrap problem — a client could show up and register without a human pre-provisioning it — which is exactly why MCP leaned on it. Every "add auth to your MCP server" walkthrough, including our own MCP authorization explainer, assumed it.
The cost is a write you can't easily take back. Every client that registers leaves a row in the authorization server's database. In a world where agents spin up, do one job, and disappear, DCR turns into unbounded registration growth and a spam surface: anything that can reach the endpoint can create records. Nobody owns cleaning them up.
What CIMD does instead#
CIMD inverts the direction. Your client_id is a URL like https://client.example.com/oauth/metadata. Behind it you serve a JSON document that mirrors the familiar registration fields — client_name, redirect_uris, grant_types — but self-hosted, not stored server-side:
{
"client_id": "https://client.example.com/oauth/metadata",
"client_name": "Acme Agent",
"redirect_uris": ["https://client.example.com/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"token_endpoint_auth_method": "none"
}
When the authorization server sees a client_id that is a URL, it issues a GET, expects Content-Type: application/json, and runs three checks: the document is well-formed, its own client_id field equals the URL that was fetched, and the redirect_uri in the request appears in the document's allowlist. There is no write endpoint — the server reads, it never stores a new registration. The trust anchor is the domain: only whoever controls client.example.com can serve that document, so DNS and TLS do the work a registration row used to.
For ephemeral clients this is the whole point. There is nothing to garbage-collect, because the identity is the URL. This is tracked in MCP as SEP-991, and the 2026-07-28 release candidate makes it the recommended path while keeping DCR alive for authorization servers that haven't shipped CIMD support.
The catch: you just gave the AS an outbound fetch#
CIMD's elegance is that the authorization server fetches a URL the client supplies. That sentence should make anyone who has written a webhook consumer wince — it is a textbook server-side request forgery (SSRF) surface. If you run the authorization server, the fetch is now yours to harden:
- HTTPS only. Reject
http://and anything that isn't a public HTTPS URL. - Block internal targets. No link-local, loopback, or private-range addresses — a
client_idofhttps://169.254.169.254/...must never resolve to your cloud metadata endpoint. - Bound the request. Tight timeouts and a response size cap; a metadata document is kilobytes, not megabytes.
- Cache the document. Token requests are hot; don't re-
GETthe client's URL on every one. Cache with a sane TTL and you avoid both latency and a self-inflicted amplification vector.
That is the honest trade. DCR made you manage registration lifecycle; CIMD makes you manage an outbound fetch. For most teams the fetch is the easier problem — it is one well-understood hardening checklist instead of an open-ended cleanup job — but it is not free.
Which one to ship#
Ship CIMD for new clients, keep DCR as the fallback, and assume neither side supports only one of them.
Building a client? Host a CIMD document and use its URL as your client_id; fall back to DCR only when you hit an authorization server that doesn't understand CIMD yet. Running a server? Add the CIMD fetch path with the SSRF guards above, and don't rip out DCR — the ecosystem will straddle both for a while.
And remember what CIMD does not touch. Registration is only the introduction. The token still has to be audience-bound with RFC 8707 Resource Indicators, PKCE is still mandatory, and your server is still a plain OAuth 2.1 resource server that validates tokens someone else issued. CIMD changes how your client says its name at the door — the rest of the MCP auth model is exactly where the 2026-07-28 spec left it.



