New in version: 2.12.4 This guide shows you how to secure your FastMCP server using Descope, a complete authentication and user management solution. This integration uses the Remote OAuth pattern, where Descope handles user login and your FastMCP server validates the tokens.

Configuration

Prerequisites

Before you begin, you will need:
  1. To sign up for a Free Forever Descope account
  2. Your Project ID from the Descope Console
  3. Your FastMCP server’s URL (can be localhost for development, e.g., http://localhost:3000)

Step 1: Configure Descope

1

Enable Dynamic Client Registration

  1. Go to the Inbound Apps page of the Descope Console
  2. Click DCR Settings
  3. Enable Dynamic Client Registration (DCR)
  4. Define allowed scopes
DCR is required for FastMCP clients to automatically register with your authentication server.
2

Note Your Project ID

Save your Project ID from Project Settings:
Project ID: P2abc...123

Step 2: Environment Setup

Create a .env file with your Descope configuration:
DESCOPE_PROJECT_ID=P2abc...123      # Your Descope Project ID
DESCOPE_BASE_URL=https://api.descope.com   # Descope API URL
SERVER_URL=http://localhost:3000     # Your server's base URL
You can find your project’s Descope Base URL in the Multi-Region Support Guide.

Step 3: FastMCP Configuration

Create your FastMCP server file and use the DescopeProvider to handle all the OAuth integration automatically:
server.py
from fastmcp import FastMCP
from fastmcp.server.auth.providers.descope import DescopeProvider

# The DescopeProvider automatically discovers Descope endpoints
# and configures JWT token validation
auth_provider = DescopeProvider(
    project_id=DESCOPE_PROJECT_ID,        # Your Descope Project ID
    base_url=SERVER_URL,                  # Your server's public URL
    descope_base_url=DESCOPE_BASE_URL,    # Descope API base URL
)

# Create FastMCP server with auth
mcp = FastMCP(name="My Descope Protected Server", auth=auth_provider)

Testing

To test your server, you can use the fastmcp CLI to run it locally. Assuming you’ve saved the above code to server.py (after replacing the project_id, base_url, and descope_base_url with your actual values!), you can run the following command:
fastmcp run server.py --transport http --port 8000
Now, you can use a FastMCP client to test that you can reach your server after authenticating:
from fastmcp import Client
import asyncio

async def main():
    async with Client("http://localhost:8000/mcp/", auth="oauth") as client:
        assert await client.ping()

if __name__ == "__main__":
    asyncio.run(main())

Environment Variables

For production deployments, use environment variables instead of hardcoding credentials.

Provider Selection

Setting this environment variable allows the Descope provider to be used automatically without explicitly instantiating it in code.

FASTMCP_SERVER_AUTH
default:"Not set"
Set to fastmcp.server.auth.providers.descope.DescopeProvider to use Descope authentication.

Descope-Specific Configuration

These environment variables provide default values for the Descope provider, whether it’s instantiated manually or configured via FASTMCP_SERVER_AUTH.

FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_PROJECT_ID
required
Your Descope Project ID from the Descope Console
FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_BASE_URL
required
Public URL of your FastMCP server (e.g., https://your-server.com or http://localhost:8000 for development)
FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_DESCOPE_BASE_URL
default:"https://api.descope.com"
Descope API base URL for your region/environment
Example .env file:
# Use the Descope provider
FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.descope.DescopeProvider

# Descope configuration
FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_PROJECT_ID=P2abc...123
FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_BASE_URL=https://your-server.com
FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_DESCOPE_BASE_URL=https://api.descope.com
With environment variables set, your server code simplifies to:
server.py
from fastmcp import FastMCP

# Authentication is automatically configured from environment
mcp = FastMCP(name="My Descope Protected Server")