# lzwcai-mcp 项目交接文档 本文档面向接手本仓库的技术人员,重点说明整体架构、各子项目职责、运行方式与配置要点,便于快速上手维护与扩展。 ## 一、项目整体概览 - 仓库名称:`lzwcai-mcp` - 项目类型:一组基于 MCP(Model Context Protocol)的独立服务,每个服务都是一个「技能包」,通过 `stdio` 与上层 MCP Agent 通信。 - 主要能力: - Feishu/Lark 卡片发送、图片上传、OKR 查询等企业协同能力(`lzwcai_lark_mcp`) - 文件与 URL 的 Base64 编解码、临时文件处理、MinIO 上传等通用文件工具(`file_tools`) - 金蝶云星空单据保存与查询能力,封装 DynamicFormService.Save / View 接口(`k3cloud_mcp`) - 访客信息查询与登记、门禁控制(`terminal_dhr_mcp`) - Temi 轮足机器人导航与业务动作控制(`terminal_temi_mcp`) - Go2 机器人运动控制、避障、服务管理等(`terminal_go2_mcp`) 各子项目都是独立的 Python 包,拥有各自的 `pyproject.toml` 与入口脚本,通过 JSON 配置文件被 MCP Agent 挂载为工具服务器。 ## 二、代码结构概览 仓库根目录主要结构: - `file_tools/` - `file_tools/`:文件工具 MCP 服务器实现(入口 `file_tools.main`)。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `lzwcai-file-tools-mcp`。 - `k3cloud_mcp/` - `k3cloud_mcp/`:金蝶云星空 MCP 服务器实现。 - `mcp-server.json`:MCP Agent 挂载示例,包含 `k3cloud-mcp` 的启动方式与环境变量示例。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `k3cloud-mcp`。 - `lzwcai_lark_mcp/` - `lzwcai_lark_mcp/`:Lark 相关 MCP 服务器实现(入口 `lzwcai_lark_mcp.main`)。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `lzwcai-lark-mcp`。 - `lzwcai_temi_mcp/` - `lzwcai_temi_mcp/`:另一个 Temi 机器人相关 MCP 服务(目前主要用到 `main.py`、`mcp_mqtt.py`、`nav_server.py`)。 - `mcp-server.json`:MCP Agent 挂载示例。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `lzwcai_temi_mcp`。 - `terminal_dhr_mcp/` - `terminal_dhr_mcp/`:访客系统 + 门禁控制 MCP 服务器。 - `.env`:示例环境变量。 - `pyproject.toml`:基于 `setuptools` 的构建配置,脚本名 `terminal-dhr-mcp`。 - `terminal_go2_mcp/` - `terminal_go2_mcp/`:Go2 机器人 MCP 服务器。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `terminal_go2_mcp`。 - `terminal_temi_mcp/` - `terminal_temi_mcp/`:Temi 轮足机器人 MCP 服务器。 - `pyproject.toml`:使用 `hatchling` 构建,脚本名 `terminal_temi_mcp`。 - 根目录其他文件: - `README.md`:顶层简介与部分子项目说明。 - `mcp.json`:示例 MCP 服务器配置(目前包含一个 JS 实现的 `lark-mcp` 示例,与本仓库 Python 版本的 Lark MCP 可共存)。 - `LICENSE`、`.gitignore` 等。 ## 三、运行环境与基础依赖 总体建议: - Python 版本:优先使用 **3.10+**。 - `terminal-dhr-mcp` 声明支持 3.8+,但其他项目为 3.10+,统一到 3.10 可以减少环境碎片。 - 依赖管理:建议使用虚拟环境(`venv` 或 `uv` 等)分别在各子项目目录下执行安装。 核心依赖: - 统一: - `mcp[cli]` 或 `mcp`:MCP 协议实现。 - `python-dotenv`:从 `.env` 加载配置。 - Lark 相关(`lzwcai_lark_mcp`): - `requests`:调用 Feishu/Lark HTTP API。 - `openpyxl`:从 Excel 中解析 `image_key` 及图片路径。 - 文件工具(`file_tools`): - `httpx`:下载远程文件。 - `minio`:将文件上传到 MinIO 对象存储。 - `openpyxl`:Excel 图片解析。 - 金蝶云星空(`k3cloud_mcp`): - `requests`:调用 K3Cloud Web API。 - 访客/门禁(`terminal_dhr_mcp`): - `httpx`、`pydantic`、`python-dotenv` 等,用于 HTTP 调用与配置。 - 机器人相关(`terminal_temi_mcp`、`terminal_go2_mcp`): - `fastapi`、`uvicorn`(部分场景)、`paho-mqtt`、`pydantic`、`requests`。 ## 四、各子项目详细说明 ### 4.1 Lark MCP(`lzwcai_lark_mcp`) - 入口: - 包:`lzwcai_lark_mcp` - 入口函数:`lzwcai_lark_mcp.main:main` - MCP Server 名称:`lzwcai-mcpskills-lark-mcp` - 核心文件: - `main.py`:MCP server 启动逻辑,负责: - 初始化 `Server`。 - 通过 `_request_token` 根据 `app_id` / `app_secret` 获取 Lark `tenant_access_token`,带过期时间缓存。 - 注册 `list_tools` / `call_tool`,在调用工具前自动确保 token 有效。 - `config.py`: - 从环境变量读取: - `app_id` - `app_secret` - `tools.py`: - 定义对外暴露的 `Tool` 列表。 - 实现具体业务函数,如: - 图片上传:`upload_image_by_url` / `upload_image_by_file` - Excel 定位图片源:`_resolve_image_source_from_excel` - OKR 查询:`get_user_okr_list`、`batch_get_okr` - 资产确认/复核/陌生人处理/反馈等多种交互卡片:`send_confirmation_card`、`send_review_card`、`send_stranger_card`、`send_feedback_card` - 入库通知卡片:`send_notion_card` / `send_card_message` - `handle_call_tool`:根据 `name` 分发到对应的 Python 函数,处理参数校验、错误返回等。 - 外部依赖与接口: - Feishu/Lark Open API: - 认证:`/open-apis/auth/v3/tenant_access_token/internal` - 消息/图片:`/open-apis/im/v1/images`、`/open-apis/im/v1/messages` - 通讯录:`/open-apis/contact/v3/users/{user_id}` - OKR:`/open-apis/okr/v1/users/{user_id}/okrs`、`/open-apis/okr/v1/okrs/batch_get` - 配置要点: - 必需环境变量: - `app_id`:Lark 应用的 app id。 - `app_secret`:Lark 应用的 app secret。 - 可选:`LOG_LEVEL`(通过 logging.basicConfig 读取)。 ### 4.2 文件工具 MCP(`file_tools`) - 入口: - 包:`file_tools` - 入口函数:`file_tools.main:main` - MCP Server 名称:`lzwcai-mcpskills-file-tools-mcp` - 核心文件: - `main.py`: - 初始化 MCP `Server`,注册 `list_tools` / `call_tool`。 - `tools.py`: - 工具列表: - `file_to_json`:将文件对象或本地路径转成 JSON 结构(带 base64 内容)。 - `file_to_data_uri`:将文件转为 `data URI`。 - `file_path_to_data_uri`:本地文件路径 -> `data URI`。 - `url_to_data_uri`:URL 下载并转为 `data URI`。 - `url_to_temp_file`:URL 下载为本地临时文件,返回路径。 - `excel_image_key_to_temp_file`:从 Excel 中按 `image_key` 找到图片并写入临时文件。 - `upload_file_to_minio`:将文件上传到 MinIO,返回访问 URL。 - 工具内部大量使用 `Path`、`tempfile`、`httpx`、`minio` 等。 - 配置要点: - MinIO 相关配置位于 `config.py`(`minio_endpoint`、`minio_access_key`、`minio_secret_key`),通过环境变量读取。 - 当前 `upload_file_to_minio` 里的 bucket 名称固定为 `lzwcai`(写在 `tools.py`),如需多环境隔离建议改为可配置项。 ### 4.3 金蝶云星空 MCP(`k3cloud_mcp`) - 入口: - 包:`k3cloud_mcp` - 入口函数:`k3cloud_mcp.main:main` - MCP Server 名称:`k3cloud-mcp` - 核心文件: - `main.py`: - 初始化 MCP `Server`。 - 注册 `list_tools` / `call_tool`。 - 运行 `stdio_server`,供上层 MCP Agent 调用。 - `tools.py`: - 当前暴露两个工具:`save_form`、`view_form`。 - `save_form` 参数: - `formid`:业务对象表单 Id,例如 `SAL_QUOTATION`。 - `data_payload`:可传 JSON 对象或 JSON 字符串。 - `timeout`:HTTP 超时时间,默认 30 秒。 - `view_form` 参数: - `formid`:业务对象表单 Id,例如 `SAL_QUOTATION`。 - `payload`:可传 JSON 对象或 JSON 字符串。 - `timeout`:HTTP 超时时间,默认 30 秒。 - `handle_call_tool()` 负责做参数校验、分发到底层 `save()` / `view()`,并把响应序列化为文本返回。 - `client.py`: - 封装 `save(formid, data_payload, timeout=30)` 与 `view(formid, payload, timeout=30)`。 - 分别调用 `DynamicFormService.Save.common.kdsvc` 与 `DynamicFormService.View.common.kdsvc` 接口。 - 会自动将对象型 payload 转为 JSON 字符串后再提交。 - `signing.py`: - 负责生成 K3Cloud 所需签名头。 - 包含 `APP_ID` 拆分、`APP_SECRET` 解码、HMAC 签名等逻辑。 - `config.py`: - 从环境变量读取 `K3CLOUD_*` 配置。 - 缺少必填项时会在导入阶段直接抛出异常。 - `demo_save.py` / `demo_save.json`: - 用于本地直接测试 `save()` 函数。 - `demo_view.py` / `demo_view.json`: - 用于本地直接测试 `view()` 函数。 - 外部依赖与接口: - 金蝶云星空 Web API: - 保存接口:`/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc` - 查询接口:`/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View.common.kdsvc` - 配置要点: - 必需环境变量: - `K3CLOUD_BASE_URL`:K3Cloud 站点根地址。 - `K3CLOUD_ACCT_ID`:账套标识。 - `K3CLOUD_APP_ID`:应用标识。 - `K3CLOUD_USERNAME`:调用用户名。 - `K3CLOUD_APP_SECRET`:应用密钥。 - 可选环境变量: - `K3CLOUD_LCID`:语言代码,默认 `2052`。 - `K3CLOUD_ORG_NUM`:组织编号,默认 `0`。 - `LOG_LEVEL`:日志级别。 - 本地测试方式: - 保存接口联调: - `python k3cloud_mcp/demo_save.py --payload k3cloud_mcp/demo_save.json` - 查询接口联调: - `python k3cloud_mcp/demo_view.py --payload k3cloud_mcp/demo_view.json` - 当前测试脚本会优先使用当前进程环境变量;若未设置,则补读子项目目录下 `mcp-server.json` 中 `k3cloud-mcp.env` 的配置,便于本地快速验证。 ### 4.4 访客系统 + 门禁 MCP(`terminal_dhr_mcp`) - 入口: - 包:`terminal_dhr_mcp` - 入口函数:`terminal_dhr_mcp.main:main` - MCP Server 名称:`terminal-dhr-mcp` - 核心文件: - `main.py`: - 定义 `DhrMCPServer` 类,注册 `list_tools` / `call_tool`,调用 `tools.py` 中的逻辑。 - `tools.py`: - 工具列表包括: - `query_visitor`:根据 `user_id` 查询访客预约记录。 - `register_visitor`:登记新访客。 - `control_door`:控制门禁开关。 - `get_door_status`:查询门禁状态。 - `config.py`: - 关键配置: - `EMPLOYEE_ID`:从环境变量 `employeeId` 读取,用于请求访客系统。 - `BASE_URL`:访客系统服务地址。 - `VISITOR_QUERY_ENDPOINT`、`VISITOR_REGISTER_ENDPOINT`:固定后缀路径。 - 门禁相关: - `DOOR_API_ENDPOINT` - `DOOR_ENTERPRISE_ID` - `DOOR_DEFAULT_ENTITY_ID` - `LOG_LEVEL`、若干长度限制常量等。 - 典型环境配置: - 可在 `terminal_dhr_mcp/.env` 中配置: - `employeeId` - `BASE_URL` - `DOOR_ENTERPRISE_ID` - `DOOR_DEFAULT_ENTITY_ID` - `LOG_LEVEL` ### 4.5 Temi 轮足机器人 MCP(`terminal_temi_mcp`) - 入口: - 包:`terminal_temi_mcp` - 入口函数:`terminal_temi_mcp.main:main` - MCP Server 名称:`terminal_temi_mcp` - 核心文件: - `main.py`: - 定义 `NavServer`,通过 `mcp_mqtt.get_mcpmqtt_handler()` 获取 MQTT 客户端。 - 封装业务命令: - `nav_to`:导航到指定地点。 - `speak`:语音播报。 - `reception`:迎宾。 - `notification`(目前工具层注释掉)。 - `repose`:重新定位。 - `delivery`:配送任务。 - `patrol`:巡逻。 - 若干人脸识别 / 扫码相关函数目前未对外暴露。 - `list_tools` 中暴露的工具包括 `nav_to`、`speak`、`reception`、`repose`、`delivery`、`patrol` 等,对输入参数做了详细描述。 - `call_tool` 根据工具名分发到 `NavServer` 方法,并做参数校验与错误转换。 - `mcp_mqtt.py`: - 封装 MQTT Broker 连接、客户端初始化与复用。 - 配置要点: - `.env`(参考 README): - `LOG_LEVEL` - `MQTT_BROKER_ADDRESS` - `MQTT_PORT` - `MQTT_USERNAME` - `MQTT_PASSWORD` - MCP Agent 配置文件(示例在子项目 README 中)会把 `employeeId`、`userId` 作为环境变量注入。 ### 4.6 Go2 机器人 MCP(`terminal_go2_mcp`) - 入口: - 包:`terminal_go2_mcp` - 入口函数:`terminal_go2_mcp.main:main` - MCP Server 名称:`terminal_go2_mcp` - 核心文件: - `main.py`: - `TerminalGo2McpServer` 提供对 Go2 机器人的封装: - 低层统一接口 `pubCmd(type, cmd, params)` 通过 MQTT 发布到 `unitree/go2/cmd`。 - 运动相关:`custom_action`、`ContinuousMove`、`move`、`euler`、`set_speed_level`、`pose` 等。 - 避障相关:`obstacle_avoidance_switch`、`obstacle_move`。 - 导航相关:`start_mapping`、`end_mapping`、`initialize_pose`、`pose_navigation`、`pause_navigation`、`resume_navigation` 等(部分在工具层已注释)。 - 充电:`start_recharge`、`stop_recharge`。 - 服务管理:`list_services`、`switch_service`、`set_report_freq`。 - `serve()` 中: - 注册工具列表(Tool 定义),描述参数与取值范围。 - 在 `call_tool` 中根据 `name` 分发到对应协程函数。 - `mcp_mqtt.py`: - 和 Temi 类似,管理 MQTT 客户端。 - 配置要点: - MQTT 连接参数在 `mcp_mqtt.py` 或 `.env` 中通过环境变量读取(具体字段请在接手时查看该文件)。 ### 4.7 Temi 机器人 MCP(旧版,`lzwcai_temi_mcp`) - 入口: - 包:`lzwcai_temi_mcp` - 入口函数:`lzwcai_temi_mcp.main:main` - MCP Server 名称:`lzwcai_temi_mcp` - 核心文件: - `main.py`: - 当前暴露工具包含 `recharge`、`terminate`、`goto`、`speak`、`reception`、`notification`、`repose`、`patrol`、`dance`。 - `mcp_mqtt.py`: - 管理 MQTT 连接与消息发布。 - `nav_server.py`: - 封装导航与动作编排逻辑。 - 维护建议: - 仓库内同时存在 `terminal_temi_mcp` 与 `lzwcai_temi_mcp` 两套 Temi 服务,接手时建议先和业务方确认实际在线使用的是哪一套,避免重复维护。 ## 五、安装与运行方式(面向开发/调试) 以下步骤均建议在虚拟环境中执行。 1. 克隆仓库: ```bash git clone cd lzwcai-mcp ``` 2. 进入某个子项目目录并安装: ```bash cd terminal_dhr_mcp pip install -e .[dev] # 或仅运行所需: pip install -e . ``` 其他子项目类似: - `cd lzwcai_lark_mcp && pip install -e .` - `cd file_tools && pip install -e .` - `cd k3cloud_mcp && pip install -e .` - `cd lzwcai_temi_mcp && pip install -e .` - `cd terminal_temi_mcp && pip install -e .` - `cd terminal_go2_mcp && pip install -e .` 3. 启动某个 MCP 服务器(本地调试): ```bash # Lark lzwcai-lark-mcp # 文件工具 lzwcai-file-tools-mcp # 金蝶云星空 k3cloud-mcp # 访客系统 + 门禁 terminal-dhr-mcp # Temi 机器人(旧版) lzwcai_temi_mcp # Temi 机器人 terminal_temi_mcp # Go2 机器人 terminal_go2_mcp ``` 4. 与 MCP Agent 集成: - 顶层或子项目中提供示例配置文件,如: - `lzwcai_lark_mcp/mcp-server.json` - `terminal_dhr_mcp/mcp-server-dhr.json` - `terminal_temi_mcp/mcp-server-temi.json` - `terminal_go2_mcp/mcp-server-go2.json` - `lzwcai_temi_mcp/mcp-server.json` - `file_tools/mcp-server-file-tools.json` - `k3cloud_mcp/mcp-server.json` - 在上层 Agent 的配置(例如 IDE 插件或自研 Agent)中引入这些 JSON 即可通过 `stdio` 调起对应服务器。 ## 六、配置与敏感信息管理 - 所有敏感信息(token、密钥、账号密码)均通过环境变量或 `.env` 文件注入,不应直接写入代码或仓库。 - 当前仓库中的部分 `mcp-server*.json` 已包含真实或准生产敏感配置示例;对外共享仓库前建议先做脱敏或改成占位符。 - 推荐做法: - 针对每个子项目,在其根目录创建 `.env`,仅存放本项目相关配置。 - 在部署环境中,通过进程管理器(如 systemd、Docker、K8s)把 `.env` 或环境变量挂载进去。 - 接手时建议重点确认: - Lark 应用的 `app_id`/`app_secret` 是否有效,是否具备所需 API 权限。 - K3Cloud 的 `BASE_URL`、账套、应用标识、用户名、密钥是否仍然有效,签名规则是否与现网一致。 - 访客系统 / 门禁接口 `BASE_URL`、企业 ID、门禁实体 ID 是否与现网一致。 - MQTT Broker 地址、账号密码是否与机器人当前网络环境匹配。 - MinIO 的 endpoint、access key、secret key、bucket 名称是否存在且有权限。 ## 七、开发规范与注意事项 - 编码风格: - Python 代码整体接近 PEP 8 风格。 - 部分子项目(如 `terminal_dhr_mcp`)在 `pyproject.toml` 中配置了 `black`、`isort`、`ruff`、`mypy` 等工具,对应规则可作为编码参考。 - 日志: - 所有服务器都使用 `logging.basicConfig` 统一输出日志,日志级别可通过 `LOG_LEVEL` 环境变量控制。 - 出错时通常会在日志中打印详细异常,并向 MCP Agent 返回友好文本。 - 错误处理: - 多数工具会对必需参数做显式校验,缺失时抛出 `ValueError` 或返回带错误信息的字符串。 - 对外 HTTP/MQTT 调用失败时,会记录错误日志,并抛出异常或返回失败说明。 - 工具定义: - 工具使用 `mcp.types.Tool` 定义,`inputSchema` 为 JSON Schema 格式,方便上层 Agent 自动生成表单或进行参数校验。 - 若新增工具,请保持命名风格一致,并且在 `list_tools` 与 `call_tool` 实现中同步更新。 ## 八、后续扩展建议 - 如需扩展新的硬件或业务系统,建议: - 新增独立子项目目录(与现有结构一致),保持「一个 MCP 服务一个 Python 包」的模式。 - 优先复用现有 MQTT/HTTP 封装模式与错误处理风格。 - 在子项目内补充 README,简要说明工具列表与配置方式,并在顶层 `README.md` 中更新项目清单。 ## 九、已知问题与接手优先项 - `file_tools/config.py` 默认从 `mcp-server-file-tools.json` 读取配置时,查找的 server key 是 `lzwcai-mcpskills-file-tools-mcp`,而当前示例文件使用的是 `lzwcai-file-tools-mcp`,可能导致本地自动注入环境变量失效。 - `terminal_temi_mcp` 与 `lzwcai_temi_mcp` 为并行存在的两套 Temi MCP 服务,能力与工具名不完全一致,建议先统一服务边界再继续演进。 如在接手过程中遇到不清楚的业务规则(例如具体资产变动业务、访客流程、机器人业务场景),建议先与业务方确认需求,再在对应子项目中补充或调整工具逻辑。