From 697b7d4b3aeecc5a9e6166c2106ded005e6fd5d6 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Mon, 1 Dec 2025 00:42:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(mcp):=20=E4=BC=98=E5=8C=96MCP=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8CDocker=E6=9E=84=E5=BB=BA=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除不再使用的paddleocr依赖 - 清理并注释MCP服务器配置,增加错误追踪 - 重构Dockerfile以提高构建效率和减小镜像体积 - 更新文档添加MCP服务器配置方式的详细说明 --- docker/api.Dockerfile | 39 ++++++---- docs/latest/advanced/agents-config.md | 107 ++++++++++++++++++++++++++ pyproject.toml | 1 - src/agents/common/mcp.py | 28 +++---- 4 files changed, 140 insertions(+), 35 deletions(-) diff --git a/docker/api.Dockerfile b/docker/api.Dockerfile index 1ebeb8ee..bf6e87fc 100644 --- a/docker/api.Dockerfile +++ b/docker/api.Dockerfile @@ -1,35 +1,40 @@ # 使用轻量级Python基础镜像 FROM python:3.12-slim COPY --from=ghcr.io/astral-sh/uv:0.7.2 /uv /uvx /bin/ +COPY --from=node:20-slim /usr/local/bin /usr/local/bin +COPY --from=node:20-slim /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=node:20-slim /usr/local/include /usr/local/include +COPY --from=node:20-slim /usr/local/share /usr/local/share # 设置工作目录 WORKDIR /app # 环境变量设置 ENV TZ=Asia/Shanghai \ - UV_LINK_MODE=copy \ + UV_PROJECT_ENVIRONMENT="/usr/local" \ + UV_COMPILE_BYTECODE=1 \ DEBIAN_FRONTEND=noninteractive +RUN npm install -g npm@latest && npm cache clean --force + # 设置代理和时区,更换镜像源,安装系统依赖 - 合并为一个RUN减少层数 -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \ - # 更换为阿里云镜像源加速下载 - sed -i 's|http://deb.debian.org/debian|http://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list.d/debian.sources && \ - sed -i 's|http://security.debian.org/debian-security|http://mirrors.tuna.tsinghua.edu.cn/debian-security|g' /etc/apt/sources.list.d/debian.sources && \ - # sed -i 's|mirrors.aliyun.com|mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources && \ - # 清理apt缓存并更新,避免空间不足问题 - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* && \ - apt-get update && \ - # 安装系统依赖,减少缓存占用 - apt-get install -y --no-install-recommends --fix-missing \ - python3-dev \ +RUN set -ex \ + # (A) 设置时区 + && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \ + # (B) 替换清华源 (针对 Debian Bookworm 的新版格式) + && sed -i 's|deb.debian.org|mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/debian.sources \ + && sed -i 's|security.debian.org/debian-security|mirrors.tuna.tsinghua.edu.cn/debian-security|g' /etc/apt/sources.list.d/debian.sources \ + # (C) 安装必要的系统库 + && apt-get update \ + && apt-get install -y --no-install-recommends --fix-missing \ + curl \ ffmpeg \ libsm6 \ libxext6 \ - curl \ - && apt-get autoremove -y && \ - apt-get autoclean && \ - rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* /tmp/* /var/tmp/* + # (D) 清理垃圾,减小体积 + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + # 复制项目配置文件 COPY ../pyproject.toml /app/pyproject.toml diff --git a/docs/latest/advanced/agents-config.md b/docs/latest/advanced/agents-config.md index 26cb5c72..614efc3b 100644 --- a/docs/latest/advanced/agents-config.md +++ b/docs/latest/advanced/agents-config.md @@ -108,6 +108,113 @@ async def get_graph(self): 工具的启用状态和描述由配置文件或环境变量决定,当依赖缺失时会被中间件自动忽略,从而避免在图中加载不可用能力。MCP Server 的接入方式保持不变,只需在 `src/agents/common/mcp.py` 的 `MCP_SERVERS` 中填入服务地址与 `transport` 类型,如需更多范式可参阅 LangChain 官方文档。 +### MCP 服务器配置方式 + +系统支持四种 MCP 服务器配置方式,可根据具体场景选择: + +#### 1. 远程 HTTP 服务器 + +```python +MCP_SERVERS = { + "sequentialthinking": { + "url": "https://remote.mcpservers.org/sequentialthinking/mcp", + "transport": "streamable_http", + } +} +``` + +**特点**: +- 通过 HTTP 远程访问,无需本地安装,适合公开可用的 MCP 服务 +- 启动速度快,无需本地依赖 + +#### 2. 使用 npx 运行 Node.js 包 + +```python +MCP_SERVERS = { + "mcp_server_chart": { + "command": "npx", + "args": ["-y", "@antv/mcp-server-chart"], + "transport": "stdio" + }, +} +``` + +**特点**: +- 使用 npx 直接运行 Node.js 包,`-y` 参数自动下载并运行指定包 +- 适合 Node.js 生态的 MCP 服务,需要确保 npx 可以使用 + +#### 3. 使用 uvx 运行 Python 包 + +```python +MCP_SERVERS = { + "mysql-mcp-server": { + "command": "uvx", + "args": ["mysql_mcp_server"], + "env": { + "MYSQL_DATABASE": "your_database", + "MYSQL_HOST": "localhost", + "MYSQL_PASSWORD": "your_password", + "MYSQL_PORT": "3306", + "MYSQL_USER": "your_username" + }, + "transport": "stdio" + } +} +``` + +**特点**: +- 使用 uvx 运行已发布的 Python 包,自动管理虚拟环境和依赖 +- 适合 PyPI 上已发布的 MCP 服务 + +#### 4. 使用 uv 运行本地仓库 + +```python +MCP_SERVERS = { + "arxiv-mcp-server": { + "command": "uv", + "args": [ + "tool", + "run", + "arxiv-mcp-server", + "--storage-path", "src/agents/mcp_repos/arxiv-mcp-server" + ], + "transport": "stdio" + } +} +``` + +**特点**: +- 直接运行本地 git 仓库中的 MCP 服务 +- 加载速度快,支持热重载,适合开发调试和自定义 MCP 服务 +- 需要先 git clone 对应仓库到指定路径 + +### 配置参数说明 + +- `url`: 远程 HTTP 服务器的 URL(仅 streamable_http 传输) +- `command`: 启动 MCP 服务的命令 +- `args`: 启动参数列表 +- `env`: 环境变量配置,用于数据库连接等敏感信息 +- `transport`: 传输协议,支持 `stdio`(本地)和 `streamable_http`(远程) + +### 动态工具加载 + +系统支持动态加载 MCP 工具: + +```python +from src.agents.common.mcp import get_mcp_tools, add_mcp_server + +# 获取特定服务器的工具 +tools = await get_mcp_tools("sequentialthinking") + +# 动态添加新的 MCP 服务器 +add_mcp_server("custom-server", { + "url": "https://your-mcp-server.com/mcp", + "transport": "streamable_http" +}) + +# 获取所有 MCP 工具 +all_tools = await get_all_mcp_tools() +``` ### MySQL 数据库 设置数据库连接时,在 `.env` 中提供以下字段: diff --git a/pyproject.toml b/pyproject.toml index ec4f6338..38deff1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,6 @@ dependencies = [ "networkx>=3.5", "openai>=1.109", "opencv-python-headless>=4.11.0.86", - "paddleocr>=3.3", "pyjwt>=2.8.0", "pymilvus>=2.5.8", "pymupdf>=1.25.5", diff --git a/src/agents/common/mcp.py b/src/agents/common/mcp.py index e470b64e..9d0dfdf6 100644 --- a/src/agents/common/mcp.py +++ b/src/agents/common/mcp.py @@ -1,7 +1,9 @@ """MCP Client setup and management for LangGraph ReAct Agent.""" +import os from collections.abc import Callable from typing import Any, cast +import traceback from langchain_mcp_adapters.client import ( # type: ignore[import-untyped] MultiServerMCPClient, @@ -18,32 +20,24 @@ MCP_SERVERS = { "url": "https://remote.mcpservers.org/sequentialthinking/mcp", "transport": "streamable_http", }, + # "zhipu-web-search-sse": { + # "url": f"https://open.bigmodel.cn/api/mcp/web_search/sse?Authorization={os.getenv('ZHIPU_API_KEY')}", + # "transport": "streamable_http", + # }, # 这些 stdio 的 MCP server 需要在本地启动,启动的时候需要安装对应的包,需要时间 # "time": { # "command": "uvx", # "args": ["mcp-server-time"], # "transport": "stdio", # }, - # "mcp-server-chart": { - # "url": "https://mcp.api-inference.modelscope.net/9993ae42524c4c/mcp", - # "transport": "streamable_http", - # }, - # 需要在 docker 内安装 npx - # "mysql": { + # "mcp_server_chart": { # "command": "npx", - # "args": ["-y", "@benborla29/mcp-server-mysql@2.0.2"], - # "env": { - # "MYSQL_HOST": "172.19.13.6", - # "MYSQL_PORT": "3306", - # "MYSQL_USER": "read-only", - # "MYSQL_PASS": "password123", - # "MYSQL_DB": "feed" - # }, + # "args": ["-y", "@antv/mcp-server-chart"], # "transport": "stdio" - # } + # }, + # 更多用法参考:https://xerrors.github.io/Yuxi-Know/latest/advanced/agents-config.html#内置工具与-mcp-集成 } - async def get_mcp_client( server_configs: dict[str, Any] | None = None, ) -> MultiServerMCPClient | None: @@ -85,7 +79,7 @@ async def get_mcp_tools(server_name: str, additional_servers: dict[str, dict] = logger.warning(f"Failed to load tools from MCP server '{server_name}': {e}") return [] except Exception as e: - logger.error(f"Failed to load tools from MCP server '{server_name}': {e}") + logger.error(f"Failed to load tools from MCP server '{server_name}': {e}, traceback: {traceback.format_exc()}") return []