Skip to main content
The MCP Gateway implements OAuth 2.1 with PKCE for spec-compliant MCP clients. This is the recommended authentication method for interactive desktop applications like Claude Desktop and MCP Inspector.
For server-to-server integrations, use an Agent API Key (bak_) or User API Key (oag_) instead — they skip the browser redirect flow entirely.

Flow overview

Step 1: Dynamic Client Registration

Register a new OAuth client. Only public clients (no client_secret) are supported, per the MCP Authorization spec.
curl -s -X POST "https://mcp.beeos.ai/oauth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "my-mcp-client",
    "redirect_uris": ["http://localhost:5173/callback"]
  }' | jq
Response:
{
  "client_id": "mcp_client_abc123",
  "client_name": "my-mcp-client",
  "redirect_uris": ["http://localhost:5173/callback"]
}

Step 2: Authorization request

Generate a PKCE code verifier and challenge, then redirect the user:
GET https://mcp.beeos.ai/oauth/authorize
  ?client_id=mcp_client_abc123
  &redirect_uri=http://localhost:5173/callback
  &response_type=code
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
  &state=random_state_value
The gateway redirects the browser to the BeeOS web app login page. After the user authenticates, the browser is redirected back to your redirect_uri with an authorization code:
http://localhost:5173/callback?code=auth_code_xyz&state=random_state_value

Step 3: Token exchange

Exchange the authorization code for an access token:
curl -s -X POST "https://mcp.beeos.ai/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=auth_code_xyz" \
  -d "client_id=mcp_client_abc123" \
  -d "redirect_uri=http://localhost:5173/callback" \
  -d "code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk" | jq
Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Step 4: Use the token

Include the access token in MCP requests:
curl -s -X POST "https://mcp.beeos.ai/${AGENT_ID}/mcp" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Discovery endpoints

MCP clients use these well-known endpoints to discover the OAuth server:
EndpointPurpose
GET /.well-known/oauth-authorization-serverOAuth 2.1 Authorization Server Metadata (RFC 8414)
GET /.well-known/oauth-protected-resourceMCP Protected Resource Metadata (pointer to AS)
curl -s "https://mcp.beeos.ai/.well-known/oauth-authorization-server" | jq

Token details

PropertyValue
AlgorithmHS256
Default TTL60 minutes
Authorization code TTL120 seconds
Client typePublic only (no client_secret)
Authorization codes expire in 120 seconds. Exchange them promptly after the redirect callback.

401 response behavior

When a request fails authentication, the gateway returns:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="MCP", resource_metadata="/.well-known/oauth-protected-resource"
Spec-compliant MCP clients use the resource_metadata URL to discover the authorization server and initiate the OAuth flow automatically.