New in version: 2.6.0
Authentication and authorization are only relevant for HTTP-based transports.
The MCP specification requires servers to implement full OAuth 2.1 authorization flows with dynamic client registration, server metadata discovery, and complete token endpoints. FastMCP’s Bearer Token authentication provides a simpler, more practical alternative by directly validating pre-issued JWT tokens—ideal for service-to-service communication and programmatic environments where full OAuth flows may be impractical, and in accordance with how the MCP ecosystem is pragmatically evolving. However, please note that since it doesn’t implement the full OAuth 2.1 flow, this implementation does not strictly comply with the MCP specification.
Bearer Token authentication is a common way to secure HTTP-based APIs. In this model, the client sends a token (usually a JSON Web Token or JWT) in the Authorization header with the “Bearer” scheme. The server then validates this token to grant or deny access. FastMCP supports Bearer Token authentication for its HTTP-based transports (http and sse), allowing you to protect your server from unauthorized access.

Authentication Strategy

FastMCP uses asymmetric encryption for token validation, which provides a clean security separation between token issuers and FastMCP servers. This approach means:
  • No shared secrets: Your FastMCP server never needs access to private keys or client secrets
  • Public key verification: The server only needs a public key (or JWKS endpoint) to verify token signatures
  • Secure token issuance: Tokens are signed by an external service using a private key that never leaves the issuer
  • Scalable architecture: Multiple FastMCP servers can validate tokens without coordinating secrets
This design allows you to integrate FastMCP servers into existing authentication infrastructures without compromising security boundaries.

Configuration

To enable Bearer Token validation on your FastMCP server, use the BearerAuthProvider class. This provider validates incoming JWTs by verifying signatures, checking expiration, and optionally validating claims.
The BearerAuthProvider validates tokens; it does not issue them (or implement any part of an OAuth flow). You’ll need to generate tokens separately, either using FastMCP utilities or an external Identity Provider (IdP) or OAuth 2.1 Authorization Server.

Basic Setup

To configure bearer token authentication, instantiate a BearerAuthProvider instance and pass it to the auth parameter of the FastMCP instance. The BearerAuthProvider requires either a static public key or a JWKS URI (but not both!) in order to verify the token’s signature. All other parameters are optional — if they are provided, they will be used as additional validation criteria.
from fastmcp import FastMCP
from fastmcp.server.auth import BearerAuthProvider

auth = BearerAuthProvider(
    jwks_uri="https://my-identity-provider.com/.well-known/jwks.json",
    issuer="https://my-identity-provider.com/",
    algorithm="RS512",
    audience="my-mcp-server"
)

mcp = FastMCP(name="My MCP Server", auth=auth)

Configuration Parameters

BearerAuthProvider Configuration

public_key
str
RSA public key in PEM format for static key validation. Required if jwks_uri is not provided
jwks_uri
str
URL for JSON Web Key Set endpoint. Required if public_key is not provided
issuer
str | None
Expected JWT iss claim value
algorithm
str | None
Algorithm for decoding JWT token. Defaults to ‘RS256’
audience
str | None
Expected JWT aud claim value
required_scopes
list[str] | None
Global scopes required for all requests

Public Key

If you have a public key in PEM format, you can provide it to the BearerAuthProvider as a string.
from fastmcp.server.auth import BearerAuthProvider
import inspect

public_key_pem = inspect.cleandoc(
    """
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy...
    -----END PUBLIC KEY-----
    """
)

auth = BearerAuthProvider(public_key=public_key_pem)

JWKS URI

provider = BearerAuthProvider(
    jwks_uri="https://idp.example.com/.well-known/jwks.json"
)
JWKS is recommended for production as it supports automatic key rotation and multiple signing keys.

Generating Tokens

For development and testing, FastMCP provides the RSAKeyPair utility class to generate tokens without needing an external OAuth provider.
The RSAKeyPair utility is intended for development and testing only. For production, use a proper OAuth 2.1 Authorization Server or Identity Provider.

Basic Token Generation

from fastmcp import FastMCP
from fastmcp.server.auth import BearerAuthProvider
from fastmcp.server.auth.providers.bearer import RSAKeyPair

# Generate a new key pair
key_pair = RSAKeyPair.generate()

# Configure the auth provider with the public key
auth = BearerAuthProvider(
    public_key=key_pair.public_key,
    issuer="https://dev.example.com",
    audience="my-dev-server"
)

mcp = FastMCP(name="Development Server", auth=auth)

# Generate a token for testing
token = key_pair.create_token(
    subject="dev-user",
    issuer="https://dev.example.com",
    audience="my-dev-server",
    scopes=["read", "write"]
)

print(f"Test token: {token}")

Token Creation Parameters

The create_token() method accepts these parameters:

create_token() Parameters

subject
str
default:"fastmcp-user"
JWT subject claim (usually user ID)
issuer
str
default:"https://fastmcp.example.com"
JWT issuer claim
audience
str | None
JWT audience claim
scopes
list[str] | None
OAuth scopes to include
expires_in_seconds
int
default:"3600"
Token expiration time in seconds
additional_claims
dict | None
Extra claims to include in the token
kid
str | None
Key ID for JWKS lookup

Accessing Token Claims

Once authenticated, your tools, resources, or prompts can access token information using the get_access_token() dependency function:
from fastmcp import FastMCP, Context, ToolError
from fastmcp.server.dependencies import get_access_token, AccessToken

@mcp.tool
async def get_my_data(ctx: Context) -> dict:
    access_token: AccessToken = get_access_token()
    
    user_id = access_token.client_id  # From JWT 'sub' or 'client_id' claim
    user_scopes = access_token.scopes
    
    if "data:read_sensitive" not in user_scopes:
        raise ToolError("Insufficient permissions: 'data:read_sensitive' scope required.")
    
    return {
        "user": user_id,
        "sensitive_data": f"Private data for {user_id}",
        "granted_scopes": user_scopes
    }

AccessToken Properties

AccessToken Properties

token
str
The raw JWT string
client_id
str
Authenticated principal identifier
scopes
list[str]
Granted scopes
expires_at
datetime | None
Token expiration timestamp