modelcontextprotocol / modelcontextprotocol/python-sdk

[v2] Allow MCPServer to disable subscriptions/listen

Offen
#3,357 5 Kommentare 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

spec-2026-07-28 v2
Vorherrschende Sprache
Python
Sterne
24.3k
Forks
4k
Ø Merge
1 T. 1 Std.
Gemergte PRs (30 T.)
31

Beschreibung

Initial Checks
Release line

2.x (current stable)

Description
What happened?

MCPServer always installs a subscriptions/listen handler:

on_subscriptions_listen=ListenHandler(self._subscriptions)

The constructor exposes subscriptions: SubscriptionBus | None = None, but None creates an InMemorySubscriptionBus; it does not disable subscriptions.

This causes server/discover to advertise:

{
  "tools": {"listChanged": true},
  "prompts": {"listChanged": true},
  "resources": {"listChanged": true, "subscribe": true}
}

Our MCP server has a static catalog and never publishes change notifications. It runs as a stateless Streamable HTTP server on AWS Lambda.

Claude Code 2.1.235 automatically opened four subscriptions/listen streams during discovery. Each request followed the long-lived SSE path and held a Lambda invocation until timeout.

We currently reject these requests in ASGI middleware. This prevents the timeout, but the server still advertises subscription support, so clients continue attempting the requests.

The low-level Server supports disabling this correctly through:

Server(..., on_subscriptions_listen=None)

The high-level MCPServer has no equivalent public option. Removing the handler through _lowlevel_server._request_handlers works, but relies on private internals.

What did you expect?

MCPServer should provide a supported opt-out, for example:

MCPServer(..., subscriptions=False)

or:

MCPServer(..., enable_subscriptions=False)

When disabled:

  • subscriptions/listen should not be registered.
  • server/discover should advertise the relevant change and subscription capabilities as false.
  • An unsolicited subscriptions/listen call should return Method not found.
  • Existing behavior should remain the default for compatibility.
    This matches SEP-2575’s stateless-first, “pay as you go” design. Long-lived streams should only be enabled when the server uses them.
Area

Server

References

AI assistance disclosure: I used an AI coding assistant to inspect the SDK source and help draft this report. I reviewed and verified the contents.

Example Code
from mcp.server import MCPServer

server = MCPServer("static-server")

capabilities = server._lowlevel_server.get_capabilities(
    protocol_version="2026-07-28"
)

print(capabilities.model_dump(by_alias=True, exclude_none=True))
Python & MCP Python SDK
Python 3.11
mcp 2.0.0
AWS Lambda
Streamable HTTP
json_response=True
stateless_http=True

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 mit dem MCPServer-Konstruktor und seiner Registrierung von on_subscriptions_listen=ListenHandler(self._subscriptions), und untersuche anschließend _lowlevel_server.get_capabilities sowie den Request-Pfad für subscriptions/listen. Definiere den öffentlichen Opt-out, wobei das aktuelle Standardverhalten erhalten bleibt. Fertig ist es, wenn deaktivierte Server den Handler weglassen, die relevanten Capabilities als false ankündigen und bei nicht angeforderten subscriptions/listen-Aufrufen Method not found zurückgeben.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
api, backend-api-design
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
68/100

Neue Issues direkt in Ihr Postfach

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