Authentication and Security
Relevant source files
The following files were used as context for generating this wiki page:The Model Context Protocol (MCP) Python SDK implements a robust security model based on OAuth 2.0, ensuring secure communication between clients and servers. The architecture emphasizes modern security standards, including Proof Key for Code Exchange (PKCE) and a clear separation of concerns between Authorization Servers and Resource Servers, compliant with RFC 9728. This ensures that MCP servers can protect their resources effectively while delegating the complexities of user authentication and token issuance to a dedicated service.
The system is designed for flexibility, supporting both the modern decoupled architecture and providing backwards compatibility for legacy implementations where an MCP server might also act as its own Authorization Server. Security is a top priority, with a formal process for reporting vulnerabilities managed through HackerOne.
Sources: examples/servers/simple-auth/README.md, SECURITY.md
Architecture
The authentication architecture follows the RFC 9728 specification, which separates the roles of the Authorization Server (AS) and the Resource Server (RS).
- Resource Server (RS): This is the MCP Server itself. Its primary role is to serve MCP tools and resources. It protects these resources and requires a valid access token for access. It does not handle user authentication directly.
- Authorization Server (AS): This is a separate server responsible for authenticating users and issuing access tokens. The RS trusts the AS to perform this function correctly.
This separation allows the MCP server (RS) to focus on its core logic, while the AS can be a specialized identity provider.
Sources: examples/servers/simple-auth/README.md:3-5
Discovery Flow
The client discovers the necessary endpoints through a standardized discovery process.
This diagram illustrates the discovery process where a client first contacts the Resource Server to find the Authorization Server, and then contacts the Authorization Server to get the specific OAuth endpoints.
- The client makes a GET request to the Resource Server's discovery endpoint:
/.well-known/oauth-protected-resource. - The Resource Server responds with a JSON object containing the URL(s) of its trusted Authorization Server(s).
- The client then makes a GET request to the Authorization Server's metadata endpoint:
/.well-known/oauth-authorization-server. - The Authorization Server responds with its metadata, including the
authorization_endpointandtoken_endpoint.
Sources: examples/servers/simple-auth/README.md:27-44
Backwards Compatibility
For older MCP implementations, the client supports a fallback mechanism. If the /.well-known/oauth-protected-resource endpoint returns a 404, the client will attempt to find the OAuth metadata directly at the MCP server's /.well-known/oauth-authorization-server endpoint. This allows the client to work with legacy servers that act as their own Authorization Server.
Sources: examples/servers/simple-auth/README.md:67-73
OAuth 2.0 Authorization Code Flow with PKCE
The SDK uses the Authorization Code grant with PKCE, which is the recommended secure flow for public clients like command-line tools or desktop applications.
The following diagram shows the complete sequence from client registration to token revocation.
This sequence demonstrates the key steps: dynamic client registration, the PKCE-enhanced authorization code flow, token refresh, and token revocation.
Sources: tests/server/fastmcp/auth/test_auth_integration.py:734-825
Server-Side Components
Authorization Server Provider
The core of the server-side authentication logic is the OAuthAuthorizationServerProvider. This is an abstract base class that defines the contract for handling OAuth operations. A concrete implementation of this provider must be supplied to the server.
The MockOAuthProvider in the integration tests serves as a reference implementation, defining the necessary data stores and logic for a complete OAuth flow.
Sources: tests/server/fastmcp/auth/test_auth_integration.py:22-205
Key Data Models and Provider Interface
This diagram shows the abstract OAuthAuthorizationServerProvider and the main data structures it manages for tokens and authorization codes.
Sources: tests/server/fastmcp/auth/test_auth_integration.py:22-205
Bearer Token Authentication Middleware
Incoming requests to protected endpoints are handled by a chain of middleware that authenticates the user based on a Bearer token.
BearerAuthBackend
This backend is responsible for extracting and validating the token from the Authorization header.
This flowchart outlines the logic of the BearerAuthBackend in processing the Authorization header to authenticate a request.
Sources: tests/server/auth/middleware/test_bearer_auth.py:102-149
RequireAuthMiddleware
This middleware enforces authentication and authorization on specific routes. It checks if a user has been authenticated by a preceding backend and if they possess the required scopes for the requested operation.
- If the user is not authenticated, it returns a
401 Unauthorizedresponse. - If the user is authenticated but lacks the necessary scopes, it returns a
403 Forbiddenresponse. - If the user is authenticated and has the required scopes, it passes the request to the next application in the ASGI stack.
Sources: tests/server/auth/middleware/test_bearer_auth.py:284-394
API Endpoints
The Authorization Server exposes several standard OAuth 2.0 endpoints.
| Endpoint | Method | Description |
|---|---|---|
/.well-known/oauth-authorization-server | GET | Provides server metadata, including other endpoint URLs, supported grant types, and PKCE methods. |
/register | POST | Allows dynamic client registration. The client sends its metadata (e.g., redirect_uris, client_name) and receives a client_id and client_secret. |
/authorize | GET/POST | Initiates the authorization flow. The user is redirected here to grant consent. It requires parameters like client_id, redirect_uri, code_challenge, and response_type=code. |
/token | POST | Used to exchange an authorization code for an access token (grant_type=authorization_code) or to refresh an access token (grant_type=refresh_token). |
/revoke | POST | Revokes an access or refresh token, invalidating it. Per the RFC, this endpoint always returns a 200 OK response, even for invalid tokens, to prevent leaking information about token validity. |
Sources: tests/server/fastmcp/auth/test_auth_integration.py, examples/servers/simple-auth/README.md
Client-Side Authentication
The client-side implementation handles the OAuth flow transparently. When connecting to a server, it performs the discovery process described above. The client will open the system's default browser to the authorization URL for the user to complete the authentication and consent flow. After authorization, it automatically handles the token exchange and subsequent token refreshes.
Sources: examples/clients/simple-auth-client/README.md:16-20
Security Reporting
The project maintains a formal security policy for reporting vulnerabilities. All security issues should be reported through Anthropic's HackerOne program to ensure they are handled promptly and securely. The program's guidelines are defined on the HackerOne program page.
Sources: SECURITY.md:5-15
Summary
The authentication and security system within the MCP Python SDK is a comprehensive implementation of modern, standardized protocols. By separating the Authorization and Resource Server roles (RFC 9728) and mandating the secure PKCE flow, it provides a strong foundation for protecting MCP resources. The system is built for both correctness and developer experience, with clear interfaces for server-side implementation and a transparent, automated flow for client-side consumers. The formal security disclosure process underscores the project's commitment to maintaining a secure ecosystem.