Spaces:
Running
Running
Jeremiah Lowin
Add OAuth proxy that allows authentication with social IDPs without DCR support (#1434)
f5238eb unverified | --- | |
| title: Google OAuth 🤝 FastMCP | |
| sidebarTitle: Google OAuth | |
| description: Secure your FastMCP server with Google OAuth | |
| icon: google | |
| tag: NEW | |
| --- | |
| import { VersionBadge } from "/snippets/version-badge.mdx" | |
| <VersionBadge version="2.12.0" /> | |
| This guide shows you how to secure your FastMCP server using **Google OAuth**. Since Google doesn't support Dynamic Client Registration, this integration uses the [**OAuth Proxy**](/servers/auth/oauth-proxy) pattern to bridge Google's traditional OAuth with MCP's authentication requirements. | |
| ## Configuration | |
| ### Prerequisites | |
| Before you begin, you will need: | |
| 1. A **[Google Cloud Account](https://console.cloud.google.com/)** with access to create OAuth 2.0 Client IDs | |
| 2. Your FastMCP server's URL (can be localhost for development, e.g., `http://localhost:8000`) | |
| ### Step 1: Create a Google OAuth 2.0 Client ID | |
| Create an OAuth 2.0 Client ID in your Google Cloud Console to get the credentials needed for authentication: | |
| <Steps> | |
| <Step title="Navigate to OAuth Consent Screen"> | |
| Go to the [Google Cloud Console](https://console.cloud.google.com/apis/credentials) and select your project (or create a new one). | |
| First, configure the OAuth consent screen by navigating to **APIs & Services → OAuth consent screen**. Choose "External" for testing or "Internal" for G Suite organizations. | |
| </Step> | |
| <Step title="Create OAuth 2.0 Client ID"> | |
| Navigate to **APIs & Services → Credentials** and click **"+ CREATE CREDENTIALS"** → **"OAuth client ID"**. | |
| Configure your OAuth client: | |
| - **Application type**: Web application | |
| - **Name**: Choose a descriptive name (e.g., "FastMCP Server") | |
| - **Authorized JavaScript origins**: Add your server's base URL (e.g., `http://localhost:8000`) | |
| - **Authorized redirect URIs**: Add your server URL + `/oauth/callback` (e.g., `http://localhost:8000/oauth/callback`) | |
| <Warning> | |
| The redirect URI must match exactly. The default path is `/oauth/callback`, but you can customize it using the `redirect_path` parameter. For local development, Google allows `http://localhost` URLs with various ports. For production, you must use HTTPS. | |
| </Warning> | |
| <Tip> | |
| If you want to use a custom callback path (e.g., `/auth/google/callback`), make sure to set the same path in both your Google OAuth Client settings and the `redirect_path` parameter when configuring the GoogleProvider. | |
| </Tip> | |
| </Step> | |
| <Step title="Save Your Credentials"> | |
| After creating the client, you'll receive: | |
| - **Client ID**: A string ending in `.apps.googleusercontent.com` | |
| - **Client Secret**: A string starting with `GOCSPX-` | |
| Download the JSON credentials or copy these values securely. | |
| <Tip> | |
| Store these credentials securely. Never commit them to version control. Use environment variables or a secrets manager in production. | |
| </Tip> | |
| </Step> | |
| </Steps> | |
| ### Step 2: FastMCP Configuration | |
| Create your FastMCP server using the `GoogleProvider`, which handles Google's OAuth flow automatically: | |
| ```python server.py | |
| from fastmcp import FastMCP | |
| from fastmcp.server.auth.providers.google import GoogleProvider | |
| # The GoogleProvider handles Google's token format and validation | |
| auth_provider = GoogleProvider( | |
| client_id="123456789.apps.googleusercontent.com", # Your Google OAuth Client ID | |
| client_secret="GOCSPX-abc123...", # Your Google OAuth Client Secret | |
| base_url="http://localhost:8000", # Must match your OAuth configuration | |
| required_scopes=["openid", "email", "profile"], # Request user information | |
| # redirect_path="/oauth/callback" # Default value, customize if needed | |
| ) | |
| mcp = FastMCP(name="Google Secured App", auth=auth_provider) | |
| # Add a protected tool to test authentication | |
| @mcp.tool | |
| async def get_user_info() -> dict: | |
| """Returns information about the authenticated Google user.""" | |
| from fastmcp.server.dependencies import get_access_token | |
| token = get_access_token() | |
| # The GoogleProvider stores user data in token claims | |
| return { | |
| "google_id": token.claims.get("sub"), | |
| "email": token.claims.get("email"), | |
| "name": token.claims.get("name"), | |
| "picture": token.claims.get("picture"), | |
| "locale": token.claims.get("locale") | |
| } | |
| ``` | |
| ## Testing | |
| ### Running the Server | |
| Start your FastMCP server with HTTP transport to enable OAuth flows: | |
| ```bash | |
| fastmcp run server.py --transport http --port 8000 | |
| ``` | |
| Your server is now running and protected by Google OAuth authentication. | |
| ### Testing with a Client | |
| Create a test client that authenticates with your Google-protected server: | |
| ```python test_client.py | |
| from fastmcp import Client | |
| import asyncio | |
| async def main(): | |
| # The client will automatically handle Google OAuth | |
| async with Client("http://localhost:8000/mcp/", auth="oauth") as client: | |
| # First-time connection will open Google login in your browser | |
| print("✓ Authenticated with Google!") | |
| # Test the protected tool | |
| result = await client.call_tool("get_user_info") | |
| print(f"Google user: {result['email']}") | |
| print(f"Name: {result['name']}") | |
| if __name__ == "__main__": | |
| asyncio.run(main()) | |
| ``` | |
| When you run the client for the first time: | |
| 1. Your browser will open to Google's authorization page | |
| 2. Sign in with your Google account and grant the requested permissions | |
| 3. After authorization, you'll be redirected back | |
| 4. The client receives the token and can make authenticated requests | |
| <Info> | |
| The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. | |
| </Info> | |
| ## Environment Variables | |
| For production deployments, use environment variables instead of hardcoding credentials. | |
| <Info> | |
| To use the registered Google provider, you must set `FASTMCP_SERVER_AUTH=GOOGLE`. Learn more about [registered providers](/servers/auth/authentication#registered-providers). | |
| </Info> | |
| ### Provider Selection | |
| <ParamField path="FASTMCP_SERVER_AUTH" default="Not set" required> | |
| Set to `GOOGLE` to use the registered GoogleProvider with default configuration. | |
| </ParamField> | |
| ### Google-Specific Configuration | |
| <Card> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_ID" required> | |
| Your Google OAuth 2.0 Client ID (e.g., `123456789.apps.googleusercontent.com`) | |
| </ParamField> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_SECRET" required> | |
| Your Google OAuth 2.0 Client Secret (e.g., `GOCSPX-abc123...`) | |
| </ParamField> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_BASE_URL" default="http://localhost:8000"> | |
| Public URL of your FastMCP server for OAuth callbacks | |
| </ParamField> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_REDIRECT_PATH" default="/oauth/callback"> | |
| Redirect path configured in your Google OAuth Client | |
| </ParamField> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_REQUIRED_SCOPES" default="[]"> | |
| Comma-separated list of required Google scopes (e.g., `openid`) | |
| </ParamField> | |
| <ParamField path="FASTMCP_SERVER_AUTH_GOOGLE_TIMEOUT_SECONDS" default="10"> | |
| HTTP request timeout for Google API calls | |
| </ParamField> | |
| </Card> | |
| Example `.env` file: | |
| ```bash | |
| # Use the registered Google provider | |
| FASTMCP_SERVER_AUTH=GOOGLE | |
| # Google OAuth credentials | |
| FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_ID=123456789.apps.googleusercontent.com | |
| FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_SECRET=GOCSPX-abc123... | |
| FASTMCP_SERVER_AUTH_GOOGLE_BASE_URL=https://your-server.com | |
| FASTMCP_SERVER_AUTH_GOOGLE_REQUIRED_SCOPES=openid,email,profile | |
| ``` | |
| With environment variables set, your server code simplifies to: | |
| ```python server.py | |
| from fastmcp import FastMCP | |
| # Authentication is automatically configured from environment | |
| mcp = FastMCP(name="Google Secured App") | |
| @mcp.tool | |
| async def protected_tool(query: str) -> str: | |
| """A tool that requires Google authentication to access.""" | |
| # Your tool implementation here | |
| return f"Processing authenticated request: {query}" | |
| ``` |