You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
core: client notifications carry "id":null; JSON-RPC notifications omit id #1520
core.Request.MarshalJSON always emits "id", so every notification the client sends goes out as {"jsonrpc":"2.0","id":null,"method":"notifications/initialized"}. JSON-RPC 2.0 defines a notification as a request object without an id member. With "id":null it's a request with a null id, which the spec discourages and a strict peer may answer or reject. It applies to every transport, since client.notifyMethod marshals through core.Request.
Seen while fixing #1517 (client/stdio_framing_test.go asserts the method rather than the exact bytes because of it). Both reference SDKs tolerate it today: @modelcontextprotocol/server-everything (TS, via tests/e2e/stdio_interop_test.go) and the Python mcp 2.3.0 client session against our server. So nothing is broken that we know of.
Wanted
Omit id when Request.ID is nil (json:"id,omitempty" in the marshal shim), and check the server's IsNotification and the stateless wire still classify both shapes the same way.
A wire test pinning a notification's exact bytes.
waiting — trigger: a peer rejects or answers an mcpkit notification, or the 1.0 wire freeze (#1356 is the same kind of decision).
Planned 2026-10-14, parked in favour of #1502. Two more findings for whoever picks it up:
server/dispatch.go:377 (panic recovery) checks req.ID != nil, so a notification sent with "id":null whose handler panics gets a -32603 response. Everywhere else uses req.IsNotification(), which treats nil and null alike; use it here too.
Fix shape: omitempty on id in the Request.MarshalJSON shim (an explicit json.RawMessage("null") would still be written). core.Response stays as is. No fixture in the tree pins "id":null, and server-side notifications already omit id via core.MarshalNotification. Tighten client/stdio_framing_test.go back to an exact-bytes check as the wire test.
Activity
panyam commentedon Oct 14, 2026
Planned 2026-10-14, parked in favour of #1502. Two more findings for whoever picks it up:
server/dispatch.go:377(panic recovery) checksreq.ID != nil, so a notification sent with"id":nullwhose handler panics gets a-32603response. Everywhere else usesreq.IsNotification(), which treats nil andnullalike; use it here too.omitemptyonidin theRequest.MarshalJSONshim (an explicitjson.RawMessage("null")would still be written).core.Responsestays as is. No fixture in the tree pins"id":null, and server-side notifications already omitidviacore.MarshalNotification. Tightenclient/stdio_framing_test.goback to an exact-bytes check as the wire test.panyam commentedon Oct 16, 2026
P3/waiting → P2: JSON-RPC wire correctness, which mission #1552 covers; it was parked only because no mission held it.