KICCO_AI_IMAGE/mcp_server/mcp.py

245 lines
7.6 KiB
Python
Raw Normal View History

2025-04-24 19:25:29 +08:00
import asyncio
import logging
from typing import Dict, List, Optional, Any, Callable, Union
import os
# 导入MCP SDK相关库
from mcp.server.fastmcp import FastMCP
from mcp.types import Resource, Tool, Prompt
from mcp import types
class MCPServer:
"""
Model Context Protocol 服务器
用于管理模型连接和资源交互
"""
instance = None
def __init__(self, server_name: str = "ComfyUI-MCP"):
"""
初始化MCP服务器
参数:
server_name: 服务器名称
"""
MCPServer.instance = self
# 初始化FastMCP实例
self.mcp = FastMCP(server_name)
# 存储注册的资源、工具和提示
self.registered_resources: Dict[str, Callable] = {}
self.registered_tools: Dict[str, Callable] = {}
self.registered_prompts: Dict[str, Callable] = {}
# 存储模型连接信息
self.active_models: Dict[str, Dict[str, Any]] = {}
self.model_count: int = 0
# 状态标志
self.is_running: bool = False
# 设置基本资源和工具
self._setup_default_handlers()
logging.info(f"[MCP服务器] 已初始化,服务器名称: {server_name}")
def _setup_default_handlers(self):
"""设置默认的资源处理器和工具"""
# 注册状态资源
@self.mcp.resource("status://server")
def get_server_status() -> str:
"""返回服务器状态信息"""
return f"""
服务器状态:
- 运行中: {self.is_running}
- 活跃模型数: {len(self.active_models)}
- 已注册资源数: {len(self.registered_resources)}
- 已注册工具数: {len(self.registered_tools)}
- 已注册提示数: {len(self.registered_prompts)}
"""
# 注册模型列表资源
@self.mcp.resource("models://list")
def list_models() -> str:
"""返回当前连接的模型列表"""
if not self.active_models:
return "当前没有活跃的模型连接"
result = "活跃模型列表:\n"
for model_id, model_info in self.active_models.items():
result += f"- ID: {model_id}, 名称: {model_info.get('name', 'Unknown')}\n"
return result
# 注册Echo工具
@self.mcp.tool()
def echo(message: str) -> str:
"""简单的Echo工具用于测试连接"""
return f"MCP服务器回声: {message}"
# 注册系统信息工具
@self.mcp.tool()
def system_info() -> dict:
"""返回系统信息"""
import platform
return {
"os": platform.system(),
"python_version": platform.python_version(),
"hostname": platform.node(),
"cpu": platform.processor()
}
def register_resource(self, uri_pattern: str):
"""
注册一个资源处理函数
参数:
uri_pattern: 资源URI模式
"""
def decorator(func):
self.registered_resources[uri_pattern] = func
self.mcp.resource(uri_pattern)(func)
logging.info(f"[MCP服务器] 已注册资源: {uri_pattern}")
return func
return decorator
def register_tool(self, name: Optional[str] = None):
"""
注册一个工具函数
参数:
name: 工具名称可选
"""
def decorator(func):
tool_name = name or func.__name__
self.registered_tools[tool_name] = func
self.mcp.tool(name=tool_name)(func)
logging.info(f"[MCP服务器] 已注册工具: {tool_name}")
return func
return decorator
def register_prompt(self, name: Optional[str] = None):
"""
注册一个提示模板
参数:
name: 提示名称可选
"""
def decorator(func):
prompt_name = name or func.__name__
self.registered_prompts[prompt_name] = func
self.mcp.prompt(name=prompt_name)(func)
logging.info(f"[MCP服务器] 已注册提示: {prompt_name}")
return func
return decorator
def register_model(self, model_info: Dict[str, Any]) -> str:
"""
注册一个模型到MCP服务器
参数:
model_info: 模型信息字典
返回:
model_id: 模型ID
"""
model_id = f"model_{self.model_count}"
self.model_count += 1
self.active_models[model_id] = {
"id": model_id,
"registered_at": asyncio.get_event_loop().time(),
**model_info
}
logging.info(f"[MCP服务器] 已注册模型: {model_id}")
return model_id
def unregister_model(self, model_id: str) -> bool:
"""
从MCP服务器注销一个模型
参数:
model_id: 模型ID
返回:
成功与否
"""
if model_id in self.active_models:
del self.active_models[model_id]
logging.info(f"[MCP服务器] 已注销模型: {model_id}")
return True
logging.warning(f"[MCP服务器] 尝试注销未知模型: {model_id}")
return False
async def start(self, host: str = "127.0.0.1", port: int = 8189):
"""
启动MCP服务器
参数:
host: 主机地址
port: 端口号
"""
self.is_running = True
try:
# 启动FastMCP HTTP服务器
uvicorn_config = {
"host": host,
"port": port,
"log_level": "info"
}
logging.info(f"[MCP服务器] 正在启动... 地址: {host}:{port}")
# 使用FastMCP的HTTP服务器启动方法
await self.mcp.serve(**uvicorn_config)
except Exception as e:
self.is_running = False
logging.error(f"[MCP服务器] 启动失败: {str(e)}")
raise
finally:
self.is_running = False
def get_stats(self) -> Dict[str, Any]:
"""获取服务器统计信息"""
return {
"is_running": self.is_running,
"active_models_count": len(self.active_models),
"resources_count": len(self.registered_resources),
"tools_count": len(self.registered_tools),
"prompts_count": len(self.registered_prompts)
}
# 运行MCP服务器的异步函数
async def run_server(server_name: str = "ComfyUI-MCP", host: str = "127.0.0.1", port: int = 8189):
"""
运行MCP服务器的便捷函数
参数:
server_name: 服务器名称
host: 主机地址
port: 端口号
"""
server = MCPServer(server_name)
await server.start(host, port)
return server
# 同步运行MCP服务器的函数
def run(server_name: str = "ComfyUI-MCP", host: str = "127.0.0.1", port: int = 8189):
"""
同步运行MCP服务器
参数:
server_name: 服务器名称
host: 主机地址
port: 端口号
"""
loop = asyncio.get_event_loop()
try:
return loop.run_until_complete(run_server(server_name, host, port))
except KeyboardInterrupt:
logging.info("[MCP服务器] 收到中断信号,正在关闭...")
finally:
loop.close()