r/mcp • u/lordVader1138 • 2h ago
article MCP OAuth is three primitives, not six RFCs. Traced end to end, plus the part where my server becomes a client.
Finally I understood what happens on the other side when Claude calls connect, and the server identifies you and your access.. (Or better say, Claude helped me understand it). At first it was all acronyms for me. What made it click was understanding one client connect, once, end to end. Everything collapsed into three primitives that each fire exactly once, in a fixed order.
Discovery. A fresh client POSTs with no token and gets a 401 back carrying a WWW-Authenticate header that points at /.well-known/oauth-protected-resource. That header is the whole trick. The 401 is not the server slamming a door, it is the server handing over directions. Two GETs later (protected resource metadata names the auth server, auth server metadata lists the endpoints) the client knows everything it needs, having sent zero credentials.
Registration. No developer console. The client POSTs its own details to the registration endpoint and gets a client id on the spot. This is RFC 7591, and it is the part people trip on when they ask why this could not just be an API key. An API key assumes you already know the caller and can hand it a secret. MCP clients are strangers by design, so dynamic registration is the only model that works.
The grant. One human moment: a PKCE challenge, a consent screen that names the client, approve, done. At consent time the server bakes the user identity into the grant as props, so every later request just unwraps it. No per-request session lookup on the hot path.
There is one more cool trick: my server also performs OAuth as a client, upstream, because it bundles other servers that demand their own auth. Same three primitives, walked from the other side. Doing it by hand gave me real appreciation for how much invisible work Claude does every time you click connect and it just works. So it's just a multiplexer (not sure if it's a right term) for MCP servers.
Full walkthrough with the actual responses from the live server: https://prashamhtrivedi.in/mcp-oauth-primitives/
Curious how the rest of you are handling MCP auth right now. Across my own fleet I have Better Auth, an OAuth envelope wrapped around an API key, a hand-rolled JWT setup, and one static bearer token still holding out, so I do not think there is one right answer yet.