Secure Your FastMCP Server: 3 Auth Patterns That Scale
FastMCP offers three complementary ways to protect your MCP servers over HTTP/SSE, ranging from simple token checks to a full OAuth 2.0 stack. This guide summarizes each pattern, when to use it, and how to get started—complete with architecture diagrams you can share with your team.
Reference: see the FastMCP Authentication docs: Authentication — FastMCP.
Pattern 1: Token Validation (JWT Verifier)
Validate structured tokens (typically JWTs) that were issued elsewhere. Your FastMCP server acts as a resource server: it trusts tokens signed by a known issuer and focuses on authorization based on claims.
- When it fits: you already have an IdP/API gateway issuing JWTs; microservices need consistent validation; lowest implementation complexity.
- What you manage: verification config (issuer, audience, JWKS URI) and authorization logic.
- What you delegate: user authentication and token issuance.
Architecture
flowchart TD
A[Client] -->|Bearer token| B[FastMCP Server]
B --> C[JWT Verifier]
C -->|fetch keys| D[Issuer JWKS]
C -->|verify signature+exp+aud+iss| E{Valid?}
E -- yes --> F[Authorize & Serve]
E -- no --> G[401/403]
Diagram walkthrough
- Client sends a request with a Bearer access token.
- FastMCP passes the token to the JWT verifier component.
- Verifier fetches public keys from the issuer’s JWKS (and caches them).
- Verifier checks signature, expiration/nbf, issuer, and audience claims.
- If valid, the server enforces authorization (scopes/claims) and serves; otherwise it returns 401/403.
Minimal setup
from fastmcp import FastMCP
from fastmcp.server.auth.providers.jwt import JWTVerifier
auth = JWTVerifier(
jwks_uri="https://your-auth-system.com/.well-known/jwks.json",
issuer="https://your-auth-system.com",
audience="your-mcp-server",
)
mcp = FastMCP(name="Protected Server", auth=auth)
Environment-based configuration also works well for deployments:
export FASTMCP_SERVER_AUTH=JWT
export FASTMCP_SERVER_AUTH_JWT_JWKS_URI="https://auth.example.com/jwks"
export FASTMCP_SERVER_AUTH_JWT_ISSUER="https://auth.example.com"
export FASTMCP_SERVER_AUTH_JWT_AUDIENCE="mcp-server"
Pattern 2: Remote OAuth (External Identity Provider)
Advertise OAuth metadata so MCP clients can automatically discover how to obtain tokens from a trusted external provider (e.g., WorkOS, Auth0, Azure AD). FastMCP validates tokens while the IdP handles login, MFA, recovery, and security hardening.
- When it fits: production apps needing enterprise-grade auth without building it yourself; consistent SSO; dynamic client registration.
- What you manage: which IdPs you trust and your authorization rules.
- What you delegate: all user authentication flows and token lifecycle.
Architecture
flowchart LR
A[Client] -->|Discover OAuth metadata| B[FastMCP Server]
B --> C[OAuth Discovery Endpoints]
A -->|Obtain token| D[External IdP]
D -->|JWT/OIDC token| A
A -->|Bearer token| B
B --> E[Token Verifier]
E -->|validate| F{Valid?}
F -- yes --> G[Authorize & Serve]
F -- no --> H[401/403]
Diagram walkthrough
- Client discovers the server’s OAuth metadata endpoints exposed by FastMCP.
- Using that metadata, the client obtains a token from the external IdP (e.g., device flow, client credentials).
- The IdP issues an OIDC/JWT access token to the client.
- Client calls the FastMCP server with the Bearer token.
- FastMCP validates the token using the verifier (via the IdP’s JWKS) and authorizes on success; otherwise 401/403.
Minimal setup (example: WorkOS AuthKit)
from fastmcp import FastMCP
from fastmcp.server.auth.providers.workos import AuthKitProvider
auth = AuthKitProvider(
authkit_domain="https://your-project.authkit.app",
base_url="https://your-fastmcp-server.com",
)
mcp = FastMCP(name="Enterprise Server", auth=auth)
Pattern 3: Full OAuth (Built-in Authorization Server)
Run the entire OAuth 2.0 authorization server inside FastMCP. You implement credential verification, consent, token issuance/refresh, client registration, and storage.
- When it fits: air-gapped or highly specialized environments; strict compliance; bespoke flows you must own end-to-end.
- Trade-off: maximum control with maximum complexity and ongoing security responsibilities.
Architecture
flowchart TD
subgraph FastMCP Server
B[Resource Endpoints]
C[Authorization Endpoint]
D[Token Endpoint]
E[Client Registry]
F[User Store]
end
A[Client] -->|Authorize| C
C -->|Consent/AuthN| F
C -->|Code| A
A -->|Code| D
D -->|Access/Refresh Tokens| A
A -->|Bearer token| B
B -->|Authorize & Serve| A
Diagram walkthrough
- Client initiates authorization at the Authorization Endpoint.
- FastMCP authenticates the user and handles consent using the configured user store/policies.
- Authorization Endpoint returns an authorization code to the client.
- Client exchanges the code at the Token Endpoint for access (and optionally refresh) tokens.
- Client calls protected resource endpoints with the access token; server validates and authorizes based on scopes/claims.
- Client registry maintains client IDs/secrets and allowed grant types.
Minimal structure
from fastmcp import FastMCP
from fastmcp.server.auth.providers.oauth import MyOAuthProvider
auth = MyOAuthProvider(
user_store=your_user_database,
client_store=your_client_registry,
# additional configuration...
)
mcp = FastMCP(name="Auth Server", auth=auth)
Choosing Your Path (Quick Guide)
Pattern | Control | Complexity | Best for |
---|---|---|---|
Token Validation | Low | Low | Teams with existing JWT/SSO issuing tokens |
Remote OAuth | Medium | Medium | Production apps needing enterprise IdP integration |
Full OAuth | High | High | Specialized/air-gapped environments with strict requirements |
Tips:
- Start simple with Token Validation if your platform already issues JWTs.
- Prefer Remote OAuth for most production use-cases; it balances features and effort.
- Choose Full OAuth only when you have clear, compelling reasons and the expertise to own it securely.
Further Reading
- FastMCP Authentication overview: Authentication — FastMCP