Troubleshooting
This page troubleshoots the NEXUS local MCP server, not an external MCP server connected to Chainabit. 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.