Who Is This MCP Client? Dynamic Registration, CIMD and Consent
8 min read Fullmakt Team
- business-case
- mcp
- authentication
- login-handshake
- governance
- agentic-ai-gone-wrong
When a person clicks “connect” on an MCP connector, a login handshake starts. A browser opens, a consent page appears, and the person types a password. The question almost nobody asks at that moment is the one that matters most: who is the client asking for access, and how does the server know?
An MCP client is the application, such as Claude Desktop, ChatGPT or a custom agent, that connects to an MCP server on a person’s behalf. In the MCP authorization model, clients are often unknown to the server in advance. They either register themselves on the fly or identify themselves with a URL. Both are convenient. Both are also a place where an attacker can pretend to be someone else.
This post explains how MCP client identity works, how a fake client turns a legitimate login into a consent phishing attack, and what a server should check.
Three ways an MCP client gets a client_id
OAuth needs a client_id. MCP servers cannot pre-register every client in the
world, so three patterns exist.
- Pre-registration. An administrator creates the client by hand. It is the strongest identity, and it does not scale to the open connector ecosystem.
- Dynamic client registration (RFC 7591). The client POSTs its name and
redirect URIs to a registration endpoint and gets a
client_idback. It is usually anonymous, because the client has nothing to prove yet. It is automatic, and the server has to treat every field as attacker-controlled. - Client ID Metadata Documents (CIMD). The
client_idis an HTTPS URL. The server fetches the document at that URL to learn the client’s name and allowed redirect URIs. The identity is tied to a domain the client controls, rather than a self-declared label.
For public clients, which is what desktop and chat connectors are, there is no client secret. The proof of a legitimate exchange is the one-time authorization code plus a PKCE verifier. PKCE protects the code from interception. It says nothing about whether the client should have been shown to the user as trustworthy in the first place. For the full flow see MCP OAuth for AI agents and login handshake procedures compared.
How a fake client phishes consent
Consider an attacker who wants access to a company’s MCP tools.
- They register a client named “Official Claude Connector” with a redirect URI they control. Dynamic registration allows this by design.
- They send a target a link to the real server’s authorization page.
- The consent page is genuine, served from the real domain, with a real login form. The person signs in, because everything they can see looks right.
- The server redirects the one-time code to the attacker’s redirect URI.
- The attacker exchanges the code, using their own PKCE verifier, and now holds a token for the victim’s tools.
No password was stolen from the login page, and no vulnerability was exploited. The system did what it was built to do for a client it knew nothing about. This is consent phishing, and it is the AI-era version of the malicious OAuth app that tricks users into granting mailbox access. The related credential phishing through elicitation attack comes at the same trust gap from inside the session.
What a server should check
The defenses are about narrowing what a client can claim and showing the person the truth.
- Exact redirect URI matching. Compare the redirect URI as a whole string against what was registered. Prefix or wildcard matching lets an attacker smuggle a code to a look-alike path or host. The one deliberate exception is loopback redirects for native apps (RFC 8252), where the port may vary.
- Show the redirect destination on the consent page. A client name is a label anyone can choose. The host the code will be sent to is harder to fake. Warn explicitly when the destination is a loopback address.
- Prefer CIMD where you can. A URL-based
client_idties the identity to a domain. If you fetch that document, treat it as an outbound request an attacker influences: block private and internal addresses (SSRF), cap the size, set a short timeout and cache with sensible limits. This links to SSRF in agentic AI. - Require PKCE with S256. Reject the plain method and reject missing challenges.
- Bind the token to the resource. Honor the RFC 8707
resourceparameter so the token’s audience is your MCP endpoint and nothing else. See audience binding and token passthrough. - Make codes single-use and short-lived, and rotate refresh tokens. A reused refresh token should be treated as theft. See refresh tokens for AI agents.
- Rate limit and reap. Anonymous registration invites junk. Limit it, and delete clients that stop being used.
- Limit what a connector token can reach. A token minted for the interactive connector flow should not also work on your admin API.
How Fullmakt approaches it
Fullmakt is a credential broker for AI agents. Interactive MCP clients connect through an OAuth authorization-code flow with PKCE, and the checks above are built into it.
- Registration and CIMD. Clients can register dynamically or identify with a CIMD URL, which is how Claude Code and ChatGPT identify themselves. The metadata fetch is SSRF-guarded, time-limited, size-capped and cached.
- Exact redirect matching. Redirect URIs are matched exactly. Loopback redirects ignore the port per RFC 8252, and the consent page names the redirect host and warns on loopback.
- PKCE with S256 only. Authorization codes are one-time and short-lived, and the stored codes and refresh tokens are hashed. Refresh tokens rotate on use, and presenting a used one revokes the whole token family.
- Resource and issuer. An RFC 8707
resourcemust match the server’s MCP URL and becomes the token audience. Authorization responses carry the issuer (RFC 9207). - A confined connector token. The token this flow issues is accepted on the MCP endpoint only. It is rejected on the management API and on per-collection MCP routes.
- Rate limits and cleanup. Authorize and token endpoints are rate limited, and registered clients that go unused are swept after a retention window.
Honest limits: the token endpoint for public clients takes no client secret, so possession of the code and PKCE verifier is the entire proof, and registration is anonymous by design. The consent page is where a person decides, so what it shows matters, and no server can stop a determined person approving a client they should not trust. Pair the flow with policy and approvals so a connected client still cannot do everything. See human-in-the-loop approval.
The business case
Client identity sounds like plumbing until a customer asks, “which AI tools can reach our data, and who approved them?”
- Enterprise sales unblocked. Security questionnaires now ask how AI connectors are authorized. “Exact redirects, PKCE, hashed and rotating tokens, audience-bound, confined to one endpoint” is a short, credible answer. See audit controls for SOC 2.
- Smaller blast radius. If a consent phish succeeds, the stolen token reaches only the MCP surface and still passes policy, approvals and audit. Compare that with a token that opens the whole API.
- Traceability for governance. Each connector call is attributed to a user and a client, which is what non-human identity governance and the EU AI Act and ISO 42001 expect.
- Less to build. Getting an OAuth server right for MCP, with CIMD, PKCE, rotation and discovery metadata, is a real project. See build vs buy for an agent credential proxy.
Checklist
- [ ] Redirect URIs match exactly, with only the loopback port exception.
- [ ] The consent page shows the redirect host, not just a client name.
- [ ] PKCE with S256 is required.
- [ ] CIMD fetches block internal addresses and limit size and time.
- [ ] Tokens carry an audience bound to the MCP resource.
- [ ] Authorization codes are single-use; refresh tokens rotate and reuse revokes.
- [ ] Anonymous registration is rate limited and stale clients are removed.
- [ ] Connector tokens cannot reach admin or management APIs.
- [ ] Brokered calls are policy-checked and audited after login.
FAQ
What is dynamic client registration in MCP?
It lets an MCP client register itself with an authorization server by posting its
name and redirect URIs, and receive a client_id without an administrator. It is
defined in RFC 7591 and is usually anonymous.
What is a Client ID Metadata Document (CIMD)?
A CIMD is a JSON document hosted at an HTTPS URL that doubles as the client’s
client_id. The server fetches it to learn the client’s name and allowed
redirect URIs, which ties the client’s identity to a domain it controls.
Does PKCE prove an MCP client is legitimate? No. PKCE protects the authorization code from interception, so only the party that started the flow can redeem it. It does not tell you whether that party is a trustworthy application. Redirect checks, CIMD and a clear consent page do that.
What is consent phishing against MCP servers? An attacker registers a client with a convincing name and their own redirect URI, then lures a user to the genuine consent page. The user logs in, and the authorization code goes to the attacker.
How does Fullmakt reduce the risk? It matches redirect URIs exactly, shows the redirect host on the consent page, requires PKCE S256, binds tokens to the MCP resource, rotates refresh tokens, and confines the connector token to the MCP endpoint, with policy and audit behind every brokered call.
See how Fullmakt brokers credentials for AI agents or read how it works across the rest of the blog.