fastmcp/examples/auth/api_key_oauth/server.py

51 lines
1.6 KiB
Python

"""A FastMCP server protected by API-key-backed OAuth.
OAuth-only clients (Claude Desktop, ChatGPT) connect, get redirected to a
"paste your API key" page, and from then on the server can read each user's key
inside tools — without those clients ever needing to send a custom header.
To run:
python server.py
Then point an OAuth-capable MCP client at http://127.0.0.1:8000/mcp, or use the
companion client.py.
"""
from provider import API_KEY_CLAIM, APIKeyOAuthProvider
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_access_token
SERVER_URL = "http://127.0.0.1:8000"
def validate_api_key(key: str) -> bool:
# Replace with a real check against your service. Returning True here means
# any non-empty key is accepted at the authorize step.
return bool(key)
auth = APIKeyOAuthProvider(
base_url=SERVER_URL,
# Derives the token signing key and the storage encryption key. Load this
# from your secret store in production; the same secret keeps previously
# issued tokens valid across restarts.
jwt_signing_key="change-me-to-a-real-secret",
validate_api_key=validate_api_key,
)
mcp = FastMCP("API-Key OAuth Demo", auth=auth)
@mcp.tool
def whoami() -> str:
"""Return the API key the current user authenticated with."""
token = get_access_token()
api_key = token.claims[API_KEY_CLAIM]
# In a real server you would instantiate your client here, e.g.
# client = my_service.Client(api_key=api_key)
return f"Authenticated with API key: {api_key[:4]}"
if __name__ == "__main__":
mcp.run(transport="http", host="127.0.0.1", port=8000)