Spaces:
Paused
Paused
| # -*- coding: utf-8 -*- | |
| """The MCP client test module in agentscope.""" | |
| import asyncio | |
| from multiprocessing import Process | |
| from unittest.async_case import IsolatedAsyncioTestCase | |
| from mcp.server import FastMCP | |
| from mcp.types import EmbeddedResource, TextResourceContents | |
| from agentscope.mcp import MCPClient, HttpMCPConfig | |
| from agentscope.tool import ToolChunk | |
| async def tool_1(arg1: str, arg2: list[int]) -> str: | |
| """A test tool function. | |
| Args: | |
| arg1 (`str`): | |
| The first argument named arg1. | |
| arg2 (`list[int]`): | |
| The second argument named arg2. | |
| """ | |
| return f"arg1: {arg1}, arg2: {arg2}" | |
| async def tool_2() -> list: | |
| """ | |
| A test tool function return the EmbeddedResource type | |
| """ | |
| return [ | |
| EmbeddedResource( | |
| type="resource", | |
| resource=TextResourceContents( | |
| uri="file://tmp.txt", | |
| mimeType="text/plain", | |
| text="test content", | |
| ), | |
| ), | |
| ] | |
| def setup_server() -> None: | |
| """Set up the streamable HTTP MCP server.""" | |
| sse_server = FastMCP("StreamableHTTP", port=8002) | |
| sse_server.tool(description="A test tool function.")(tool_1) | |
| sse_server.tool( | |
| description="A test tool function with embedded resource.", | |
| )(tool_2) | |
| sse_server.run(transport="streamable-http") | |
| class StreamableHttpMCPClientTest(IsolatedAsyncioTestCase): | |
| """Test class for streamable HTTP MCP client.""" | |
| async def asyncTearDown(self) -> None: | |
| """Tear down the test environment.""" | |
| while self.process.is_alive(): | |
| self.process.terminate() | |
| await asyncio.sleep(5) | |
| async def asyncSetUp(self) -> None: | |
| """Set up the test environment.""" | |
| self.port = 8002 | |
| self.process = Process(target=setup_server) | |
| self.process.start() | |
| await asyncio.sleep(10) | |
| async def test_streamable_http_stateless_client(self) -> None: | |
| """Test the MCP server connection functionality.""" | |
| # Test stateless client (is_stateful=False) | |
| client = MCPClient( | |
| name="test_streamable_http_stateless_client", | |
| is_stateful=False, | |
| mcp_config=HttpMCPConfig( | |
| type="http_mcp", | |
| url=f"http://127.0.0.1:{self.port}/mcp", | |
| ), | |
| ) | |
| my_tool_1 = await client.get_tool("tool_1") | |
| res_1: ToolChunk = await my_tool_1(arg1="123", arg2=[1, 2, 3]) | |
| self.assertEqual( | |
| res_1.content[0].text, | |
| "arg1: 123, arg2: [1, 2, 3]", | |
| ) | |
| res_2: ToolChunk = await my_tool_1(arg1="345", arg2=[4, 5, 6]) | |
| self.assertEqual( | |
| res_2.content[0].text, | |
| "arg1: 345, arg2: [4, 5, 6]", | |
| ) | |
| # Test stateful client (is_stateful=True) | |
| client = MCPClient( | |
| name="test_streamable_http_stateful_client", | |
| is_stateful=True, | |
| mcp_config=HttpMCPConfig( | |
| type="http_mcp", | |
| url=f"http://127.0.0.1:{self.port}/mcp", | |
| ), | |
| ) | |
| self.assertFalse(client.is_connected) | |
| await client.connect() | |
| self.assertTrue(client.is_connected) | |
| my_tool_1 = await client.get_tool("tool_1") | |
| res_3: ToolChunk = await my_tool_1(arg1="12", arg2=[1, 2]) | |
| self.assertEqual( | |
| res_3.content[0].text, | |
| "arg1: 12, arg2: [1, 2]", | |
| ) | |
| res_4: ToolChunk = await my_tool_1(arg1="34", arg2=[4, 5]) | |
| self.assertEqual( | |
| res_4.content[0].text, | |
| "arg1: 34, arg2: [4, 5]", | |
| ) | |
| await client.close() | |
| self.assertFalse(client.is_connected) | |
| async def test_embedded_content(self) -> None: | |
| """Test the EmbeddedContent functionality.""" | |
| # Test with stateless client (is_stateful=False) | |
| client = MCPClient( | |
| name="test_embedded_content", | |
| is_stateful=False, | |
| mcp_config=HttpMCPConfig( | |
| type="http_mcp", | |
| url=f"http://127.0.0.1:{self.port}/mcp", | |
| ), | |
| ) | |
| my_tool_2 = await client.get_tool("tool_2") | |
| res: ToolChunk = await my_tool_2() | |
| self.assertEqual( | |
| res.content[0].text, | |
| """{ | |
| "uri": "file://tmp.txt/", | |
| "mimeType": "text/plain", | |
| "meta": null, | |
| "text": "test content" | |
| }""", | |
| ) | |