Repository navigation
server/discover returns -32601 Method not found, so every modern MCP SDK connect logs an error #2433
Description
Version
codebase-memory-mcp 0.11.0
Platform
macOS (Apple Silicon)
Install channel
GitHub release archive / install.sh
Binary variant
ui
What happened, and what did you expect?
The current official MCP SDK client uses server/discover as its default connect probe (see @modelcontextprotocol/client, connect mode auto: it sends server/discover, and falls back to the 2025-era initialize handshake only if the probe fails). Against CBM 0.11.0 that probe is answered with -32601 Method not found on every connection, and the daemon records it as an error.
From ~/.cache/codebase-memory-mcp/logs/cbm-daemon.log:
level=warn msg=mcp.request protocol=jsonrpc method=server/discover status=error duration_ms=0
45 occurrences in the log; server/discover is the only method that ever reports status=error (every initialize, tools/list, prompts/list etc. is status=ok).
Impact:
- Every modern-SDK connect produces a spurious error/warn line in the daemon log.
- No modern (
2026-07-28) revision is ever advertised, so clients cannot use the modern revision even when they ask for it — the server silently negotiates down to2025-11-25.
Expected: implement server/discover (returning supportedVersions, capabilities, instructions, plus cache hints) as required for protocol revision 2026-07-28; or, if the modern revision is intentionally unsupported, don't log the expected fallback probe as an error.
This is not the same as #1813: there the server exited / never answered in the test container. Here the server answers promptly with a well-formed JSON-RPC error while tools/list works normally.
Reproduction
- Start the MCP server on stdio:
codebase-memory-mcp initialize, claiming the modern revision (the server negotiates down to2025-11-25):
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}Result:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","serverInfo":{"name":"codebase-memory-mcp","version":"0.11.0"},"capabilities":{"tools":{"listChanged":false},"prompts":{"listChanged":false}},"instructions":"..."}}server/discover:
{"jsonrpc":"2.0","id":2,"method":"server/discover","params":{}}Result:
{"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"Method not found"}}Expected: a DiscoverResult (supportedVersions + capabilities), since the official client uses this as its connect probe.
- Sanity check — the same session's
tools/listsucceeds, so the transport/handshake is fine:
{"jsonrpc":"2.0","id":3,"method":"tools/list","params":{}}→ returns the 15 tools.
The same -32601 is returned when initialize is sent at 2025-06-18 or 2025-11-25; the client always probes server/discover first.
Logs
level=info msg=mcp.request protocol=jsonrpc method=initialize status=ok duration_ms=0
level=info msg=mcp.request protocol=jsonrpc method=tools/list status=ok duration_ms=0
level=info msg=mcp.request protocol=jsonrpc method=prompts/list status=ok duration_ms=0
level=warn msg=mcp.request protocol=jsonrpc method=server/discover status=error duration_ms=0
Only server/discover errors; cbm-daemon.log contains zero level=error/panic/fatal lines, i.e. this is the sole recurring error surface.
Confirmations
- I searched existing issues and this is not a duplicate (closest is MCP spec conformance: 10 requirement(s) violated (via @hasmcp/mcp-spec-test) — spec 2026-07-28 #1813, which is the test-container exit, not this).
- My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.
Activity
Zhuoxi2000 commentedon Oct 6, 2026
Drafted with an AI coding assistant (Claude). Line numbers are at
main268a9d8.Read against the 2026-07-28 versioning page (https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning), the
-32601reply looks correct for the server as it is today, and only the log line looks wrong.Why the reply itself is correct
2025-11-25and earlier "legacy" versions.SUPPORTED_PROTOCOL_VERSIONS(src/mcp/mcp.c:1382) stops at2025-11-25, so CBM is a legacy server. The "Servers MUST implementserver/discover" requirement sits in the Protocol Version Negotiation section, which describes the modern per-request_metaversioning.initialize." That is the sequence in the report: discover gets-32601, theninitializeandtools/listsucceed.DiscoverResulton its own would probably make things worse. Per the row for a dual-era client and a modern server, the client then "stays modern". From that point it sends requests with per-request_metaand noinitialize, and expects stateless serving and-32022 UnsupportedProtocolVersionErrorfor version mismatches. A server that answers discover but still requiresinitializewould break the fallback that currently works.The part that does look like a defect
The method-not-found branch (
src/mcp/mcp.c, around line 18684) callscbm_log_mcp_request(req.method, NULL, true, ...).cbm_log_mcp_request(src/foundation/log.c:365) mapsis_errortolevel=warn ... status=error. Every modern-SDK connect therefore leaves one warn line incbm-daemon.log, even though the probe outcome is the expected one. The branch does not touchcbm_diag_record_query, so only the log is affected, not the query counters.Two possible directions
server/discoveras an expected connect probe, in the same spirit as the Cline connection throws status=error on resource and prompt template discovery queries #958 handling ofresources/list. Keep the-32601reply unchanged, but log it asinfo/ok(or a distinct status) instead ofwarn/error. Add a test intests/test_mcp.cnext toserver_handle_unknown_method, using the existingmcp_capture_logsink to check that the warn line is not emitted. Other unknown methods would keep logging at warn. This is small. Open PR fix(mcp): report request timing and transport failures #2372 changes thecbm_log_mcp_requestsignature and touches the same branch, so I would rebase onto it if it lands first.Which of these, if either, would you like? If it is (1), should the discover probe be logged at
infowithstatus=ok, or with its own status such asstatus=legacy_probe, so it can still be grepped? I'm happy to open a focused PR with a regression test for (1) once you say which one you want.mvanhorn commentedon Oct 6, 2026
The method-not-found path in cbm_mcp_server_handle always called cbm_log_mcp_request with the error argument set to true, which is written as level=warn and status=error. server/discover is not implemented, so the modern connect probe takes that path and gets the same log treatment as any other unknown method.
That call now passes false for the error argument when the method is server/discover and true for every other unknown method, so the probe is logged as level=info with status=ok while other misses stay level=warn and status=error.
DeusData commentedon Oct 19, 2026
Thank you for the follow-up analysis and the distinction between legacy fallback logging and full modern protocol support. I have read the report of a log-only change, but have not verified its landing or release status. The broader protocol direction remains a separate maintainer decision.
DeusData commentedon Oct 20, 2026
Fixed on main by 9c89041 (PR #2556, thanks to @mvanhorn): the server/discover connect probe is now logged at level=info with status=ok, and the reply stays -32601 Method not found so current MCP clients fall back to initialize as before. Other unknown methods still log as warnings.
Thank you @xxww0098 for the precise report with log excerpts and a runnable reproduction, and @Zhuoxi2000 for reading the 2026-07-28 versioning rules against the code. Support for the 2026-07-28 protocol revision itself is a separate question and is not part of this change.
fix(mcp): log the server/discover connect probe as info, not an error