Skip to content

fix(vaden_mcp): remove spurious initialized notification on startup - #171

Open
tecrodrigocastro wants to merge 2 commits into
Flutterando:mainfrom
tecrodrigocastro:fix/mcp-server-spurious-initialized-notification
Open

tecrodrigocastro wants to merge 2 commits into
Flutterando:mainfrom
tecrodrigocastro:fix/mcp-server-spurious-initialized-notification

Conversation

@tecrodrigocastro

@tecrodrigocastro tecrodrigocastro commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

This fixes two related JSON-RPC protocol violations in vaden_mcp that break strict MCP clients (observed with Claude Desktop, which rejects both messages with a Zod invalid_union schema error).

1. Spurious server-initiated initialized notification on boot

  • vaden_mcp sent a bogus initialized message to stdout immediately on startup, before any client request.
  • Per the MCP spec, notifications/initialized is sent by the client after the initialize handshake completes — never by the server on boot. The message was also missing the notifications/ prefix.
  • Removed the startup notification and the now-unused _sendNotification helper. Server info is still returned correctly via the initialize response handler (_handleInitialize).

2. Server responded to notifications it didn't recognize

  • _handleRequest treated every incoming message as a request. When the client sent a notification (no id field, e.g. the client's own notifications/initialized) for a method not in the switch statement, it fell into the default case and got an unsolicited error response with id: null.
  • Per JSON-RPC 2.0, notifications must never receive a response, regardless of whether the method is recognized. id: null also doesn't fit the schema's expected string | number id, compounding the failure.
  • Added an isNotification check (message has no id) so the server no longer replies to notifications in the unknown-method and internal-error paths.

Test plan

  • dart analyze on vaden_mcp — no new issues
  • dart test in vaden_mcp — all 3 existing tests pass
  • Manually piped initializenotifications/initializedtools/listresources/list into dart run bin/vaden_mcp.dart — stdout now contains only the correct responses, in order, with no extraneous or invalid messages
  • Verified against Claude Desktop's MCP log locally: the exact sequence that previously produced the ZodError: invalid_union now completes cleanly

vaden_mcp sent a server->client "initialized" notification immediately
on boot, before any client request. Per the MCP spec, notifications/
initialized is sent by the client after the initialize handshake, not
by the server. The bogus message (also missing the notifications/
prefix) breaks strict MCP clients like Claude Desktop, which fail to
match it against any known request/response/notification schema.
_handleRequest treated every incoming message as a request, so a
client notification (no "id" field, e.g. notifications/initialized)
that didn't match a known method fell into the default case and got
an unsolicited error response with id: null.

Per JSON-RPC 2.0, notifications must never receive a response. Strict
MCP clients like Claude Desktop reject that response outright: id null
doesn't fit the expected string|number id, and the payload doesn't
match a notification schema either, so it surfaces as a Zod
invalid_union error right after the initialize handshake.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant