Skip to content

feat: add X-Accel-Buffering: no header to SSE responses - #1139

Open
Debasishhh wants to merge 2 commits into
modelcontextprotocol:mainfrom
Debasishhh:fix/sse-x-accel-buffering-header
Open

Debasishhh wants to merge 2 commits into
modelcontextprotocol:mainfrom
Debasishhh:fix/sse-x-accel-buffering-header

Conversation

@Debasishhh

Copy link
Copy Markdown

Summary

Fixes #293.

None of the servlet-based SSE responses set X-Accel-Buffering: no. Without it, reverse proxies like Nginx buffer the response by default, batching what should be a real-time stream of JSON-RPC messages/notifications instead of forwarding each one as it's written.

Changes

Added the header alongside the existing Cache-Control/Connection headers at all three places an SSE response is opened:

  • HttpServletSseServerTransportProvider#doGet (the legacy SSE transport's connection endpoint)
  • HttpServletStreamableServerTransportProvider#doGet (the streamable transport's GET listening stream)
  • HttpServletStreamableServerTransportProvider#doPost (the streamable transport's SSE response to a streamed tool call)

Tests

Added one integration test per call site above, each opening a real connection through a real Tomcat instance and asserting X-Accel-Buffering: no is present on the response. I verified all three fail without the header and pass with it (reverted the header lines locally, confirmed the exact assertion failures, then restored the fix).

Verification

  • ./mvnw -pl mcp-core -am install && ./mvnw -pl mcp-test -Dtest=HttpServletSseIntegrationTests,HttpServletStreamableIntegrationTests test — 43 + 55 tests, 0 failures.
  • ./mvnw -pl mcp-core,mcp-test -am spring-javaformat:validate — clean.

Related PR

#848 proposed the same header addition (2 of the 3 sites) but appears to have gone stale without review. This PR covers all three SSE response sites and adds test coverage.

Without this header, reverse proxies like Nginx buffer SSE responses by
default, delaying delivery of streamed content instead of forwarding it
in real time. Adds the header to all three SSE-producing response paths
in the servlet-based SSE and streamable HTTP transports.

Fixes modelcontextprotocol#293
Covers all three response paths that open an SSE stream: the legacy SSE
transport's GET endpoint, the streamable transport's GET listening
stream, and the streamable transport's POST tool-call response. Verified
each test fails without the header and passes with it.
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.

Add X-Accel-Buffering: no Header for SSE Responses

1 participant