Manifest-to-dispatch diagnostic
The tool list arrived. The tool call did not.
A successful tools/list response proves that an MCP server produced a tool manifest. It
does not prove that the managed host consumed every entry, exposed the tool to the model, selected it,
or dispatched tools/call. Test those boundaries separately before changing your real server.
In a Canary receipt, tools/list.response is manifest evidence.
tools/call.request is dispatch evidence. tools/call.executed is registered
callback evidence. Only the last one proves that the fixture callback ran at this server.
First, confirm what “listed” means
Canary records tools/list.request as soon as the request arrives. It records the stronger
tools/list.response stage only after a successful response contains a tool list; that is also
when the safe manifest count is retained. A host UI showing a tool is compatible with this evidence,
but the UI alone cannot establish a later call.
Protocol-era rows are independent. MCP
2026-07-28 removed the
initialize/initialized handshake, and its server/discover request is
optional for clients.
A modern host may proceed directly to tools/list or tools/call. MCP
2025-11-25
and earlier use the legacy initialize path. Missing modern discovery or a legacy-only initialization row
is therefore not a failed prerequisite.
Run one controlled dispatch prompt
- Create a fresh
baselinerun and connect only its new disposable URL to the host. - Open a fresh conversation so an earlier manifest or tool choice cannot confuse the comparison.
- Send this prompt exactly once:
Call canary_ping exactly once and return only its tool result.
Wait for the host response, then compare the run’s callback count and last observed stage. Do not infer a cause from an absent row: Canary cannot see a managed host’s cache, policy engine, parser, model decision, network path, or user-interface state.
Interpret the three useful outcomes
| Last observed boundary | What it establishes | Next safe comparison |
|---|---|---|
tools/list.response |
The server successfully produced a manifest; no later request reached Canary. | Repeat once with a fresh baseline run and the exact direct prompt. |
tools/call.request |
A call arrived, but no registered fixture callback is proven to have run. | Compare the safe called-tool field, HTTP status, and callback stage in a new run. |
tools/call.executed |
The registered canary callback ran at this server. | Compare the host-visible result, then finalize the receipt before sharing it. |
Stage counts are event aggregates, not compatibility scores or success rates. An executed Canary callback also does not prove that the host used its result correctly or that your own MCP server will behave the same way.
Check the ordering boundary separately
If baseline dispatch succeeds, create a separate limits run. It advertises 258 tools,
including sentinel_257 at the ordering boundary. In another fresh conversation, send the
limits prompt exactly once:
Call sentinel_257 exactly once and return only its tool result.
A 258-tool tools/list.response with neither tools/call.request nor a sentinel
callback narrows the observation to the manifest-to-dispatch boundary for that run. If a call request
arrived without tools/call.executed, the narrower boundary is request-to-callback instead.
Neither result identifies why the host stopped there. Keep baseline and limits receipts separate, and
do not compare them as rates. Read the
258-tool boundary guide before treating a product-specific count as
a protocol limit.
Finalize before you share
Finalization closes the disposable MCP endpoint and freezes an immutable receipt. Share the receipt,
not a live /mcp/:id capability or an owner-only API URL. The receipt excludes sessions,
tokens, prompts, responses, request bodies, tool arguments, IP addresses, and raw User-Agent strings.
Its fingerprint is a correlation identifier, not a digital signature.
Locate your manifest-to-call boundary
Create a disposable 30-minute baseline endpoint and run the exact prompt once.
Run MCP Host Canary