Found while fuzzing the MCP stdio server (fixmap mcp, v0.9.0 built from main).
What happens
The MCP server answers tools/list (and presumably other calls) even though the client never sent initialize:
$ echo '{"jsonrpc":"2.0","id":9,"method":"tools/list"}' | fixmap mcp
{"result":{"tools":[...],"jsonrpc":"2.0","id":9}}
Per the MCP specification, a server must not service requests before the client completes the initialize handshake.
Why it matters
- Version/capability negotiation can be silently skipped, so a client built against an older protocol version gets served anyway instead of negotiating.
- It weakens the contract tools rely on: any state the server sets up during
initialize cannot be assumed to exist when handling tool calls.
Also observed (same area)
Malformed JSON lines on stdin produce no response at all (no -32700 Parse error). A client that sends one malformed line and then waits for a reply will hang until timeout. The JSON-RPC 2.0 spec expects a parse-error response for unparseable messages.
Suggested fix
Track whether initialize has completed and return error code -32002 (Server not initialized, per spec) for other requests before it; respond with -32700 for unparseable JSON lines.
Found while fuzzing the MCP stdio server (
fixmap mcp, v0.9.0 built from main).What happens
The MCP server answers
tools/list(and presumably other calls) even though the client never sentinitialize:Per the MCP specification, a server must not service requests before the client completes the
initializehandshake.Why it matters
initializecannot be assumed to exist when handling tool calls.Also observed (same area)
Malformed JSON lines on stdin produce no response at all (no
-32700 Parse error). A client that sends one malformed line and then waits for a reply will hang until timeout. The JSON-RPC 2.0 spec expects a parse-error response for unparseable messages.Suggested fix
Track whether
initializehas completed and return error code-32002(Server not initialized, per spec) for other requests before it; respond with-32700for unparseable JSON lines.