Automatic MCP server generator for FastAPI applications - converts FastAPI endpoints to MCP tools for LLM integration
—
Complete OAuth 2.0 authentication system designed for MCP compliance. FastAPI-MCP integrates seamlessly with FastAPI's dependency injection system while providing MCP-specific OAuth flows, proxy configurations, and dynamic client registration.
Configure OAuth 2.0 authentication for MCP clients with extensive customization options.
class AuthConfig:
version: Literal["2025-03-26"] = "2025-03-26"
dependencies: Sequence[params.Depends] = None
issuer: str = None
oauth_metadata_url: StrHttpUrl = None
authorize_url: StrHttpUrl = None
audience: str = None
default_scope: str = "openid profile email"
client_id: str = None
client_secret: str = None
custom_oauth_metadata: OAuthMetadataDict = None
setup_proxies: bool = False
setup_fake_dynamic_registration: bool = True
metadata_path: str = "/.well-known/oauth-authorization-server"
def __init__(self, **data):
"""
Configure OAuth 2.0 authentication for MCP.
Parameters:
- version: MCP spec version (currently only "2025-03-26" supported)
- dependencies: FastAPI dependencies for authentication/authorization checks
- issuer: OAuth 2.0 server issuer (required if custom_oauth_metadata not provided)
- oauth_metadata_url: Full URL of OAuth provider's metadata endpoint
- authorize_url: OAuth authorization endpoint URL
- audience: Default audience for OAuth requests (fallback when client doesn't specify)
- default_scope: Default OAuth scope (fallback when client doesn't specify)
- client_id: OAuth client ID (required if setup_proxies is True)
- client_secret: OAuth client secret (required if setup_fake_dynamic_registration is True)
- custom_oauth_metadata: Custom OAuth metadata to register
- setup_proxies: Whether to setup MCP-compliant OAuth proxies
- setup_fake_dynamic_registration: Whether to setup fake dynamic client registration
- metadata_path: Path to mount OAuth metadata endpoint
"""from fastapi import Depends, HTTPException, Request
from fastapi.security import HTTPBearer
from fastapi_mcp import FastApiMCP, AuthConfig
# Authentication dependency
security = HTTPBearer()
async def authenticate_request(request: Request, token: str = Depends(security)):
# Verify token logic here
if not verify_token(token.credentials):
raise HTTPException(status_code=401, detail="Unauthorized")
return {"user_id": "extracted_from_token"}
# Configure authentication
auth_config = AuthConfig(
dependencies=[Depends(authenticate_request)],
issuer="https://your-auth-provider.com",
client_id="your-client-id",
setup_proxies=True
)
mcp_server = FastApiMCP(
fastapi=app,
auth_config=auth_config
)Define OAuth 2.0 server metadata according to RFC 8414 for MCP clients.
class OAuthMetadata:
issuer: StrHttpUrl
authorization_endpoint: StrHttpUrl = None
token_endpoint: StrHttpUrl
scopes_supported: List[str] = ["openid", "profile", "email"]
response_types_supported: List[str] = ["code"]
grant_types_supported: List[str] = ["authorization_code", "client_credentials"]
token_endpoint_auth_methods_supported: List[str] = ["none"]
code_challenge_methods_supported: List[str] = ["S256"]
registration_endpoint: StrHttpUrl = None
def __init__(self, **data):
"""
OAuth 2.0 Server Metadata according to RFC 8414.
Parameters:
- issuer: Authorization server's issuer identifier (required)
- authorization_endpoint: Authorization endpoint URL (required for authorization_code grant)
- token_endpoint: Token endpoint URL (required)
- scopes_supported: List of supported OAuth scopes
- response_types_supported: List of supported response types
- grant_types_supported: List of supported grant types
- token_endpoint_auth_methods_supported: List of supported token endpoint auth methods
- code_challenge_methods_supported: List of supported PKCE code challenge methods
- registration_endpoint: Client registration endpoint URL (optional)
"""
def model_dump(self, **kwargs) -> Dict[str, Any]:
"""
Serialize to dictionary with OAuth-specific defaults.
Always excludes unset and None fields for client compatibility.
"""from fastapi_mcp import AuthConfig, OAuthMetadata
# Custom OAuth metadata
oauth_metadata = OAuthMetadata(
issuer="https://api.example.com",
authorization_endpoint="https://auth.example.com/oauth/authorize",
token_endpoint="https://auth.example.com/oauth/token",
scopes_supported=["read", "write", "admin"],
grant_types_supported=["authorization_code", "client_credentials"],
registration_endpoint="https://auth.example.com/oauth/register"
)
auth_config = AuthConfig(
custom_oauth_metadata=oauth_metadata,
dependencies=[Depends(authenticate_request)]
)Models for OAuth 2.0 dynamic client registration (RFC 7591).
class ClientRegistrationRequest:
redirect_uris: List[str]
client_name: Optional[str] = None
grant_types: Optional[List[str]] = ["authorization_code"]
token_endpoint_auth_method: Optional[str] = "none"
def __init__(self, **data):
"""
OAuth 2.0 dynamic client registration request.
Parameters:
- redirect_uris: List of redirect URIs for the client
- client_name: Human-readable client name
- grant_types: List of OAuth grant types the client will use
- token_endpoint_auth_method: Authentication method for token endpoint
"""
class ClientRegistrationResponse:
client_id: str
client_id_issued_at: int
client_secret: Optional[str] = None
client_secret_expires_at: int = 0
redirect_uris: List[str]
grant_types: List[str]
token_endpoint_auth_method: str
client_name: str
def __init__(self, **data):
"""
OAuth 2.0 dynamic client registration response.
Parameters:
- client_id: Generated client identifier
- client_id_issued_at: Time when client_id was issued (Unix timestamp)
- client_secret: Client secret (if applicable)
- client_secret_expires_at: Client secret expiration time (0 = never expires)
- redirect_uris: Registered redirect URIs
- grant_types: Registered grant types
- token_endpoint_auth_method: Token endpoint authentication method
- client_name: Human-readable client name
"""Seamlessly integrate with existing FastAPI authentication systems:
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
return {"username": username}
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
# Use with MCP
auth_config = AuthConfig(
dependencies=[Depends(get_current_user)],
issuer="https://your-app.com",
client_id="mcp-client"
)Configure for external OAuth providers like Auth0, Okta, or custom solutions:
# Auth0 configuration
auth_config = AuthConfig(
issuer="https://your-tenant.auth0.com",
oauth_metadata_url="https://your-tenant.auth0.com/.well-known/openid_configuration",
authorize_url="https://your-tenant.auth0.com/authorize",
client_id="your-auth0-client-id",
audience="https://your-api.com",
setup_proxies=True
)
# Okta configuration
auth_config = AuthConfig(
issuer="https://your-org.okta.com/oauth2/default",
client_id="your-okta-client-id",
setup_proxies=True,
default_scope="openid profile email api:read"
)Automatically setup MCP-compliant proxy endpoints around existing OAuth providers:
auth_config = AuthConfig(
issuer="https://external-oauth-provider.com",
client_id="your-client-id",
client_secret="your-client-secret",
setup_proxies=True, # Creates MCP-compliant proxy endpoints
setup_fake_dynamic_registration=True # Adds dynamic client registration
)
# This automatically creates:
# GET /.well-known/oauth-authorization-server - OAuth metadata
# GET /oauth/authorize - Authorization proxy
# POST /oauth/register - Dynamic client registration (fake)For development or internal use without authentication:
# No authentication required
mcp_server = FastApiMCP(fastapi=app) # No auth_config
# Or with custom metadata but no auth checks
auth_config = AuthConfig(
custom_oauth_metadata=OAuthMetadata(
issuer="https://api.example.com",
token_endpoint="https://api.example.com/token"
)
# No dependencies specified
)Support multiple OAuth providers by configuring different auth configs for different routes:
# Different auth configs for different API versions
v1_auth = AuthConfig(
issuer="https://legacy-auth.com",
client_id="legacy-client"
)
v2_auth = AuthConfig(
issuer="https://new-auth.com",
client_id="new-client",
setup_proxies=True
)
# Mount different MCP servers with different auth
v1_mcp = FastApiMCP(app, auth_config=v1_auth)
v1_mcp.mount_http(mount_path="/mcp/v1")
v2_mcp = FastApiMCP(app, auth_config=v2_auth)
v2_mcp.mount_http(mount_path="/mcp/v2")Forward specific authentication headers from MCP clients to API endpoints:
auth_config = AuthConfig(
dependencies=[Depends(api_key_auth)],
# ... other config
)
mcp_server = FastApiMCP(
fastapi=app,
auth_config=auth_config,
headers=["authorization", "x-api-key", "x-tenant-id"] # Forward these headers
)Install with Tessl CLI
npx tessl i tessl/pypi-fastapi-mcp