OAuth for MCP servers: the three changes in 2026-07-28
MCP 2026-07-28 hardens authorization on three points: iss validation, application_type at registration, and credentials bound to their issuer.
The MCP 2026-07-28 revision does not only touch the transport. It also hardens authorization, with three changes driven by a simple observation: in practice, an MCP client talks to many servers, often dozens. That is not the deployment shape OAuth was originally designed around.
The three changes are small in code and large in consequence. None of them is visible until something goes wrong.
Why the deployment shape changes everything
A classic web application talks to an authorization server it already knows. An MCP client discovers servers it has never seen, each with its own authorization server, and stores credentials for all of them.
That asymmetry opens a class of attacks: convincing the client it is talking to authorization server A when it is talking to B, or reusing credentials issued by one against another. The three changes close those doors.
1. The iss parameter must be validated
The authorization server should include the iss parameter in its authorization responses. And the client must validate that iss against the issuer it recorded, before redeeming the authorization code.
This is the protection against authorization server substitution. Without the check, a client that started a flow toward A can receive a response crafted by B and redeem its code in the wrong place.
What to verify on your side:
- If you operate an authorization server, does it actually emit
iss? - If you wrote an MCP client, does it validate
issbefore the code exchange, not after? - Is a failed validation treated as a rejection rather than a warning?
That last point is the one people miss. A check that logs and continues protects nothing.
2. application_type must be specified at registration
The client must declare an appropriate application_type when registering, to avoid OpenID Connect redirect URI conflicts.
The problem it solves is concrete. OIDC applies different constraints depending on whether a client is native or web, particularly on allowed redirect URIs (localhost, custom schemes, strict HTTPS). A command-line MCP client and a web application do not have the same needs, and the authorization server cannot guess.
If you build a client, declare the right type. If you operate an authorization server, decide what you do with registrations that omit it.
3. Credentials are bound to their issuer
A client's credentials are bound to the authorization server that issued them. Concretely: they must be stored keyed by issuer, and the client must re-register if the authorization server changes.
This is the easiest rule to break by accident, because many clients store a client_id and a client_secret in a global config, as if there were only one. That works while you talk to a single server. From two onward, you reuse credentials where they have no standing, and behaviour depends on how tolerant the other side is.
The fix is structural: your storage key is not the service name, it is the issuer.
And Dynamic Client Registration
On top of the three, OAuth 2.0 Dynamic Client Registration is formally deprecated as a registration mechanism, in favour of Client ID Metadata Documents.
It still works for backwards compatibility, but it is on a clock. That is a separate project, covered in its own article.
What this means if you operate an MCP server
Many teams read these changes as "a client problem". Partly true. But three things concern you directly:
Your authorization server has to emit iss****. If you delegate to an identity provider, verify it does so in the configuration you actually use, not just in theory.
Your in-house clients are MCP clients. The internal script that calls your own server falls under the same rules, and it is almost always the loosest of the lot.
Your integration documentation has to follow. If you explain to customers how to connect, your code samples become the reference they copy. A sample that skips iss validation propagates the flaw.
The most frequent mistakes
Validating after the code exchange. The check has to happen before, or it protects nothing.
One credential set for every server. See point 3. That is the default by convenience, not by decision.
Treating authorization as settled once. The protocol now has a deprecation policy and a conformance suite. Auth is the area most likely to keep moving across revisions.
Confusing authentication with per-tool authorization. Knowing who is calling does not say what they are allowed to call. A valid token that opens every tool is the most widespread default in production.
FAQ
Do I have to rebuild everything?
No. These three changes are added checks, not a new architecture. A few days if your OAuth chain is clean, longer if credentials are stored globally.
I use an identity provider, am I covered?
Partly. The provider handles issuance, but client-side validation and issuer-keyed storage remain yours.
Does this block a connector directory submission?
A non-conformant OAuth chain is one of the most classic reasons for rejection. Do this upgrade before preparing a submission, not after.
Get your OAuth chain checked
The audit covers all three points, plus credential storage, scope granularity and per-client revocation. Within 24 business hours you get the report and a quote.
Ready to check? Get my MCP server audited →
Related reading
Got an MCP server to audit?
Five minutes to describe it. I reply within one business day with a first written diagnosis, free of charge.
Get my MCP server audited