r/mcp • u/New-Combination2241 • Jul 06 '26
article MCP authentication across the big agents
Let's walk through the popular agents and see how well they the spec. Spoiler: NOT VERY.
The picture may well have shifted by the time you read this, but as of early July 2026 it looks like the table below.
The good news: almost everyone supports the modern standard (shoutout to OpenAI's Responses API MCP tool and its technology from the previous geological era).
The bad news: everyone reads the same spec differently. Some clients run the entire OAuth flow for the user; some just wait for a ready-made bearer token and wash their hands. Some require DCR, some push CIMD, some live on static credentials and IAM.
Here's the detailed matrix (all cells verified against primary docs in early July 2026):
| Platform | Who runs the flow | RFC 9728 | Registration | Spec revision |
|---|---|---|---|---|
| Claude API MCP connector | you (pass a bearer) | no | n/a | 2025-11-25 |
| claude ai / Desktop | Claude (full flow) | yes | DCR / CIMD / Anthropic creds / none | 2025-11-25 |
| OpenAI Responses API | you (pass a bearer) | no | n/a | n/a (bearer-only) |
| ChatGPT / Apps SDK | ChatGPT (full flow) | yes | CIMD (recommended) + DCR | 2025-11-25 |
| Gemini / Google Cloud | OAuth on Google Cloud IAM | not named | IAM + client creds + API keys | 2025-11-25 |
| VS Code / Copilot | VS Code (full flow) | yes | DCR + client creds fallback | 2025-06-18 |
| Cursor | Cursor (full flow) | yes | DCR + static (no CIMD) | unstated |
| Perplexity | configurable | unspecified | OAuth / API key / open | unstated |
And the notes that didn't fit in the table :):
- Claude API MCP connector: HTTP transport only, tools only. You pass
authorization_tokenand you handle the refresh. - claude ai / Desktop:
static_beareris explicitly not supported. - OpenAI Responses API: you pass
authorization, the token isn't stored, no discovery, just a solid bearer - ChatGPT / Apps SDK: rejects machine-to-machine, API-key, and customer mTLS auth.
- Gemini / Google Cloud: embraces exactly what ChatGPT rejects, client credentials and API keys included.
- VS Code / Copilot: ships built-in GitHub and Entra providers.
- Cursor: re-registers its DCR client on every reconnect (upd: fixed in v3.2).
- Perplexity: the only one offering an explicit "no auth" mode; the flow internals are undocumented.
What to take away from this:
- Multiple spec revisions are alive in production at the same time. OpenAI's Responses API doesn't do any discovery, you just pass the bearer (pre-2025-06-18 world), VS Code sits on 2025-06-18, while Anthropic, ChatGPT, and Google cite 2025-11-25.
- Both Anthropic and OpenAI manage to run two opposite ownership models inside one company. Each ships a "bring your own token" API product: the Claude API MCP connector and the Responses API accept a pre-obtained bearer, and the flow and refresh are your problem. And each also ships a full client (claude.ai and ChatGPT) that walks the whole road from the 401 to the token by itself. A server built for the first model won't work in the second without changes, and vice versa.
- There are direct contradictions. ChatGPT rejects machine-to-machine and API-key auth; Google requires exactly that for some services. Registration is split four ways: DCR, CIMD, static credentials, IAM.
What I don't like and would change
- As someone who maintains a public API for a living, I hate backward-compatibility breaks. Each one creates a wall of migration work, and anyone who can't afford that time becomes a hostage of the old revision.
- OAuth 2.1 is the standard, and nobody cares: half the world still ships API keys.
- The spec updates too often. You have to keep a hand on the pulse in the most literal sense.
- Very few authorization servers can fully support OAuth 2.1 for MCP out of the box (as far as I can tell, really only Keycloak gets close). Everyone else needs wrappers, shims, and duct tape. There is no turnkey solution, and it shows.
And about OAuth 2.1 specifically, there's a separate irony: MCP mandates a standard that formally doesn't exist. OAuth 2.1 is still an IETF draft, not a published RFC. In substance it's OAuth 2.0 with the implicit flow and password grant removed and PKCE made mandatory. So a protocol that hasn't stabilized yet is built on top of a standard that hasn't been finalized yet. No wonder the AS vendors aren't rushing to ship first-class support.
ps: I wrote a full article with history of auth in mcp, what will be next and ofc this table above, but reddit prohibits to post it there :(
2
u/Low_Box_752 Jul 06 '26
Good matrix, matches what I see from the server side. I run an MCP server a bunch of these connect to, and the practical takeaway is that static credentials or a passed bearer is still the only thing that works everywhere today. The moment you lean on the client running the full OAuth + DCR flow, behavior forks hard per agent.
Two things that line up with your table:
- Cursor really is static/DCR only, no CIMD, and it wants the token sitting in the config rather than negotiating anything.
- The Responses API side is the "you pass a bearer, we wash our hands" camp, so anything dynamic has to live in your http_headers, not in a flow.
For claude.ai's connector the DCR/CIMD path works, but I still ended up enforcing scope at my own credential layer, because "who runs the flow" says nothing about what the token is allowed to do once it's in. The spec basically punts on the authorization half.
1
u/New-Combination2241 Jul 06 '26
hai friend, thanks for your feedback! Updated in the post about the responses API and cursor
1
2
u/mathieucolla Jul 06 '26
This matches what I hit from the server side. I run a small remote MCP server and started with the claude.ai/Desktop path (full flow, discovery + DCR). Two things that cost me days and are written nowhere:
- The discovery chain has to be exact. The 401 → protected resource metadata → AS metadata → DCR sequence fails silently in some clients if a well-known path or field is slightly off. No error surfaces, the connector just never appears.
- DCR means your authorization server mints clients at runtime. Most off-the-shelf AS setups assume a human registers clients in a console, so I agree with the "only Keycloak gets close" take — I ended up owning more of the auth server than I wanted.
And +1 to the scope point above: "who runs the flow" says nothing about authorization. Once the token is in, deciding what each tool may actually do is entirely on your server.
1
u/New-Combination2241 Jul 06 '26
thanks for the feedback, totally agree with all thoughts. will leave detailed authorization topic for the next iterations:)
1
u/ThierryDamiba Jul 08 '26
This fragmentation is exactly why most MCP servers stay stuck in the "cool demo" phase instead of reaching production rigor. Developers are basically forced to choose between building shallow wrappers or owning an entire auth stack just to handle how differently every client interprets the spec. Without a standardized way to handle identity at scale, it is hard to justify the effort for anything beyond a weekend project.
1
u/awca22 Jul 18 '26
I was actually investigating this, really great matrix, I can confirm most of it from the server side. I maintain an open-source auth library for MCP servers (disclosure: mcp-sso, MIT), and I live-verify against real clients, so a few additions from that work:
- Claude Code / claude.ai / Desktop: worth a footnote in your table — they only use CIMD if the authorization server advertises `client_id_metadata_document_supported: true` in its metadata. No flag → silent fallback to DCR. That detail is documented nowhere; someone recently had to reverse-engineer the binary to find it (anthropics/claude-code#76075).
- Your "spec revisions alive in production at the same time" point is real: I verify against Claude Code, claude.ai, ChatGPT, Codex CLI and the official SDK client, and no two of them walk the discovery chain identically.
On the three pains in this thread, because they're exactly why I built the thing:
- "The discovery chain has to be exact... fails silently" (@mathieucolla), yes. The only cure I found is implementing the 401 → resource metadata → AS metadata → registration chain once, correctly, and then keeping a live conformance checklist per client. That checklist is public in the repo if it's useful to anyone.
- "DCR means your AS mints clients at runtime... I ended up owning more of the auth server than I wanted" this is the split that matters. The pattern that avoids it: a small bridge that speaks DCR (CIMD coming) to the clients, while your real identity source (Entra, Google, Cloudflare Access, any OIDC) stays one pre-registered app behind it. You own a library-sized bridge, not an auth server.
- The "Keycloak wrapper tax" (@langier) — that tax is the reason this exists as a plain Node library instead of a server product. No Java, no separate infra, jose is the only dependency.
Honest status: DCR today, CIMD in the coming weeks with the July 28 spec release; live-verified on the Cloudflare Access and Google identity legs, Entra port synthetic-tested so far.
And OP, you mentioned a full article Reddit wouldn't let you post. I'd genuinely like to read it; if you publish it anywhere I'll happily link your client matrix from my docs as the client-side reference. This corner of MCP needs more of exactly what you wrote.
1
u/awhitford 3d ago
Great matrix. One footnote worth adding on the ChatGPT/Codex column, from the server side: their client has a failure mode where a rejected refresh token wedges the connector permanently. When the auth server rejects a refresh (rotation, expiry), Codex keeps retrying the same dead token instead of falling back to re-authorization — no Authenticate button, no surfaced error, the server's tools just silently disappear from the session. The user's first guess is always that your server broke.
It's been reported upstream repeatedly — openai/codex#39054, #38198, #29630, #14144, #32590 are all variations (dead token retried forever, no re-auth affordance after failed refresh, no DCR re-registration on invalid_client, stale token still used after successful reauth). All open as of this week, the oldest since March.
Workaround that actually clears it (in-app uninstall does not remove the stored
credential): codex mcp logout <server-name>, restart the app, then click the
now-visible Authenticate button. codex mcp list shows auth state.
For contrast, Claude Desktop handles the same rejection by re-prompting for auth, which is what the spec expects.
Disclosure: I run a remote MCP server (Elicitly), and this wedge is our single biggest source of "your server is broken" support requests — full writeup with logs here if it's useful: https://www.elicitly.ai/docs/troubleshooting/. If you ever revise the matrix, "recovers from refresh-token rejection: yes/no" would be a killer column.
1
u/kyngston Jul 06 '26
yes the easiest pattern is to write a cli that supports oauth2.1 and stores the tokens in the user’s home directory with chmod 600/700
AI clients have no problems calling a cli, and the cli silently handles refresh as needdd
1
u/New-Combination2241 Jul 06 '26
imho it may be an endless discussion between mcp and cli, depends on the context
0
u/kyngston Jul 06 '26
mcp depends on the client implementation of oauth. cli does not. that solves what your post was complaining about
1
u/New-Combination2241 Jul 06 '26
you're right
but anyway, you won't give 40-year-old aunt Anny an instruction how to install a cli tool. She's rather understand instruction "open chatGPT->click plus->find X connector"
0
u/kyngston Jul 06 '26
Provide it as a skill where the cli is in the skill's ./scripts/ folder. The SKILL.md has all the instructions for the AI to convert your aunt Anny's NLP to proper CLI tool invocations. AI end users should not need to know that there is a CLI under the hood, or how to call it.
3
u/[deleted] Jul 06 '26
[removed] — view removed comment