mctxdocs
Reference

How Authentication Works

Technical deep-dive into OAuth 2.0 authentication for MCP servers on mctx. Understand the protocol-level details of how MCP clients discover and authenticate with mctx servers.

Overview

mctx uses OAuth 2.0 for authentication, following the MCP specification. MCP clients automatically discover authentication requirements and handle the OAuth flow without user intervention.

Key point: You do not need to manually manage access tokens. When you use installation commands from the mctx dashboard (like npx @anthropic-ai/claude-code mcp install ...), the MCP client handles authentication automatically.

This page explains what happens behind the scenes for those who want to understand the technical details.

The Authentication Flow

When an MCP client connects to a server on mctx, this is what happens:

MCP Client                     mctx Server                    Auth0
    │                               │                           │
    ├── Request without token ─────>│                           │
    │<─── 401 + WWW-Authenticate ───│                           │
    │                               │                           │
    ├── GET /.well-known/oauth-     │                           │
    │      protected-resource ─────>│                           │
    │<─── OAuth metadata ───────────│                           │
    │                               │                           │
    ├── OAuth authorization flow ───────────────────────────────>
    │<── Access token ──────────────────────────────────────────│
    │                               │                           │
    ├── Request with Bearer token ─>│                           │
    │                               ├── Validate via /userinfo ─>
    │                               │<── User info ─────────────│
    │<─── MCP response ─────────────│                           │

Step 1: Discovery via RFC 9728

When a request arrives without authentication, mctx returns a 401 response with a WWW-Authenticate header that tells the client where to find authentication metadata:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://my-server.mctx.ai/.well-known/oauth-protected-resource"
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32001,
    "message": "Unauthorized",
    "data": {
      "error": "unauthorized",
      "description": "Authentication required to access this MCP server"
    }
  },
  "id": null
}

Step 2: OAuth Metadata

The client fetches the OAuth Protected Resource metadata (per RFC 9728):

GET /.well-known/oauth-protected-resource HTTP/1.1
Host: my-server.mctx.ai

Response:

{
  "resource": "https://my-server.mctx.ai",
  "authorization_servers": ["https://auth.mctx.ai"],
  "bearer_methods_supported": ["header"],
  "scopes_supported": ["openid", "profile", "email"]
}

This tells the client that Auth0 (via auth.mctx.ai) is the authorization server for this resource.

Step 3: OAuth Authorization

The MCP client performs an OAuth 2.1 authorization flow with Auth0. This typically involves:

  1. Opening a browser window for the user to sign in
  2. Exchanging the authorization code for an access token
  3. Storing the token securely for future requests

Most MCP clients (like Claude Desktop) handle this automatically.

Step 4: Authenticated Requests

Once the client has a token, it includes it in the Authorization header:

POST /v1.0.0 HTTP/1.1
Host: my-server.mctx.ai
Authorization: Bearer eyJhbGciOiJSUzI1...
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

Step 5: Token Validation

mctx validates the token by calling Auth0's /userinfo endpoint. This verifies:

  • The token is valid and not expired
  • The token was issued by the expected authorization server
  • The user identity associated with the token

Validation results are cached for 5 minutes to reduce latency on subsequent requests.

Error Responses

401 Unauthorized

Returned when authentication is missing or invalid:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32001,
    "message": "Unauthorized",
    "data": {
      "error": "unauthorized",
      "description": "Authentication required to access this MCP server"
    }
  },
  "id": null
}

What this means:

  • No Authorization header was provided
  • The token format was invalid (not a Bearer token)
  • The token could not be validated with Auth0

What to do:

  • If using an MCP client, re-authenticate through the client's normal flow
  • The client should automatically handle the OAuth discovery and authentication

402 Payment Required

Returned when authentication succeeds but you don't have an active subscription:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32002,
    "message": "Payment Required",
    "data": {
      "error": "payment_required",
      "description": "Active subscription required to access my-server"
    }
  },
  "id": null
}

What this means:

  • Your identity was verified successfully
  • You don't have an active subscription to this server

What to do:

  • Subscribe to the server at its info page (visit {slug}.mctx.ai in a browser)
  • Check your subscriptions in the mctx dashboard

429 Rate Limited

Returned when you've exceeded request limits:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Rate limit exceeded",
    "data": {
      "limit": 60,
      "resetAt": 1704067260,
      "retryAfter": 45,
      "windowType": "minute"
    }
  },
  "id": null
}

For MCP Client Developers

If you're building an MCP client, here's what you need to implement:

  1. Detect 401 responses and extract the resource_metadata URL from the WWW-Authenticate header
  2. Fetch OAuth metadata from the .well-known/oauth-protected-resource endpoint
  3. Perform OAuth 2.1 authorization with the authorization server specified in the metadata
  4. Include tokens in the Authorization: Bearer <token> header on all requests
  5. Handle token refresh when tokens expire (check for 401 responses)

The MCP specification provides detailed guidance on the authorization flow in the Authorization section.

Security Details

Token Caching

mctx caches token validation results for 5 minutes to reduce latency. This means:

  • First request with a new token: validated against Auth0
  • Subsequent requests within 5 minutes: served from cache
  • Cache is shared across all edge locations

Resilience

The token validation system includes:

  • Circuit breaker: If Auth0 is experiencing issues, requests fail fast rather than timing out
  • Retry with backoff: Transient errors are automatically retried
  • Graceful degradation: Network issues don't cascade to all requests

What mctx Never Exposes

  • Access tokens are never displayed in the UI
  • You cannot copy or view your token in the dashboard
  • Tokens exist only between your MCP client and mctx servers

See something wrong? Report it or suggest an improvement — your feedback helps make these docs better.