From 1feb2ae7d541581cbc1173240cd5d4c32c9ea993 Mon Sep 17 00:00:00 2001 From: Paulo Victor Cordeiro <146781332+pvcordeiro@users.noreply.github.com> Date: Wed, 3 Jun 2026 06:23:46 +0100 Subject: [PATCH] fix: close AsyncExitStack on MCP init/tool-discovery failure (#1493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If session.initialize() or list_tools() raises after the stdio subprocess or SSE connection is already open, the AsyncExitStack is never closed — leaking the child process or HTTP connection. Wrap the setup phase in try/except to aclose() the stack before re-raising. --- src/mcp_manager.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mcp_manager.py b/src/mcp_manager.py index e588a10..811094f 100644 --- a/src/mcp_manager.py +++ b/src/mcp_manager.py @@ -89,14 +89,18 @@ class McpManager: ) stack = AsyncExitStack() - transport = await stack.enter_async_context(stdio_client(server_params)) - read_stream, write_stream = transport - session = await stack.enter_async_context(ClientSession(read_stream, write_stream)) + try: + transport = await stack.enter_async_context(stdio_client(server_params)) + read_stream, write_stream = transport + session = await stack.enter_async_context(ClientSession(read_stream, write_stream)) - await session.initialize() + await session.initialize() - # Discover tools - tools_result = await session.list_tools() + # Discover tools + tools_result = await session.list_tools() + except Exception: + await stack.aclose() + raise tools = [] for tool in tools_result.tools: tools.append({ @@ -142,14 +146,18 @@ class McpManager: from contextlib import AsyncExitStack stack = AsyncExitStack() - transport = await stack.enter_async_context(sse_client(url)) - read_stream, write_stream = transport - session = await stack.enter_async_context(ClientSession(read_stream, write_stream)) + try: + transport = await stack.enter_async_context(sse_client(url)) + read_stream, write_stream = transport + session = await stack.enter_async_context(ClientSession(read_stream, write_stream)) - await session.initialize() + await session.initialize() - # Discover tools - tools_result = await session.list_tools() + # Discover tools + tools_result = await session.list_tools() + except Exception: + await stack.aclose() + raise tools = [] for tool in tools_result.tools: tools.append({