fastapi_mcp icon indicating copy to clipboard operation
fastapi_mcp copied to clipboard

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

Open dustinblack opened this issue 3 months ago • 2 comments

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

  • Model Context Protocol Specification: https://spec.modelcontextprotocol.io/
  • JSON-RPC 2.0 Specification: https://www.jsonrpc.org/specification
  • Gemini CLI MCP Integration: https://github.com/google-gemini/gemini-cli
  • fastapi-mcp GitHub: https://github.com/tadata-org/fastapi_mcp

dustinblack avatar Oct 07 '25 11:10 dustinblack

I am facing the same problem. Was there a solution?

domingasp avatar Oct 27 '25 18:10 domingasp

I'm also facing same issue. but when I added text/event-stream then I'm getting Bad Request: Missing session ID.

Image

sbhardwaj-godaddy avatar Oct 31 '25 06:10 sbhardwaj-godaddy