import uvicorn import logging from mcp.server.fastmcp import FastMCP from typing import List, Dict, Any import threading # --- 配置 --- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) # --- MCP Server 定义 --- mcp = FastMCP() # 使用一个简单的字典和线程锁来安全地管理状态 test_state: Dict[str, Any] = {} state_lock = threading.Lock() def _reset_state(): """重置测试状态,不加锁,供内部调用""" global test_state test_state = { "results": {}, # e.g., {"api_id_1": [{"task_name": "...", "status": "...", "details": "..."}]} "apis_pending_init": [], } _reset_state() # 初始化状态 @mcp.tool() def initialize_test_plan(api_ids: List[str]) -> Dict[str, Any]: """ 根据提供的API ID列表,初始化测试计划。 这会重置所有测试状态,并为每个API准备好存储多次任务结果的列表。 """ with state_lock: _reset_state() for api_id in api_ids: test_state["results"][api_id] = [] test_state["apis_pending_init"] = list(api_ids) logger.info(f"TestManager: Initialized test plan with {len(api_ids)} APIs.") return { "status": "success", "message": f"Test plan initialized for {len(api_ids)} APIs.", "apis_pending": list(api_ids) } @mcp.tool() def record_test_result(api_id: str, task_name: str, status: str, details: str) -> Dict[str, Any]: """ 记录一个API在一个特定任务上的测试结果。 Args: api_id (str): 被测试的API的ID。 task_name (str): 执行的任务的名称。 status (str): 测试状态,例如 'passed' 或 'failed'。 details (str): 关于测试结果的详细描述或摘要。 """ with state_lock: if api_id not in test_state["results"]: # 如果由于某种原因API ID不存在,先创建它 test_state["results"][api_id] = [] # 将本次任务的结果追加到列表中 test_state["results"][api_id].append({ "task_name": task_name, "status": status, "details": details }) logger.info(f"TestManager: Recorded result for {api_id} on task '{task_name}': {status}") return {"status": "success", "message": f"Result for {api_id} on task '{task_name}' recorded."} @mcp.tool() def get_test_summary() -> Dict[str, Any]: """ 获取整个测试活动的最终摘要。 """ with state_lock: total_apis = len(test_state["results"]) tasks_completed_count = sum(len(tasks) for tasks in test_state["results"].values()) summary = { "total_apis": total_apis, "total_tasks_completed": tasks_completed_count, "results": test_state["results"] } logger.info("TestManager: Providing test summary.") return summary # --- 启动服务器 --- if __name__ == "__main__": import uvicorn # 移除get_next_api_to_test工具,因为它在M*N模型中不再需要。 # 我们使用 try...except 来确保即使工具不存在或属性名不正确,程序也不会崩溃。 try: # 基于之前的观察,我们尝试使用 _tools 属性 if "get_next_api_to_test" in mcp._tools: del mcp._tools["get_next_api_to_test"] logger.info("Successfully removed deprecated tool: get_next_api_to_test") except (AttributeError, KeyError): logger.warning("Could not remove 'get_next_api_to_test' tool (it may not exist or the tools attribute name is different). Continuing...") pass uvicorn.run(mcp.streamable_http_app(), host="127.0.0.1", port=8004)