docs/v2/integrations/github.mdx
import { VersionBadge } from "/snippets/version-badge.mdx"
<VersionBadge version="2.12.0" />This guide shows you how to secure your FastMCP server using GitHub OAuth. Since GitHub doesn't support Dynamic Client Registration, this integration uses the OAuth Proxy pattern to bridge GitHub's traditional OAuth with MCP's authentication requirements.
Before you begin, you will need:
http://localhost:8000)Create an OAuth App in your GitHub settings to get the credentials needed for authentication:
<Steps> <Step title="Navigate to OAuth Apps"> Go to **Settings → Developer settings → OAuth Apps** in your GitHub account, or visit [github.com/settings/developers](https://github.com/settings/developers).Click **"New OAuth App"** to create a new application.
- **Application name**: Choose a name users will recognize (e.g., "My FastMCP Server")
- **Homepage URL**: Your application's homepage or documentation URL
- **Authorization callback URL**: Your server URL + `/auth/callback` (e.g., `http://localhost:8000/auth/callback`)
<Warning>
The callback URL must match exactly. The default path is `/auth/callback`, but you can customize it using the `redirect_path` parameter. For local development, GitHub allows `http://localhost` URLs. For production, you must use HTTPS.
</Warning>
<Tip>
If you want to use a custom callback path (e.g., `/auth/github/callback`), make sure to set the same path in both your GitHub OAuth App settings and the `redirect_path` parameter when configuring the GitHubProvider.
</Tip>
- **Client ID**: A public identifier like `Ov23liAbcDefGhiJkLmN`
- **Client Secret**: Click "Generate a new client secret" and save the value securely
<Tip>
Store these credentials securely. Never commit them to version control. Use environment variables or a secrets manager in production.
</Tip>
Create your FastMCP server using the GitHubProvider, which handles GitHub's OAuth quirks automatically:
from fastmcp import FastMCP
from fastmcp.server.auth.providers.github import GitHubProvider
# The GitHubProvider handles GitHub's token format and validation
auth_provider = GitHubProvider(
client_id="Ov23liAbcDefGhiJkLmN", # Your GitHub OAuth App Client ID
client_secret="github_pat_...", # Your GitHub OAuth App Client Secret
base_url="http://localhost:8000", # Must match your OAuth App configuration
# redirect_path="/auth/callback" # Default value, customize if needed
)
mcp = FastMCP(name="GitHub 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 GitHub user."""
from fastmcp.server.dependencies import get_access_token
token = get_access_token()
# The GitHubProvider stores user data in token claims
return {
"github_user": token.claims.get("login"),
"name": token.claims.get("name"),
"email": token.claims.get("email")
}
Start your FastMCP server with HTTP transport to enable OAuth flows:
fastmcp run server.py --transport http --port 8000
Your server is now running and protected by GitHub OAuth authentication.
Create a test client that authenticates with your GitHub-protected server:
from fastmcp import Client
import asyncio
async def main():
# The client will automatically handle GitHub OAuth
async with Client("http://localhost:8000/mcp", auth="oauth") as client:
# First-time connection will open GitHub login in your browser
print("✓ Authenticated with GitHub!")
# Test the protected tool
result = await client.call_tool("get_user_info")
print(f"GitHub user: {result['github_user']}")
if __name__ == "__main__":
asyncio.run(main())
When you run the client for the first time:
For production deployments with persistent token management across server restarts, configure jwt_signing_key and client_storage:
import os
from fastmcp import FastMCP
from fastmcp.server.auth.providers.github import GitHubProvider
from key_value.aio.stores.redis import RedisStore
from key_value.aio.wrappers.encryption import FernetEncryptionWrapper
from cryptography.fernet import Fernet
# Production setup with encrypted persistent token storage
auth_provider = GitHubProvider(
client_id="Ov23liAbcDefGhiJkLmN",
client_secret="github_pat_...",
base_url="https://your-production-domain.com",
# Production token management
jwt_signing_key=os.environ["JWT_SIGNING_KEY"],
client_storage=FernetEncryptionWrapper(
key_value=RedisStore(
host=os.environ["REDIS_HOST"],
port=int(os.environ["REDIS_PORT"])
),
fernet=Fernet(os.environ["STORAGE_ENCRYPTION_KEY"])
)
)
mcp = FastMCP(name="Production GitHub App", auth=auth_provider)
For complete details on these parameters, see the OAuth Proxy documentation. </Note>
For production deployments, use environment variables instead of hardcoding credentials.
Setting this environment variable allows the GitHub provider to be used automatically without explicitly instantiating it in code.
<Card> <ParamField path="FASTMCP_SERVER_AUTH" default="Not set"> Set to `fastmcp.server.auth.providers.github.GitHubProvider` to use GitHub authentication. </ParamField> </Card>These environment variables provide default values for the GitHub provider, whether it's instantiated manually or configured via FASTMCP_SERVER_AUTH.
Example .env file:
# Use the GitHub provider
FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.github.GitHubProvider
# GitHub OAuth credentials
FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID=Ov23liAbcDefGhiJkLmN
FASTMCP_SERVER_AUTH_GITHUB_CLIENT_SECRET=github_pat_...
FASTMCP_SERVER_AUTH_GITHUB_BASE_URL=https://your-server.com
FASTMCP_SERVER_AUTH_GITHUB_REQUIRED_SCOPES=user,repo
With environment variables set, your server code simplifies to:
from fastmcp import FastMCP
# Authentication is automatically configured from environment
mcp = FastMCP(name="GitHub Secured App")
@mcp.tool
async def list_repos() -> list[str]:
"""List the authenticated user's repositories."""
# Your tool implementation here
pass