Skip to content

Commit 5a470d7

Browse files
committed
refactor(server): always return CallToolResult from MCPServer.call_tool
1 parent d40d00e commit 5a470d7

1 file changed

Lines changed: 15 additions & 13 deletions

File tree

src/mcp/server/mcpserver/server.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import re
88
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence
99
from contextlib import AbstractAsyncContextManager, asynccontextmanager
10-
from typing import Any, Generic, Literal, TypeVar, overload
10+
from typing import Any, Generic, Literal, TypeVar, cast, overload
1111

1212
import anyio
1313
import pydantic_core
@@ -308,20 +308,11 @@ async def _handle_call_tool(
308308
) -> CallToolResult:
309309
context = Context(request_context=ctx, mcp_server=self)
310310
try:
311-
result = await self.call_tool(params.name, params.arguments or {}, context)
311+
return await self.call_tool(params.name, params.arguments or {}, context)
312312
except MCPError:
313313
raise
314314
except Exception as e:
315315
return CallToolResult(content=[TextContent(type="text", text=str(e))], is_error=True)
316-
if isinstance(result, CallToolResult):
317-
return result
318-
if isinstance(result, tuple) and len(result) == 2:
319-
unstructured_content, structured_content = result
320-
return CallToolResult(
321-
content=list(unstructured_content), # type: ignore[arg-type]
322-
structured_content=structured_content, # type: ignore[arg-type]
323-
)
324-
return CallToolResult(content=list(result))
325316

326317
async def _handle_list_resources(
327318
self, ctx: ServerRequestContext[LifespanResultT], params: PaginatedRequestParams | None
@@ -390,11 +381,22 @@ async def list_tools(self) -> list[MCPTool]:
390381

391382
async def call_tool(
392383
self, name: str, arguments: dict[str, Any], context: Context[LifespanResultT, Any] | None = None
393-
) -> CallToolResult | Sequence[ContentBlock] | tuple[Sequence[ContentBlock], dict[str, Any]]:
384+
) -> CallToolResult:
394385
"""Call a tool by name with arguments."""
395386
if context is None:
396387
context = Context(mcp_server=self)
397-
return await self._tool_manager.call_tool(name, arguments, context, convert_result=True)
388+
result = await self._tool_manager.call_tool(name, arguments, context, convert_result=True)
389+
if isinstance(result, CallToolResult):
390+
return result
391+
if isinstance(result, tuple) and len(result) == 2: # type: ignore[arg-type]
392+
unstructured_content, structured_content = cast(
393+
tuple[Sequence[ContentBlock], dict[str, Any]], result
394+
)
395+
return CallToolResult(
396+
content=list(unstructured_content),
397+
structured_content=structured_content,
398+
)
399+
return CallToolResult(content=list(result)) # type: ignore[arg-type]
398400

399401
async def list_resources(self) -> list[MCPResource]:
400402
"""List all available resources."""

0 commit comments

Comments
 (0)