Skip to content

Commit cbbd552

Browse files
committed
fix(client): avoid KeyError and preserve exit stacks when connecting ClientSessionGroup to empty servers
1 parent d2290ca commit cbbd552

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

src/mcp/client/session_group.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,6 @@ async def _aggregate_components(self, server_info: types.Implementation, session
414414
except MCPError as err: # pragma: no cover
415415
logging.warning(f"Could not fetch tools: {err}")
416416

417-
# Clean up exit stack for session if we couldn't retrieve anything
418-
# from the server.
419-
if not any((prompts_temp, resources_temp, tools_temp)):
420-
del self._session_exit_stacks[session] # pragma: no cover
421-
422417
# Check for duplicates.
423418
matching_prompts = prompts_temp.keys() & self._prompts.keys()
424419
if matching_prompts:

tests/client/test_session_group.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,23 @@ async def test_client_session_group_establish_session_parameterized(
402402
# 3. Assert returned values
403403
assert returned_server_info is mock_initialize_result.server_info
404404
assert returned_session is mock_entered_session
405+
406+
407+
@pytest.mark.anyio
408+
async def test_client_session_group_connect_empty_server():
409+
"""Test connecting to a server that registers no tools, resources, or prompts."""
410+
mock_session = mock.AsyncMock(spec=mcp.ClientSession)
411+
mock_session.list_prompts.return_value = types.ListPromptsResult(prompts=[])
412+
mock_session.list_resources.return_value = types.ListResourcesResult(resources=[])
413+
mock_session.list_tools.return_value = types.ListToolsResult(tools=[])
414+
415+
server_info = types.Implementation(name="empty_server", version="1.0")
416+
group = ClientSessionGroup()
417+
418+
# Should not raise KeyError when aggregating empty server
419+
session = await group.connect_with_session(server_info, mock_session)
420+
assert session is mock_session
421+
assert mock_session in group._sessions
422+
assert not group.tools
423+
assert not group.resources
424+
assert not group.prompts

0 commit comments

Comments
 (0)