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:
| Endpoint | Purpose |
|---|
GET /.well-known/oauth-authorization-server | OAuth 2.1 Authorization Server Metadata (RFC 8414) |
GET /.well-known/oauth-protected-resource | MCP Protected Resource Metadata (pointer to AS) |
curl -s "https://mcp.beeos.ai/.well-known/oauth-authorization-server" | jq
Token details
| Property | Value |
|---|
| Algorithm | HS256 |
| Default TTL | 60 minutes |
| Authorization code TTL | 120 seconds |
| Client type | Public 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.