The MCP failure modes nobody tests: bad key, missing key, unknown tool, garbage params
Everyone tests the happy path on their MCP server. I did too, and it hid the problems that actually bite in a real client.
So I wrote a harness that drives the server over stdio the way Claude Code does, and deliberately broke things. Setup: 45 tools, protocol 2024-11-05.
The four cases worth asserting on, in rough order of how much pain they cause:
1. Missing credentials entirely. Should fail immediately with a message naming the variable. If it starts fine and only dies inside a tool call, the model will try to work around it, and you end up debugging the model instead of the server.
2. Bad credentials. Should surface a readable error. A raw stack trace here is worse than useless, because the model cannot tell an auth problem from a transport problem.
3. Unknown tool name. Should be rejected cleanly. Models hallucinate tool names more often than people expect, especially with 40+ tools listed.
4. Invalid params. Should come back as an error the model can act on. This is the one that decides whether the model self-corrects or gives up.
The other assertion I would not skip: on tools/list, check every tool has a non-empty description and a valid inputSchema. Boring, and it caught a real problem for me. Separately, if any tool is long-running and returns a job id rather than a result, make sure the description says so. Mine did not, in 43 of 45 tools.
Implementation notes if you build one: read stdout line by line on a background thread, parse each line as JSON, match responses by request id rather than assuming order, and give the poll loop a hard timeout so a hung server fails your test instead of hanging it.
Took an afternoon. I would not ship an MCP server without it now.
Disclosure: I build an SEO API for agents, and this was our own MCP server. Nothing to buy here, the failure-mode list is the point.