Skip to main content
Glama

MCP Server

by freedanfan
tool_router.py7.36 kB
#!/usr/bin/env python # -*- coding: utf-8 -*- """ MCP 工具集成路由器 处理工具相关的 MCP 请求 """ import os import json import logging import asyncio from typing import Dict, Any, Optional, List from .base_router import MCPBaseRouter logger = logging.getLogger("tool_router") class ToolRouter(MCPBaseRouter): """工具集成路由器""" def __init__(self): """初始化路由器""" super().__init__() self.tools = {} self._register_methods() self._register_tools() def _register_methods(self): """注册方法处理器""" self.register_method("tools/list", self.handle_list_tools) self.register_method("tools/execute", self.handle_execute_tool) self.register_method("tools/cancel", self.handle_cancel_tool) def _register_tools(self): """注册工具""" # 注册示例工具 self.tools["search"] = { "id": "search", "name": "搜索工具", "description": "在代码库中搜索内容", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "搜索查询" }, "scope": { "type": "string", "description": "搜索范围", "enum": ["all", "code", "docs"] } }, "required": ["query"] }, "handler": self._search_tool_handler } self.tools["fileSystem"] = { "id": "fileSystem", "name": "文件系统工具", "description": "访问和操作文件系统", "parameters": { "type": "object", "properties": { "action": { "type": "string", "description": "操作类型", "enum": ["read", "write", "list", "delete"] }, "path": { "type": "string", "description": "文件或目录路径" }, "content": { "type": "string", "description": "写入的内容(仅用于写入操作)" } }, "required": ["action", "path"] }, "handler": self._file_system_tool_handler } def handle_list_tools(self, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """处理工具列表请求""" logger.info("处理工具列表请求") # 构建工具列表(不包含处理器) tools_list = [] for tool_id, tool in self.tools.items(): tools_list.append({ "id": tool["id"], "name": tool["name"], "description": tool["description"], "parameters": tool["parameters"] }) return { "tools": tools_list } async def handle_execute_tool(self, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """处理执行工具请求(异步)""" if not params or "id" not in params: raise ValueError("缺少工具 ID 参数") tool_id = params["id"] tool_params = params.get("params", {}) logger.info(f"处理执行工具请求,工具 ID: {tool_id},参数: {tool_params}") # 查找工具 if tool_id not in self.tools: raise ValueError(f"工具 ID '{tool_id}' 不存在") tool = self.tools[tool_id] handler = tool["handler"] # 执行工具 try: if asyncio.iscoroutinefunction(handler): result = await handler(tool_params) else: result = handler(tool_params) return { "id": tool_id, "status": "success", "result": result } except Exception as e: logger.exception(f"执行工具 '{tool_id}' 时出错") return { "id": tool_id, "status": "error", "error": str(e) } def handle_cancel_tool(self, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """处理取消工具执行请求""" if not params or "id" not in params: raise ValueError("缺少工具 ID 参数") tool_id = params["id"] logger.info(f"处理取消工具执行请求,工具 ID: {tool_id}") # 在实际应用中,这里会取消正在执行的工具 return { "id": tool_id, "cancelled": True } def _search_tool_handler(self, params: Dict[str, Any]) -> Dict[str, Any]: """搜索工具处理器""" query = params.get("query", "") scope = params.get("scope", "all") # 示例搜索结果 results = [] if scope in ["all", "code"]: results.append({ "path": "/examples/example.py", "snippet": "def hello_world():", "relevance": 0.95 }) if scope in ["all", "docs"]: results.append({ "path": "/docs/example.md", "snippet": "# 示例文档", "relevance": 0.85 }) return { "query": query, "scope": scope, "results": results } async def _file_system_tool_handler(self, params: Dict[str, Any]) -> Dict[str, Any]: """文件系统工具处理器(异步)""" action = params.get("action") path = params.get("path") if not action or not path: raise ValueError("缺少必要参数") # 模拟异步操作 await asyncio.sleep(0.1) # 示例实现 if action == "read": # 模拟读取文件 content = "这是模拟的文件内容" return { "path": path, "content": content, "size": len(content) } elif action == "write": # 模拟写入文件 content = params.get("content", "") return { "path": path, "written": True, "size": len(content) } elif action == "list": # 模拟列出目录 return { "path": path, "items": [ {"name": "file1.txt", "type": "file", "size": 1024}, {"name": "file2.py", "type": "file", "size": 2048}, {"name": "subdir", "type": "directory"} ] } elif action == "delete": # 模拟删除文件 return { "path": path, "deleted": True } else: raise ValueError(f"不支持的操作: {action}")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/freedanfan/mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server