mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix mcp list result parsing
This commit is contained in:
parent
3448bf79f8
commit
4df4c9cf00
2 changed files with 56 additions and 3 deletions
|
|
@ -18,6 +18,7 @@ from typing import (
|
|||
Union,
|
||||
)
|
||||
import httpx
|
||||
import mcp.types as types
|
||||
from mcp import ClientSession, ReadResourceResult, Resource, StdioServerParameters
|
||||
from mcp.client.sse import sse_client
|
||||
from mcp.client.stdio import stdio_client
|
||||
|
|
@ -41,7 +42,7 @@ from mcp.types import (
|
|||
TextContent,
|
||||
)
|
||||
from mcp.types import Tool as MCPTool
|
||||
from pydantic import AnyUrl
|
||||
from pydantic import AnyUrl, Field
|
||||
from litellm._logging import verbose_logger
|
||||
from litellm.constants import MCP_CLIENT_TIMEOUT, MCP_NPM_CACHE_DIR
|
||||
from litellm.llms.custom_httpx.http_handler import get_ssl_configuration
|
||||
|
|
@ -81,6 +82,14 @@ def _first_non_cancelled_cause(exc: BaseException) -> Optional[BaseException]:
|
|||
return None
|
||||
|
||||
|
||||
class _LenientListPromptsResult(types.ListPromptsResult):
|
||||
prompts: List[Prompt] = Field(default_factory=list)
|
||||
|
||||
|
||||
class _LenientListResourcesResult(types.ListResourcesResult):
|
||||
resources: List[Resource] = Field(default_factory=list)
|
||||
|
||||
|
||||
TSessionResult = TypeVar("TSessionResult")
|
||||
|
||||
|
||||
|
|
@ -628,7 +637,10 @@ class MCPClient:
|
|||
)
|
||||
|
||||
async def _list_prompts_operation(session: ClientSession):
|
||||
return await session.list_prompts()
|
||||
return await session.send_request(
|
||||
types.ClientRequest(types.ListPromptsRequest(params=None)),
|
||||
_LenientListPromptsResult,
|
||||
)
|
||||
|
||||
try:
|
||||
result = await self.run_with_session(_list_prompts_operation)
|
||||
|
|
@ -713,7 +725,10 @@ class MCPClient:
|
|||
)
|
||||
|
||||
async def _list_resources_operation(session: ClientSession):
|
||||
return await session.list_resources()
|
||||
return await session.send_request(
|
||||
types.ClientRequest(types.ListResourcesRequest(params=None)),
|
||||
_LenientListResourcesResult,
|
||||
)
|
||||
|
||||
try:
|
||||
result = await self.run_with_session(_list_resources_operation)
|
||||
|
|
|
|||
|
|
@ -542,6 +542,44 @@ class TestExecuteSessionOperationSurfacesTransportError:
|
|||
result = await client._execute_session_operation(transport_ctx, _op)
|
||||
assert result == "done"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_resources_tolerates_missing_resources_field(self):
|
||||
client = MCPClient(server_url="http://example.com/mcp", transport_type="http")
|
||||
session = AsyncMock()
|
||||
|
||||
async def send_request(_request, result_type):
|
||||
assert result_type is mcp_client_module._LenientListResourcesResult
|
||||
return result_type.model_validate({})
|
||||
|
||||
session.send_request = AsyncMock(side_effect=send_request)
|
||||
|
||||
async def run_with_session(operation):
|
||||
return await operation(session)
|
||||
|
||||
client.run_with_session = AsyncMock(side_effect=run_with_session)
|
||||
|
||||
assert await client.list_resources() == []
|
||||
session.send_request.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_prompts_tolerates_missing_prompts_field(self):
|
||||
client = MCPClient(server_url="http://example.com/mcp", transport_type="http")
|
||||
session = AsyncMock()
|
||||
|
||||
async def send_request(_request, result_type):
|
||||
assert result_type is mcp_client_module._LenientListPromptsResult
|
||||
return result_type.model_validate({})
|
||||
|
||||
session.send_request = AsyncMock(side_effect=send_request)
|
||||
|
||||
async def run_with_session(operation):
|
||||
return await operation(session)
|
||||
|
||||
client.run_with_session = AsyncMock(side_effect=run_with_session)
|
||||
|
||||
assert await client.list_prompts() == []
|
||||
session.send_request.assert_awaited_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue