modelcontextprotocol / modelcontextprotocol/python-sdk

Return 405 on GET when stateless_http=True

Offen Anfängerfreundlich
#2,474 4 Kommentare 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug P2
Vorherrschende Sprache
Python
Sterne
24.3k
Forks
4k
Ø Merge
1 T. 1 Std.
Gemergte PRs (30 T.)
31

Beschreibung

Initial Checks
Description

When a Streamable HTTP server is configured with stateless_http=True, GET /mcp is still accepted and opens an SSE stream that has no session context and can never receive server-initiated messages — a dead-end.

The MCP Streamable HTTP spec explicitly permits returning 405 Method Not Allowed when the server does not offer an SSE stream at the endpoint
(spec):

The server MUST return HTTP 405 Method Not Allowed if an SSE stream is
not offered at the endpoint.

A stateless server cannot offer one — there is no session to push to — so GET should 405. The TypeScript SDK already behaves this way in its stateless example.

A prior PR (#2262) proposed essentially this change but was closed for lack of a corresponding issue per CONTRIBUTING.md.
Opening this issue to agree on scope so the fix can be re-submitted.

Example Code
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("my-server", stateless_http=True, json_response=True)

@mcp.tool()
def ping() -> str:
    return "pong"

app = mcp.streamable_http_app()

A couple of clarifications for triage:

Current vs expected behavior

Today (v1.27.0):

$ curl -i -X GET http://localhost:8000/mcp
HTTP/1.1 200 OK
content-type: text/event-stream
... (stream idles until platform timeout)

Expected:

$ curl -i -X GET http://localhost:8000/mcp
HTTP/1.1 405 Method Not Allowed
Allow: POST
Concrete impact

The idle GET SSE stream holds a long-lived connection per client with no useful payload, exhausting concurrent connection limits on serverless platforms like Cloud Run. Background previously raised in #2232 / #1941.

Proposed resolution

PR #2262 already has a working implementation. Once this issue is labeled ready for work, reopening it (narrowed to GET per this issue's scope) should be sufficient — no new PR needed.

Python & MCP Python SDK
1.27.0

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne bei FastMCP.streamable_http_app() und untersuche, wie GET /mcp für stateless_http=True behandelt wird; PR #2262 enthält die vorherige Implementierung zur Überprüfung. Verwende das curl-Beispiel, um zu überprüfen, dass GET 405 Method Not Allowed mit Allow: POST zurückgibt, während das angegebene zustandslose POST-Verhalten unverändert bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
api, backend
Issue-Typ
Bug
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Ruhig
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
68/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.