RSS Amplifier

The API Changelog · May 29, 2026

Fixing the MCP Onboarding Mess

0
Sign in to vote or save

Bruno Pedro · The API Changelog

MCP is becoming the standard way of consuming APIs. Well, not just APIs, to be fair. It can connect AI agents to anything, from databases to home devices like lamps and switches. With such a diversity of possibilities, any friction that you can remove from client registration is welcome. But, how does an AI agent securely prove its identity to an MCP server it has never connected with before? Let's look at what a person would do. A human would probably go to a website, sign up, create an OAuth client, and copy the client ID and secret along with a redirect URI into a local configuration file. Too many things could go wrong. And many did. And too many times, people would simply give up. So, how can you solve all this mess? Stay with me.

This article is brought to you with the help of our supporter, n8n.

n8n is the fastest way to plug AI into your own data. Build autonomous, multi-step agents, using any model, including self-hosted. Use over 400 integrations to build powerful AI-native workflows.

Try n8n now!

The best way to eliminate manual effort is to automate it. And that’s exactly what we did. In March 2025, MCP introduced a recommendation to use the OAuth 2.0 Dynamic Client Registration (DCR). This was the perfect solution to the onboarding friction. However, it created another problem. But before that, if you don’t know what DCR does, here’s a quick refresh. When a new OAuth client instance starts, it automatically sends an HTTP POST request containing its metadata to the authorization server’s /register endpoint. The server dynamically registers the client, saves its details to a database, and returns a unique client_id. There, a new OAuth client is now registered, and no human was ever involved in the process. While this works for static, long-lived clients, it’s completely useless in the world of AI agents and ephemeral MCP clients. There are three main problems with this approach. The first one has to do with sprawl. Every time a new AI agent instance starts, it initiates a new DCR request. The authorization server’s database quickly becomes cluttered with thousands of orphaned client registrations. Most of these records are never used again, yet they must be stored and indexed. Then you have the problem of server-side request vulnerabilities. Leaving a registration endpoint wide open to the public is an operational hazard. Malicious actors can easily flood the /register endpoint with automated requests, consuming database connections, exhausting disk storage, and causing immediate Denial of Service (DoS). And, finally, you have to deal with potential revocation and auditing nightmares. How do you audit a system with thousands (or millions) of dynamically registered clients? Distinguishing between a legitimate, inactive agent and an old, compromised key becomes an administrative impossibility. You see, what was born as a solution to the manual onboarding friction quickly created a new problem of its own. What can you do to solve it? Go back to manual onboarding? Keep reading to find out.

The solution to the sprawl that DCR introduced is to make client registration less dynamic. By doing so, every time you register the same AI agent, the client information will be the same. But to do that, there must be a way to store client information so that the authorization server can use it. In November 2025, MCP changed its recommendation to something called Client ID Metadata Documents (CIMD). While this is still an early IETF draft, it’s looking very promising. How does this work then? Well, to begin with, we stop forcing the authorization server to store metadata for every client. Instead, with CIMD, metadata is stored on a URL managed by the client. The client then uses that URL as its client_id. With this approach, the authorization server no longer needs a registration database. It simply fetches the metadata document on demand to process each authentication request. Looks quite smart, right? So, how do you implement it?

To support CIMD, your authorization server must replace static database queries with an on-demand resolution and validation engine. Let’s start by understanding how your server can extract OAuth client information. When an OAuth authorization request arrives, the server must inspect the incoming client_id parameter to determine if it’s a URL or a legacy string. If the client_id is a valid URL, it will treat the request as CIMD. Then, it must read the CIMD document by requesting it from the given URL. To avoid performance degradation, having a cache layer at this point can be a good idea. You shouldn’t cache the document forever, though. You can use the information provided by the client’s HTTP Cache-Control headers. If there’s no cache information, use a reasonable timeout, like 24 hours. After you have grabbed the client’s metadata document, you must run three non-negotiable checks before accepting the client’s identity. The first, and easiest one, is to verify if the client_id value inside the document is exactly the same as the URL where the document is located. Then, as a security measure, you should guarantee that the redirect URLs in the document all share the same origin as the client_id URL. And, finally, you should set the appropriate authentication scheme depending on the public or confidential nature of the client. For public clients, you should enforce PKCE, while private clients should work with public keys obtained from a JWKS URL. With all this, you should be ready to support CIMD on your authorization server.

As you can see, while CIMD sounds elegant, implementing it is quite complex. On top of the complexity, you also have to deal with potential security traps. I’m thinking of things like SSRF, where anyone could make your authorization server use private or internal credentials. Or things like cache poisoning, metadata URL downtime retries, and denial-of-service loop attacks. Because you need to make outbound HTTP requests to arbitrary URLs, you get exposed to numerous types of risks. On top of all this, there aren’t a lot of open-source or even commercial CIMD solutions because everything is still new. Identity providers are all still looking for client_id values in a local database. You’d need to refactor the system you’re using or wait for it to support CIMD.

Ultimately, you have to make a strategic architectural decision. You have two options. On the one hand, you can continue to use manual configurations or maintain your existing DCR implementation. It means writing and running automated cleanup scripts to sweep your database of dead client registrations, accepting the administrative overhead of manual key management, and dealing with developer friction during setup. It is painful, but it is a predictable, familiar pain. On the other hand, you can invest the engineering weeks required to build a hardened, SSRF-resistant, highly available CIMD validation engine. The industry is moving toward stateless agent identity. Will you build the infrastructure to support it, or will you continue managing the database bloat?

Read the original on apichangelog.substack.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.