ChangeGamer

← All resources

MCP Server Authentication: OAuth 2.1 for Remote Servers

Reference · updated 2026-06-15 · Markdown variant

How OAuth 2.1 works for remote MCP servers: transport differences, Protected Resource Metadata discovery, PKCE, Resource Indicators, and token-audience security — with a step-by-step client flow and honest notes on what ChangeGamer's own /mcp endpoint does.


Remote MCP authentication is one of the most commonly misunderstood parts of the spec. The confusion usually comes from conflating the two transports, which have completely different auth models.

Transport split: stdio vs Streamable HTTP

stdio (local) — the MCP server runs as a child process on the same machine as the client. No network exposure. Credentials (API keys, tokens for upstream services the server calls) are injected via environment variables or the host process. The MCP spec explicitly states that stdio implementations SHOULD NOT follow the HTTP-based OAuth authorization spec — OAuth is not applicable here.

Streamable HTTP (remote) — the MCP server is a network endpoint. This is the transport that requires OAuth 2.1. The 2025-06-18 MCP spec revision made Streamable HTTP the current standard remote transport (replacing the older HTTP+SSE transport) and simultaneously overhauled the auth section, mandating RFC 9728, RFC 8707, and removing the old fallback-endpoint discovery in favour of explicit metadata discovery.

The OAuth 2.1 model for remote MCP servers

The MCP spec assigns roles clearly:

This separation means the MCP server has no knowledge of credentials — it only validates tokens it receives. Any MCP server that issues its own tokens is operating outside the spec.

Discovery chain (what a client must do)

The 2025-06-18 spec removed hardcoded fallback endpoints (/authorize, /token, /register) in favor of a two-step metadata discovery defined by two RFCs:

Step 1 — Protected Resource Metadata (RFC 9728) The client fetches /.well-known/oauth-protected-resource from the MCP server's base URL. This JSON document (the Protected Resource Metadata) lists which authorization servers are trusted for this resource. RFC 9728 was published in April 2025 after an 8-year standardization process.

Step 2 — Authorization Server Metadata (RFC 8414) The client fetches /.well-known/oauth-authorization-server from the authorization server URL found in step 1. This document provides the authorization_endpoint, token_endpoint, and registration_endpoint.

Step 3 — Client registration (RFC 7591) If the client does not yet have a client ID at that AS, it may dynamically register via the registration endpoint (RFC 7591 Dynamic Client Registration). As of the 2025-11-25 spec revision, RFC 7591 support is optional rather than required — the spec also recognizes Client ID Metadata Documents as an alternative.

Step 4 — Authorization with PKCE (mandatory) The client performs an OAuth 2.1 authorization code flow with PKCE (Proof Key for Code Exchange). PKCE is mandatory for all clients — there is no PKCE exemption for confidential clients in the MCP spec. The client generates a code verifier, derives a code challenge (S256), and includes the resource parameter (RFC 8707, see below) in the authorization request and token request.

Step 5 — Token exchange and calling the MCP server The client exchanges the authorization code + code verifier for an access token, then calls the MCP server with Authorization: Bearer <token>. The MCP server validates the token and its audience before responding.

Resource Indicators (RFC 8707): the audience-binding mechanism

RFC 8707 (Resource Indicators for OAuth 2.0, February 2020) adds a resource parameter to OAuth authorization and token requests. The client includes the MCP server's URL as the resource value. The AS then issues a token whose audience (aud claim) is bound to that specific MCP server.

The MCP spec (2025-06-18 and later) requires MCP clients to use RFC 8707 and requires MCP servers to validate that received tokens were issued for them as the intended audience (per RFC 8707 Section 2).

Why this matters — the confused-deputy attack: Without audience binding, an attacker could obtain a legitimate token for a low-privilege MCP server and replay it against a different MCP server that trusts the same AS. RFC 8707 closes this by making the token audience explicit and server-specific.

Token passthrough is explicitly forbidden: An MCP server that receives a Bearer token from a client and forwards that same token to an upstream API violates the spec and creates a confused-deputy vulnerability. If the MCP server needs to call an upstream API on behalf of the client, it must obtain a separate token from the upstream authorization server using its own credentials.

Security guidance summary

ChangeGamer's own /mcp endpoint

ChangeGamer runs a remote MCP server at https://changegamer.ai/mcp using the Streamable HTTP transport. It is currently unauthenticated — no OAuth flow is required to connect. It is open and read-only. Premium resource bodies still require an api_key argument passed to the get_resource tool; this is an application-layer key check, not OAuth. ChangeGamer does not implement RFC 9728 Protected Resource Metadata at this time.

Verified sources

#mcp #oauth #authentication #security #pkce #agents #protocols

Category: Reference