Skip to content

fix: accept single supported content type in SSE mode Accept header#2361

Open
4444J99 wants to merge 1 commit intomodelcontextprotocol:mainfrom
4444J99:fix/accept-header-sse-only-2349
Open

fix: accept single supported content type in SSE mode Accept header#2361
4444J99 wants to merge 1 commit intomodelcontextprotocol:mainfrom
4444J99:fix/accept-header-sse-only-2349

Conversation

@4444J99
Copy link
Copy Markdown

@4444J99 4444J99 commented Mar 27, 2026

Summary

Relax the Accept header validation for SSE-mode POST requests from requiring both application/json AND text/event-stream to requiring at least one. This restores compatibility with clients that send only Accept: text/event-stream, such as Anthropic's MCP proxy used by Claude.ai for remote MCP integrations.

Closes #2349

Problem

The _validate_accept_header() method uses a strict AND condition:

elif not (has_json and has_sse):

This rejects clients sending Accept: text/event-stream without application/json, returning 406 Not Acceptable. The MCP spec uses SHOULD (not MUST) for clients accepting both content types, and the server already negotiates response format based on message type — notifications/responses get JSON 202s regardless, and request responses use SSE streams.

Changes

  • src/mcp/server/streamable_http.py: Change AND to OR in _validate_accept_header() for SSE mode, requiring at least one supported content type instead of both
  • tests/shared/test_streamable_http.py: Add test_accept_header_single_type parametrized test covering text/event-stream, application/json, application/*, and text/* as individually sufficient Accept values; update incompatible test to remove values that now pass
  • tests/issues/test_1363_race_condition_streamable_http.py: Update race condition test expectations — single supported Accept types now return 200 instead of 406

Test plan

  • New test_accept_header_single_type — verifies each supported type individually accepted (4 cases)
  • Incompatible types (text/html, image/png) still correctly rejected with 406
  • Wildcard tests unchanged and passing
  • JSON-only mode (is_json_response_enabled=True) unchanged — still requires application/json
  • Missing Accept header still rejected with 406
  • Race condition regression test (Race Condition in StreamableHTTP Transport Causes ClosedResourceError #1363) updated and passing
  • Full test suite: 1146 passed, 0 failed
  • ruff check clean
  • pyright clean (0 errors)

…alidation

Relax the Accept header validation for SSE-mode POST requests from
requiring both application/json AND text/event-stream to requiring
at least one. This restores compatibility with clients that send only
Accept: text/event-stream (e.g. Anthropic's MCP proxy used by Claude.ai
for remote MCP integrations).

The MCP spec uses SHOULD (not MUST) for clients accepting both content
types. The server already negotiates the response format based on the
message type — notifications/responses get JSON 202s, requests get SSE
streams — so requiring both types in the Accept header is stricter than
necessary.

Closes modelcontextprotocol#2349
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.

Streamable HTTP transport rejects Accept: text/event-stream without application/json

1 participant