MCP servers in production need to migrate to OAuth Resource Servers under the June 2025 spec
Anyone still using a static API key risks becoming incompatible with MCP clients that already follow the 2025-06-18 revision of the specification.

The 2025-06-18 revision of the Model Context Protocol turned every MCP server into an OAuth Resource Server. Anyone still using a static API key risks becoming incompatible with MCP clients that already follow this revision of the specification.
If your company's MCP server (Model Context Protocol) still authenticates clients with a fixed key in a custom header, it is running against a version of the specification that was superseded more than a year ago. The protocol's official changelog, published for the 2025-06-18 revision, formalized an authorization model that classifies MCP servers as OAuth Resource Servers and changes how MCP clients and specification-compliant agents negotiate access to an MCP server.
Anyone who deployed an MCP server in 2024 or early 2025, before this revision, likely implemented authentication on their own: a static token, an API key in the Authorization header, or not even that. The June 2025 revision formalized a specific authorization model, and that has concrete implications for anyone who already has a service running.
What the Changelog Actually Changed
The source document lists this change as the third item under "major changes": classifying MCP servers as OAuth Resource Servers, with protected resource metadata to point to the corresponding Authorization Server.

Classify MCP servers as OAuth Resource Servers, adding protected resource metadata to discover the corresponding Authorization server.
Model Context Protocol, 2025-06-18 specification
In practice, this means the MCP server is no longer responsible for validating credentials on its own. It delegates that function to an external Authorization Server (which could be Auth0, Okta, Keycloak, or a custom provider) and only needs to announce where that server is.
The changelog also brings two changes that catch out anyone who only skimmed the migration headline:
- Mandatory Resource Indicators (RFC 8707): MCP clients now need to declare which server the token was requested for, preventing a token issued for one service from being reused on another (the classic "confused deputy" attack).
- Mandatory
MCP-Protocol-Versionheader: every HTTP request after the initial handshake must declare the negotiated protocol version, not just the first one.
Why the Old Auth Model Becomes a Risk
An MCP server with a fixed API key works fine as long as only one trusted client accesses it. The problem appears when the same token circulates among multiple agents, third-party integrations, or automated pipelines: there is no way to revoke a specific client's access without breaking all the others, and there is no validation that the token was issued for that server.
With Resource Indicators, the flow requires the token to carry an audience claim (aud) matching the requested resource. A server that doesn't validate this claim remains vulnerable even after "migrating" by simply switching the transport to HTTPS with a Bearer token: the point of the change is validation, not just the header format.
Step-by-Step to Migrate an Existing MCP Server
Editor's note: the code in this section was not run in a real environment. Validate it before using it in production.
1. Map the Current Auth Flow
Before touching any code, identify where identity verification happens today: middleware that reads a custom header, an API key check against a database, or no real verification at all. This inventory determines how much of the flow can be preserved and how much needs to be replaced by a dedicated Authorization Server.
2. Expose the Protected Resource Metadata
The server needs to respond on a well-known endpoint with the data of the Authorization Server that protects the resource. A minimal example response:
{
"resource": "https://mcp.suaempresa.com",
"authorization_servers": [
"https://auth.suaempresa.com"
],
"bearer_methods_supported": ["header"]
}This is the document an MCP client consults before starting the OAuth flow, instead of assuming the MCP server itself validates the password.
3. Validate the Resource Indicator in the Received Token
The point most people skip: receiving a valid Bearer token isn't enough, you need to confirm it was issued for this resource. An example check in Node.js, assuming a JWT with an aud claim:
function validarToken(payload, resourceEsperado) {
const audiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
if (!audiences.includes(resourceEsperado)) {
throw new Error('Token não emitido para este recurso');
}
return true;
}Without this check, the server accepts a stolen or leaked token from another integration, even if the JWT's signature is valid.
4. Add the Version Header to Every Request
The spec no longer accepts MCP-Protocol-Version only in the initial handshake. Every subsequent request over HTTP needs to declare the negotiated version. A simple middleware handles this:
app.use((req, res, next) => {
const versao = req.headers['mcp-protocol-version'];
if (versao !== '2025-06-18') {
return res.status(400).json({ error: 'protocol_version_mismatch' });
}
next();
});5. Test Locally Before Releasing to Production
To validate the flow without depending on real infrastructure, spin up the MCP server on localhost and a test Authorization Server (Keycloak in a container, for example). Point a test MCP client at the local metadata endpoint and confirm three things: the client can discover the Authorization Server via the metadata, the authorization flow returns a token with the correct aud, and the server rejects tokens with a different audience.
What Breaks If the Server Doesn't Migrate
MCP clients that already follow the 2025-06-18 revision expect to find the Protected Resource Metadata endpoint before negotiating access. A server that doesn't expose it may simply fail the handshake silently, depending on how the client handles the absence of that metadata. More seriously: a server that accepts any Bearer token without validating the Resource Indicator is exposed to the reuse of tokens issued for other services, exactly the scenario RFC 8707 was designed to close.
The change from SHOULD to MUST in the Lifecycle Operation section reinforces this point: what used to be a best-practice recommendation became a compliance requirement. Servers that ignore this part of the spec aren't simply "outdated," they are outside the specification that modern clients assume as the standard.
When It's Not Worth Migrating Right Now
If the MCP server runs only internally, behind a VPN, with a single trusted client and no external exposure, the cost of implementing a full Authorization Server may not pay off in the short term. In that scenario, it's worth keeping an eye on the official changelog and planning the migration as part of a security hardening cycle, not as an emergency fix. The real risk appears when the server serves multiple clients or is accessed by third-party agents, in which case audience validation stops being optional.
Source 1: Model Context Protocol, Specification Changelog (2025-06-18) (https://modelcontextprotocol.io/specification/2025-06-18/changelog)
Key Changes - Model Context Protocol
Documentation Index Fetch the complete documentation index at: /llms.txt Use this file to discover all available pages before exploring further. Skip to main content This document lists changes made to the Model Context Protocol (MCP) specification since the previous revision, 2025-03-26 .
Major changes
Remove support for JSON-RPC batching (PR #416 )
Add support for structured tool output (PR #371 )
Classify MCP servers as OAuth Resource Servers , adding protected resource metadata to discover the corresponding Authorization server. (PR #338 )
Require MCP clients to implement Resource Indicators as described in RFC 8707 to prevent malicious servers from obtaining access tokens. (PR #734 )
Clarify security considerations and best practices in the authorization spec and in a new security best practices page .
Add support for elicitation , enabling servers to request additional information from users during interactions. (PR #382 )
Add support for resource links in tool call results. (PR #603 )
Require negotiated protocol version to be specified via MCP-Protocol-Version header in subsequent requests when using HTTP (PR #548 ).
Change SHOULD to MUST in Lifecycle Operation
Other schema changes
Add _meta field to additional interface types (PR #710 ), and specify proper usage .
Add context field to CompletionRequest , providing for completion requests to include previously-resolved variables (PR #598 ).
Add title field for human-friendly display names, so that name can be used as a programmatic identifier (PR #663 )
Full changelog For a complete list of all changes that have been made since the last protocol revision, see GitHub . Was this page helpful? Yes No Assistant Responses are generated using AI and may contain mistakes.
Translated from the Brazilian Portuguese original · Read the original
PHP2Shell: critical flaws in PHP's core found by AI affect WordPress, Drupal, and Joomla
Researchers using models like GPT-5.6 Sol and Gemini 4 Argon independently discovered two flaws in PHP's core that allow attackers to break into websites without a password. The patch was released this week, after two months of silent coordination.





