From 686d4837dacdae621ac8de6b8654bdc7cd7900a2 Mon Sep 17 00:00:00 2001 From: Kaushik Iyer <54633514+kaushik701@users.noreply.github.com> Date: Sun, 31 May 2026 17:26:38 -0700 Subject: [PATCH 1/2] fix: gracefully terminate active StreamableHTTP sessions during shutdown --- src/mcp/server/streamable_http_manager.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mcp/server/streamable_http_manager.py b/src/mcp/server/streamable_http_manager.py index 81350a8f2..b9a27a41f 100644 --- a/src/mcp/server/streamable_http_manager.py +++ b/src/mcp/server/streamable_http_manager.py @@ -133,6 +133,12 @@ async def lifespan(app: Starlette) -> AsyncIterator[None]: yield # Let the application run finally: logger.info("StreamableHTTP session manager shutting down") + # Gracefully terminate all active sessions before cancelling tasks + for transport in list(self._server_instances.values()): + try: + await transport.terminate() + except Exception: + logger.debug("Error terminating transport during shutdown", exc_info=True) # Cancel task group to stop all spawned tasks tg.cancel_scope.cancel() self._task_group = None From e37d8aaaa3fb9f8fc894d921240207929bf03b1f Mon Sep 17 00:00:00 2001 From: Kaushik Iyer <54633514+kaushik701@users.noreply.github.com> Date: Sun, 31 May 2026 17:28:37 -0700 Subject: [PATCH 2/2] fix: close SSE stream writers in terminate() to allow graceful completion --- src/mcp/server/streamable_http.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mcp/server/streamable_http.py b/src/mcp/server/streamable_http.py index f2f4407ce..bfe3abcd7 100644 --- a/src/mcp/server/streamable_http.py +++ b/src/mcp/server/streamable_http.py @@ -771,6 +771,11 @@ async def terminate(self) -> None: self._terminated = True logger.info(f"Terminating session: {self.mcp_session_id}") + # Close all SSE stream writers to allow EventSourceResponse to complete gracefully + for writer in list(self._sse_stream_writers.values()): + writer.close() + self._sse_stream_writers.clear() + # We need a copy of the keys to avoid modification during iteration request_stream_keys = list(self._request_streams.keys())