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:
{
"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:
{
"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
| Symptom | Code | What it means |
|---|---|---|
| Every real call fails immediately, handshake-only methods still work | -32603 | No live session to forward to — start or reconnect a workspace session |
| Connection rejected before any method runs | -32022 | The 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
- MCP Protocol — the complete error catalog and negotiation contract.
- Paths & Credentials — the credential file's location, naming, and lifecycle.
- Connect a Client — getting the entry right in the first place.