heymcp probe. Each finding links here.
They exist because MCP client failures are mostly silent. These are the
mistakes that produce no error message anywhere — the connector simply doesn’t
work, or the tool simply never gets called.
Severities
Client limits these checks use
Where a rule refers to “the strictest client”, these are the numbers:Transport
transport/content-type
will break · Response content-type is wrong for streamable HTTP
initialize with a content-type that isn’t
application/json or text/event-stream.
Why it matters. This is the classic silent Claude.ai failure. Streamable
HTTP requires one of those two content types, and a server that answers with
anything else simply never connects — no error in the UI, nothing in the browser
console, and frequently nothing in your own logs either.
If you have ever added a connector and watched it do absolutely nothing, this is
the first thing to check.
How to fix it. Set the header on your MCP route. text/plain is the usual
culprit, often from a framework’s default for a string return value.
transport/accept-sse
will break · Server rejects
Accept: text/event-streamAccept: text/event-stream was rejected, usually with a 406
or 415.
Why it matters. Every agent client asks for streaming on the MCP route, so
this blocks all of them. It is not a Claude-specific quirk.
How to fix it. Accept both application/json and text/event-stream on the
MCP route. If you’re using a content-negotiation middleware, this is normally
where it’s coming from.
When this fires, the probe retries without SSE so you still get the rest of the
report. A half report with a named cause beats no report.
Protocol
mcp/protocol-version
heads up · Negotiated protocol version some clients cannot speak
2024-11-05 — a server pinned to it locks ChatGPT out entirely.
How to fix it. Support a newer revision, or accept that the named clients
won’t work.
A server newer than the check is not flagged. Comparison is against each
client’s oldest supported revision, because a client that speaks newer versions
negotiates down — that’s what negotiation is for.
Tools
tool/no-description
heads up · A tool has no description
check_order_status does from its name
alone. Sometimes they guess right. When they guess wrong, the tool either never
gets called or gets called in the wrong situation, and there’s no error to
notice — it just quietly doesn’t work as well as it should.
How to fix it. A single line. What it does, and when to use it.
tools/description-length
heads up · Tool description exceeds a client’s limit
tools/name-length
heads up · Tool name exceeds a client’s limit
tools/name-collision
will break · Two tools differ only by case
Schemas
schema/no-format
heads up · String parameter looks semantic but has no
formatformat constraint to say so.
Why it matters. This is the finding behind the canonical HeyMCP demo. Ask
Claude to book a table for seven and it will send:
2026-08-15T19:00:00Z. "7pm". Your parser throws, the agent sees an
opaque failure, and it may well try again with "19:00" and fail differently.
The check recognises three groups:
How to fix it. Add the format and an example. The example does most of the
work — models pattern-match on it.
schema/missing-required
heads up · Object schema marks nothing as required
required array for the parameters you genuinely need.
schema/deep-nesting
heads up · Input schema nests deeper than clients handle well
schema/additionalProperties-strict
heads up · Strict schema plus chatty client equals validation storms
"additionalProperties": false.
Why it matters. Agents routinely add an unasked-for key — a notes, a
reason, something they thought would help. With strict validation that
bounces, and the agent frequently retries in a loop, adding a slightly different
extra key each time. You get a burst of near-identical failures rather than one
clean error.
How to fix it. Drop the constraint, or ignore unknown keys server-side. If
you need to reject unexpected input for real reasons, do it with a clear error
message that tells the agent what was wrong, rather than a schema rejection it
can’t read.