Audience: developers integrating BeeOS agents into an LLM tool
host — Claude Desktop, Cursor, OpenAI’s MCP support, n8n, MCP
Inspector, or any Model Context Protocol
client.
mcp_enabled=true on the agent and you’re done.”
For the decision of whether MCP is the right surface (vs.
OpenAPI or A2A), see
Choosing a Protocol. This guide
covers MCP-specific integration once you’ve made that choice.
1. Where it lives
| Item | Value |
|---|---|
| Host | https://mcp.beeos.ai |
| MCP endpoint shape | POST /{agentId}/mcp |
| Transport | Streamable HTTP (JSON-RPC 2.0 over HTTP, SSE for streaming) |
| OAuth metadata | GET /.well-known/oauth-authorization-server |
| Protected resource metadata | GET /.well-known/oauth-protected-resource |
| Health probe | GET /healthz |
http://localhost:8094
with the same path shape; see
backend/services/mcp-gateway/README.md
for the goreman wiring.
The agent ID in the URL pins each MCP session to one BeeOS agent.
A single MCP host can mount multiple BeeOS agents by registering
multiple endpoints with different {agentId} segments.
2. Authentication — three credentials, one endpoint
/{agentId}/mcp accepts three credential types. Pick the one
that matches your client’s identity model.
| Credential | Header | Best for | Scope |
|---|---|---|---|
OAuth 2.1 Bearer (HS256 JWT from /oauth/token) | Authorization: Bearer <jwt> | Spec-compliant MCP clients (Claude Desktop, MCP Inspector) | Per-session, agent set granted at consent time |
User API Key (oag_…) | Authorization: Bearer oag_… | Scripts, CI, n8n acting as a BeeOS user | All MCP-enabled agents the user owns |
Agent API Key (bak_…) | X-Agent-API-Key: bak_… or Authorization: Bearer bak_… | Third-party integrations bound to a single agent | One agent (the URL’s {agentId} MUST match) |
Authorization: Bearer oag_… plus
X-Agent-API-Key: bak_… with a different value) returns 401.
Sending the same bak_ in both Authorization and
X-Agent-API-Key for a stubborn proxy is fine.
For credential rotation and revocation, see
Authentication & API Keys.
2.1 OAuth 2.1 flow (spec-compliant MCP clients)
Claude Desktop / Cursor / MCP Inspector use Dynamic Client Registration (DCR) + Authorization Code + PKCE per the MCP Authorization spec:- Client POSTs
/oauth/register→{client_id, …}. - Client opens browser at
/oauth/authorize?client_id=…&code_challenge=…&redirect_uri=…&state=…. - MCP Gateway redirects to BeeOS web login
(
MCP_WEB_LOGIN_URL/mcp-login?return_to=…). - User signs into BeeOS, picks which agents to grant.
- Web app redirects back to MCP Gateway, gateway redirects to
redirect_uriwith?code=…&state=…. - Client POSTs
/oauth/tokenwithcode_verifier→ access token. - Client uses token on
/{agentId}/mcpfrom then on.
- Your BeeOS user account has at least one MCP-enabled agent
(
mcp_enabled=true). Check withGET /api/v1/agentson the OpenAPI surface — themcp_enabledfield surfaces in the catalog response. - Your client’s
redirect_uriis reachable from a browser (the authorization-code redirect can’t go to a non-routable host). - For local dev:
MCP_PUBLIC_URL=http://localhost:8094is in the gateway’s env, and the web app atlocalhost:3000exposes a/mcp-loginroute.
2.2 API-key-only flow (n8n, scripts, CI)
For non-interactive callers, skip the OAuth flow entirely and use anoag_ (User API Key) or bak_ (Agent API Key) as a bearer
credential:
bak_ is the right choice for third-party apps because:
- The key is bound to ONE agent — losing the key compromises only that integration, not your whole user account.
- It can be revoked independently of your
oag_keys. - The agent owner (you) explicitly issued it, so consent is audit-traceable.
3. What each MCP method does
The gateway implements four JSON-RPC methods. All requests are POST to/{agentId}/mcp; responses are JSON-RPC 2.0 envelopes.
3.1 initialize
Standard MCP handshake. The gateway returns its protocol version
and capabilities. Clients that auto-reconnect should re-issue
this on every session start.
3.2 tools/list
Enumerates the single BeeOS agent reachable through this
endpoint as one tool. The tool’s name, description, and input
schema come from the agent’s
Agent Card
(pkg/agentcard resolves it).
message → reply tool to MCP. If your agent
needs structured input, validate inside the agent process (the
message field is the JSON or natural-language envelope the
agent expects); MCP itself doesn’t model per-agent schemas
deeply.
3.3 tools/call
Invokes the agent. Synchronous by default; pass an SSE-capable
Accept header to stream notifications/progress events as the
agent emits agent_reply_delta.
notifications/progress events on the SSE stream as the agent
emits agent_reply_delta, then closes with the final result.
3.4 tools/call cancel
The MCP spec doesn’t standardise cancel today. If you need
cancel semantics for a long-running call, use the
OpenAPI tasks surface in
parallel — submit the same work as a BeeOS task and cancel via
POST /tasks/{id}/cancel. The MCP tools/call will see the
agent’s terminal state through the underlying Message Service
channel.
4. Behavioural contract — what MCP guarantees, what it doesn’t
Guaranteed:tools/listis read-only and idempotent. Safe to call repeatedly across reconnects.tools/callalways delivers exactly oneresult(or oneerror) per JSON-RPC ID. Cancellation triggered server-side (deadline, agent crash) surfaces as a JSON-RPC error with a stablecodefrom Error Reference.- The same agent reachable via OpenAPI / A2A is reachable here;
responses are bit-identical (same
agent_replyfrom the same Message Service channel). - Idempotency: pass
params.arguments.idempotency_keyand the gateway honours it on the underlying L0 invoke. See Calling Agents § Idempotency. - Attachments: pass
params.arguments.attachments[]withfile_idvalues fromPOST /api/v1/files/presign-upload. The agent sees a normal multi-partchat_message.
- Durable async — MCP
tools/callis request-response. Long-running work that needs to survive client disconnects belongs on OpenAPI tasks. Reaching for “fire-and-forget MCP tool” is a sign the protocol’s wrong for the use case. - Multi-turn within one call — every
tools/callis a fresh turn. To chain related turns, the MCP host typically keeps the conversation context client-side and includes the relevant history in the nextmessage. If you need server-side conversation continuity, use the OpenAPI conversations surface and reference the conversation ID fromarguments.context_idon MCP calls. - Webhook push — MCP has no notion of server-pushed events outside the in-flight call. For “tell me when this task finishes” semantics, use OpenAPI webhooks (P2-A — see the webhooks guide).
- Rate-limit visibility — the gateway enforces rate limits
per credential × agent, but rate-limit metadata is returned in
the standard MCP error shape (
code,message). Inspect thecode(rate_limited) to back off; the wire doesn’t carryRetry-Aftertoday.
5. Common failure modes
| Symptom | Likely cause | Fix |
|---|---|---|
401 unauthorized even after DCR + PKCE | The agent isn’t MCP-enabled. | Flip mcp_enabled=true on the agent (PATCH /api/v1/agents/{id}). |
401 with WWW-Authenticate: Bearer realm="MCP", resource_metadata="…/.well-known/oauth-protected-resource" | Credential missing or expired. The header points at the OAuth metadata so spec-aware clients auto-retry. | Re-run the OAuth flow (most clients do this automatically). |
400 invalid_param on tools/call | arguments.message empty, or attachments[i].file_id references a missing / mismatched-owner file. | Verify the file ID in GET /api/v1/files/{id} from your oag_ first. |
503 agent_service_unavailable | Agent pod is offline or has no Message Service subscription. | Check the agent’s instance state via GET /api/v1/instances; restart if delivery_mode=push and the pod is in STOPPED. |
409 conflict on duplicate idempotency_key | A previous call with the same key is still in flight. | Either wait for the prior reply or rotate the key. |
6. End-to-end example — Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json:
/oauth/authorize → the BeeOS
consent screen → token → tools/list → tools/call. You’ll see
“BeeOS CSV Analyst” appear as a tool in Claude’s prompt menu.
After the first session the token is cached locally; refreshes
follow standard OAuth refresh-token semantics.
7. See also
- Choosing a Protocol — when MCP is the right surface vs. OpenAPI / A2A.
- Authentication & API Keys —
oag_/bak_/ OAuth lifecycle, scopes, rotation. - Error Reference — stable wire codes the MCP error envelope can return.
- Public Architecture Overview — how MCP relates to the other two caller surfaces.
backend/services/mcp-gateway/README.md— service-side README (env vars, local dev, deployment).- MCP Authorization Spec — the canonical OAuth / DCR / PKCE spec the gateway implements.