MCP API server troubleshooting
Diagnose authentication, JSON-RPC, rate limits, tool scope, and runtime issues for the AffinityBots MCP endpoint at /api/mcp/server.
This guide goes deeper than the MCP Server overview. It reflects how the public MCP endpoint (POST /api/mcp/server) validates requests, which errors you may see from clients such as Claude Desktop or Cursor, and how that differs from in-app MCP integrations under Tools.
How the endpoint behaves
- Authentication — Every
POSTmust send an API key in theAuthorizationheader. The server acceptsBearer ab_live_...or a raw header value starting withab_live_. Keys are validated with thevalidate_api_keydatabase function (hash lookup, revocation, expiry, then usage counters). - Rate limiting — After a successful validation, a per-key limit runs before the body is parsed. Exceeding it returns HTTP
429with a JSON-RPC-shaped error. - JSON-RPC — The body must be JSON-RPC
2.0with amethodstring. Supported methods:initialize,tools/list,tools/call, andping. Anything else returnsmethod not found. - Tool execution —
tools/callruns server-side handlers that read your agents and workflows from Postgres and, for chat and threads, call the LangGraph API withLANGGRAPH_API_URLandLANGSMITH_API_KEY.
GET /api/mcp/server returns static server metadata and does not require a Bearer token. You can use it to confirm the deployment and documentation URL.
Quick checks
| Check | What to verify |
|---|---|
| URL | POST target is /api/mcp/server on your environment (e.g. production https://affinitybots.com/api/mcp/server). |
| Transport | Client is configured for streamable HTTP, not stdio-only MCP. |
| Header | Authorization: Bearer ab_live_... with no extra spaces or quoted values. |
| Key format | Secret portion is hex; full key starts with ab_live_. |
| Scope | Key scope is Agents & Workflows (or all) if you need both tool groups. |
| Restart | After editing MCP config, fully restart the client (not always a hot reload). |
HTTP status codes and JSON-RPC errors
Responses are JSON. Transport-level failures use HTTP status; protocol errors include a JSON-RPC error object with a numeric code.
| HTTP | Typical meaning |
|---|---|
401 | Missing key, malformed Authorization, invalid hash, revoked key, or expired key. Message text comes from validation (e.g. Invalid API key, API key has been revoked, API key has expired). |
429 | Per-key rate limit exceeded for the current minute window. Retry with backoff. |
400 | Body is not valid JSON-RPC (jsonrpc, method, etc.). |
500 | Unhandled server error during processing. |
Custom and standard JSON-RPC codes used in responses include:
| Code | Meaning |
|---|---|
-32700 | Parse error |
-32601 | Method not found |
-32602 | Invalid params (e.g. missing tool name) |
-32603 | Internal error |
-32001 | Unauthorized |
-32004 | Rate limited |
Authentication edge cases
- "Invalid API key" when the key looks right — Only values starting with
ab_live_are extracted. If the header isBearer <something_else>or the secret was truncated when copying, validation fails. Regenerate a key if unsure. - Bearer required in practice — Some clients send only
Bearer; rawab_live_without theBearerprefix is accepted by the server only when the entire header value is the key (seeextractApiKey). Prefer the documentedBearerform for compatibility. - Internal validation error — Rare; indicates a database or RPC failure during
validate_api_key, not a bad key. Retry later; if it persists, capture the time and environment for support.
Tools missing or "not allowed for scope"
tools/listis filtered by key scope —agentsreturns only agent tools;workflowsonly workflow tools; full access returns the combined list. If a tool never appears, create a key with Agents & Workflows (or the narrow scope you need).Tool '…' is not allowed for scope '…'— The tool exists but the key used for the call does not include that category. This returns as a successful JSON-RPC result withisError: trueand a JSON payload describing the error, not as HTTP403.- Unknown tool — Usually a typo in
params.nameor a client calling a tool name that is not defined on this server.
Agent tools: empty lists, "Agent not found", chat failures
- Listed agents respect workspace — If the API key has a
workspace_id, agent lists are filtered to rows whoseworkspace_id,metadata.workspace_id, orconfig.configurable.workspace_idmatches. If you see no agents, try a key scoped to the correct workspace or create agents in that workspace. - Access model — Agents are visible if you own them (
metadata.owner_id) or they are linked viauser_assistants. An ID copied from another account or workspace will yield Agent not found for chat and get. Failed to chat with agent/ thread errors — Chat and thread APIs use the LangGraph SDK. Failures often mean the graph runtime is unreachable, misconfigured in the deployment (LANGGRAPH_API_URL,LANGSMITH_API_KEY), or the assistant ID is not a valid graph assistant in that environment. Operators should verify env vars and LangGraph health; end users should retry and confirm the agent runs in the product UI.
Workflow tools: activation, triggers, run status
Workflow is not activated—affinitybots_execute_workflowrequiresactivated_atto be set. Activate the workflow in the app first.No trigger available for this workflow— The handler picks a manual trigger by default, or thetrigger_idyou pass. Ensure at least one trigger exists.Workflow not found/Run not found— IDs must belong to the same user as the API key; run lookups also enforce ownership via the related workflow.
Important: affinitybots_execute_workflow creates a workflow_runs row and returns a run_id. It does not call the same HTTP execution pipeline as the interactive workflow runner. If status never advances beyond running or no output appears, run the workflow from the app or use the standard workflow execution API you rely on in production. Treat MCP execution behavior as environment-dependent until you confirm runs complete end-to-end.
Rate limiting details
Limits are enforced per API key ID using an in-memory counter per deployment process, reset on a sliding minute boundary after the first request in a window. On a single Node instance this matches “N requests per minute per key.” If you self-host multiple instances without a shared limiter, effective throughput can be higher than the documented plan cap until a shared store is introduced—hitting 429 still means that instance saw too many requests for that key in its window.
CORS
OPTIONS /api/mcp/server returns permissive CORS headers for Content-Type and Authorization. Browser-based MCP clients are uncommon; if you build one and see preflight failures, confirm the custom domain and method are allowed.
In-app MCP vs this endpoint
Problems connecting external MCP servers inside AffinityBots (OAuth, discovery, diagnostics under /api/mcp/diagnostics, Smithery, etc.) use different routes and lib/mcp/* code paths. This page focuses on your clients talking to /api/mcp/server. For integration OAuth and discovery issues, use the in-app Tools experience and Adding integrations.
Still stuck?
If you have checked the items above and something still fails consistently—including suspected bugs with workflow runs from MCP, LangGraph connectivity, or key validation—contact the AffinityBots team (for example via in-app chat or your account representative) with the approximate time of the request, the HTTP status or JSON-RPC error (redact your full API key), and which client you use. That context allows the team to trace logs and reproduce the path quickly.