Skip to content

Repository files navigation

MCP Auth0 Authentication

This repository is a fork of the simple-auth example from the MCP Python SDK.

Unlike the original example, which uses a self-hosted Authorization Server, this version uses Auth0 as the Authorization Server.


Step 1: Set Up Auth0

  1. Sign up at Auth0.
  2. Enable Dynamic Client Registration.
  3. Promote Connections to Domain Level.
    Dynamic clients are third-party apps and require dynamic connections.
    First, obtain a management token.
  4. Register the MCP server as an API in Auth0, so it can be used as a valid audience/resource in the generated JWT.
    The URL must match exactly, including the trailing slash (e.g., http://localhost:8042/).

Step 2: Start the Resource Server (MCP Server)

# Start the Resource Server on port 8042, connected to the Auth0 Authorization Server
# Replace https://xxxxxxxxx.us.auth0.com/ with your Auth0 domain
uv run mcp-simple-auth0-rs --port=8042 --auth-server=https://xxxxxxxxx.us.auth0.com/ --transport=streamable-http

Step 3: Test with Claude Desktop

// Add the MCP server to your `claude_desktop_config.json`
// Auth0 requires the `audience` parameter in the /authorize GET request to return a JWT instead of a JWE.
// See: https://auth0.com/docs/secure/tokens/access-tokens/get-access-tokens#control-access-token-audience
// We use `pnpm dlx` to run a specific git commit of a modified `mcp-remote` version,
// which includes the `audience` query parameter to ensure a JWT is returned.
// or you can clone the repo 
// `git clone https://github.com/CefBoud/mcp-remote.git && cd mcp-remote && npm i && npm run build && npm link" 
// then use `mcp-remote` command without pnpm.
"auth0-mcp": {
  "command": "pnpm",
  "args": [
    "dlx",
    "github:CefBoud/mcp-remote#8226c8b08cf281b782ccc0967f4664ec087f7269",
    "http://localhost:8042/mcp",
    "--resource",
    "http://localhost:8042/"
  ]
}

Note: Auth0 requires an audience parameter in the /authorize GET request to issue a JWT instead of a JWE. The mcp-remote version above includes this behavior.

When you launch Claude Desktop, a browser tab opens prompting for authorization:

alt text

After granting access, you're redirected to a localhost server started by mcp-remote to redeem the authorization code for a token:

alt text

You can inspect the saved tokens and challenges via:

ls -lat ~/.mcp-auth/*/

How It Works

RFC 9728 Discovery

Client → Resource Server:

curl http://localhost:8042/.well-known/oauth-protected-resource
{
  "resource": "http://localhost:8042/",
  "authorization_servers": [
    "https://xxxxxxxxx.us.auth0.com/"
  ],
  "scopes_supported": [],
  "bearer_methods_supported": [
    "header"
  ]
}

Client → Authorization Server:

curl https://xxxxxxxxx.us.auth0.com/.well-known/oauth-authorization-server
{
  "issuer": "https://xxxxxxxxx.us.auth0.com/",
  "authorization_endpoint": "https://xxxxxxxxx.us.auth0.com/authorize",
  "token_endpoint": "https://xxxxxxxxx.us.auth0.com/oauth/token",
  "device_authorization_endpoint": "https://xxxxxxxxx.us.auth0.com/oauth/device/code",
  "userinfo_endpoint": "https://xxxxxxxxx.us.auth0.com/userinfo",
  "mfa_challenge_endpoint": "https://xxxxxxxxx.us.auth0.com/mfa/challenge",
  "jwks_uri": "https://xxxxxxxxx.us.auth0.com/.well-known/jwks.json",
  "registration_endpoint": "https://xxxxxxxxx.us.auth0.com/oidc/register",
  "revocation_endpoint": "https://xxxxxxxxx.us.auth0.com/oauth/revoke"
  // ...
}

The client dynamically registers an app (per RFC 7591), then proceeds with the regular OAuth flow.

About

This repo is an example of an MCP server that uses OAuth for authentication, with Auth0 as the authorization server.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages