docs/python-sdk/fastmcp-server-auth-oauth_proxy-models.mdx
fastmcp.server.auth.oauth_proxy.modelsOAuth Proxy Models and Constants.
This module contains all Pydantic models and constants used by the OAuth proxy.
OAuthTransaction <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L44" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>OAuth transaction state for consent flow.
Stored server-side to track active authorization flows with client context. Includes CSRF tokens for consent protection per MCP security best practices.
ConsentCSRFToken <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L70" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>One CSRF token issued for one render of the consent page.
Stored under a key derived from the token itself rather than on the
transaction. Every render of a consent page issues its own token, and two
renders can be in flight at once (a reload, a browser preload, an extension
re-fetching the URL). Appending to a list on the transaction loses one of
them whenever that happens: AsyncKeyValue has no compare-and-swap, so two
handlers read the same transaction, each append their own token, and the
second write drops the first. Giving each token its own key makes the
writes independent, which holds across processes sharing one backend.
ClientCode <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L87" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Client authorization code with PKCE and upstream tokens.
Stored server-side after upstream IdP callback. Contains the upstream tokens bound to the client's PKCE challenge for secure token exchange.
UpstreamTokenSet <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L105" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Stored upstream OAuth tokens from identity provider.
These tokens are obtained from the upstream provider (Google, GitHub, etc.) and stored in plaintext within this model. Encryption is handled transparently at the storage layer via FernetEncryptionWrapper. Tokens are never exposed to MCP clients.
JTIMapping <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L127" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Maps FastMCP token JTI to upstream token ID.
This allows stateless JWT validation while still being able to look up the corresponding upstream token when tools need to access upstream APIs.
RefreshTokenMetadata <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L139" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Metadata for a refresh token, stored keyed by token hash.
We store only metadata (not the token itself) for security - if storage is compromised, attackers get hashes they can't reverse into usable tokens.
ProxyDCRClient <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L208" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Client for DCR proxy with configurable redirect URI validation.
This special client class is critical for the OAuth proxy to work correctly with Dynamic Client Registration (DCR). Here's why it exists:
When MCP clients use OAuth, they dynamically register with random localhost ports (e.g., http://localhost:55454/callback). The OAuth proxy needs to:
This class validates redirect URIs against configurable patterns, while the proxy internally uses its own fixed redirect URI with the upstream provider. This allows the flow to work even when clients reconnect with different ports or when tokens are cached.
Without proper validation, clients could get "Redirect URI not registered" errors when trying to authenticate with cached tokens, or security vulnerabilities could arise from accepting arbitrary redirect URIs.
Methods:
validate_redirect_uri <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/server/auth/oauth_proxy/models.py#L256" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>validate_redirect_uri(self, redirect_uri: AnyUrl | None) -> AnyUrl
Validate redirect URI against proxy patterns and optionally CIMD redirect_uris.
For CIMD clients: validates against BOTH the CIMD document's redirect_uris AND the proxy's allowed patterns (if configured). Both must pass.
For DCR clients: validates against proxy patterns when configured. Without proxy patterns, validates against registered redirect_uris while allowing loopback ports to vary for MCP client compatibility.