modelcontextprotocol / modelcontextprotocol/python-sdk

[v2] Allow MCPServer to disable subscriptions/listen

Abierto
#3,357 5 comentarios 4 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

spec-2026-07-28 v2
Lenguaje dominante
Python
Estrellas
24.3k
Forks
4k
Merge medio
1 d 1 h
PR fusionados (30 d)
31

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el constructor de MCPServer y su registro de on_subscriptions_listen=ListenHandler(self._subscriptions), y después inspecciona _lowlevel_server.get_capabilities y la ruta de solicitudes de subscriptions/listen. Define el opt-out público conservando el comportamiento predeterminado actual. Se considera terminado cuando los servidores deshabilitados omiten el handler, anuncian las capabilities relevantes como false y devuelven Method not found para las llamadas no solicitadas a subscriptions/listen.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
api, backend-api-design
Tipo de issue
Nueva funcionalidad
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Activo
Claridad
Bastante claro
Aptitud para principiantes
68/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.