This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 5, 2026. Spotted a mistake? Tell us.
A remote MCP server holds tools, data and actions that a model can invoke. Authorization is what stops any client that knows the URL from using them. The Model Context Protocol answers this with OAuth 2.1 and a small set of discovery standards.
Short answer: an HTTP-based MCP server acts as an OAuth 2.1 resource server. A client that has no token gets a 401 with a pointer to the server's protected-resource metadata, discovers the authorization server, registers itself dynamically, runs the authorization code flow with PKCE and a resource parameter, and then sends a bearer token that is scoped to that one MCP server.
The three roles
The MCP authorization spec reuses the OAuth roles:
- MCP client: the AI application or agent runtime. In OAuth terms it is the client.
- MCP server: the service exposing tools and resources. In OAuth terms it is the resource server.
- Authorization server: the system that authenticates the user, gets consent and issues access tokens. It can be the same service as the MCP server or a separate identity provider.
The spec makes authorization optional for MCP implementations, but when an HTTP transport supports it, the implementation should follow the specification. STDIO transports should not use this flow; they should take credentials from the environment.
The flow, step by step
- The client calls the MCP server without a token.
- The server returns 401 Unauthorized with a WWW-Authenticate header that points at its protected-resource metadata.
- The client fetches the metadata document from the server, normally at /.well-known/oauth-protected-resource, and reads the authorization_servers field.
- The client fetches the authorization server metadata at /.well-known/oauth-authorization-server, following RFC 8414.
- The client registers itself with the authorization server using dynamic client registration (RFC 7591), unless the server provides client credentials another way.
- The client generates PKCE parameters and sends the user to the authorization endpoint with the code challenge and the resource parameter.
- The authorization server authenticates the user, obtains consent, and redirects back with an authorization code.
- The client exchanges the code and the verifier at the token endpoint, again including the resource parameter.
- The client calls the MCP server with Authorization: Bearer and the access token.
The spec is deliberate about discovery: MCP clients must use protected-resource metadata to find the authorization server, and must use the authorization server metadata document. Hard-coding endpoints is not the intended design.
What the spec requires
| Requirement | Level | What it means in practice |
|---|---|---|
| OAuth 2.1 with appropriate security measures | MUST for authorization servers | Code flow with PKCE, no implicit flow, exact redirect URI matching |
| Protected Resource Metadata (RFC 9728) | MUST for MCP servers | Publish authorization_servers and the resource identifier |
| Authorization Server Metadata (RFC 8414) | MUST for authorization servers | Publish endpoints, supported grants and signing keys |
| Dynamic Client Registration (RFC 7591) | SHOULD | Let clients register without manual paperwork |
| PKCE | MUST for clients | A fresh verifier per authorization request, S256 |
| Resource parameter (RFC 8707) | MUST for clients | Include the MCP server URI in both the authorization and token requests |
| Audience validation | MUST for servers | Reject tokens that were not issued for this server |
| Bearer token in the Authorization header | MUST | Never put the token in the query string |
Why the resource parameter matters
The resource parameter is the part teams most often skip. It tells the authorization server which API the token is for. Without it, a token issued for one MCP server can be replayed against another server that trusts the same authorization server. With it, the token is bound to the intended audience, and the MCP server can verify that it is the intended recipient.
The spec also forbids token passthrough: if an MCP server calls an upstream API, it must not forward the token it received from the client. It obtains a separate token for the upstream service, as an OAuth client in its own right. This is what prevents the confused-deputy problem where a downstream API trusts a token that was never meant for it.
Common mistakes
- Using OAuth without PKCE. The MCP spec builds on OAuth 2.1, which requires PKCE for authorization code flows. A client that omits it is not compliant.
- Skipping protected-resource metadata. A server that only returns a bare 401 forces clients to guess the authorization server. Publish the metadata document.
- Accepting any bearer token. Validate the issuer, signature, expiry and audience. A token minted for another service is not valid here.
- Putting tokens in URLs. Bearer tokens belong in the Authorization header, not in query strings or logs.
- Using OAuth for STDIO servers. Local STDIO servers should read credentials from the environment, not run a browser flow.
- Passing the client's token upstream. Exchange it for a token that the upstream API issued for the MCP server.
Where Casdoor fits
Casdoor is an OpenID Connect and OAuth 2.0 identity provider that can act as the authorization server in this flow. It supports the authorization code flow with PKCE (S256), publishes authorization server metadata, supports dynamic client registration, and can restrict an application to specific redirect URIs. The MCP server still has to implement protected-resource metadata and audience validation; those are server responsibilities, not the identity provider's.
For the client side, see connecting ChatGPT to an MCP server and adding an MCP server to Claude. For the OAuth mechanics underneath, see PKCE and OAuth for AI agents. Casdoor is open source and self-hostable; Casdoor Cloud starts at $9 per month for a dedicated instance.
Related reading: MCP authorization servers compared, dynamic client registration and token introspection.
Sources
- MCP specification 2025-06-18: Authorization
- MCP security best practices
- RFC 9728: OAuth 2.0 Protected Resource Metadata
- RFC 8414: OAuth 2.0 Authorization Server Metadata
- RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol
- RFC 8707: Resource Indicators for OAuth 2.0
- OAuth 2.1 draft
Product names are trademarks of their respective owners.