Source code for agentscope.mcp._mcp_function

# -*- coding: utf-8 -*-
"""The MCP tool function class in AgentScope."""
from contextlib import _AsyncGeneratorContextManager
from typing import Any, Callable

import mcp
from mcp import ClientSession

from ._client_base import MCPClientBase
from .._utils._common import _extract_json_schema_from_mcp_tool
from ..tool import ToolResponse


[docs] class MCPToolFunction: """An MCP tool function class that can be called directly.""" name: str """The name of the tool function.""" description: str """The description of the tool function.""" json_schema: dict[str, Any] """JSON schema of the tool function"""
[docs] def __init__( self, mcp_name: str, tool: mcp.types.Tool, wrap_tool_result: bool, client_gen: Callable[..., _AsyncGeneratorContextManager[Any]] | None = None, session: ClientSession | None = None, ) -> None: """Initialize the MCP function.""" self.mcp_name = mcp_name self.name = tool.name self.description = tool.description self.json_schema = _extract_json_schema_from_mcp_tool(tool) self.wrap_tool_result = wrap_tool_result # Cannot be None at the same time if ( client_gen is None and session is None or (client_gen is not None and session is not None) ): raise ValueError( "Either client or session must be provided, but not both.", ) self.client_gen = client_gen self.session = session
[docs] async def __call__( self, **kwargs: Any, ) -> mcp.types.CallToolResult | ToolResponse: """Call the MCP tool function with the given arguments, and return the result.""" if self.client_gen: async with self.client_gen() as cli: read_stream, write_stream = cli[0], cli[1] async with ClientSession(read_stream, write_stream) as session: await session.initialize() res = await session.call_tool( self.name, arguments=kwargs, ) else: res = await self.session.call_tool( self.name, arguments=kwargs, ) if self.wrap_tool_result: as_content = MCPClientBase._convert_mcp_content_to_as_blocks( res.content, ) return ToolResponse( content=as_content, metadata=res.meta, ) return res