|
4 | 4 |
|
5 | 5 | import base64 |
6 | 6 | import inspect |
7 | | -import json |
8 | 7 | import re |
9 | 8 | from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence |
10 | 9 | from contextlib import AbstractAsyncContextManager, asynccontextmanager |
11 | | -from typing import Any, Generic, Literal, TypeVar, overload |
| 10 | +from typing import Any, Generic, Literal, TypeVar, cast, overload |
12 | 11 |
|
13 | 12 | import anyio |
14 | 13 | import pydantic_core |
|
36 | 35 | from mcp.server.mcpserver.resources import FunctionResource, Resource, ResourceManager |
37 | 36 | from mcp.server.mcpserver.tools import Tool, ToolManager |
38 | 37 | from mcp.server.mcpserver.utilities.context_injection import find_context_parameter |
| 38 | +from mcp.server.mcpserver.utilities.func_metadata import ConvertedToolResult |
39 | 39 | from mcp.server.mcpserver.utilities.logging import configure_logging, get_logger |
40 | 40 | from mcp.server.sse import SseServerTransport |
41 | 41 | from mcp.server.stdio import stdio_server |
@@ -308,18 +308,13 @@ async def _handle_call_tool( |
308 | 308 | if isinstance(result, CallToolResult): |
309 | 309 | return result |
310 | 310 | if isinstance(result, tuple) and len(result) == 2: |
311 | | - unstructured_content, structured_content = result |
312 | | - return CallToolResult( |
313 | | - content=list(unstructured_content), # type: ignore[arg-type] |
314 | | - structured_content=structured_content, # type: ignore[arg-type] |
| 311 | + unstructured_content, structured_content = cast( |
| 312 | + tuple[Sequence[ContentBlock], dict[str, Any]], |
| 313 | + result, |
315 | 314 | ) |
316 | | - if isinstance(result, dict): # pragma: no cover |
317 | | - # TODO: this code path is unreachable — convert_result never returns a raw dict. |
318 | | - # The call_tool return type (Sequence[ContentBlock] | dict[str, Any]) is wrong |
319 | | - # and needs to be cleaned up. |
320 | 315 | return CallToolResult( |
321 | | - content=[TextContent(type="text", text=json.dumps(result, indent=2))], |
322 | | - structured_content=result, |
| 316 | + content=list(unstructured_content), |
| 317 | + structured_content=structured_content, |
323 | 318 | ) |
324 | 319 | return CallToolResult(content=list(result)) |
325 | 320 |
|
@@ -390,7 +385,7 @@ async def list_tools(self) -> list[MCPTool]: |
390 | 385 |
|
391 | 386 | async def call_tool( |
392 | 387 | self, name: str, arguments: dict[str, Any], context: Context[LifespanResultT, Any] | None = None |
393 | | - ) -> Sequence[ContentBlock] | dict[str, Any]: |
| 388 | + ) -> ConvertedToolResult: |
394 | 389 | """Call a tool by name with arguments.""" |
395 | 390 | if context is None: |
396 | 391 | context = Context(mcp_server=self) |
|
0 commit comments