"""真实模型 + stdio MCP，只暴露两个白名单只读教学工具。本轮未运行。"""
import asyncio
from mcp import Client
from claude_tool_loop import run_loop
from mcp_client_demo import all_tools, server_parameters
from tool_contracts import ToolFailure, validate_order_args


async def main() -> None:
    async with Client(server_parameters()) as client:
        # 工具清单来自外部边界，不能不加筛选就交给模型。
        approved_names = {"get_order", "get_refund_policy"}
        discovered = await all_tools(client)
        selected = [t for t in discovered if t.name in approved_names]
        if {t.name for t in selected} != approved_names:
            raise RuntimeError("所需工具未完整发现")
        tools = [{"name": t.name, "description": t.description or "",
                  "input_schema": t.input_schema} for t in selected]

        async def execute(name: str, arguments: dict) -> tuple[dict, bool]:
            if name not in approved_names:
                return {"error": "tool_not_allowed"}, True
            try:
                validate_order_args(arguments)  # Host 再检查已知契约，不信任模型额外参数。
            except ToolFailure as error:
                return {"error": str(error)}, True
            result = await client.call_tool(name, arguments, read_timeout_seconds=10)
            if result.is_error:
                return {"error": "mcp_tool_error", "details": [
                    block.text for block in result.content if block.type == "text"]}, True
            if not isinstance(result.structured_content, dict):
                raise RuntimeError("预期工具未返回结构化对象")
            return result.structured_content, False

        print(await run_loop(tools, execute))


if __name__ == "__main__":
    asyncio.run(main())
