Skip to content

[BUG] HTTP endpoint incorrectly requires text/event-stream Accept header #233

@dustinblack

Description

@dustinblack

Describe the bug

The /mcp/http endpoint (mounted via mount_http()) incorrectly rejects HTTP
requests that only include Accept: application/json in the Accept header. It
requires BOTH application/json AND text/event-stream, even though the HTTP
JSON-RPC endpoint returns JSON responses, not Server-Sent Events streams.

This breaks compatibility with MCP clients that use native HTTP JSON-RPC
transport and only send Accept: application/json, specifically:

  • Google Gemini CLI's native HTTP transport (httpUrl configuration)
  • Other standard HTTP JSON-RPC clients

The error message returned is:

{
  "jsonrpc": "2.0",
  "id": "server-error",
  "error": {
    "code": -32600,
    "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
  }
}

To Reproduce

Server Setup:

from fastapi import FastAPI
from fastapi_mcp import FastApiMCP

app = FastAPI()

# Add some MCP tools (example)
@app.post("/tools/example", operation_id="example", tags=["mcp-tools"])
async def example_tool():
    return {"result": "success"}

# Mount MCP transports
mcp = FastApiMCP(
    app,
    name="test-server",
    description="Test MCP server",
    include_tags=["mcp-tools"],
)
mcp.mount_http(mount_path="/mcp/http")

Test 1 - Fails (only application/json):

curl -X POST http://localhost:8080/mcp/http \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {"name": "test", "version": "1.0"}
    }
  }'

Response:

{
  "jsonrpc": "2.0",
  "id": "server-error",
  "error": {
    "code": -32600,
    "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
  }
}

Test 2 - Works (both accept headers):

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

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {...},
    "serverInfo": {...}
  }
}

Gemini CLI Configuration (broken):

{
  "mcpServers": {
    "test-server": {
      "httpUrl": "http://localhost:8080/mcp/http",
      "trust": true
    }
  }
}

Gemini CLI fails to connect because it only sends Accept: application/json
for HTTP JSON-RPC endpoints.

Expected behavior

The /mcp/http endpoint should accept HTTP requests with only
Accept: application/json since:

  1. It's an HTTP JSON-RPC endpoint, not an SSE endpoint
  2. It returns JSON responses (Content-Type: application/json), not event streams
  3. The SSE transport is separately mounted at /mcp for clients that need streaming
  4. Standard HTTP JSON-RPC clients only send Accept: application/json

The text/event-stream accept header should only be required for the SSE
endpoint (/mcp), not the HTTP endpoint (/mcp/http).

System Info

  • fastapi-mcp version: 0.4.0
  • Python version: 3.13.0
  • FastAPI version: 0.115.5
  • sse-starlette version: 1.8.2
  • Operating System: Fedora Linux 42
  • MCP Client: Google Gemini CLI (native HTTP transport)

Additional context

Workarounds

  1. Use SSE transport instead: Configure Gemini to use "url": "http://localhost:8080/mcp"
    (SSE endpoint) instead of "httpUrl" (HTTP endpoint)

  2. Use a proxy script: Use an intermediate proxy that adds both accept headers:

    const baseHeaders = {
      'Content-Type': 'application/json',
      Accept: 'application/json, text/event-stream',
    };

Impact

This bug prevents Gemini CLI (and potentially other HTTP JSON-RPC MCP clients)
from using their native HTTP transport with fastapi-mcp servers. Users are
forced to either:

  • Use SSE transport (which may not be preferred for all use cases)
  • Use an intermediate proxy/bridge script (adds complexity)
  • Use stdio-based connection with a proxy (defeats the purpose of native HTTP)

Suggested fix

The HTTP endpoint handler should accept requests with:

  • Accept: application/json (JSON-RPC clients)
  • Accept: application/json, text/event-stream (current requirement)
  • Accept: */* (permissive clients)

But should NOT require text/event-stream for the HTTP JSON-RPC endpoint, as
that's only relevant for the SSE endpoint.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions