Skip to content

Troubleshooting

Three distinct failures account for most of what goes wrong while connecting to nexus-mcp. Each has its own shape on the wire — the point of this page is to tell them apart quickly rather than treating every non-response the same way.

A failed discovery call

tools/list (and, in the current era, server/discover-adjacent calls) is served live from the running workspace. With no workspace running, or no live session for the connecting process to reach, the call fails closed — it does not fall back to a cached catalog and does not return an empty result dressed up as success. What you get back is an explicit JSON-RPC error rather than a hang:

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32603,
    "message": "No live NEXUS session credential"
  }
}

The exact wording shown above is illustrative, not a guaranteed constant — what's stable is the shape: a standard JSON-RPC -32603 (Internal error), returned promptly, rather than the connection hanging or the call silently returning nothing. Treat this as "start a workspace and retry," not as evidence of a broken client.

An unsupported protocol version

Declare a protocolVersion — via _meta in the current era, or via initialize.params in the legacy one — that isn't in supportedVersions, and the request is rejected before anything else about it is examined:

json
{
  "jsonrpc": "2.0",
  "id": 7,
  "error": {
    "code": -32022,
    "message": "Unsupported protocol version",
    "data": { "supported": ["2026-07-28", "2025-06-18"], "requested": "2024-11-05" }
  }
}

data.supported and data.requested are always both present, so a client that speaks more than one MCP era can decide programmatically whether to retry on a version it also supports. See Protocol Eras for the negotiation model this guards.

A closely related failure: a request that engages the reserved io.modelcontextprotocol/ namespace at all but doesn't supply a valid string protocolVersion is rejected as malformed rather than guessed at, with -32602 (Invalid params). See MCP Protocol for that exact payload — it's easy to trigger by accident if you build the _meta block by hand and forget the version key while still setting client identity or capabilities.

A missing or expired session credential

A connecting CLI reads a per-session credential file rather than an environment variable — see Paths & Credentials. That file is rewritten during normal operation and removed when the session closes. Two ways this shows up as a failure:

  • The file never existed for this process in the first place (nothing has ever connected this CLI to a live NEXUS session).
  • The file existed but the session it pointed at has since ended, and nothing has replaced it.

Both surface the same way: every call other than the locally-answered handshake methods fails with -32603 and a message indicating there's no live session to forward to, rather than a partial or stale response. There is no separate, credential-specific error code — the signal to look for is which calls fail (everything requiring the live app) versus which don't (initialize, server/discover, and other locally-answered methods still respond, since those don't need to reach the app at all).

A quick reference

SymptomCodeWhat it means
Every real call fails immediately, handshake-only methods still work-32603No live session to forward to — start or reconnect a workspace session
Connection rejected before any method runs-32022The declared protocol version isn't in supportedVersions
Rejected with "Invalid params"-32602_meta used the reserved namespace without a valid protocolVersion
Hangs indefinitely after agent_trigger(no error)Expected — see Delivery Semantics; this tool never replies synchronously

Where to go next

Built with purpose.