Fastmcp Oauth Poc
FastMCP OAuth Integration with Okta
Ask AI about Fastmcp Oauth Poc
Powered by Claude · Grounded in docs
I know everything about Fastmcp Oauth Poc. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
FastMCP Demo Server
This project demonstrates a FastMCP server with custom JWT and authentication, leveraging Remote OAuth with Dynamic Client Registration (DCR) via Okta, and deployed to Google Cloud Run. Valkey is used as optional session backend.
1. Introduction
This FastMCP server is configured to use either RemoteAuthProvider for and OAuthProxy authentication.
RemoteAuthProvider is designed for identity providers supporting Dynamic Client Registration (DCR). This allows MCP clients to automatically register and obtain credentials, streamlining authentication for automated systems. Okta is used as the identity provider in this demonstration. While generally the recommended option,
OAuthProxy OAuth Proxy enables authentication with OAuth providers that don’t support Dynamic Client Registration (DCR) by presenting a DCR-compliant interface to MCP clients while using your pre-registered credentials with the upstream provider.
NOTE: Okta supports DCR, and I recommend the use of RemoteAuthProvider in our internal setup. A great general decision guide for the protocol to use is available on the FastMCP Auth page.
Demo Video

And if the session times out during a chat:

2. Local Development
To run the application locally, you need to start the Valkey server, the MCP server, and the inspector separately.
2.1. Start Local MCP Server
Export the desired set of environment variables. E.g.:
export $(grep -v '^#' .env.auth_proxy | xargs)
uv run main.py
2.2. Start Inspector
npx @modelcontextprotocol/inspector
2.3. Start Valkey Server (Docker)
This server can optionally use Valkey (Redis-compatible) as a session backend to store call counts for authenticated users.
To disable the Valkey session backend, set the ENABLE_VALKEY_SESSION_BACKEND environment variable to false in your .env file:
ENABLE_VALKEY_SESSION_BACKEND=true
Ensure that a Valkey instance is running and accessible at the VALKEY_URL specified in your environment variables (default: redis://localhost:6379/0).
docker run --name valkey-server -p 6379:6379 valkey/valkey
To remove Valkey:
docker rm valkey-server
3. Configuration
Environment variables are used to configure the application. A .env file is provided for local development and is loaded by docker-compose.
Environment Variables
For details on which variables are required, please check out the example .env files, auth.py and the FastMCP documentation. We are keeping the documentation minimal here.
- FastMCP
FASTMCP_LOG_LEVEL: Log level for FastMCP (default:INFO)MCP_SERVER_NAME: Name of the MCP server (default:demo-server)MCP_SERVER_HOST: Host for the MCP server (default:127.0.0.1)MCP_SERVER_PORT: Port for the MCP server (default:8000)MCP_SERVER_BASE_URL: For Auth Flows. This value might be different than Host and Port if behind reverse proxy
- Session Management
ENABLE_VALKEY_SESSION_BACKEND: Enable or disable the Valkey session backend (default:true)VALKEY_URL: URL for the Valkey (Redis) instance (default:redis://localhost:6379/0)
- OAuth
ENABLE_AUTH: Enable or disable authentication (default:True)OAUTH_AUTHORIZATION_ENDPOINT: Authorization server URL (default:https://<your-auth-provider>.com/oauth2/v1/authorize)OAUTH_SCOPES: Space-separated list of required OAuth scopes (default:openid email)OAUTH_JWKS_URI: JWKS URI for token verification (default:https://<your-auth-provider>.com/oauth2/v1/keys?client_id=<your-cleint-id>)OAUTH_ISSUER: OAuth2 issuer URL (default:https://<your-auth-provider>.com)OAUTH_AUDIENCE: OAuth2 audience (default:https://<your-auth-provider>.com)OAUTH_TOKEN_ENDPOINT: OAuth2 token endpoint. Only required for OAuthProxy.OAUTH_CLIENT_ID: OAuth2 Client ID. Only required for OAuthProxy.OAUTH_CLIENT_SECRET: OAuth2 Client Secret. Only required for OAuthProxy.OAUTH_REDIRECT_PATH: Optional Custom redirect path for OAuth Proxy.
5. RemoteAuthProvider
When using the RemoteAuthProvider the Okta Application must be configured as Single Page Application. The biggest advantage is that we do not need to handle any secrets using this method and the client configuration remains minimal, thus flexible and will support various clients. The FastMCP Server Auth documentation also outlines when to use this method.
sequenceDiagram
participant Client
participant FastMCPServer as FastMCP Server
participant OktaIDP as Okta Identity Provider
Client->>FastMCPServer: 1. GET /.well-known/oauth-protected-resource
FastMCPServer-->>Client: 2. "Use Okta for auth"
%% Client retrieves authorization server metadata
Client->>OktaIDP: 3. GET /.well-known/oauth-authorization-server
OktaIDP-->>Client: 4. Authorization Server Metadata
Note right of Client: Register Client - Dynamic Client Registration (DCR)
%% Client proceeds with authorization
Client->>OktaIDP: 5. Authorization Request with Redirect URI
Activate OktaIDP
Note right of Client: User Authenticates with Auth Provider
OktaIDP-->>Client: 7. Redirect with Authorization Code
Client->>OktaIDP: 8. Token Request with Authorization Code
OktaIDP-->>Client: 9. Access Token & ID Token
Deactivate OktaIDP
Client->>FastMCPServer: 10. MCP request with Bearer token
FastMCPServer->>FastMCPServer: 11. Verify token signature
FastMCPServer-->>Client: 12. MCP response
Okta: General Settings (SPA)
- Client ID: e.g.
0oatjlyvubHBNtamB4x7(Public identifier for the client) - Client authentication: None
- PKCE: Proof Key for Code Exchange (PKCE) is required as additional verification)
- Application type: Single Page App (SPA)
- Proof of possession: Not required
- Grant types:
- Authorization Code
- User consent: Require consent
Okta: Login Configuration (SPA) for Dev
- Sign-in redirect URIs:
http://localhost:6274/oauth/callback/debug(for the MCP Inspector)http://127.0.0.1:6274/oauth/callback/debug(for the MCP Inspector)http://127.0.0.1:6274/oauth/callback(for the MCP Inspector)http://localhost:6274/oauth/callback(for the MCP Inspector)http://localhost:3080/api/mcp/oauth-api-server/oauth/callback(for LibreChat)
- Sign-out redirect URIs:
http://localhost:6274 - Login initiated by: App Only
Librechat with RemoteAuthProvider
Unfortunately, LibreChat does not support the discovery though the .well-known/oauth-authorization-server endpoint (yet). For this reason, the configuration needs to be a little more verbose.
mcpServers:
oauth-api-server:
type: streamable-http
url: http://host.docker.internal:8000/mcp
startup: false
oauth:
client_id: 0oatjlyvubHBNtamB4x7
authorization_url: https://<your-auth-provider>.okta.com/oauth2/v1/authorize
token_url: https://<your-auth-provider>.okta.com/oauth2/v1/token
redirect_uri: http://localhost:3080/api/mcp/oauth-api-server/oauth/callback
scope: "openid email"
code_challenge_methods_supported: ["S256"]
grant_types_supported: ["authorization_code"]
MCP Inspector with RemoteAuthProvider
Set the Client ID (e.g. 0oatjlyvubHBNtamB4x7) in the authentication config.
6. OAuthProxy
When using the OAuthProxy the Okta Application must be configured as Web Application.
Okta: General Settings (Web Application)
- Client ID: e.g.
<your-cleint-id>(Public identifier for the client) - Client authentication: Client Secret (Post)
- Application type: Web Application
- Proof of possession: Not required
- Grant types:
- Authorization Code
- Refresh Token
- User consent: Require consent
Okta: Login Configuration (Web Application)
Equal to Single Page application above.
Librechat with OAuthProxy
This configuration is used when the backend of the UI (as is the case for LibreChat) is authenticating, and Okta is set up as a Web Application, requiring a client secret.
NOTE: This is an odd setup, because we are bypassing the proxy here and again set client_id and client_secret which should not be necessary. There seem to be limitations in the OAuth implementation with LibreChat at the moment.
mcpServers:
oauth-api-server:
type: streamable-http
url: http://host.docker.internal:8000/mcp
startup: false
oauth:
client_id: <your-cleint-id>
client_secret: <client_secret>
authorization_url: https://<your-auth-provider>.com/oauth2/v1/authorize
token_url: https://<your-auth-provider>.com/oauth2/v1/token
redirect_uri: http://localhost:3080/api/mcp/oauth-api-server/oauth/callback
scope: "openid email"
code_challenge_methods_supported: ["S256"]
grant_types_supported: ["authorization_code"]
Note: The latest LibreChat image also seems to be a bit broken regarding auth, hence using a slightly earlier Librechat version until fixed: ghcr.io/danny-avila/librechat-dev:a1471c2f37f127ab87cc951d040c62c5c5bd5475
