Files
lzwcai-mcp/交接文档.md
tanjianbin 7e33e398ce feat(k3cloud): 新增单据查看功能并重构演示代码
- 在 client.py 中新增 view() 函数,支持调用金蝶云星空 DynamicFormService.View 接口
- 在 tools.py 中新增 view_form 工具,供 MCP 客户端调用
- 添加演示脚本 demo_view.py 和示例配置文件 demo_view.json
- 重构 demo_save.py 为通用演示脚本,支持自定义 payload 文件
- 删除过时的 demo.json,新增 userful_save.json 作为实用示例
- 添加项目交接文档,详细说明各子项目架构和配置
- 优化 payload 序列化逻辑,提取为共享函数 _serialize_payload
2026-05-08 17:15:20 +08:00

409 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# lzwcai-mcp 项目交接文档
本文档面向接手本仓库的技术人员,重点说明整体架构、各子项目职责、运行方式与配置要点,便于快速上手维护与扩展。
## 一、项目整体概览
- 仓库名称:`lzwcai-mcp`
- 项目类型:一组基于 MCPModel 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 <formid> --payload k3cloud_mcp/demo_save.json`
- 查询接口联调:
- `python k3cloud_mcp/demo_view.py <formid> --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 <repo-url>
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 服务,能力与工具名不完全一致,建议先统一服务边界再继续演进。
如在接手过程中遇到不清楚的业务规则(例如具体资产变动业务、访客流程、机器人业务场景),建议先与业务方确认需求,再在对应子项目中补充或调整工具逻辑。