Troubleshooting
When something goes wrong, the fastest path is almost always: reproduce in the MCP Inspector or with curl, then read the JSON-RPC payload directly. The patterns below cover the most common stumbles.
Connection issues
HTTP 401 — Unauthorized
- The
Authorizationheader is missing, or not literallyBearer <TOKEN>. - The token doesn't match the value in Secrets Manager.
- You rotated the secret but didn't restart the MCP server.
Reproduce with curl to isolate from the client:
curl -i http://localhost:3002/mcp \
-H "Authorization: Bearer dev-mcp-token-CHANGE-ME" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'HTTP 429 — Too Many Requests
You burned through the per-minute (20), daily (1000), or daily inference budget cap. The response carries a Retry-After header in seconds; sleep that long before retrying. See Rate limits.
Client never connects, no HTTP response
- Server isn't running on
localhost:3002. Checklsof -nP -iTCP:3002 -sTCP:LISTEN. - Client is targeting the production URL but it isn't live yet (ships July 20, 2026).
- CORS preflight failing because the client is web-based. Inspect Network tab; check the
OPTIONSresponse.
Session issues
HTTP 404 with body {"jsonrpc":"2.0","error":{"code":-32001,"message":"Session not found"}}
You sent a request with an mcp-session-id header that doesn't exist on the server — usually because the server restarted (sessions are in-memory, not persisted) or because you copy-pasted an expired id.
Fix: drop the mcp-session-id header, send initialize again, and use the new session id from the response headers.
GET /mcp returns 405
You opened an SSE stream without a session. Either send initialize first to get an mcp-session-id, or use stateless mode and skip the SSE channel.
Tool-call issues
Tool returns { ok: false, error: "feature_not_available" }
Currently affects entity.resolve and entity.relationships. The consolidation pipeline they depend on is not yet wired. See All tools for status pills per tool.
Action tool returns { status: "pending_approval" } when you expected execution
This is the designed Phase 0 behavior — the action engine isn't wired yet, so every send-class action defers to approval. Once Story 7-33 lands (July 20, 2026), tools will either execute (Level 3 trust) or return pending_approval based on actual trust state.
Schema validation failures (invalid_arguments)
- Empty string on a
min(1)field. Send a non-empty value or omit if the field is optional. - Wrong type (number vs string, array vs object). Check the per-tool reference under All tools.
- Extra unknown fields. The schema is permissive on extras today, but you can't rely on it — only send documented fields.
Production / deployment
Production URL isn't responding
https://mcp.cortex.jakeselby.com/mcp is reserved but not deployed until July 20, 2026. Until then, use http://localhost:3002/mcp against a local server. See Changelog & roadmap.
Token rotated and clients started failing
The server caches the bearer in-process. After updating Secrets Manager, restart the service to pick up the new value. In production this means rolling the ECS task. There is no overlap window today — schedule rotations for maintenance windows.
When to email founder@jakeselby.com
- You can reproduce a failure in the MCP Inspector and the server logs show a 5xx.
- A tool returned a result that violates its documented schema.
- You hit a rate-limit cap that doesn't match the documented limits.
- You think the surface needs a new tool. Include the use case and what you tried as a workaround.
Include: the exact request body, the response body, the mcp-session-id (if any), and the server requestId from your client's logs (if you have it).