docs/integrations/supabase.mdx
import { VersionBadge } from "/snippets/version-badge.mdx"
<VersionBadge version="2.13.0" />This guide shows you how to secure your FastMCP server using Supabase Auth. This integration uses the Remote OAuth pattern, where Supabase handles user authentication and your FastMCP server validates the tokens.
<Warning> Supabase Auth does not currently support [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) resource indicators, so FastMCP cannot validate that tokens were issued for the specific resource server. </Warning>Supabase's OAuth Server delegates the user consent screen to your application. When an MCP client initiates authorization, Supabase authenticates the user and then redirects to your application at a configured callback URL (e.g., https://your-app.com/oauth/callback?authorization_id=...). Your application must host a page that calls Supabase's approveAuthorization() or denyAuthorization() APIs to complete the flow.
SupabaseProvider handles the resource server side (token verification and metadata), but you are responsible for building and hosting the consent UI separately. See Supabase's OAuth Server documentation for details on implementing the authorization page.
Before you begin, you will need:
http://localhost:8000)In your Supabase Dashboard:
/oauth/callback)In your Supabase Dashboard:
https://abc123.supabase.co)Create your FastMCP server using the SupabaseProvider:
from fastmcp import FastMCP
from fastmcp.server.auth.providers.supabase import SupabaseProvider
auth = SupabaseProvider(
project_url="https://abc123.supabase.co",
base_url="http://localhost:8000",
)
mcp = FastMCP("Supabase Protected Server", auth=auth)
@mcp.tool
def protected_tool(message: str) -> str:
"""This tool requires authentication."""
return f"Authenticated user says: {message}"
if __name__ == "__main__":
mcp.run(transport="http", port=8000)
Start your FastMCP server with HTTP transport to enable OAuth flows:
fastmcp run server.py --transport http --port 8000
Create a test client that authenticates with your Supabase-protected server:
from fastmcp import Client
import asyncio
async def main():
async with Client("http://localhost:8000/mcp", auth="oauth") as client:
print("Authenticated with Supabase!")
result = await client.call_tool("protected_tool", {"message": "Hello!"})
print(result)
if __name__ == "__main__":
asyncio.run(main())
When you run the client for the first time:
For production deployments, load configuration from environment variables:
import os
from fastmcp import FastMCP
from fastmcp.server.auth.providers.supabase import SupabaseProvider
auth = SupabaseProvider(
project_url=os.environ["SUPABASE_PROJECT_URL"],
base_url=os.environ.get("BASE_URL", "https://your-server.com"),
)
mcp = FastMCP(name="Supabase Secured App", auth=auth)