MCP Auth
Using https://github.com/mcp-auth

MCP Servers
+ Auth0
- Sign up with Auth0* (other providers available)
- Create API
- Go to https://mcp-auth.dev and follow tutorial

from mcpauth import MCPAuth
from mcpauth.config import AuthServerType
from mcpauth.utils import fetch_server_config
# CORRECT issuer, based on your region (.us.auth0.com)
issuer = "https://dev-o6sdfsdfs6ul6pc1m.us.auth0.com"
mcp_auth = MCPAuth(
server=fetch_server_config(
issuer,
type=AuthServerType.OIDC
)
)
[project]
name = "xp-auth"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"mcpauth>=0.1.1",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

uvicorn whoami:app --host 0.0.0.0 --port 3001
❯ inspector
Starting MCP inspector...
⚙️ Proxy server listening on 127.0.0.1:6277
⚠️ WARNING: Authentication is disabled. This is not recommended.
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
New SSE connection request. NOTE: The sse transport is deprecated and has been replaced by StreamableHttp
Query parameters: {"url":"http://localhost:3001/sse","transportType":"sse"}
SSE transport: url=http://localhost:3001/sse, headers={"Accept":"text/event-stream"}
Created client transport

Next:
create the custom access token verifier that will fetch the user identity information from the authorization server (Auth0) using the access token provided by the MCP inspector.
whoami.py example
So far we just checked we can do auth, now let’s use with a toy MCP in Python
from mcp.server.fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount
from typing import Any
from mcpauth import MCPAuth
from mcpauth.config import AuthServerType
from mcpauth.utils import fetch_server_config
auth_issuer = 'https://dev-o5hdfhfd5p6ul6pc1m.us.auth0.com' # Replace with your issuer endpoint
auth_server_config = fetch_server_config(auth_issuer, type=AuthServerType.OIDC)
mcp_auth = MCPAuth(server=auth_server_config)
mcp = FastMCP("WhoAmI")
@mcp.tool()
def whoami() -> dict[str, Any]:
"""A tool that returns the current user's information."""
return {"error": "Not authenticated"}
app = Starlette(
routes=[Mount('/', app=mcp.sse_app())]
)
add the “MCP” part:
@mcp.tool()
def whoami() -> dict[str, Any]:
"""A tool that returns the current user's information."""
return (
mcp_auth.auth_info.claims
if mcp_auth.auth_info # This will be populated by the Bearer auth middleware
else {"error": "Not authenticated"}
)
# ...
bearer_auth = Middleware(mcp_auth.bearer_auth_middleware(verify_access_token))
app = Starlette(
routes=[
# Add the metadata route (`/.well-known/oauth-authorization-server`)
mcp_auth.metadata_route(),
# Protect the MCP server with the Bearer auth middleware
Mount('/', app=mcp.sse_app(), middleware=[bearer_auth]),
],
)
- We end up with 2 files:
- whoami.py calls verify.py


Requesting an Access Token via Client Credentials (Auth0)

curl --request POST \
--url https://example-1234.us.auth0.com/oauth/token \
--header 'content-type: application/json' \
--data '{
"client_id": "abc123DEF456ghi789JKL000",
"client_secret": "s3cr3tK3yExAmpl3ForWebArticle_xyz123",
"audience": "https://example-1234.us.auth0.com/api/v2/",
"grant_type": "client_credentials"
}'