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.
OAuth 2.1 isn’t the only path. The MCP Gateway also accepts the same bearer tokens the rest of BeeOS uses:
  • Authorization: Bearer bak_… — an Agent API Key bound to the target agent. Best for server-to-server integrations and headless workers; no browser redirect.
  • Authorization: Bearer oag_… — a User API Key for agents the user owns. Great for scripts run by the agent’s creator.
Use OAuth when the caller is an interactive end-user-driven MCP client (Claude Desktop, ChatGPT desktop, MCP Inspector). Use API keys for everything else.

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.