git_mcp_server
This commit is contained in:
parent
0b72ed20bc
commit
b354afb235
|
|
@ -0,0 +1,152 @@
|
|||
"""
|
||||
MCP Server 基类
|
||||
提供通用的 MCP 服务器基础设施
|
||||
|
||||
设计说明:
|
||||
- McpServer: 通用 MCP 服务器基类
|
||||
- 子类在 __init__ 中通过 self.tools = [...] 赋值工具实例
|
||||
- 提供工具列表展示、调用处理、服务器启动等通用逻辑
|
||||
|
||||
使用示例:
|
||||
class MyServer(McpServer):
|
||||
def __init__(self):
|
||||
super().__init__("my-mcp", "1.0.0")
|
||||
# 直接赋值工具实例列表
|
||||
self.tools = [MyTool1(), MyTool2()]
|
||||
|
||||
# 启动服务器
|
||||
server = MyServer()
|
||||
await server.run_stdio()
|
||||
"""
|
||||
import asyncio
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from mcp.server import Server
|
||||
from mcp.server.models import InitializationOptions
|
||||
from mcp.types import (
|
||||
Tool,
|
||||
TextContent,
|
||||
ImageContent,
|
||||
EmbeddedResource,
|
||||
ServerCapabilities,
|
||||
)
|
||||
|
||||
|
||||
class BaseMcpServer:
|
||||
"""
|
||||
通用 MCP 服务器基类
|
||||
|
||||
子类在 __init__ 中通过 self.tools 属性赋值工具实例列表。
|
||||
封装了工具列表展示、调用处理、结果格式化、服务器启动等通用逻辑。
|
||||
"""
|
||||
|
||||
def __init__(self, server_name: str, version: str = "1.0.0"):
|
||||
"""
|
||||
初始化 MCP 服务器
|
||||
|
||||
Args:
|
||||
server_name: 服务器名称
|
||||
version: 服务器版本
|
||||
"""
|
||||
self.server_name = server_name
|
||||
self.version = version
|
||||
self.server = Server(server_name)
|
||||
|
||||
# 工具列表(子类在 __init__ 中赋值)
|
||||
self.tools: List[Any] = []
|
||||
|
||||
# 注册处理器
|
||||
self.server.list_tools()(self._handle_list_tools)
|
||||
self.server.call_tool()(self._handle_call_tool)
|
||||
|
||||
async def _handle_list_tools(self) -> list[Tool]:
|
||||
"""列出所有可用的工具"""
|
||||
return [
|
||||
Tool(
|
||||
name=tool.name,
|
||||
description=tool.description,
|
||||
inputSchema=tool.parameters_schema,
|
||||
)
|
||||
for tool in self.tools
|
||||
]
|
||||
|
||||
async def _handle_call_tool(
|
||||
self, name: str, arguments: Optional[dict[str, Any]] = None
|
||||
) -> list[TextContent | ImageContent | EmbeddedResource]:
|
||||
"""处理工具调用"""
|
||||
if not arguments:
|
||||
arguments = {}
|
||||
|
||||
# 查找工具
|
||||
tool = next((t for t in self.tools if t.name == name), None)
|
||||
if not tool:
|
||||
return [TextContent(type="text", text=f"未知工具:{name}")]
|
||||
|
||||
try:
|
||||
result = tool.execute(**arguments)
|
||||
response_text = self._format_tool_result(result)
|
||||
return [TextContent(type="text", text=response_text)]
|
||||
|
||||
except ValueError as e:
|
||||
return [TextContent(type="text", text=f"❌ 参数错误:{str(e)}")]
|
||||
except RuntimeError as e:
|
||||
return [TextContent(type="text", text=f"❌ 执行失败:{str(e)}")]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"❌ 未知错误:{str(e)}")]
|
||||
|
||||
@staticmethod
|
||||
def _format_tool_result(result: Any) -> str:
|
||||
"""
|
||||
格式化工具执行结果
|
||||
|
||||
支持多种返回格式:
|
||||
- 包含 message/data 属性的对象
|
||||
- 字典(包含 message/data 键)
|
||||
- 其他类型(直接转为字符串)
|
||||
"""
|
||||
response_text = ""
|
||||
|
||||
# 提取消息
|
||||
message = getattr(result, 'message', None)
|
||||
if message:
|
||||
response_text += f"✅ {message}\n\n"
|
||||
elif isinstance(result, dict) and 'message' in result:
|
||||
response_text += f"✅ {result['message']}\n\n"
|
||||
|
||||
# 提取数据
|
||||
data = getattr(result, 'data', None)
|
||||
if data is None and isinstance(result, dict):
|
||||
data = result.get('data')
|
||||
|
||||
if data:
|
||||
response_text += "详情:\n"
|
||||
if isinstance(data, dict):
|
||||
for key, value in data.items():
|
||||
response_text += f" - {key}: {value}\n"
|
||||
else:
|
||||
response_text += f" {data}\n"
|
||||
|
||||
# 如果没有消息也没有数据,直接返回结果的字符串形式
|
||||
if not response_text:
|
||||
response_text = str(result)
|
||||
|
||||
return response_text
|
||||
|
||||
async def run_stdio(self):
|
||||
"""
|
||||
启动服务器,使用标准输入输出通信
|
||||
"""
|
||||
from mcp.server.stdio import stdio_server
|
||||
|
||||
async with stdio_server() as (read_stream, write_stream):
|
||||
await self.server.run(
|
||||
read_stream,
|
||||
write_stream,
|
||||
InitializationOptions(
|
||||
server_name=self.server_name,
|
||||
server_version=self.version,
|
||||
capabilities=ServerCapabilities(
|
||||
tools={} # 启用工具能力
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
"""
|
||||
Git MCP 服务器
|
||||
整合所有 Git 工具为 MCP Server
|
||||
|
||||
设计说明:
|
||||
- GitServer 继承自 McpServer,提供 Git 相关的工具
|
||||
- 在 __init__ 中直接实例化并赋值工具列表
|
||||
- 工具定义在各自的文件中,git_server 负责组装
|
||||
"""
|
||||
import asyncio
|
||||
from app.tools.base_mcp_server import BaseMcpServer
|
||||
from app.tools.git.git_clone_tool import GitCloneTool
|
||||
from app.tools.git.git_checkout_tool import GitCheckoutTool
|
||||
from app.tools.git.git_add_tool import GitAddTool
|
||||
from app.tools.git.git_commit_tool import GitCommitTool
|
||||
from app.tools.git.git_push_tool import GitPushTool
|
||||
|
||||
|
||||
class GitMcpServer(BaseMcpServer):
|
||||
"""
|
||||
Git MCP 服务器
|
||||
|
||||
继承 McpServer,在 __init__ 中直接赋值 Git 工具实例列表。
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# 初始化父类,设置服务器名称和版本
|
||||
super().__init__(server_name="git-mcp", version="1.0.0")
|
||||
|
||||
# 直接赋值工具实例列表
|
||||
self.tools = [
|
||||
GitCloneTool(),
|
||||
GitCheckoutTool(),
|
||||
GitAddTool(),
|
||||
GitCommitTool(),
|
||||
GitPushTool(),
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
"""启动 Git MCP 服务器"""
|
||||
server = GitMcpServer()
|
||||
await server.run_stdio()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
|
@ -1,27 +1,10 @@
|
|||
fastapi==0.104.1
|
||||
uvicorn==0.24.0
|
||||
sqlalchemy>=2.0.49
|
||||
pymysql==1.1.0
|
||||
minio==7.2.0
|
||||
anyio>=4.5
|
||||
fastapi>=0.104.1
|
||||
uvicorn==0.31.1
|
||||
openai>=1.12.0
|
||||
python-multipart==0.0.6
|
||||
python-dotenv~=1.2.2
|
||||
pydantic>=2.10.0
|
||||
pydantic-settings>=2.1.0
|
||||
httpx>=0.27.0
|
||||
pypandoc==1.17
|
||||
MyApplication~=0.1.0
|
||||
starlette~=0.27.0
|
||||
requests==2.31.0
|
||||
beautifulsoup4==4.12.2
|
||||
pdfplumber==0.10.3
|
||||
python-docx==1.1.0
|
||||
pywin32==311
|
||||
markitdown~=0.0.2
|
||||
bs4~=0.0.2
|
||||
docxcompose~=2.1.0
|
||||
docxtpl~=0.20.2
|
||||
asyncio~=4.0.0
|
||||
vosk~=0.3.45
|
||||
pydub~=0.25.1
|
||||
mcp>=1.0.0
|
||||
Loading…
Reference in New Issue