Client: Authenticating with a Server
Relevant source files
The following files were used as context for generating this wiki page:
The MCP Python SDK provides a robust authentication mechanism for clients to securely connect with MCP servers using the OAuth 2.0 Authorization Code Flow with Proof Key for Code Exchange (PKCE). This ensures that communication is authorized and secure.
The authentication system is designed to be compliant with modern standards, specifically RFC 9728, which promotes the separation of the Resource Server (the MCP server) from a dedicated Authorization Server. For backwards compatibility, the system also supports a legacy mode where an MCP server can act as its own Authorization Server. The client SDK is capable of discovering and adapting to both architectures automatically.
Authentication Architecture
The SDK supports two primary architectural models for authentication.
Modern Architecture (RFC 9728)
This is the recommended architecture, which separates the roles of the Authorization Server (AS) and the Resource Server (RS).
- Resource Server (RS): The MCP server that provides tools and resources. It is responsible for validating access tokens but does not issue them.
- Authorization Server (AS): A separate server responsible for authenticating users, obtaining consent, and issuing access and refresh tokens.
This separation of concerns enhances security and modularity. The RS validates tokens by communicating with the AS's introspection endpoint.
Sources: examples/servers/simple-auth/README.md
Legacy Architecture (Backwards Compatibility)
For compatibility with older MCP implementations, a legacy mode is supported where the MCP server itself acts as both the Resource Server and the Authorization Server.
- Combined AS/RS: The MCP server provides its own OAuth endpoints (
/authorize,/token) and validates tokens internally. - No RFC 9728 Discovery: This architecture does not use the
/.well-known/oauth-protected-resourcediscovery endpoint.
The client SDK can automatically detect and fall back to this mode if the modern discovery mechanism fails.
Sources: examples/servers/simple-auth/README.md
Service Discovery
The client automatically discovers the necessary OAuth endpoints. The process differs slightly between the modern and legacy architectures.
This diagram illustrates the client's discovery logic.
Modern Discovery
- The client first queries the Resource Server (MCP Server) at the
/.well-known/oauth-protected-resourceendpoint. - The RS responds with a JSON object containing a list of
authorization_servers. - The client then queries the Authorization Server's
/.well-known/oauth-authorization-serverendpoint to get the specific URLs for authorization, token exchange, and other functions.
Sources: examples/servers/simple-auth/README.md
Legacy Discovery Fallback
- If the request to
/.well-known/oauth-protected-resourcefails (e.g., with a 404 error), the client assumes a legacy architecture. - It then directly queries the
/.well-known/oauth-authorization-serverendpoint on the MCP server itself to discover the auth endpoints.
Sources: examples/servers/simple-auth/README.md
Authorization Code Flow with PKCE
The SDK implements the standard OAuth 2.0 Authorization Code Flow with PKCE to securely obtain tokens.
The following sequence diagram shows the complete interaction between the user, client, Authorization Server, and Resource Server.
OAuth Endpoints
The authentication process involves several key server endpoints.
| Endpoint | HTTP Method | Description |
|---|---|---|
/.well-known/oauth-authorization-server | GET | Provides metadata about the AS, including other endpoint URLs. |
/register | POST | Allows dynamic client registration. Enabled via ClientRegistrationOptions. |
/authorize | GET, POST | Initiates the authorization flow, redirecting the user for login and consent. |
/token | POST | Exchanges an authorization code or a refresh token for a new access token. |
/revoke | POST | Revokes an access or refresh token. Enabled via RevocationOptions. |
/introspect | POST | Used by the Resource Server to validate an access token with the Authorization Server. |
Sources: tests/server/fastmcp/auth/test_auth_integration.py:400-421, 550-562, examples/servers/simple-auth/README.md
Key Data Structures
OAuthToken
This structure holds the tokens returned by the Authorization Server.
| Field | Type | Description |
|---|---|---|
access_token | string | The token used to access protected resources. |
token_type | string | The type of token, typically "Bearer". |
expires_in | int | The lifetime in seconds of the access token. |
refresh_token | string | Token used to obtain a new access token. |
scope | string | The scope of the access token. |
Sources: tests/server/fastmcp/auth/test_auth_integration.py:87-103
Error Handling
The authentication flow includes robust error handling as defined by the OAuth 2.0 specification. If something goes wrong during the process, the Authorization Server will respond with a specific error code.
| Error Code | Description |
|---|---|
invalid_request | The request is missing a required parameter, includes an invalid parameter, or is otherwise malformed. |
invalid_grant | The provided authorization grant (e.g., authorization code, refresh token) or PKCE verifier is invalid. |
invalid_client | Client authentication failed (e.g., unknown client, no client authentication included). |
unsupported_grant_type | The authorization grant type is not supported by the authorization server. |
invalid_scope | The requested scope is invalid, unknown, or malformed. |
invalid_client_metadata | The client registration metadata is invalid. |
Sources: tests/server/fastmcp/auth/test_auth_integration.py:424-436, 459-467, 501-509, 878-888
Client Configuration
The example authentication client can be configured using environment variables.
| Variable | Description | Default |
|---|---|---|
MCP_SERVER_PORT | The port of the MCP server to connect to. | 8000 |
MCP_TRANSPORT_TYPE | The transport to use: streamable_http or sse. | streamable_http |