MCP Authorization Server

Single OAuth 2.1 authorization server for every MCP server at MAJORITY. Users sign in with their Google Workspace account (@majority.com); MCP servers receive short-lived ES256 JWT access tokens bound to their own URL. Follows the MCP 2026-07-28 authorization spec.

Discovery

Authorization server metadatahttps://mcp-auth.majority.dev/.well-known/oauth-authorization-server
JWKS (public keys)https://mcp-auth.majority.dev/.well-known/jwks.json
Authorizehttps://mcp-auth.majority.dev/authorize
Tokenhttps://mcp-auth.majority.dev/token
Register (DCR, deprecated)https://mcp-auth.majority.dev/register
Revokehttps://mcp-auth.majority.dev/revoke

What clients get

PKCE S256 (required), Resource Indicators (RFC 8707, resource required), iss in authorization responses (RFC 9207), Client ID Metadata Documents, Dynamic Client Registration with application_type, rotating refresh tokens.

Protect your MCP server in three steps

  1. Copy apps/mcp-auth/client/mcp-auth-verify.js into your Worker and create createMcpAuth({ issuer: "https://mcp-auth.majority.dev", resource: "https://your-mcp.majority.dev/mcp" }).
  2. Serve auth.metadata() at auth.metadataPath (RFC 9728 Protected Resource Metadata).
  3. Call await auth.verify(request) on every MCP request. Return its response on failure (401 with WWW-Authenticate); otherwise use claims.email.

Your server's hostname must match ALLOWED_RESOURCE_HOSTS (*.majority.dev, *.mcp.minority.com). A live example is at https://mcp-auth.majority.dev/demo.

Token claims

{ "iss": "https://mcp-auth.majority.dev", "aud": "<resource>", "sub": "<google user id>",
  "email": "user@majority.com", "name": "…", "client_id": "…",
  "scope": "…", "iat": …, "exp": … (3600s), "jti": "…" }