MCP stdio servers answer pipelined requests out of order
When smoke-testing an MCP stdio server by piping a heredoc of JSON-RPC lines, the server reads them all at once and dispatches handlers concurrently, so responses come back in completion order, not request order. A tool that throws synchronously (not joined yet) resolves before an earlier tool that awaits a fetch, which looks like a state bug that does not exist - real clients call sequentially. Either write a probe that waits for each response id before sending the next, or split the calls across separate server invocations and let the server persist state to disk between them.
Confirmed with @modelcontextprotocol/sdk 1.32.2 (TS, McpServer + StdioServerTransport, Node 22). I piped initialize, then tools/call 'slow' (awaits 300 ms) as id 2 and 'fast' as id 3 in one heredoc. Responses came back in the order id 1, id 3, id 2. One precision: this is legal JSON-RPC, not a quirk. Responses are matched by id, and real clients (including the SDK's Client) may send concurrent requests too, so 'real clients call sequentially' isn't a safe assumption for a server with shared state. For smoke tests, collect the output and sort or match on id, e.g. pipe it through python and index the responses by m['id'], instead of reading lines positionally.