Skip to content

Ignore the body of an HTTP notification response - #1413

Open
psp65 wants to merge 1 commit into
smithy-lang:mainfrom
psp65:fix-http-notification-body
Open

psp65 wants to merge 1 commit into
smithy-lang:mainfrom
psp65:fix-http-notification-body

Conversation

@psp65

@psp65 psp65 commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

What behavior changes?

  • HttpMcpClient.exchange no longer parses the response body of a notification (a request without an id). It returns null, as StdioMcpClient does.
  • A short body of known length (up to 8 KiB) is read and discarded, so the connection can be reused.
  • Any other body, including a text/event-stream or one of unknown length, is closed unread. A misbehaving server can't block the client or make it buffer without bound.
  • Error responses (non-2xx) and responses to requests with an id are handled as before.

Why is this change needed?

Fixes #1412. A server that accepts notifications/initialized with 202 and a {} body made McpRemoteClient.initialize fail with Missing required members: [jsonrpc], so the remote server contributed no tools. The spec requires 202 with no body, but the client loses nothing by tolerating one.

How was this validated?

New HttpMcpClientTest cases:

  • testNotificationIgnoresBodyOfAcceptedResponse: a 202 with {} returns null.
  • initializeSucceedsWhenInitializedNotificationIsAcceptedWithABody: a full initialize against such a server succeeds, and the next request works.
  • testNotificationDoesNotReadAStreamingResponseBody: a never-ending event stream answering a notification doesn't block exchange. It times out if the body is read in full.

The first two fail without the fix. ./gradlew :mcp:mcp-server:test :mcp:mcp-server:integ :mcp:mcp-server:spotlessCheck passes: 255 unit and 125 integration tests.

What should reviewers focus on?

HttpMcpClient.exchange and discardBody: the notification branch sits after the session-404 and non-2xx handling, so error bodies still surface. Also the 8 KiB threshold for reading versus closing.

Additional Links


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Streamable HTTP answers an accepted notification with 202 and no body,
but some servers send a body anyway, such as {}. HttpMcpClient parsed
that body as a JSON-RPC response and failed with "Missing required
members: [jsonrpc]". For notifications/initialized that failed
McpRemoteClient.initialize, so the remote server contributed no tools.

A notification has no JSON-RPC response, so discard the body, as
StdioMcpClient does. A short body of known length is read so the
connection can be reused; anything else, including a stream, is closed
unread so a misbehaving server cannot block the client or make it
buffer without bound.
@psp65
psp65 force-pushed the fix-http-notification-body branch from b2c6fb4 to a528f29 Compare October 13, 2026 23:01
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.

MCP server: HttpMcpClient fails to initialize when a notification is accepted with a 202 body

1 participant