MCP channel notifications with list- or int-valued params.meta fields are silently dropped (no error, connection stays healthy)
Environment
- Claude Code 2.1.221 (Windows, native), MCP server over stdio (Python), channels enabled via
--dangerously-load-development-channels - Still apparently unfixed: CHANGELOG entries 2.1.222–2.1.229 contain no channel/meta/notification fix (not re-tested on latest; happy to re-verify on request)
Summary
notifications/claude/channel notifications are silently dropped when params.meta contains a list- or int-valued field. Flat all-string meta (or empty/absent meta) injects fine. The drop is per-notification: no error is surfaced anywhere (client UI, logs, MCP debug), the stdio connection stays alive, and subsequent flat-meta notifications continue to inject normally.
Reproduction
- Minimal stdio MCP server registered as a channel source; launch Claude Code with
--dangerously-load-development-channels. - Send two notifications identical except for
metavalue types:
{"jsonrpc":"2.0","method":"notifications/claude/channel",
"params":{"content":"hello A","meta":{"t0":"2026-08-05T12:00:00Z","path":"inbox/a.md"}}}
→ injected (surfaces in the session as expected).
{"jsonrpc":"2.0","method":"notifications/claude/channel",
"params":{"content":"hello B","meta":{"count":1,"ids":[1,2]}}}
→ silently vanishes. No client error, no log line, no MCP debug output; connection healthy; a following flat-meta notification injects fine.
- Bisected with an stdio tee proxy between server and client, confirming the notification bytes leave the server correctly framed (LF-only) and are consumed by the client — the drop is client-side.
Value-shape matrix observed:
| meta | Result |
|---|---|
| {"t0": "...", "path": "..."} (flat strings) | injected |
| {"t0": "..."} | injected |
| {} | injected |
| {"count": 1, "ids": [1, 2]} (int + list) | silently dropped |
Expected behavior
Either arbitrary JSON values in params.meta are accepted (matching the spirit of MCP _meta, which permits arbitrary JSON), or a non-string value produces a loud validation error. A silent per-notification drop is the worst of both: senders get a success-shaped outcome and the message is gone.
Probably related, but not duplicates
- #67482 — non-string
metavalue (a bool) raises an uncaught ZodError that kills the whole stdio connection (loud, logged). Likely the same validation area, but a materially different observed failure: ours is silent, single-notification, and the connection survives. It may be that list/int values hit a different branch of the same handler that swallows instead of throwing. - #61797 — silent notification drops framed as an idle-session race (non-deterministic, fleet-scale). Ours is deterministic and keyed purely on
metavalue type. - #44181 — older (2.1.81/2.1.92) silent-drop report whose repro
metais all flat strings — the exact shape that injects fine for us; closed as duplicate of pre-2.1.221 issues.
Workaround
Restrict params.meta to flat string scalars. Cost: any structured metadata must be stringified or dropped.