Code2Flow MCP Server

by kursk-ye
Verified
import asyncio import json import os from typing import Dict, Any # 这个例子使用的是模拟的MCP客户端 # 在真实场景中,你需要安装并使用实际的MCP客户端库 class MockMCPClient: """模拟的MCP客户端,用于演示""" def __init__(self, server_url: str = "http://localhost:8000"): self.server_url = server_url print(f"连接到MCP服务器: {server_url}") async def create_session(self): """创建一个新的会话""" print("创建新会话...") return MockMCPSession(self) class MockMCPSession: """模拟的MCP会话,用于演示""" def __init__(self, client: MockMCPClient): self.client = client async def call_tool(self, tool_name: str, arguments: Dict[str, Any] = None): """ 调用服务器上的工具 参数: - tool_name: 工具名称 - arguments: 工具参数 返回: - 工具执行结果 """ print(f"调用工具: {tool_name}") print(f"参数: {json.dumps(arguments, ensure_ascii=False, indent=2)}") # 在这里,我们实际上是调用本地的code2flow命令 # 在真实场景中,这将通过MCP协议发送到服务器执行 if tool_name == "generate_call_graph": import subprocess import tempfile source_paths = arguments.get("source_paths", []) output_path = arguments.get("output_path") language = arguments.get("language") if not source_paths: return {"error": "缺少必要参数: source_paths"} if not output_path: temp_dir = tempfile.mkdtemp() output_path = os.path.join(temp_dir, "call_graph.png") cmd = ["code2flow"] if language: cmd.extend(["--language", language]) cmd.extend(["--output", output_path]) cmd.extend(source_paths) try: result = subprocess.run( cmd, capture_output=True, text=True, check=True ) print(f"调用图生成成功: {output_path}") return { "success": True, "resource_id": f"call-graph://{os.path.basename(output_path)}", "output_path": output_path } except subprocess.CalledProcessError as e: return {"error": f"生成调用图失败: {e.stderr}"} except FileNotFoundError: return {"error": "未找到code2flow命令,请确保已正确安装"} elif tool_name == "check_code2flow_version": # 模拟版本检查 import subprocess try: result = subprocess.run( ["code2flow", "--version"], capture_output=True, text=True, check=True ) return {"version": result.stdout.strip()} except: return {"error": "无法获取版本信息"} else: return {"error": f"未知工具: {tool_name}"} async def read_resource(self, resource_uri: str): """ 读取资源内容 参数: - resource_uri: 资源URI 返回: - 资源内容和MIME类型 """ print(f"读取资源: {resource_uri}") # 在这个模拟实现中,我们只处理本地文件 if resource_uri.startswith("call-graph://"): # 提取文件名 filename = resource_uri.replace("call-graph://", "") try: with open(filename, "rb") as f: content = f.read() return content, "image/png" except: return None, None elif resource_uri == "help://code2flow": help_text = """ # Code2Flow MCP服务器 此服务器提供Code2Flow功能,用于生成代码调用图。 ## 主要功能 - `generate_call_graph`: 生成代码调用图并返回PNG图像 - `check_code2flow_version`: 检查安装的code2flow版本信息 - `analyze_code_complexity`: 分析源代码复杂度 """ return help_text, "text/markdown" else: return None, None async def main(): """主函数,演示如何使用MCP客户端与服务器交互""" # 创建一个临时的测试文件 import tempfile test_dir = tempfile.mkdtemp() test_file_path = os.path.join(test_dir, "test_file.py") with open(test_file_path, "w", encoding="utf-8") as f: f.write(""" def function1(): print("This is function 1") function2() function3() def function2(): print("This is function 2") def function3(): print("This is function 3") def main(): function1() if __name__ == "__main__": main() """) print(f"创建测试文件: {test_file_path}") # 创建MCP客户端并与服务器交互 client = MockMCPClient() session = await client.create_session() # 检查code2flow版本 version_result = await session.call_tool("check_code2flow_version") print(f"版本信息: {version_result}") # 生成调用图 output_path = os.path.join(test_dir, "output.png") graph_result = await session.call_tool("generate_call_graph", { "source_paths": [test_file_path], "output_path": output_path, "language": "python" }) print(f"调用图生成结果: {graph_result}") # 如果成功,检查输出文件 if graph_result.get("success") and os.path.exists(output_path): print(f"生成的图像文件大小: {os.path.getsize(output_path)} 字节") print("\n演示完成!") if __name__ == "__main__": asyncio.run(main())