Skip to content
Wiki

MCP authorization makes an HTTP server an OAuth resource server that advertises its authorization server via 401 and RFC 9728 metadata

DrFritzi · Reviewed · Updated 28 Sept 2026 · Markdown

Answer

In MCP, authorization is optional and applies to HTTP transports. A protected MCP server is an OAuth 2.1 resource server. It must publish OAuth 2.0 Protected Resource Metadata (RFC 9728) that names at least one authorization server in authorization_servers. An unauthenticated request gets 401 with a WWW-Authenticate header that can carry a resource_metadata URL. The client discovers the authorization server, registers, runs an authorization code flow with PKCE and an RFC 8707 resource parameter, and sends Authorization: Bearer <token> on every request. This page describes specification 2026-07-28, the latest revision. Servers on stdio SHOULD NOT follow this flow and instead get credentials from the environment.

Details

Step by step

# Client action Server response
1 MCP request without a token MCP server: 401 Unauthorized, WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource", optionally scope="files:read"
2 GET the resource_metadata URL. Without that parameter, try /.well-known/oauth-protected-resource/<endpoint path>, then /.well-known/oauth-protected-resource MCP server: metadata with authorization_servers
3 Pick an authorization server, GET its metadata (/.well-known/oauth-authorization-server, then /.well-known/openid-configuration) Authorization server: metadata. The issuer must equal the issuer used to build the URL
4 Check that code_challenge_methods_supported is present, otherwise stop
5 Get a client ID (see below) Authorization server
6 Browser to the authorization endpoint with code_challenge (S256), resource, scopes Authorization server: user consents, redirects with a code (and iss)
7 Token request with code_verifier and resource Authorization server: access token
8 MCP request with Authorization: Bearer <token> MCP server: validates audience, then answers. Bad or expired token: 401. Insufficient scope: 403 with error="insufficient_scope"

Client registration

Clients that support every option SHOULD prefer, in order: pre-registered client information, Client ID Metadata Documents (when the authorization server sets client_id_metadata_document_supported), Dynamic Client Registration (when it offers a registration_endpoint), then asking the user. With a Client ID Metadata Document, the client_id is an HTTPS URL with a path that serves a JSON document with at least client_id, client_name and redirect_uris. Dynamic Client Registration (RFC 7591) is deprecated in this revision and kept for backwards compatibility.

Server duties

  • Validate that the token was issued for this server as audience, and reject others (RFC 8707).
  • Never pass the received token to an upstream API. If you call one, use a separate token from that API's authorization server.
  • The resource value is the server's canonical URI, for example https://mcp.example.com/mcp, with no fragment.

Common mistakes

  • Serving no Protected Resource Metadata at all. The spec requires one of the WWW-Authenticate header or a well-known URI.
  • Accepting any valid token from the same authorization server without an audience check.
  • Forwarding the client's token to a third-party API.
  • Putting the access token in the URL query string. The spec forbids it.
  • Treating scope as fixed. Clients must treat the challenged scopes as authoritative for the current operation.
  • Applying this flow to a stdio server.

See also

Sources