Summary
rmcp::model::DiscoverResult requires a top-level serverInfo, but the
official MCP conformance server and TypeScript example server return server
identity under _meta["io.modelcontextprotocol/serverInfo"].
Consequently, valid 2026-07-28 discovery responses are rejected or
misclassified as CallToolResult.
Observed against real implementations
The official MCP conformance server directly implements the namespaced response:
The conformance implementation explicitly notes that server identity lives in
result metadata rather than the DiscoverResult body.
Reproduction
Deserialize this conformance-server response as ServerJsonRpcMessage:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"supportedVersions": ["2026-07-28"],
"capabilities": {},
"ttlMs": 0,
"cacheScope": "private",
"_meta": {
"io.modelcontextprotocol/serverInfo": {
"name": "conformance-mock-server",
"version": "1.0.0"
}
}
}
}
DiscoverResult fails because its server_info: Implementation field expects
the top-level serverInfo member. Since ServerResult is untagged and
CallToolResult accepts _meta, the same payload can then match the wrong
result variant.
Observed client trace:
→ server/discover
← HTTP 200; supportedVersions = ["2026-07-28"]
_meta["io.modelcontextprotocol/serverInfo"] = {...}
top-level serverInfo = absent
✗ expect initialized result, but received: Some(CallToolResult(...))
A related rmcp revision produced
expect initialized result, but received: Some(CustomResult(...)).
The client never proceeds to tools/list. Modern stdio inventory, tool calls,
resources, and multi-round operations fail at startup.
As an isolation control, copying the same identity into a synthetic top-level
serverInfo immediately allows discovery and subsequent tool calls to succeed.
Expected behavior
Both top-level serverInfo and
_meta["io.modelcontextprotocol/serverInfo"] should deserialize as
ServerResult::DiscoverResult. The resolved server identity and unrelated
metadata should be preserved, and discovery responses must not be classified
as completed tool-call results.
Summary
rmcp::model::DiscoverResultrequires a top-levelserverInfo, but theofficial MCP conformance server and TypeScript example server return server
identity under
_meta["io.modelcontextprotocol/serverInfo"].Consequently, valid
2026-07-28discovery responses are rejected ormisclassified as
CallToolResult.Observed against real implementations
The official MCP conformance server directly implements the namespaced response:
everything-serverusing the same representationThe conformance implementation explicitly notes that server identity lives in
result metadata rather than the
DiscoverResultbody.Reproduction
Deserialize this conformance-server response as
ServerJsonRpcMessage:{ "jsonrpc": "2.0", "id": 1, "result": { "resultType": "complete", "supportedVersions": ["2026-07-28"], "capabilities": {}, "ttlMs": 0, "cacheScope": "private", "_meta": { "io.modelcontextprotocol/serverInfo": { "name": "conformance-mock-server", "version": "1.0.0" } } } }DiscoverResultfails because itsserver_info: Implementationfield expectsthe top-level
serverInfomember. SinceServerResultis untagged andCallToolResultaccepts_meta, the same payload can then match the wrongresult variant.
Observed client trace:
A related rmcp revision produced
expect initialized result, but received: Some(CustomResult(...)).The client never proceeds to
tools/list. Modern stdio inventory, tool calls,resources, and multi-round operations fail at startup.
As an isolation control, copying the same identity into a synthetic top-level
serverInfoimmediately allows discovery and subsequent tool calls to succeed.Expected behavior
Both top-level
serverInfoand_meta["io.modelcontextprotocol/serverInfo"]should deserialize asServerResult::DiscoverResult. The resolved server identity and unrelatedmetadata should be preserved, and discovery responses must not be classified
as completed tool-call results.