Skip to content

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

@juliendoclot

Description

@juliendoclot

Problem

The StreamableHTTPTransport server validates the Accept header with a strict AND condition, requiring clients to send both application/json and text/event-stream:

# mcp/server/streamable_http.py, _validate_accept_header()
elif not (has_json and has_sse):
    response = self._create_error_response(
        "Not Acceptable: Client must accept both application/json and text/event-stream",
        HTTPStatus.NOT_ACCEPTABLE,
    )

This rejects clients that send only Accept: text/event-stream, returning a 406 Not Acceptable.

Impact

This breaks compatibility with Anthropic's MCP proxy (used by Claude.ai for remote MCP integrations). The Anthropic proxy sends requests with Accept: text/event-stream to the /mcp endpoint and expects SSE responses. The strict AND validation rejects these requests.

When json_response=False (the spec-compliant default for SSE-capable servers), the server should be able to handle clients that accept SSE responses even if they don't explicitly accept JSON.

Expected behavior

The server should accept requests with either Accept: application/json or Accept: text/event-stream (or both). The response format should match what the client accepts:

  • Accept: text/event-stream → respond with SSE
  • Accept: application/json → respond with JSON
  • Accept: application/json, text/event-stream → respond with SSE (current spec behavior)

Suggested fix

Change the AND to OR in _validate_accept_header():

# Before
elif not (has_json and has_sse):

# After
elif not (has_json or has_sse):

This allows the server to accept clients that support at least one of the two content types, while still being able to negotiate the response format based on what the client accepts.

Reproduction

# Start any MCP server with StreamableHTTP transport (json_response=False)

# This works (both Accept types):
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'
# → 200 OK

# This fails (SSE only):
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'
# → 406 Not Acceptable

Environment

  • MCP SDK version: 1.25.0
  • Discovered while using mcp-proxy v0.11.0 with Claude.ai remote MCP integration

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions