{
  "slug": "mcp-server-authentication",
  "title": "MCP Server Authentication: OAuth 2.1 for Remote Servers",
  "description": "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.",
  "category": "Reference",
  "tags": [
    "mcp",
    "oauth",
    "authentication",
    "security",
    "pkce",
    "agents",
    "protocols"
  ],
  "updated": "2026-08-03",
  "premium": false,
  "canonical": "https://changegamer.ai/resources/mcp-server-authentication",
  "markdown": "https://changegamer.ai/resources/mcp-server-authentication.md",
  "outline": [
    {
      "depth": 2,
      "text": "Key facts",
      "anchor": "key-facts"
    },
    {
      "depth": 2,
      "text": "Transport split: stdio vs Streamable HTTP",
      "anchor": "transport-split-stdio-vs-streamable-http"
    },
    {
      "depth": 2,
      "text": "The OAuth 2.1 model for remote MCP servers",
      "anchor": "the-oauth-2-1-model-for-remote-mcp-servers"
    },
    {
      "depth": 2,
      "text": "Discovery chain (what a client must do)",
      "anchor": "discovery-chain-what-a-client-must-do"
    },
    {
      "depth": 2,
      "text": "Resource Indicators (RFC 8707): the audience-binding mechanism",
      "anchor": "resource-indicators-rfc-8707-the-audience-binding-mechanism"
    },
    {
      "depth": 2,
      "text": "Security guidance summary",
      "anchor": "security-guidance-summary"
    },
    {
      "depth": 2,
      "text": "ChangeGamer's own /mcp endpoint",
      "anchor": "changegamer-s-own-mcp-endpoint"
    },
    {
      "depth": 2,
      "text": "Verified sources",
      "anchor": "verified-sources"
    }
  ],
  "related": [
    {
      "slug": "mcp-enterprise-managed-authorization",
      "title": "MCP Enterprise-Managed Authorization: Zero-Touch SSO via ID-JAG (SEP-990)",
      "description": "What Enterprise-Managed Authorization is: the MCP extension (SEP-990) that lets an IdP grant MCP server access during SSO instead of a per-server OAuth consent screen — the ID-JAG mechanism, the RFCs it builds on, and how it layers on standard MCP OAuth 2.1.",
      "url": "https://changegamer.ai/resources/mcp-enterprise-managed-authorization"
    },
    {
      "slug": "agent-identity-authentication",
      "title": "Agent Identity and Authentication",
      "description": "How autonomous agents prove who they are and get authorized to act: workload identity vs. delegated authority, SPIFFE/SPIRE, cloud workload federation, OAuth token exchange, audience binding, and emerging standards — with practical guidance and verified sources.",
      "url": "https://changegamer.ai/resources/agent-identity-authentication"
    },
    {
      "slug": "agent-delegation-chains",
      "title": "Agent Delegation Chains: Credential Propagation in Multi-Agent Systems",
      "description": "How credential authority flows when one agent spawns another — the multi-hop delegation problem, RFC 8693 token exchange, the act/may_act claims, audience binding across hops, and the IETF drafts standardizing verifiable actor chains in 2026.",
      "url": "https://changegamer.ai/resources/agent-delegation-chains"
    },
    {
      "slug": "ai-supply-chain-provenance",
      "title": "AI Supply Chain Provenance: SBOMs, SLSA, and Artifact Signing for Agents and MCP Servers",
      "description": "How CycloneDX AI/ML-BOM, SPDX AI profiles, SLSA build levels, and in-toto/Sigstore signing let an agent check what is actually inside a model, package, or MCP server — and how it was built — before trusting it.",
      "url": "https://changegamer.ai/resources/ai-supply-chain-provenance"
    }
  ],
  "furtherReading": [
    {
      "slug": "mcp-oauth-implementation",
      "title": "How to Implement OAuth 2.1 for an MCP Server",
      "description": "A wire-level implementation walkthrough for OAuth 2.1 on a remote MCP server: what the discovery documents actually contain, CIMD vs. Dynamic Client Registration in your server code, per-SEP detail from the 2026-07-28 hardening set, and token-validation mechanics.",
      "url": "https://changegamer.ai/articles/mcp-oauth-implementation"
    },
    {
      "slug": "mcp-server-in-production",
      "title": "MCP Server in Production: How to Build, Ship and Run One",
      "description": "The operator playbook for taking an MCP server past the quickstart: transport choice, OAuth 2.1 auth, tool design, versioning against a moving spec, testing across clients, distribution, observability, cost and the failure modes that show up once real clients connect.",
      "url": "https://changegamer.ai/articles/mcp-server-in-production"
    }
  ],
  "body": "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.\n\n## Key facts\n\n- The two MCP transports use fundamentally different auth models: local stdio servers use no OAuth at all (credentials are injected directly), while remote Streamable HTTP servers require the full OAuth 2.1 flow.\n- In the MCP spec's OAuth model the MCP server only acts as a Resource Server that validates bearer tokens — it never issues them; a separate Authorization Server handles that.\n- Since the 2025-06-18 spec revision, clients discover authorization servers through a two-step metadata chain (RFC 9728, then RFC 8414) rather than relying on the old hardcoded fallback endpoints.\n- PKCE is mandatory for every client in the flow, with no exemption for confidential clients, and the spec's security guidance narrows the acceptable code-challenge hashing to just one option, S256.\n- RFC 8707 Resource Indicators bind an issued token's audience to one specific MCP server, which is what prevents a confused-deputy attack where a token for one server gets replayed against another.\n- A server is not allowed to simply relay the credential it received from its caller on to some other API it depends on; if it needs upstream access, it must go get its own token for that.\n- ChangeGamer's own /mcp endpoint is currently unauthenticated, with no OAuth flow and no RFC 9728 metadata implemented, gating only paid resource content via an application-layer `api_key` argument rather than OAuth.\n\n## Transport split: stdio vs Streamable HTTP\n\n**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.\n\n**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.\n\n## The OAuth 2.1 model for remote MCP servers\n\nThe MCP spec assigns roles clearly:\n\n- **MCP server** = OAuth 2.1 Resource Server. It accepts Bearer tokens, validates them, and serves tool/resource responses. It does NOT issue tokens.\n- **Authorization Server (AS)** = a separate service (e.g. Auth0, Keycloak, or a custom server) that authenticates users/clients and issues tokens.\n\nThis 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.\n\n## Discovery chain (what a client must do)\n\nThe 2025-06-18 spec removed hardcoded fallback endpoints (`/authorize`, `/token`, `/register`) in favor of a two-step metadata discovery defined by two RFCs:\n\n**Step 1 — Protected Resource Metadata (RFC 9728)**\nThe 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.\n\n**Step 2 — Authorization Server Metadata (RFC 8414)**\nThe 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`.\n\n**Step 3 — Client registration (RFC 7591 / CIMD)**\nIf the client does not yet have a client ID at the AS, it registers before the flow. The 2025-11-25 spec revision set a priority order: (1) pre-registration; (2) Client ID Metadata Documents (CIMD) — the `client_id` is an HTTPS URL pointing to a JSON document describing the client — now the preferred path (SHOULD); (3) Dynamic Client Registration (RFC 7591), downgraded to MAY and retained for backward compatibility only.\n\n**Step 4 — Authorization with PKCE (mandatory)**\nThe 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.\n\n**Step 5 — Token exchange and calling the MCP server**\nThe 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.\n\n## Resource Indicators (RFC 8707): the audience-binding mechanism\n\nRFC 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.\n\nThe 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).\n\n**Why this matters — the confused-deputy attack:**\nWithout 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.\n\n**Token passthrough is explicitly forbidden:**\nAn 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.\n\n## Security guidance summary\n\n- Validate token audience on every request; reject tokens not issued for your server's URI.\n- Issue short-lived access tokens; use refresh tokens for sessions.\n- Never forward a client's Bearer token to an upstream service.\n- PKCE with S256 is the only code challenge method that should be used.\n- All endpoints must be HTTPS; Bearer tokens in URI query strings are forbidden.\n- Use per-agent OAuth client registrations, not shared client IDs across agent instances (see /resources/agentic-security-checklist, section 10).\n- For protocol context on where MCP auth fits relative to A2A auth, see /resources/mcp-vs-a2a.\n\n## ChangeGamer's own /mcp endpoint\n\nChangeGamer 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.\n\n## Verified sources\n\n- MCP authorization spec (2025-06-18): https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization\n- MCP authorization spec (2025-11-25): https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization\n- RFC 9728 — OAuth 2.0 Protected Resource Metadata (April 2025): https://datatracker.ietf.org/doc/html/rfc9728\n- RFC 8414 — OAuth 2.0 Authorization Server Metadata: https://datatracker.ietf.org/doc/html/rfc8414\n- RFC 7591 — OAuth 2.0 Dynamic Client Registration Protocol: https://datatracker.ietf.org/doc/html/rfc7591\n- RFC 8707 — Resource Indicators for OAuth 2.0 (February 2020): https://datatracker.ietf.org/doc/html/rfc8707\n- MCP 2026-07-28 spec (shipped final, on schedule — hardens issuer validation per RFC 9207, DCR application_type, issuer binding; does not change the PKCE / RFC 8707 / RFC 9728 requirements): https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/",
  "sources": [
    "https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization",
    "https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization",
    "https://datatracker.ietf.org/doc/html/rfc9728",
    "https://datatracker.ietf.org/doc/html/rfc8414",
    "https://datatracker.ietf.org/doc/html/rfc7591",
    "https://datatracker.ietf.org/doc/html/rfc8707",
    "https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/"
  ]
}