"""MCP 工具转 ToolSpec 测试。""" import pytest from app.application.tool_runtime import mcp as mcp_module from app.application.tool_runtime.mcp import make_mcp_tool_specs from app.modules.safety.governor import PermissionPolicy from app.modules.tool_runtime.definition import ToolResult class _Server: def __init__(self, name, endpoint_url, auth_token=None): self.name = name self.endpoint_url = endpoint_url self.auth_token = auth_token def test_make_mcp_tool_specs_basic() -> None: tools = [{"name": "weather", "description": "查天气", "risk_level": "L1"}] specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None) assert len(specs) == 1 s = specs[0] assert s.name == "mcp_srv_weather" assert s.description == "查天气" assert s.risk_level == "L1" assert s.permission_policy == PermissionPolicy.allow def test_make_mcp_tool_specs_default_risk_l2() -> None: tools = [{"name": "t"}] specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None) assert specs[0].risk_level == "L2" assert specs[0].permission_policy == PermissionPolicy.ask def test_make_mcp_tool_specs_skips_unnamed() -> None: tools = [{"name": "t"}, {"description": "无名"}] specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None) assert len(specs) == 1 @pytest.mark.asyncio async def test_mcp_executor_calls_call_tool(monkeypatch: pytest.MonkeyPatch) -> None: captured: dict = {} async def fake_call_tool( _http_client, endpoint_url, tool_name, input, auth_token=None, **_kwargs ): captured.update(tool=tool_name, input=input, endpoint=endpoint_url, auth=auth_token) return ToolResult( ok=True, exit_code=0, stdout="ok", stderr="", duration_ms=1, timeout=False, truncated=False, trace_id="", ) monkeypatch.setattr(mcp_module, "call_tool", fake_call_tool) tools = [{"name": "t"}] specs = make_mcp_tool_specs( _Server("srv", "http://mcp.local", auth_token="tok"), tools, http_client="HTTP" ) result = await specs[0].executor({"x": 1}, None) assert result.ok is True assert captured == { "tool": "t", "input": {"x": 1}, "endpoint": "http://mcp.local", "auth": "tok", }