| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- from __future__ import annotations
- import os
- from typing import Any
- from fastmcp import FastMCP
- from .auth import load_projects_config
- from .config_api import (
- get_command_log as api_get_command_log,
- get_ai_online_v2 as api_get_ai_online_v2,
- search_ai_rcmd_operations as api_search_ai_rcmd_operations,
- search_ai_systems as api_search_ai_systems,
- )
- mcp = FastMCP("m2")
- @mcp.tool(
- name="project.list",
- title="项目列表",
- description="列出目前用户可查询的项目列表。执行其他工具前,如前置未提到要查询项目的project_key,应先让用户选择要查询的项目,再使用对应的 project_key 调用后续工具。",
- tags={"project", "list"},
- )
- def project_list() -> dict[str, Any]:
- projects = load_projects_config()
- result: list[dict[str, Any]] = []
- for item in projects:
- if not item["enabled"]:
- continue
- result.append(
- {
- "project_key": item["project_key"],
- "project_name": item["project_name"],
- }
- )
- result.sort(key=lambda item: item["project_key"])
- return {
- "projects": result,
- "total": len(result),
- }
- def _append_next_page_hint(payload: Any, page_num: int) -> Any:
- if not isinstance(payload, dict):
- return payload
- total_page = None
- data = payload.get("data")
- if isinstance(data, dict):
- total_page = data.get("total_page")
- if total_page is None:
- total_page = payload.get("total_pages")
- if total_page is None:
- total_page = payload.get("total_page")
- if isinstance(total_page, int) and total_page > page_num:
- payload.setdefault(
- "mcp_note",
- f"Current result is page {page_num}. If the target was not found, continue with page_num={page_num + 1}.",
- )
- return payload
- @mcp.tool()
- def search_ai_systems(
- project_key: str,
- keyword: str = "",
- page_size: int = 20,
- page_num: int = 1,
- order_by: list[str] | None = None,
- ) -> Any:
- """搜索AI控制系统并返回系统code。默认 page_size 为 20,除非显式传入其他值。"""
- payload = api_search_ai_systems(
- project_key,
- keyword=keyword,
- page_size=page_size,
- page_num=page_num,
- order_by=order_by,
- )
- return _append_next_page_hint(payload, page_num)
- @mcp.tool()
- def search_ai_rcmd_operations(
- project_key: str,
- codes: list[str],
- end: str,
- page_size: int = 10,
- page_num: int = 1,
- order: str = "-create_time",
- ) -> Any:
- """按AI控制系统的code查询策略记录。默认 page_size 为 10,除非显式传入其他值。auto_exec=true 表示自动控制,否则表示推荐参考。"""
- payload = api_search_ai_rcmd_operations(
- project_key,
- codes=codes,
- end=end,
- page_size=page_size,
- page_num=page_num,
- order=order,
- )
- return _append_next_page_hint(payload, page_num)
- @mcp.tool()
- def get_ai_online_v2(project_key: str, codes: list[str]) -> Any:
- """按AI控制系统的code查询控制模式和运行状态。control_mode=1 表示自动控制;status=0 表示正常,1 表示异常。"""
- return api_get_ai_online_v2(project_key, codes=codes)
- @mcp.tool()
- def get_command_log(
- project_key: str,
- point_id: str,
- begin: int,
- end: int,
- page_size: int = 20,
- page_num: int = 1,
- export: bool = False,
- ) -> Any:
- """按 point_id 和时间范围查询指令下发日志。返回结果中 status=1 表示该点位下发成功。"""
- payload = api_get_command_log(
- project_key,
- point_id=point_id,
- begin=begin,
- end=end,
- page_size=page_size,
- page_num=page_num,
- export=export,
- )
- return _append_next_page_hint(payload, page_num)
- def main() -> None:
- host = os.getenv("MCP_HOST", "0.0.0.0").strip() or "0.0.0.0"
- port = int(os.getenv("MCP_PORT", "8500"))
- path = os.getenv("MCP_PATH", "/mcp").strip() or "/mcp"
- mcp.run(transport="http", host=host, port=port, path=path)
- if __name__ == "__main__":
- main()
|