From 9b382e404cff2cdd1acc09bec959da1689d7bfab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E5=9F=BA=E9=AD=81?= <1412414664@qq.com> Date: Mon, 8 Jun 2026 21:14:06 +0800 Subject: [PATCH] fix: make MCP list tools lenient --- litellm/experimental_mcp_client/client.py | 11 ++++++++++- .../experimental_mcp_client/test_mcp_client.py | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/litellm/experimental_mcp_client/client.py b/litellm/experimental_mcp_client/client.py index d72075707c3..9ca905be333 100644 --- a/litellm/experimental_mcp_client/client.py +++ b/litellm/experimental_mcp_client/client.py @@ -43,6 +43,8 @@ from mcp.types import ( ListResourceTemplatesResult, ListResourcesRequest, ListResourcesResult, + ListToolsRequest, + ListToolsResult, Prompt, ResourceTemplate, TextContent, @@ -91,6 +93,10 @@ def _first_non_cancelled_cause(exc: BaseException) -> Optional[BaseException]: TSessionResult = TypeVar("TSessionResult") +class _LenientListToolsResult(ListToolsResult): + tools: List[MCPTool] = Field(default_factory=list) + + class _LenientListPromptsResult(ListPromptsResult): prompts: List[Prompt] = Field(default_factory=list) @@ -531,7 +537,10 @@ class MCPClient: ) async def _list_tools_operation(session: ClientSession): - return await session.list_tools() + return await session.send_request( + ClientRequest(ListToolsRequest()), + _LenientListToolsResult, + ) try: result = await self.run_with_session(_list_tools_operation) diff --git a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py index 5b1f904492c..3c00d555a86 100644 --- a/tests/test_litellm/experimental_mcp_client/test_mcp_client.py +++ b/tests/test_litellm/experimental_mcp_client/test_mcp_client.py @@ -18,6 +18,7 @@ from mcp.types import ( ListPromptsRequest, ListResourceTemplatesRequest, ListResourcesRequest, + ListToolsRequest, ) from litellm.types.mcp import MCPAuth, MCPStdioConfig, MCPTransport @@ -30,6 +31,9 @@ class _MissingListResultSession: self.requests.append((request, result_type)) return result_type.model_validate({}) + async def list_tools(self): + raise AssertionError("strict list_tools should not be used") + async def list_prompts(self): raise AssertionError("strict list_prompts should not be used") @@ -74,6 +78,7 @@ class TestMCPClient: @pytest.mark.parametrize( ("client_method", "request_type"), [ + ("list_tools", ListToolsRequest), ("list_prompts", ListPromptsRequest), ("list_resources", ListResourcesRequest), ("list_resource_templates", ListResourceTemplatesRequest),