1221 lines
63 KiB
Markdown
1221 lines
63 KiB
Markdown
# SE 工作流 MCP 工具 API 文档
|
||
|
||
> **来源**:`docs/task/se工作流mcp工具统计.md`(草稿统计)→ 本文档按 `mis-mcp-server` **源码实现**补全为可调用的 API 文档
|
||
> **覆盖范围**:SE 工作流相关的 **9 个** MCP 工具
|
||
> **生成日期**:2026-09-22
|
||
> **代码基线**:`mis-mcp-server` 分支 `dev`
|
||
>
|
||
> **一句话定位**:面向「AI 生成 SKILL / Prompt」场景的机器友好型接口文档。每个工具给出**参数表 + 返回 JSON 结构 + 字段语义 + 关联工具**。
|
||
|
||
### 修订记录(2026-09-22)
|
||
|
||
编写本文档时发现 **5 处工具描述与实现不符**,已在 `mis-mcp-server` 侧修正(**未改动 `mbx` 下游代码**):
|
||
|
||
| 工具 | 原描述问题 | 处置 |
|
||
|---|---|---|
|
||
| `queryDriverListVersion` | 说「驱动列表唯一标识」「返回 `packageFileUrl` 即可」——实为**版本**标识,且该字段**嵌套**在数组里、未裁剪 | ✅ 改描述 |
|
||
| `queryTestUnitListByProjectName` | 说「根据项目名称、**五码**查询」——下游 SQL **未按五码过滤** | ✅ 改描述 + 参数说明 |
|
||
| `queryProjectNameList` | 说「获取项目名称列表」——实为**固定最多 2 条** | ✅ 常量 `2` → `100`,并同步描述(**行为变更**) |
|
||
| `queryTestPcByUuids` | 未说明在线状态字段名——直觉会取恒为 null 的 `onlineStatus` | ✅ 描述里点明用 `onlineStatusKey` |
|
||
| `creatOrSendTask` | 未说明 `other.type` 必填——漏传会下游报错 | ✅ 描述里点明必填项 |
|
||
|
||
---
|
||
|
||
## ⚠️ 确信度标记(务必先读)
|
||
|
||
本文档所有字段名均来自**源码或真实响应样本**,不使用推测值。为便于区分,全文使用以下标记:
|
||
|
||
| 标记 | 含义 |
|
||
|---|---|
|
||
| ✅ **已确定** | 直接来自 `mis-mcp-server` 源码逻辑、下游实现源码,或真实接口响应样本,字段名与结构可信 |
|
||
| ⚠️ **透传** | MCP 层**不裁剪**,原样返回下游响应;字段结构以**下游 MIS/MBX 服务为准**,可能随下游变更 |
|
||
|
||
> 无法完全确证的少量细节**不散落在正文里**,统一收在 **§6.5 残留不确定项**。
|
||
> 写 prompt 前建议先扫一遍 **§6.4 高风险陷阱汇总**——那里是「照直觉写就会错」的地方。
|
||
|
||
> **给 AI 生成 prompt 的建议**:引用 ⚠️ 透传 字段时,prompt 里应写成「从返回的 `xxx` 字段读取」而非硬编码整个结构;
|
||
> 引用 ✅ 已确定 字段时可以放心直接取值。
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [1. 工具总览](#1-工具总览)
|
||
- [2. 全局约定](#2-全局约定)
|
||
- [3. 工具详情](#3-工具详情)
|
||
- [3.1 `debuggingProjectQuery`](#31-debuggingprojectquery)
|
||
- [3.2 `queryProjectNameList`](#32-queryprojectnamelist)
|
||
- [3.3 `queryDriverListNamesByProject`](#33-querydriverlistnamesbyproject)
|
||
- [3.4 `queryDriverListVersion`](#34-querydriverlistversion)
|
||
- [3.5 `prepareTaskFile`](#35-preparetaskfile)
|
||
- [3.6 `generatePreloadUpdateLink`](#36-generatepreloadupdatelink)
|
||
- [3.7 `creatOrSendTask`](#37-creatorsendtask)
|
||
- [3.8 `queryTestUnitListByProjectName`](#38-querytestunitlistbyprojectname)
|
||
- [3.9 `queryTestPcByUuids`](#39-querytestpcbyuuids)
|
||
- [4. 典型工作流(编排剧本)](#4-典型工作流编排剧本)
|
||
- [5. 生成 SKILL 与 Prompt 的指引](#5-生成-skill-与-prompt-的指引)
|
||
- [6. 附录](#6-附录)
|
||
- [6.1 MCP 接入信息](#61-mcp-接入信息)
|
||
- [6.2 下游接口与白名单对照](#62-下游接口与白名单对照)
|
||
- [6.3 易混淆 / 已废弃工具](#63-易混淆--已废弃工具)
|
||
- [6.4 高风险陷阱汇总(写 prompt 前必读)](#64-高风险陷阱汇总写-prompt-前必读)
|
||
- [6.5 残留不确定项](#65-残留不确定项)
|
||
|
||
---
|
||
|
||
## 1. 工具总览
|
||
|
||
### 1.1 速查表
|
||
|
||
| # | MCP 工具名 | 所属服务 | 用途 | 必填参数 | 返回形态 |
|
||
|---|---|---|---|---|---|
|
||
| 1 | `debuggingProjectQuery` | `mis-mcp-tool-debugging` | 按项目名称/别名/五码查**项目基础信息** | 无(全部可选) | 分页信封 `{code,msg,total,rows[]}` ⚠️ |
|
||
| 2 | `queryProjectNameList` | `mis-mcp-tool-driver` | 取 MBX 侧**项目名称 + projectUuid** | 无(`creatorCode` 可选) | 数组 `[{name,projectUuid}]` ✅ |
|
||
| 3 | `queryDriverListNamesByProject` | `mis-mcp-tool-driver` | 按项目组/项目取**全部 Driver List Name** | `projectGroupUuid` 或 `projectUuid` | 数组 `[{driverListVersionUuid,driverListName}]` ✅ |
|
||
| 4 | `queryDriverListVersion` | `mis-mcp-tool-driver` | 取驱动列表版本的**包下载地址** | `driverListVersionUuid` | 下游对象 ⚠️(含 `packageFileUrl`) |
|
||
| 5 | `prepareTaskFile` | `mis-mcp-tool-driver` | 下载文件→重传到文件服务,换**任务下发可用的 fileUuid** | `fileUrl` | 对象 `{fileUuid,fileUrl,fileName,fileExtensionKey}` ✅ |
|
||
| 6 | `generatePreloadUpdateLink` | `mis-mcp-tool-vlab` | 生成 VLAB Preload 向导的**更新下载链接** | `project` | 对象(成功/失败两种结构)✅ |
|
||
| 7 | `creatOrSendTask` | `mis-mcp-tool-vlab` | **创建或下发测试任务** | `creatorCode`,`requestBodyJson` | 下游对象 ⚠️ / 纯文本提示 ✅ |
|
||
| 8 | `queryTestUnitListByProjectName` | `mis-mcp-tool-vlab` | 按项目名+五码查**机器列表** | `projectName`,`modelCode`,`ownerCode` | 下游列表 ⚠️ / 纯文本提示 ✅ |
|
||
| 9 | `queryTestPcByUuids` | `mis-mcp-tool-vlab` | 按 UUID 批量查**测试机在线状态** | `testUnitUuids` | 下游列表 ⚠️ |
|
||
|
||
> **参数必填标记来自源码**:`@ToolParam` 未写 `required = false` 即为**必填**。
|
||
|
||
### 1.2 数据依赖关系(谁喂谁)
|
||
|
||
这是生成 prompt 时最关键的一张图——**ID 都是一跳一跳传递的**:
|
||
|
||
```
|
||
① debuggingProjectQuery ──► projectName / projectUuid / modelCode
|
||
│
|
||
② queryProjectNameList ──────► projectUuid(MBX 侧)──┐
|
||
│
|
||
③ queryDriverListNamesByProject ◄─────────────────────┘
|
||
│ (需要 projectGroupUuid 或 projectUuid)
|
||
└──► driverListVersionUuid
|
||
│
|
||
④ queryDriverListVersion ◄──┘
|
||
└──► packageFileUrl
|
||
│
|
||
⑤ prepareTaskFile ◄─┘
|
||
└──► fileUuid
|
||
│
|
||
⑦ creatOrSendTask ◄──┘ (填入 requestBodyJson.model.children[].documentCopyDTOList[].fileUuid)
|
||
|
||
⑥ generatePreloadUpdateLink 独立链路,只需 project 名称(+ 可选 osVer)
|
||
⑧ queryTestUnitListByProjectName ──► testUnitUuid[]
|
||
│
|
||
⑨ queryTestPcByUuids ◄────────────────────┘ (查在线状态)
|
||
```
|
||
|
||
**关键 ID 传递表**:
|
||
|
||
| 上游工具 | 产出字段 | 下游工具 | 填入位置 |
|
||
|---|---|---|---|
|
||
| `queryDriverListNamesByProject` | `driverListVersionUuid` | `queryDriverListVersion` | 入参 `driverListVersionUuid` |
|
||
| `queryDriverListVersion` | `driverPackageVersionList[].packageFileUrl` | `prepareTaskFile` | 入参 `fileUrl` |
|
||
| `prepareTaskFile` | `fileUuid` | `creatOrSendTask` | `requestBodyJson.model.children[].documentCopyDTOList[].fileUuid` |
|
||
| `queryProjectNameList` | `projectUuid` | `queryDriverListNamesByProject` | 入参 `projectUuid` |
|
||
| `queryTestUnitListByProjectName` | `testUnitUuid` | `queryTestPcByUuids` | 入参 `testUnitUuids[]` |
|
||
|
||
### 1.3 语义说明:两个「项目查询」不重复(用户补充)
|
||
|
||
- `debuggingProjectQuery` —— 查的是 **SE 系统同步过来的 project** 信息;
|
||
- `queryProjectNameList` —— 查的是 **MBX 系统**的 project 信息;
|
||
- **两边的 project 的 `name` 值是对应的**,可互为参照。
|
||
|
||
> AI 写 prompt 时:要「项目基础信息」用 ①;要「能直接喂给 Driver 链路的 `projectUuid`」用 ②。
|
||
|
||
---
|
||
|
||
## 2. 全局约定
|
||
|
||
### 2.1 返回信封与三种裁剪行为
|
||
|
||
MCP 工具**全部返回字符串**(JSON 文本)。脱掉下游信封 `{code, msg, data}` 后,按模块有**三种**不同行为——写 prompt 时必须区分:
|
||
|
||
| 行为 | 工具 | 返回内容 |
|
||
|---|---|---|
|
||
| **A. 全量透传** | `debuggingProjectQuery` | 返回**整个信封** `{code,msg,total,rows[]}`,`rows[]` 内字段**不裁剪** ⚠️ |
|
||
| **B. 取 data(分页自动展平)** | `queryDriverListVersion`、`creatOrSendTask`、`queryTestUnitListByProjectName`、`queryTestPcByUuids` | 若 `data` 是对象且含 `records`,**只返回 `records` 数组**;否则返回 `data` 本身;`data` 为空返回 `"[]"` ⚠️ |
|
||
| **C. 取 data + 字段裁剪** | `queryProjectNameList`、`queryDriverListNamesByProject`、`prepareTaskFile`、`generatePreloadUpdateLink` | 只返回源码中显式挑出的字段 ✅ |
|
||
|
||
> **注意 B 类的空值表现**:`data` 为空时返回字符串 `"[]"`(**空数组**,不是空对象)。
|
||
|
||
### 2.2 分页参数命名不统一(易错点)
|
||
|
||
| 服务 | 页码参数 | 每页参数 | 默认值 |
|
||
|---|---|---|---|
|
||
| `mis-mcp-tool-debugging` | `pageNum` | `pageSize` | 1 / 10 |
|
||
| `mis-mcp-tool-driver` | `current` | `size` | 1 / 10(`queryProjectList*` / `queryDriverChidPage` / `queryDriverPackageList` / `queryWu*`)<br>1 / 5(`queryDriverListPage`) |
|
||
| `mis-mcp-tool-vlab` | `current` | `size` | 1 / 10 |
|
||
|
||
> **两个工具没有分页参数**(内部固定,调用方无需也无法指定):
|
||
> `queryProjectNameList`(固定第 1 页、每页 **100** 条)、`queryDriverListNamesByProject`(自动翻页取全量,每页 100 条)。
|
||
|
||
### 2.3 用户 ID 与鉴权
|
||
|
||
- **两种用户 ID 不能混用**:MCP 工具入参普遍收 **MIS 系统用户 ID**(如 `creatorCode`、`ownerCode`),
|
||
由服务内部通过 `MbxUserIdConverter` 转成 **MBX 用户 ID** 后传给下游(5 分钟本地缓存)。
|
||
- **转换失败有专用提示**:部分工具转换失败时返回**纯文本**而非 JSON,见 §2.4。
|
||
- **鉴权由 MCP 客户端透传**,调用方(LLM 侧)**不需要**在工具参数里传 token;
|
||
凭证走 MCP 请求头 `auth` / `clientid`,由 `MisAuthForestInterceptor` 注入下游。
|
||
|
||
### 2.4 非 JSON 返回(prompt 必须能识别)
|
||
|
||
以下情况返回的是**纯文本字符串**,不是 JSON——AI 解析时应先判断首字符:
|
||
|
||
| 工具 | 返回文本 | 触发条件 |
|
||
|---|---|---|
|
||
| `creatOrSendTask` | `请输入当前登录人信息` | `creatorCode` 为空,或 MIS→MBX 用户 ID 转换失败 |
|
||
| `queryTestUnitListByProjectName` | `登录人信息转换异常` | `ownerCode` 有值但转换失败 |
|
||
|
||
### 2.5 异常的处理方式
|
||
|
||
参数校验失败、下游业务失败时,工具**抛异常**(`IllegalArgumentException` / `RuntimeException`),
|
||
由 MCP 协议以错误形式返回,**不会**包装成 JSON。典型触发:
|
||
|
||
- `queryDriverListVersion`、`queryTestPcByUuids` 等:必填参数为空(如 `testUnitUuids` 空列表);
|
||
- 所有工具:下游返回非 JSON、下游业务码失败(错误信息取下游 `msg`)。
|
||
|
||
---
|
||
|
||
## 3. 工具详情
|
||
|
||
### 3.1 `debuggingProjectQuery`
|
||
|
||
**摘要**:根据项目名称、项目别名、项目五码查询项目基础信息,返回项目列表分页数据。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-debugging`(端口 18780,`STATELESS`) |
|
||
| Java 方法 | `ProjectMcpService.queryProjectList` |
|
||
| MCP 工具名 | `debuggingProjectQuery`(**源码中显式指定**,与 Java 方法名不同,调用时必须用这个名字) |
|
||
| 下游接口 | `GET {misApiBaseUrl}/debugging/project`(MIS 平台,网关白名单已放行) |
|
||
| 返回裁剪 | **A 类:全量透传**(`rows[]` 内 34 个字段全部返回,不裁剪)⚠️ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `projectName` | String | 否 | — | 项目名称 | `IdeaPad 5 Pro 16ARP8` |
|
||
| `projectAlias` | String | 否 | — | 项目别名 | — |
|
||
| `modelCode` | String | 否 | — | 项目五码 | `LT4EN` |
|
||
| `ppmQuery` | String | 否 | — | 项目负责人名称或参与人 | `san.zhang` |
|
||
| `mtCode` | String | 否 | — | 项目四码 | `81S3` |
|
||
| `pageSize` | Integer | 否 | `10` | 每页条数 | `10` |
|
||
| `pageNum` | Integer | 否 | `1` | 页码 | `1` |
|
||
|
||
**返回 JSON 结构** ✅(顶层 5 字段)/ ⚠️(透传,未裁剪)
|
||
|
||
```jsonc
|
||
{
|
||
"total": 0, // number 总条数
|
||
"rows": [ /* 见下表,Project 实体,34 个字段 */ ],
|
||
"code": 200, // number 成功码固定 200
|
||
"msg": "查询成功", // string
|
||
"extraData": null // 该接口路径下恒为 null
|
||
}
|
||
```
|
||
|
||
**`rows[]` 元素字段表**(实体 `com.lcfc.debugging.domain.Project`,**无任何 JSON 重命名注解**)
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `projectUuid` | Long → number/string | 主键。**类型不确定**:雪花 ID 超 2^53-1 时会被序列化成字符串,须按「可能是数字也可能是字符串」处理 |
|
||
| `idpProjectUuid` | String | idp 项目管理表主键 |
|
||
| `projectName` | String | Project Name 数据 |
|
||
| `projectCode` | String | Project code 数据 |
|
||
| `projectAlias` | String | 项目别名 |
|
||
| `lenovoProductName` | String | 联想产品名称 |
|
||
| `issueOwners` | Array\<Object\> | Issue Owner 列表,元素为 `{category, component, owner}` |
|
||
| `modelCode` | String | 五码信息(BOX Model Code) |
|
||
| `mtCode` | String | 四码信息 |
|
||
| `finCode` | String | 财务代码 |
|
||
| `bu` | String | BU 信息 |
|
||
| `developmentType` | String | Development Type |
|
||
| `generation` | String | Generation |
|
||
| `segment` | String | Segment |
|
||
| `pm` | String | PM |
|
||
| `ppm` | Array\<String\> | PPM 列表 |
|
||
| `pje` | Array\<String\> | PJE 列表 |
|
||
| `biosCode` | String | BIOS Code |
|
||
| `ddsTime` | String | 日期,格式固定 `yyyy-MM-dd` |
|
||
| `pkoTime` | String | 同上 |
|
||
| `evtStartTime` / `evtEndTime` | String | 同上 |
|
||
| `fvtStartTime` / `fvtEndTime` | String | 同上 |
|
||
| `sitStartTime` / `sitEndTime` | String | 同上 |
|
||
| `svtStartTime` / `svtEndTime` | String | 同上 |
|
||
| `sovpTime` / `ssTime` | String | 同上 |
|
||
| `actuaiEopTime` | String | 同上。**字段名拼写就是 `actuaiEopTime`**(非 `actual`),按原样使用 |
|
||
| `sort` | Integer | 排序号 |
|
||
| `delFlag` | String | 删除标志,查询恒定返回 `"0"` |
|
||
| `ppmQuery` | null | **恒为 null**(该字段只用于查询条件,不参与返回取值) |
|
||
|
||
**返回示例**(截取)
|
||
|
||
```json
|
||
{
|
||
"total": 1,
|
||
"rows": [
|
||
{
|
||
"projectUuid": "2049298006288687105",
|
||
"projectName": "IdeaPad 5 Pro 16ARP8",
|
||
"projectAlias": "LCP8",
|
||
"modelCode": "LT4EN",
|
||
"mtCode": "81S3",
|
||
"ppm": ["san.zhang"],
|
||
"pje": [],
|
||
"ddsTime": "2026-03-01",
|
||
"delFlag": "0",
|
||
"ppmQuery": null
|
||
}
|
||
],
|
||
"code": 200,
|
||
"msg": "查询成功",
|
||
"extraData": null
|
||
}
|
||
```
|
||
|
||
**注意事项**
|
||
|
||
- 这是**唯一一个返回「整个信封」**的工具(其余 debugging 工具会裁剪成 `{code,msg,total,rows[]}` 且过滤行内字段)。若 prompt 里要遍历数据,需先取 `rows`。
|
||
- `total` 是**总条数**,不是当前页条数。
|
||
- `projectUuid` 在别的工具里常以字符串形式出现,**做参数传递时按字符串处理最安全**。
|
||
- 查的是 **SE 系统同步过来的项目信息**,与 `queryProjectNameList` 的 MBX 侧数据来源不同,但 `name` 对应(见 §1.3)。
|
||
|
||
**关联工具**:`queryDriverListNamesByProject`(其 `projectUuid` 可来自本工具)、`queryProjectNameList`
|
||
|
||
---
|
||
|
||
### 3.2 `queryProjectNameList`
|
||
|
||
**摘要**:获取项目名称列表,返回 `name` 与 `projectUuid`。`creatorCode` 有值时只查该用户所涉及的项目。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-driver`(端口 18767,`STATELESS`) |
|
||
| Java 方法 | `DriverService.queryProjectNameList` |
|
||
| MCP 工具名 | `queryProjectNameList` |
|
||
| 下游接口 | `GET {misDriverBusinessBaseUrl}/project/mcpvlabpage`(MBX `mbv-service-business`) |
|
||
| 返回裁剪 | **C 类:取 data + 裁剪**,只保留 `name` / `projectUuid` ✅ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 |
|
||
|---|---|---|---|---|
|
||
| `creatorCode` | String | 否 | — | 当前登录人 **MIS 系统用户 ID**。有值 → 只查该用户涉及的项目 |
|
||
|
||
> **入参规则**(源码 `MbxUserIdConverter`):`creatorCode` 必须是**纯数字**的 MIS 用户 ID;
|
||
> 为空、非数字、或查不到映射时,工具**不会**把用户条件传给下游(即退化成「不带用户过滤」查询),**不报错**。
|
||
|
||
**返回 JSON 结构** ✅
|
||
|
||
```jsonc
|
||
[
|
||
{
|
||
"name": "string", // 项目名称:实际取自下游 portfolioProjectName
|
||
"projectUuid": "string" // 项目唯一标识,可直接喂给 queryDriverListNamesByProject
|
||
}
|
||
]
|
||
```
|
||
|
||
> **已核实**:下游 `ProjectPageInfo` **没有 `name` 字段**,所以源码里「`portfolioProjectName` 为空则回退 `name`」的兜底**永远不会触发**。
|
||
> 实际取值路径只有 `portfolioProjectName` 一条;该字段为空的行会被**整条丢弃**(不返回)。
|
||
> 因此 prompt 中应把 `name` 理解为「下游的项目名称(portfolioProjectName)」,不要去找别的名字来源。
|
||
|
||
**返回示例**
|
||
|
||
```json
|
||
[
|
||
{ "name": "IdeaPad 5 Pro 16ARP8", "projectUuid": "018cd84ba0a82b020410bb40a1d85ba5" },
|
||
{ "name": "Legion 5 15IRX10", "projectUuid": "000c798c09d537f4f25f5b29046aebd1" }
|
||
]
|
||
```
|
||
|
||
**注意事项**
|
||
|
||
- **本工具固定只取第 1 页、每页 100 条**(源码常量 `PROJECT_NAME_LIST_SIZE = 100`),即**最多返回 100 条项目**,且**没有分页参数**。
|
||
超过 100 条时**不会自动翻页**;需要按名称检索或取更多项目请用 `debuggingProjectQuery`。
|
||
(该常量原为 `2`,2026-09-22 修正为 `100`。)
|
||
- 返回**不含分页信息**,是纯数组。
|
||
- 两个字段都为空的下游记录会被过滤掉。
|
||
- 空结果返回 `"[]"`。
|
||
|
||
**关联工具**:`queryDriverListNamesByProject`(承接 `projectUuid`)、`debuggingProjectQuery`(项目基础信息)
|
||
|
||
---
|
||
|
||
### 3.3 `queryDriverListNamesByProject`
|
||
|
||
**摘要**:根据项目组唯一标识或项目唯一标识,查询对应的**全部** Driver List Name,返回 `driverListVersionUuid` 与 `driverListName` 集合。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-driver` |
|
||
| Java 方法 | `DriverService.queryDriverListNamesByProject` |
|
||
| MCP 工具名 | `queryDriverListNamesByProject` |
|
||
| 下游接口 | `GET {misDriverBaseUrl}/driverlist/mcpvlabpage`(内部自动翻页,每页 100 条直到取完) |
|
||
| 返回裁剪 | **C 类:裁剪并去重** ✅ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `projectGroupUuid` | String | 否 | — | 项目组唯一标识(与 `projectUuid` **至少给一个**) | `d5ac3039abf4c8302cccefc40f7056dd` |
|
||
| `projectUuid` | String | 否 | — | 项目唯一标识(与 `projectGroupUuid` **至少给一个**) | `018cd84ba0a82b020410bb40a1d85ba5` |
|
||
|
||
**返回 JSON 结构** ✅
|
||
|
||
```jsonc
|
||
[
|
||
{
|
||
"driverListVersionUuid": "string", // 驱动列表【版本】唯一标识 —— 给 queryDriverListVersion 用
|
||
"driverListName": "string" // 驱动列表名称:实际取自下游 driverListName
|
||
}
|
||
]
|
||
```
|
||
|
||
> **已核实**:源码写的是「优先取 `nameRemark`,为空则回退 `driverListName`」,但下游**分页接口的 SQL 根本没查 `name_remark` 列**,
|
||
> 因此 `nameRemark` 在这个链路上**恒为 null**,回退分支**必然生效** —— 返回值里的 `driverListName` 实际就是下游的 `driverListName`。
|
||
> (`nameRemark` 只在单查版本详情、即 §3.4 的返回里才有值。)对调用方而言:**只会拿到一个非空的 `driverListName`,直接用它做筛选即可**。
|
||
|
||
**返回示例**
|
||
|
||
```json
|
||
[
|
||
{ "driverListVersionUuid": "93b947167dad2e8956a70358742f70cc", "driverListName": "MyLNBGroup_Win10 21H2_V02" },
|
||
{ "driverListVersionUuid": "c95301ca9485a1bb2102989f91e5eaf9", "driverListName": "MyLNBGroup_Win10 21H2_V01_20260407" }
|
||
]
|
||
```
|
||
|
||
**注意事项**
|
||
|
||
- 返回的是**版本级**标识(`driverListVersionUuid`),**不是**驱动列表级标识;一个驱动列表有多个版本时会有多条。
|
||
- 结果已按 `driverListVersionUuid` **去重**;名称为空、UUID 为空的记录会被跳过。
|
||
- 工具内部会**自动翻页**(`size=100`)取全量,调用方**不需要**传分页参数,也没有分页参数。
|
||
- 返回**不含分页信息**,是纯数组;空结果返回 `"[]"`。
|
||
- 项目组/项目下驱动列表很多时,返回可能较长——prompt 里应引导模型**先按名称筛选**再取版本。
|
||
- ⚠️ **已知下游缺陷**:下游分页接口对「**一个版本都没有的空驱动列表**」会抛数组越界 → 返回 **500**。
|
||
出现「Driver 接口业务失败」类报错时,除了参数问题,也要考虑该分组下存在空驱动列表这一可能。
|
||
|
||
**关联工具**:`queryDriverListVersion`(承接 `driverListVersionUuid`)、`queryProjectNameList`(提供 `projectUuid`)
|
||
|
||
---
|
||
|
||
### 3.4 `queryDriverListVersion`
|
||
|
||
**摘要**:根据驱动列表唯一标识查询驱动列表版本信息,用于拿到**驱动包的下载地址**。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-driver` |
|
||
| Java 方法 | `DriverService.queryDriverListVersion` |
|
||
| MCP 工具名 | `queryDriverListVersion` |
|
||
| 下游接口 | `GET {misDriverBaseUrl}/listversion/mcpvlab/{driverListUuid}` |
|
||
| 返回裁剪 | **B 类:取 data(未做字段裁剪)** ⚠️ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `driverListVersionUuid` | String | **是** | — | 驱动列表版本唯一标识,来自 `queryDriverListNamesByProject` 的返回 | `93b947167dad2e8956a70358742f70cc` |
|
||
|
||
**返回 JSON 结构** ⚠️ **透传(未裁剪)**
|
||
|
||
MCP 层**只拆信封**,返回下游 `data` 的**完整内容**(`data` 为分页对象时取 `records`,为空时返回 `[]`)。
|
||
`data` 的结构是 `DriverListVersionVO`:
|
||
|
||
```jsonc
|
||
{
|
||
"driverListVersionUuid": "string",
|
||
"nameRemark": "string", // 本接口有值(与分页列表不同)
|
||
"driverListUuid": "string",
|
||
"driverListVersion": 0,
|
||
"status": null, // 下游未映射,恒 null
|
||
"driverListReleaseDate": "yyyy-MM-dd",
|
||
"creatorCode": "string",
|
||
"modifierCode": "string",
|
||
"createTime": "string",
|
||
"modifyTime": "string",
|
||
"activityStatusKey": "string",
|
||
"homesFlag": true,
|
||
"driverListName": "string",
|
||
"projectGroupUuid": "string",
|
||
"projectGroupName": "string",
|
||
"spmsProjectName": "string",
|
||
"driverListGmStatus": 0,
|
||
"driverListStatus": 0, // 0-临时 1-草稿 2-发布
|
||
"changeList": "string",
|
||
"remark": "string",
|
||
"comment": "string",
|
||
"osTypeKeyList": [0],
|
||
|
||
// ★★★ 目标产物在这里 ★★★
|
||
"driverPackageVersionList": [
|
||
{
|
||
"packageFileUrl": "★★ 驱动包下载地址 —— prepareTaskFile 的 fileUrl 入参",
|
||
"...": "DriverPackageVersionVO 其余字段"
|
||
}
|
||
],
|
||
"solidifiedDriverPackageVersionList": [ /* 结构同上,仅 driverListStatus==2(发布态)时有值 */ ],
|
||
|
||
"releaseContactUuidList": ["string"],
|
||
"releaseContactList": [ /* DriverContactVO */ ],
|
||
"driverPoContactList": [ /* DriverContactVO */ ],
|
||
"packageVersionNum": 0,
|
||
"bu": 0,
|
||
"logoNeeded": [0],
|
||
"platform": "string",
|
||
"baseIntelBkcVersion": "string",
|
||
"specialField": "string"
|
||
}
|
||
```
|
||
|
||
> ### ⚠️ 最容易踩的坑:`packageFileUrl` **不在顶层**
|
||
>
|
||
> MCP 实现**不裁剪字段**,`packageFileUrl` 也**不是顶层字段**——
|
||
> 它是嵌套元素 `DriverPackageVersionVO` 的字段,位于:
|
||
>
|
||
> - `driverPackageVersionList[].packageFileUrl`,或
|
||
> - `solidifiedDriverPackageVersionList[].packageFileUrl`(仅发布态 `driverListStatus == 2` 时有值)
|
||
>
|
||
> **prompt 必须写成「从 `driverPackageVersionList[].packageFileUrl` 取值」**,
|
||
> 若写成「取返回的 `packageFileUrl`」会取到 `undefined`。
|
||
> 建议优先读 `solidifiedDriverPackageVersionList`(发布态更稳定),为空再回退 `driverPackageVersionList`。
|
||
>
|
||
> ✅ **2026-09-22 已修正**:本工具的 `description` 原先写「返回 `packageFileUrl` 的下载地址即可」,
|
||
> 与实现不符,现已改为明确说明该字段的嵌套位置(见 `DriverService.queryDriverListVersion`)。
|
||
|
||
**注意事项**
|
||
|
||
- 入参 `driverListVersionUuid` 填的是**版本 UUID**(照抄 `queryDriverListNamesByProject` 的返回值)。
|
||
MCP 源码内部把它命名成 `driverListUuid` 只是**命名失误**,下游实际按版本 UUID 查询,不影响调用。
|
||
- 拿到的 `packageFileUrl` **不能直接**用于任务下发,必须再过 `prepareTaskFile`(见 §3.5)。
|
||
- 该 URL 形如 `http://<文件服务>/mbvClient/downloadFile?objectName=...&bucketName=driver`,**必须带 `objectName` 与 `bucketName`**。
|
||
- 传错成「驱动列表 UUID」时不会报错,而是 `data` 为 null → 返回 `[]`,需按空结果处理。
|
||
|
||
**关联工具**:`queryDriverListNamesByProject`(上游,提供 `driverListVersionUuid`)、`prepareTaskFile`(下游,消费 `packageFileUrl`)
|
||
|
||
---
|
||
|
||
### 3.5 `prepareTaskFile`
|
||
|
||
**摘要**:把「文件下载地址」对应的文件**重新上传到文件服务**,返回可用于测试任务下发的文件参数。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-driver` |
|
||
| Java 方法 | `DriverService.prepareTaskFile` |
|
||
| MCP 工具名 | `prepareTaskFile` |
|
||
| 下游接口 | ① `GET {misFileServiceBaseUrl}/mbvClient/downloadFile`(下载,`mbv-service-minio`)<br>② `POST {misFileServiceBaseUrl}/uploadFileSpecial`(上传到 `document` 桶) |
|
||
| 返回裁剪 | **C 类:裁剪** ✅ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `fileUrl` | String | **是** | — | 文件下载地址,来自 `queryDriverListVersion` 返回的 `packageFileUrl` | `http://10.159.41.130:8080/mbvClient/downloadFile?objectName=20260413/16/55/33/xxx.zip&bucketName=driver` |
|
||
|
||
> **`fileUrl` 必须带 `objectName` 与 `bucketName` 两个查询参数**,否则工具直接抛错(无法解析文件名/桶名)。
|
||
|
||
**返回 JSON 结构** ✅
|
||
|
||
```jsonc
|
||
{
|
||
"fileUuid": "string", // ★ 任务下发要用的文件唯一标识
|
||
"fileUrl": "string", // 上传后文件服务返回的访问地址
|
||
"fileName": "string", // 文件名(取自 objectName 最后一段)
|
||
"fileExtensionKey": 0 // 文件扩展名标识;类型不固定(可能是数字/字符串/null),按原样传递即可
|
||
}
|
||
```
|
||
|
||
**返回示例**
|
||
|
||
```json
|
||
{
|
||
"fileUuid": "8f2a1c9e4b7d4a1f9c3e5b6a7d8e9f01",
|
||
"fileUrl": "http://10.159.41.130:8080/mbvClient/downloadFile?objectName=document/20260922/xxx.zip&bucketName=document",
|
||
"fileName": "xxx.zip",
|
||
"fileExtensionKey": 3
|
||
}
|
||
```
|
||
|
||
**它在链路中的位置**(**这是本工具存在的唯一理由**)
|
||
|
||
```
|
||
queryDriverListVersion → packageFileUrl →【prepareTaskFile】→ fileUuid
|
||
→ creatOrSendTask 的
|
||
requestBodyJson.model.children[].documentCopyDTOList[].fileUuid
|
||
```
|
||
|
||
> 为什么不能直接把 `packageFileUrl` 填进任务下发?因为 `creatOrSendTask` 的 `documentCopyDTOList` **只认 `fileUuid`**,
|
||
> 而 driver 桶的文件不落文件信息表、没有 `file_uuid`。重传到 `document` 桶才能换到一个可用的 `fileUuid`。
|
||
> **因此这一步不可省略**,顺序也不能颠倒。
|
||
|
||
**注意事项**
|
||
|
||
- ⏱ **耗时较长**:驱动包可能有几百 MB,内部超时为 **10 分钟**。prompt 里应提示用户「这一步较慢,请稍候」。
|
||
- **不校验文件内容**,只做下载 + 上传;下载得到的是「HTTP 200 + 纯文本」形式的错误提示(如「文件不存在」)时会被拦截并报错。
|
||
- 返回的 `fileUrl` 是**上传后**的新地址(`document` 桶),与入参的 `packageFileUrl`(`driver` 桶)**不同**,不要混用。
|
||
|
||
**关联工具**:`queryDriverListVersion`(上游,提供 `fileUrl`)、`creatOrSendTask`(下游,消费 `fileUuid`)
|
||
|
||
---
|
||
|
||
### 3.6 `generatePreloadUpdateLink`
|
||
|
||
**摘要**:根据项目信息生成 VLAB Preload 向导页面的 **preload 更新下载链接**。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-vlab`(端口 18769,`STREAMABLE`,端点 `/mcp`) |
|
||
| Java 方法 | `PreloadService.generatePreloadUpdateLink` |
|
||
| MCP 工具名 | `generatePreloadUpdateLink` |
|
||
| 下游接口 | `mbv-service-preload`:`/preload/preloadNameList` → `/preload/init` → `/preload/select` → `/preload/getOtherList` → `/preload/preloadVersion` → `/aod` |
|
||
| 返回裁剪 | **C 类:自行组装** ✅ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `project` | String | **是** | — | 项目名称,**必须是 Preload 向导页面下拉选项中的值** | `IdeaPad 5 Pro 16ARP8` |
|
||
| `osVer` | String | 否 | 下拉列表**第一个**版本 | 操作系统版本,可用**页面展示名**(`description`)或**目录名**(`directory`) | `9.Win11` |
|
||
|
||
> 其余页面字段(Location、Preload VER、OS Type、Language、OS Edition、HDD Config、模块穿梭框)**均按页面默认值自动提交**,
|
||
> 调用方**无需也无法**指定。
|
||
|
||
**返回 JSON 结构** ✅ —— **成功与失败是两种不同结构,prompt 必须能区分**
|
||
|
||
**① 成功**
|
||
|
||
```jsonc
|
||
{
|
||
"downloadUrl": "string", // ★ 生成的 preload 更新下载链接
|
||
"project": "string", // 实际匹配到的项目名(回显下游下拉里的原值)
|
||
"osVer": "string", // 实际匹配到的 OS 版本展示名
|
||
"os": "string", // OS 目录名(directory)
|
||
"preloadVersion": "string", // 实际使用的 Preload VER
|
||
"locationName": "string" // 实际使用的 Location
|
||
}
|
||
```
|
||
|
||
**② 失败**(三种触发场景,`msg` 不同,附加字段也不同)
|
||
|
||
```jsonc
|
||
{
|
||
"success": false, // ★ 失败标志(注意:成功时【没有】success:true)
|
||
"msg": "string", // 失败原因
|
||
// 以下附加字段随场景变化:
|
||
"project": "string", // 回显入参
|
||
"osVer": "string", // 回显入参(可能为 null)
|
||
"os": "string", // 仅「未找到 Preload VER」场景
|
||
"preloadVersion": "string", // 仅「未返回下载地址」场景
|
||
"availableProjects": ["string"], // ★ 仅「Project 不在下拉选项中」场景
|
||
"availableOsVer": ["string"] // ★ 仅「OS VER 不在下拉选项中」场景
|
||
}
|
||
```
|
||
|
||
**失败场景对照表**
|
||
|
||
| `msg` | 触发条件 | 可用来自纠偏的字段 |
|
||
|---|---|---|
|
||
| `Project 不在 Preload 向导下拉选项中` | `project` 与下游下拉值**不匹配**(忽略大小写、去空格后仍不匹配) | `availableProjects` —— 全部合法项目名 |
|
||
| `OS VER 不在 Preload 向导下拉选项中` | `osVer` 既不是某版本的 `description` 也不是 `directory` | `availableOsVer` —— 全部合法 OS 版本名 |
|
||
| `未找到对应的 Preload VER` | 项目+OS 组合下 select 返回空 | `project` / `osVer` / `os` |
|
||
| `生成 Preload 更新链接失败,下游未返回下载地址` | 走到 `/aod` 但没拿到地址 | `project` / `osVer` / `preloadVersion` |
|
||
|
||
**返回示例**
|
||
|
||
```json
|
||
{
|
||
"downloadUrl": "http://mbxqas.lcfuturecenter.com/prod-api/preloadService/xxx/download?file=xxx.zip",
|
||
"project": "IdeaPad 5 Pro 16ARP8",
|
||
"osVer": "9.Win11",
|
||
"os": "Win11",
|
||
"preloadVersion": "PR9.0.0",
|
||
"locationName": "LCFC"
|
||
}
|
||
```
|
||
|
||
**注意事项**
|
||
|
||
- ⚠️ **判成功的正确写法**:检查是否**存在 `downloadUrl`**,或检查 `success === false`。
|
||
**不要**写 `success === true` —— 成功返回里**没有** `success` 字段。
|
||
- `project` / `osVer` 都是**按下游下拉值精确匹配**(忽略大小写与首尾空格),**不是模糊查询**。
|
||
传错时不会返回空数组,而是返回**失败对象 + 候选列表**——这是自纠偏的关键:
|
||
**prompt 应引导模型用 `availableProjects` / `availableOsVer` 重新选取后再重试一次,而不是反复用同一个错值重试。**
|
||
- `osVer` 不传时取下拉列表**第一个**版本,与页面默认行为一致。
|
||
- 该工具**会真实生成下载链接**(非只读查询),属于链路中副作用最强的一步。
|
||
|
||
**关联工具**:无上游依赖;项目名可参照 `debuggingProjectQuery` / `queryProjectNameList` 的 `name`(但**必须**用 Preload 页面下拉里的值)
|
||
|
||
---
|
||
|
||
### 3.7 `creatOrSendTask`
|
||
|
||
**摘要**:创建或下发测试任务。**本工作流中唯一的写操作**。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-vlab` |
|
||
| Java 方法 | `TaskService.creatOrSendTask` |
|
||
| MCP 工具名 | `creatOrSendTask`(**注意是 `creat` 不是 `create`**) |
|
||
| 下游接口 | `POST {misDispatcherBaseUrl}/mcpvlabcreatOrSendTask?fs={fs}&userId={userId}`,请求体为任务 JSON |
|
||
| 返回裁剪 | **B 类:取 data(未做字段裁剪)** ⚠️ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 |
|
||
|---|---|---|---|---|
|
||
| `creatorCode` | String | **是** | — | 当前登录人 **MIS 系统用户 ID**(纯数字)。服务内部转成 MBX `userId` 传给下游 |
|
||
| `requestBodyJson` | String | **是** | — | **任务请求体 JSON 字符串**。结构见下方“请求体”一节 |
|
||
| `fs` | Boolean | 否 | `false` | 随请求透传给下游的 `fs` 参数 |
|
||
|
||
### 请求体 `requestBodyJson` 结构 ✅(已核实下游 `DispatcherServiceImpl.commonCreateTask`)
|
||
|
||
> **`requestBodyJson` 必须是一个 JSON 字符串**(不是对象)。模型调用时需要把整个任务体**序列化成字符串**再作为参数传入。
|
||
> 下游用 Hutool 解析(非强类型 DTO),只有一个字段是硬性必填:**`other.type`**。
|
||
|
||
**顶层结构**
|
||
|
||
```jsonc
|
||
{
|
||
"base": { /* TestTask —— 任务基本信息 */ },
|
||
"other": { "type": 2 }, // ★ 必填!1=只保存 2=创建并下发
|
||
"rule": { /* TestTaskUnitBinding —— 选机器规则 */ },
|
||
"model": { /* TestModelNode —— 任务步骤树(模型视图时必填) */ },
|
||
"testTaskIssueTypeCode": 1, // 1=模型视图(默认) 2=用例视图
|
||
"testCaseAssociationVersionUuidList": [] // 仅用例视图(2)时必填
|
||
}
|
||
```
|
||
|
||
**`base` 常用字段**(`TestTask`)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `testTaskName` | String | 任务名称 |
|
||
| `testTaskTypeKey` | Integer | 1=测试任务,2=debug 任务 |
|
||
| `projectUuid` | String | 项目唯一标识 |
|
||
| `remark` | String | 备注 |
|
||
| `scheduleTime` | Date | 定时下发时间(**必须晚于当前时间**,否则报错) |
|
||
|
||
> 下发时会被下游**强制覆盖**的字段(传了也不生效):`testTaskCode`(重新生成)、
|
||
> `testModelUuid` / `testModelVersionUuid`、`ownerCode` / `creatorCode` / `operatorCode` / `modifierCode`(一律用 `userId` 覆盖)、
|
||
> `activityStatusKey`、`testTaskStatusKey`、`submitState`。
|
||
|
||
**`other` 字段**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `type` | Integer | **必填**。1=只保存,2=创建并下发。**为 null 会导致下游 NPE(500)** |
|
||
| `isClear` | Boolean | 是否清除当前执行任务 |
|
||
| `isDevice` | Boolean | — |
|
||
| `scheduleTime` | Date | 定时下发时间 |
|
||
|
||
**`rule` 常用字段**(`TestTaskUnitBinding`)——「选哪些机器」
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `testTaskUnitBindingRuleKey` | Integer | 绑定规则:1=ssn 2=sku 3=mo 4=model 5=project |
|
||
| `bindingRulePriority` | Integer | 优先级 |
|
||
| `entityPrimaryKeyList` | Array\<String\> | ★ 选中的机器。**元素是 JSON 字符串,不是裸 UUID**,形如 `"{\"key\":\"<testUnitUuid>\",\"value\":\"<机器名>\"}"` |
|
||
|
||
**`model` 关键字段与文件挂载点**(`TestModelNode`,可递归)
|
||
|
||
```jsonc
|
||
{
|
||
"testModelUuid": "string",
|
||
"testModelVersionUuid": "string",
|
||
"testModelName": "string",
|
||
"nodeSequenceTypeKey": 1, // 1 串行 / 2 并行
|
||
"children": [
|
||
{
|
||
"testModelUuid": "string",
|
||
"testModelVersionUuid": "string",
|
||
"children": [],
|
||
|
||
// ★★★ 驱动包文件挂在这里 ★★★
|
||
"documentCopyDTOList": [
|
||
{
|
||
"fileUuid": "★ 填 prepareTaskFile 返回的 fileUuid",
|
||
"documentName": "string", // 可选
|
||
"documentVersionNo": "string" // 可选
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
> **`documentCopyDTOList` 里下游实际只用 `fileUuid`**(做判重与建文档映射),其余字段可选。
|
||
> 这与 §3.5 的链路说明一致。
|
||
|
||
**返回** ✅ / ⚠️
|
||
|
||
| 形态 | 内容 | 触发条件 |
|
||
|---|---|---|
|
||
| **纯文本** ✅ | `请输入当前登录人信息` | `creatorCode` 为空,**或** MIS→MBX 用户 ID 转换失败 |
|
||
| 异常 | `IllegalArgumentException: 任务请求体 requestBodyJson 不能为空` | `requestBodyJson` 为空 |
|
||
| **JSON** ⚠️ | 见下 | 正常调用 / 下游业务失败 |
|
||
|
||
**成功返回**(下游 `R.ok(statusMap, "任务下发已提交,正在生成中")`,MCP 取出 `data`)
|
||
|
||
```jsonc
|
||
{
|
||
"offLineTestUnit": "uuid1,uuid2,", // 离线机器 uuid,逗号拼接、末尾带逗号
|
||
"unWorkingTestUnit": "uuid3,", // 使用中机器 uuid,同上
|
||
"testTaskUuid": "string", // ★ 新建任务唯一标识
|
||
"testTaskCode": "string" // ★ 任务编号
|
||
}
|
||
```
|
||
|
||
**失败返回**(MCP 同样按 B 类处理:`data` 为 null 时返回 `[]`)
|
||
|
||
| 下游 `msg` | 含义 |
|
||
|---|---|
|
||
| `参数异常请检查` | ⚠️ 请求体为空。**下游这里返回的是 `code="0"`**,MCP 会当成成功路径处理,返回 `[]` —— 无法只靠 code 区分,需结合 `msg` |
|
||
| `任务定时下发时间需在当前时间之后,请重新设置!` | `scheduleTime` 早于当前时间 |
|
||
| `该任务含有禁用的用例关联版本,请修改重试!` | 用例关联版本被禁用 |
|
||
| `关联版本对应的绑定模型数据为空!` / `testCaseAssociationVersionUuid参数不得为空!` | 用例视图参数缺失 |
|
||
| `该任务含有不可用的原子模型,请修改重试!` | ⚠️ 此时下游 `code="26"`,`data` 是**列表** `[{deviceTypeKey, testUnitUuid, testUnitName}]`,MCP 会把该列表返回 |
|
||
|
||
**注意事项**
|
||
|
||
- ⚠️ **写操作**:会真实创建/下发任务,不可撤销。prompt 中应要求**先展示完整 `requestBodyJson` 给用户确认**再执行。
|
||
- `fileUuid` **必须**来自 `prepareTaskFile`,不能用 `packageFileUrl` 顶替(§3.5)。
|
||
- `creatorCode` 必须是**纯数字**的 MIS 用户 ID;非数字会走到「请输入当前登录人信息」分支,而不是报错——**prompt 需能识别这句纯文本并提示用户提供正确 ID**。
|
||
- `other.type` 忘了传 → 下游 NPE(500),这是最常见的构造错误。
|
||
- `fs=true` 会**跳过「机器未绑定设备类型」校验**并强制下发;默认 `false` 时该校验不过会返回 `code="26"`。
|
||
- 参数名与下游路径都是 `creat...`(少一个 e),拼错会找不到工具。
|
||
|
||
**关联工具**:`prepareTaskFile`(上游,提供 `fileUuid`)
|
||
|
||
---
|
||
|
||
### 3.8 `queryTestUnitListByProjectName`
|
||
|
||
**摘要**:根据项目名称、五码查询机器列表的数据,按列表分页显示。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-vlab` |
|
||
| Java 方法 | `UnitService.queryTestUnitListByProjectName` |
|
||
| MCP 工具名 | `queryTestUnitListByProjectName` |
|
||
| 下游接口 | `GET {misVlabBaseUrl}/testUnit/qv/mcpvlabqueryTestPcList` |
|
||
| 返回裁剪 | **B 类:取 data(未做字段裁剪)** ⚠️ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `projectName` | String | **是** | — | 项目名称 | `TNB Commercial OS Refresh-X_CS24` |
|
||
| `modelCode` | String | **是** | — | 五码 | `LT4EN` |
|
||
| `ownerCode` | String | **是** | — | 当前用户的 UUID(**MIS 用户 ID**,纯数字) | — |
|
||
| `current` | Long | 否 | `1` | 当前页码 | `1` |
|
||
| `size` | Long | 否 | `10` | 每页条数 | `10` |
|
||
|
||
> **参数名与下游字段名不一致**:工具入参叫 `modelCode`(五码),传给下游时字段名是 **`modelName`**。调用方只需按 `modelCode` 传值。
|
||
|
||
**返回** ✅ / ⚠️
|
||
|
||
| 形态 | 内容 | 触发条件 |
|
||
|---|---|---|
|
||
| **纯文本** ✅ | `登录人信息转换异常` | `ownerCode` 有值但 MIS→MBX 转换失败 |
|
||
| 异常 | `IllegalArgumentException: 项目名称 projectName 不能为空` | `projectName` 为空 |
|
||
| **JSON** ⚠️ | 下游 `data`(含 `records` 时只取 `records`;`data` 为空返回 `[]`) | 正常调用 |
|
||
|
||
**返回 JSON 结构** ⚠️ 透传(下游 `data` 是 MyBatis-Plus 分页对象,MCP 取出 `records`)
|
||
|
||
```jsonc
|
||
[
|
||
{
|
||
"testUnitUuid": "string", // ★ 测试机唯一标识 —— 给 queryTestPcByUuids 用
|
||
"testUnitName": "string", // 机器名称
|
||
"shippingSn": "string", // 出货流水号 / 机器 SSN
|
||
"onlineStatus": 2, // ★ 在线状态:1=离线 2=在线
|
||
"workingStatusKey": 2, // 机器状态:1=闲置中 2=使用中
|
||
"lockStatus": 0, // 锁定状态:0=未锁定 1=已锁定
|
||
"tokenStatus": 0, // 认领状态
|
||
"borrowStatus": 0, // 借用状态
|
||
"isStore": 0, // 是否收藏:0/1
|
||
"projectCode": "string", // 项目编号
|
||
"projectName": "string", // 项目名称
|
||
"projectPhase": "string", // 项目阶段
|
||
"programName": "string", // 项目集名称
|
||
"modelName": "string", // 五码
|
||
"groupName": "string", // 分组名称
|
||
"testUnitGroupUuid": "string", // 分组 uuid
|
||
"testUnitTypeKey": 0, // 测试机类型键 / 物料组
|
||
"matterDescription": "string", // 物料描述
|
||
"fgPn": "string", // SKU
|
||
"skuShortName": "string", // SKU 别名
|
||
"skuExtensionNo": "string", // SKU 扩展序号
|
||
"mbPn": "string", // 主板料号
|
||
"mbSn": "string", // 主板流水号
|
||
"fgSn": "string", // 整机流水号
|
||
"gerberVersion": "string", // 主板 Gerber 版本
|
||
"ipAddress": "string", // IP
|
||
"ipAddressBridge": "string", // 桥接 IP
|
||
"ownerCode": "string", // 机器管理员
|
||
"ownerName": "string", // 管理员名称
|
||
"userCode": 0, // 当前使用人编号
|
||
"userName": "string", // 当前使用人名称
|
||
"groupLeaderName": "string", // Smart FAI 组长姓名
|
||
"groupLeaderCode": "string", // Smart FAI 组长工号
|
||
"testUnitSource": "string", // 数据源:1=手工导入 2=开机注册
|
||
"comments": "string", // 备注
|
||
"gmtCreate": "yyyy-MM-dd HH:mm:ss", // 录入时间
|
||
"mbUuid": "string", // 主板 uuid
|
||
|
||
// 以下字段恒为 null(下游 SQL 未查出)
|
||
"mo": null,
|
||
"vncParam": null,
|
||
"lcfcUuid": null
|
||
}
|
||
]
|
||
```
|
||
|
||
**关键字段速查**
|
||
|
||
| 字段 | 取值 | 说明 |
|
||
|---|---|---|
|
||
| `testUnitUuid` | — | 传给 `queryTestPcByUuids` |
|
||
| `onlineStatus` | `1` 离线 / `2` 在线 | 在线状态 |
|
||
| `workingStatusKey` | `1` 闲置中 / `2` 使用中 | 机器状态 |
|
||
| `lockStatus` | `0` 未锁定 / `1` 已锁定 | 锁定状态 |
|
||
|
||
**注意事项**
|
||
|
||
- 三个入参(`projectName` / `modelCode` / `ownerCode`)在源码中**都是必填**。
|
||
- ⚠️ **`ownerCode` 不能留空**:MCP 允许它为空(不报错),但下游会直接返回
|
||
`未获取到用户信息`(`code="1"`)→ MCP 抛异常。**必须传纯数字的 MIS 用户 ID。**
|
||
- ⚠️ **`modelCode`(五码)实际不生效**:已核实下游该查询语句的 WHERE 子句里
|
||
**没有 `modelName` 过滤条件**,MCP 传过去的五码被**静默忽略**。
|
||
即实际过滤条件只有 `projectName`(+ 用户维度)。
|
||
**prompt 不要声称「按五码精确筛选」**;若确需按五码收窄,应在拿到结果后**在模型侧自行过滤** `modelName` 字段。
|
||
- 与已废弃的 `queryTestUnitList` 区分:**按项目查机器用本工具**(见 §6.3)。
|
||
|
||
**关联工具**:`queryTestPcByUuids`(下游,承接 `testUnitUuid`)、`debuggingProjectQuery`(提供 `modelCode` 五码)
|
||
|
||
---
|
||
|
||
### 3.9 `queryTestPcByUuids`
|
||
|
||
**摘要**:根据测试机 UUID 列表**批量**查询测试机在线状态信息。
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 所属服务 | `mis-mcp-tool-vlab` |
|
||
| Java 方法 | `TestUnitQvService.queryTestPcByUuids` |
|
||
| MCP 工具名 | `queryTestPcByUuids` |
|
||
| 下游接口 | `POST {misVlabBaseUrl}/testUnit/queryTestPcByUuids`,请求体 `{"testUnitUuids": [...]}` |
|
||
| 返回裁剪 | **B 类:取 data(未做字段裁剪)** ⚠️ |
|
||
|
||
**参数表**
|
||
|
||
| 参数名 | 类型 | 必填 | 默认 | 说明 | 示例 |
|
||
|---|---|---|---|---|---|
|
||
| `testUnitUuids` | Array\<String\> | **是** | — | 测试机 UUID **列表**(**批量传入**,不要循环单传) | `["0062c70e645c4d0a824d8b2c3134015d"]` |
|
||
|
||
**返回** ✅ / ⚠️
|
||
|
||
| 形态 | 内容 | 触发条件 |
|
||
|---|---|---|
|
||
| 异常 | `IllegalArgumentException: testUnitUuids 不能为空` | 入参为空列表或 null |
|
||
| **JSON** ⚠️ | 下游 `data` 本身就是一个**数组**(非分页) | 正常调用 |
|
||
|
||
**返回 JSON 结构** ⚠️ 透传
|
||
|
||
> 与 §3.8 不同,本接口的 `data` **直接就是数组**(不是分页对象),无需再取 `records`。
|
||
|
||
```jsonc
|
||
[
|
||
{
|
||
"testUnitUuid": "string", // 机器统一标识码
|
||
"testUnitName": "string", // 机器名称
|
||
"onlineStatusKey": 2, // ★★★ 在线状态:1=离线 2=在线
|
||
"workingStatusKey": 2, // 机器状态:1=空闲 2=使用中
|
||
"ownerCode": 0, // 所有者编号(数字)
|
||
"ownerName": "string", // 所有者名称
|
||
"userCode": 0, // 使用者编号(数字)
|
||
"sortField": null, // 继承自 SortEntity,非查询用途
|
||
"positiveOrReverse": null,
|
||
|
||
// ❌ 陷阱:这个字段名很像在线状态,但本接口恒为 null
|
||
"onlineStatus": null,
|
||
|
||
// 其余约 50 个字段(projectName / fgSn / lockStatus / gmtCreate …)也会出现,但恒为 null
|
||
"projectName": null,
|
||
"fgSn": null,
|
||
"lockStatus": null
|
||
}
|
||
]
|
||
```
|
||
|
||
> ### ⚠️ 最容易踩的坑:`onlineStatus` 是 null,要用 `onlineStatusKey`
|
||
>
|
||
> 下游 `Machines` 类里**同时存在**两个长得像在线状态的字段:
|
||
> - **`onlineStatusKey`** —— ✅ 本接口真正返回的在线状态(1 离线 / 2 在线)
|
||
> - `onlineStatus` —— ❌ 本接口的 SQL **没有查这一列**,恒为 `null`
|
||
>
|
||
> **prompt 里必须写 `onlineStatusKey`**。若写 `onlineStatus`,会拿到 `null` 并被误判成「离线/未知」。
|
||
|
||
**注意事项**
|
||
|
||
- **批量语义**:一次传入多个 UUID,比逐个调用高效——prompt 里应显式要求**合并成一次调用**。
|
||
- UUID 来源:`queryTestUnitListByProjectName` 返回的 `testUnitUuid`。
|
||
- 空数组会**直接抛异常**,不会返回空结果。
|
||
- 返回体很大(每台机器约 50+ 个恒 null 字段),**机器数量多时注意上下文占用**;
|
||
建议 prompt 里只提取 `testUnitUuid` / `testUnitName` / `onlineStatusKey` 三个字段。
|
||
|
||
**关联工具**:`queryTestUnitListByProjectName`(上游,提供 `testUnitUuids`)
|
||
|
||
---
|
||
|
||
## 4. 典型工作流(编排剧本)
|
||
|
||
> 每条链路都给出**步骤 → 工具 → 参数来源 → 产出**,可直接转成 SKILL 的调用顺序。
|
||
|
||
### 4.1 驱动包下发测试任务(最长链路,5 步)
|
||
|
||
| 步骤 | 工具 | 关键参数 | 取值来源 | 产出 |
|
||
|---|---|---|---|---|
|
||
| 1 | `queryProjectNameList` 或 `debuggingProjectQuery` | `projectName` / `creatorCode` | 用户输入 | `projectUuid` |
|
||
| 2 | `queryDriverListNamesByProject` | `projectUuid`(或 `projectGroupUuid`) | 步骤 1 | `driverListVersionUuid`、`driverListName` |
|
||
| 3 | `queryDriverListVersion` | `driverListVersionUuid` | 步骤 2 | `driverPackageVersionList[].packageFileUrl`(**非顶层字段**,见 §3.4) |
|
||
| 4 | `prepareTaskFile` | `fileUrl` = `packageFileUrl` | 步骤 3 | `fileUuid` ⏱ 耗时较长 |
|
||
| 5 | `creatOrSendTask` | `creatorCode`、`requestBodyJson`(含 `fileUuid`) | 步骤 4 + 用户输入 | 任务创建/下发结果 |
|
||
|
||
**决策点**(prompt 里必须交代清楚):
|
||
- 步骤 2 若匹配到**多个** `driverListName` → **列出让用户选**,不要自选。
|
||
- 步骤 4 耗时可能达数分钟 → 应提示用户。
|
||
- 步骤 5 是**写操作**(会真实创建/下发任务)→ 建议**先展示完整 `requestBodyJson` 给用户确认**再执行。
|
||
|
||
### 4.2 Preload 更新链接(单步 + 自纠偏)
|
||
|
||
| 步骤 | 工具 | 参数 | 产出 |
|
||
|---|---|---|---|
|
||
| 1 | `generatePreloadUpdateLink` | `project`(必填,页面下拉精确值)、`osVer`(可选) | `downloadUrl` |
|
||
|
||
**失败分支**:返回 `success: false` 时,用 `availableProjects` / `availableOsVer` 让用户确认后再**重试一次**(见 §3.6)。
|
||
|
||
### 4.3 项目 → 测试机 → 在线状态(3 步)
|
||
|
||
| 步骤 | 工具 | 关键参数 | 产出 |
|
||
|---|---|---|---|
|
||
| 1 | `debuggingProjectQuery` | `projectName` / `modelCode` | 项目信息(含五码 `modelCode`) |
|
||
| 2 | `queryTestUnitListByProjectName` | `projectName`、`modelCode`(五码)、`ownerCode` | 机器列表(含 `testUnitUuid`) |
|
||
| 3 | `queryTestPcByUuids` | `testUnitUuids` = 步骤 2 的 UUID 数组 | 在线状态 |
|
||
|
||
> 步骤 2 的三个参数在源码中**均为必填**(未标 `required = false`)。`ownerCode` 传 MIS 用户 ID。
|
||
|
||
---
|
||
|
||
## 5. 生成 SKILL 与 Prompt 的指引
|
||
|
||
> 本节把上文的结构化信息转成**可直接抄用的模板**。
|
||
|
||
### 5.1 推荐的 SKILL 结构
|
||
|
||
```markdown
|
||
---
|
||
name: se-driver-workflow # 建议按业务域命名,见下方 5.1.1
|
||
description: >
|
||
处理 SE 驱动的查询与测试任务下发。当用户提到「驱动列表」「Driver List」
|
||
「驱动包版本」「下发测试任务」「preload 更新链接」时使用。
|
||
覆盖 9 个 MCP 工具:项目查询、驱动列表查询、驱动包下载、文件准备、任务下发、
|
||
Preload 链接生成、测试机查询。
|
||
---
|
||
|
||
# 工具调用顺序(严格按此顺序,ID 逐跳传递)
|
||
1. queryProjectNameList / debuggingProjectQuery → 拿 projectUuid / 项目信息
|
||
2. queryDriverListNamesByProject → 拿 driverListVersionUuid
|
||
3. queryDriverListVersion → 拿 packageFileUrl
|
||
4. prepareTaskFile → 拿 fileUuid(耗时较长)
|
||
5. creatOrSendTask → 下发任务
|
||
|
||
# 详细参数与返回结构
|
||
见 `references/se工作流mcp工具API文档.md`(按需加载,不要一次性全读)
|
||
```
|
||
|
||
**5.1.1 SKILL 拆分建议**:按**链路**而非按工具拆,推荐 3 个:
|
||
|
||
| SKILL 名(建议) | 覆盖工具 | 触发场景 |
|
||
|---|---|---|
|
||
| `se-driver-workflow` | ①~⑤ + ⑦(`debuggingProjectQuery`/`queryProjectNameList`/`queryDriverListNamesByProject`/`queryDriverListVersion`/`prepareTaskFile`/`creatOrSendTask`) | 驱动查询与任务下发 |
|
||
| `se-preload-link` | ⑥ `generatePreloadUpdateLink` | 生成 Preload 更新链接 |
|
||
| `se-test-unit-query` | ⑧⑨ `queryTestUnitListByProjectName`/`queryTestPcByUuids` | 测试机列表与在线状态 |
|
||
|
||
### 5.2 工具 → 自然语言触发词
|
||
|
||
写 SKILL 的 `description` 时直接取用,能显著提高工具被正确选中的概率:
|
||
|
||
| 工具 | 用户可能说的话 |
|
||
|---|---|
|
||
| `debuggingProjectQuery` | 「查一下 XX 项目」「XX 项目的五码/四码/负责人」「项目别名是 XX 的项目」 |
|
||
| `queryProjectNameList` | 「有哪些项目」「我能看到哪些项目」「项目名和 projectUuid」 |
|
||
| `queryDriverListNamesByProject` | 「XX 项目下的 Driver List」「这个项目组有哪些驱动列表」「驱动列表版本」 |
|
||
| `queryDriverListVersion` | 「这个驱动列表的包在哪下载」「驱动包的下载地址」 |
|
||
| `prepareTaskFile` | 「准备一下这个文件」「把驱动包传上去」 |
|
||
| `generatePreloadUpdateLink` | 「生成 preload 更新链接」「Preload 更新包的下载地址」 |
|
||
| `creatOrSendTask` | 「下发测试任务」「创建测试任务」「跑一下这个驱动」 |
|
||
| `queryTestUnitListByProjectName` | 「XX 项目有哪些机器」「五码 XX 的测试机」 |
|
||
| `queryTestPcByUuids` | 「这几台机器在线吗」「机器在线状态」 |
|
||
|
||
### 5.3 编排 Prompt 模板
|
||
|
||
**模板 A:驱动包下发测试任务(最完整链路)**
|
||
|
||
```text
|
||
目标:把「{项目名}」项目下「{驱动列表名匹配词}」的驱动包,下发测试任务。
|
||
|
||
请严格按顺序执行,每步只用上一步的返回结果,不要跳步或猜 ID:
|
||
|
||
1. 调用 queryDriverListNamesByProject,参数 projectUuid = {projectUuid}(若只知道项目名,
|
||
先用 queryProjectNameList 拿 projectUuid)。
|
||
→ 从返回数组中选出名称匹配「{驱动列表名匹配词}」的那条,记下它的 driverListVersionUuid。
|
||
→ 如果匹配到多条,先列出来问我要哪一个,不要自己选。
|
||
|
||
2. 调用 queryDriverListVersion,参数 driverListVersionUuid = 上一步的值。
|
||
→ 从返回中取出 packageFileUrl。
|
||
|
||
3. 调用 prepareTaskFile,参数 fileUrl = 上一步的 packageFileUrl。
|
||
→ 这一步会下载并重新上传驱动包,可能耗时数分钟,请告知我在处理中。
|
||
→ 取出返回的 fileUuid。
|
||
|
||
4. 调用 creatOrSendTask:
|
||
- creatorCode = {当前登录人 MIS 用户 ID}
|
||
- requestBodyJson = 见下方模板,把 fileUuid 填入
|
||
model.children[].documentCopyDTOList[].fileUuid
|
||
- 执行前把完整 requestBodyJson 展示给我确认。
|
||
|
||
【重要】任何一步失败就停下来报告原因,不要用猜测的参数重试。
|
||
```
|
||
|
||
**模板 B:Preload 更新链接**
|
||
|
||
```text
|
||
帮我生成「{项目名}」的 preload 更新链接(OS VER 用 {9.Win11 / 不指定})。
|
||
|
||
调用 generatePreloadUpdateLink,参数 project = "{项目名}",osVer = "{osVer}"。
|
||
|
||
判断结果:
|
||
- 返回里有 downloadUrl → 成功,把链接给我。
|
||
- 返回里有 "success": false →
|
||
· 若带 availableProjects,从里面挑最接近的候选,把候选列表给我确认后再重试一次;
|
||
· 若带 availableOsVer,同理。
|
||
· 不要用同一个错值反复重试。
|
||
```
|
||
|
||
**模板 C:测试机在线状态**
|
||
|
||
```text
|
||
1. 调用 queryTestUnitListByProjectName:
|
||
projectName = "{项目名}",modelCode = "{五码}",ownerCode = "{当前登录人 MIS 用户 ID}"
|
||
→ 从返回里取出各机器的 testUnitUuid。
|
||
2. 调用 queryTestPcByUuids,testUnitUuids = 上一步的 UUID 数组(批量传入,不要一次一个)。
|
||
→ 汇总每台机器的在线状态给我。
|
||
```
|
||
|
||
### 5.4 反模式(写 prompt 时明确禁止)
|
||
|
||
| ❌ 不要这样写 | ✅ 应该这样写 | 原因 |
|
||
|---|---|---|
|
||
| 让模型「猜」或「编」`projectUuid` / `driverListVersionUuid` 等 UUID | 强制从上一个工具的返回中取值 | UUID 无法凭空生成,编造必然查不到 |
|
||
| 用 `queryProjectNameList` 取超过 100 条项目 | 用 `debuggingProjectQuery` 检索项目 | 前者单页最多 100 条且无分页参数(§3.2) |
|
||
| 把 `packageFileUrl` 直接填进 `creatOrSendTask` | 先过 `prepareTaskFile` 换成 `fileUuid` | 任务下发只认 `fileUuid`(§3.5) |
|
||
| 写「取返回的 `packageFileUrl`」 | 写「取 `driverPackageVersionList[].packageFileUrl`」 | 它不是顶层字段(§3.4) |
|
||
| 用 `onlineStatus` 判断测试机在线状态 | 用 `onlineStatusKey` | `onlineStatus` 恒为 null(§3.9) |
|
||
| 声称 `queryTestUnitListByProjectName` 按五码筛选 | 说明只按项目名筛选,五码需自行过滤 | 下游忽略 `modelName`(§3.8) |
|
||
| 让模型自行拼 `other.type` 等必填项 | 在 prompt 里给出完整请求体模板 | 漏传必填项会 500(§3.7) |
|
||
| 用 `success === true` 判断 Preload 成功 | 判断 `downloadUrl` 是否存在 / `success === false` | 成功返回里没有 `success` 字段(§3.6) |
|
||
| 对 `generatePreloadUpdateLink` 传模糊项目名 | 传 Preload 页面下拉里的**精确**值 | 该工具是精确匹配,不匹配会返回失败对象(§3.6) |
|
||
| 假设返回一定是 JSON | 先看首字符:`请`/`登` 开头是纯文本提示 | 两个工具会返回**纯文本**(§2.4) |
|
||
| 一次性读取整份 API 文档 | 按需加载对应工具小节 | 文档较长,全量加载浪费上下文 |
|
||
|
||
---
|
||
|
||
## 6. 附录
|
||
|
||
### 6.1 MCP 接入信息
|
||
|
||
| 服务 | 端口 | `protocol` | 配置来源 | 工具数(本工作流涉及) |
|
||
|---|---|---|---|---|
|
||
| `mis-mcp-tool-debugging` | 18780 | `STATELESS` | 仓库 `application.yml` | 1 |
|
||
| `mis-mcp-tool-driver` | 18767 | `STATELESS` | 仓库 `application.yml` | 4 |
|
||
| `mis-mcp-tool-vlab` | 18769 | `STREAMABLE`(`mcp-endpoint: /mcp`) | **Nacos**(仓库内无此配置) | 4 |
|
||
|
||
> ⚠️ **鉴权由 MCP 客户端透传**:调用方(LLM 侧)**不需要**把 token 作为工具参数传入。
|
||
> 凭证走 MCP 请求头 `auth` / `clientid`,由服务端 `MisAuthForestInterceptor` 注入下游。
|
||
> 排查「工具连不上」时,别只看仓库代码——`vlab` 的协议配置**不在代码里**,在 Nacos。
|
||
|
||
### 6.2 下游接口与白名单对照
|
||
|
||
下列路径**必须**存在于对应服务的 Nacos `security.oauth2.client.ignore-urls`(MBX 侧)或网关 `ignore.whites`(MIS 侧),
|
||
否则工具上线后必然 **401 / 403**。
|
||
|
||
| # | 工具 | 下游路径 | 下游服务 | 白名单位置 | 快照核对 |
|
||
|---|---|---|---|---|---|
|
||
| 1 | `debuggingProjectQuery` | `/debugging/project` | `mis-debugging` | **MIS 网关** `mis-gateway.yml` → `ignore.whites` | ✅ 已存在 |
|
||
| 2 | `queryProjectNameList` | `/project/mcpvlabpage` | `mbv-service-business` | `mbv-service-business-dev.yml` | ✅ 已存在 |
|
||
| 3 | `queryDriverListNamesByProject` | `/driverlist/mcpvlabpage` | `mbx-service-driver` | `mbx-service-driver-dev.yml` | ✅ 已存在 |
|
||
| 4 | `queryDriverListVersion` | `/listversion/mcpvlab/*` | `mbx-service-driver` | 同上 | ✅ 已存在 |
|
||
| 5 | `prepareTaskFile` | `/mbvClient/downloadFile`、`/uploadFileSpecial` | `mbv-service-minio` | `mbv-service-minio-dev.yml` | ✅ 已存在 |
|
||
| 6 | `generatePreloadUpdateLink` | `/preload/preloadNameList`、`/preload/init`、`/preload/select`、`/preload/getOtherList`、`/preload/preloadVersion`、`/aod` | `mbv-service-preload` | `mbv-service-preload-dev.yml` | ✅ 已存在(6 条齐全) |
|
||
| 7 | `creatOrSendTask` | `/mcpvlabcreatOrSendTask` | `mbv-service-dispatcher` | `mbv-service-dispatcher-dev.yml` | ✅ 已存在 |
|
||
| 8 | `queryTestUnitListByProjectName` | `/testUnit/qv/mcpvlabqueryTestPcList` | `mbv-service-business` | `mbv-service-business-dev.yml` | ✅ 已存在 |
|
||
| 9 | `queryTestPcByUuids` | `/testUnit/queryTestPcByUuids` | `mbv-service-business` | 同上 | ✅ 已存在 |
|
||
|
||
> **路径参数写 `*` 不写 `{}`**(如 `/listversion/mcpvlab/*`)。
|
||
> **本节结论基于本地 Nacos 快照**(`docs/nacos/`),快照是导出副本、**随时可能过期**,
|
||
> 上线前请以**远程 Nacos 实际值**为准。快照文件名是 `*-dev.yml` 但装的是 **qas** 环境的值。
|
||
|
||
### 6.3 易混淆 / 已废弃工具
|
||
|
||
| 工具 | 状态 | 说明 |
|
||
|---|---|---|
|
||
| `queryTestUnitList` | ⚠️ **已废弃**(源码 javadoc 明确标注「废弃」,但 `@Tool` 注解**未摘除**,仍会暴露给模型) | 参数多且语义宽泛,**不要**在新的 SKILL / prompt 里使用;按项目查机器请用 `queryTestUnitListByProjectName`,按 UUID 批量查用 `queryTestPcByUuids` |
|
||
| `debuggingProjectQuery` | 命名特殊 | 源码用 `@Tool(name = ...)` 显式指定,**Java 方法名是 `queryProjectList`**,两者不同名;调用时用 `debuggingProjectQuery` |
|
||
| `creatOrSendTask` | 拼写特殊 | 是 `creat` 不是 `create`,**必须原样使用** |
|
||
| `queryProjectNameList` vs `debuggingProjectQuery` | 数据源不同 | 前者查 MBX 侧,后者查 SE 同步侧;`name` 值对应(§1.3) |
|
||
|
||
### 6.4 高风险陷阱汇总(写 prompt 前必读)
|
||
|
||
> 以下每一条都来自**源码逐行核对**,都是「照直觉写就会错」的地方。
|
||
|
||
| # | 陷阱 | 正确做法 | 出处 |
|
||
|---|---|---|---|
|
||
| 1 | 以为 `queryDriverListVersion` 顶层有 `packageFileUrl` | 取 **`driverPackageVersionList[].packageFileUrl`**(或 `solidifiedDriverPackageVersionList[]`) | §3.4 |
|
||
| 2 | 用 `onlineStatus` 判断测试机在线状态 | 用 **`onlineStatusKey`**(`onlineStatus` 恒为 null) | §3.9 |
|
||
| 3 | 以为 `queryTestUnitListByProjectName` 会按五码筛选 | **`modelCode` 被下游静默忽略**;只按 `projectName` 过滤,需要五码请自行在结果里过滤 `modelName` | §3.8 |
|
||
| 4 | 给 `queryTestUnitListByProjectName` 传空 `ownerCode` | **必须传纯数字 MIS 用户 ID**,否则下游报「未获取到用户信息」 | §3.8 |
|
||
| 5 | 用 `success === true` 判断 Preload 成功 | 判断 **`downloadUrl` 是否存在** / `success === false`(成功返回里**没有** `success` 字段) | §3.6 |
|
||
| 6 | `creatOrSendTask` 漏传 `other.type` | **必须传**(`1` 只保存 / `2` 创建并下发),否则下游 NPE 500 | §3.7 |
|
||
| 7 | 把 `creatOrSendTask` 的空请求体当成失败 | 该场景下游返回 **`code="0"` + `msg="参数异常请检查"`**,是**假成功**,需结合 `msg` 判断 | §3.7 |
|
||
| 8 | 用 `queryProjectNameList` 拉取超过 100 条项目 | 它**单页最多 100 条且无分页**;项目检索用 `debuggingProjectQuery` | §3.2 |
|
||
| 9 | 假设返回值一定是 JSON | 两个工具会返回**纯文本**(`请输入当前登录人信息` / `登录人信息转换异常`) | §2.4 |
|
||
| 10 | 把 `packageFileUrl` 直接填进 `creatOrSendTask` | 必须先过 `prepareTaskFile` 换成 `fileUuid` | §3.5 |
|
||
| 11 | 把 `creatOrSendTask` 当只读查询 | 它是**写操作**,prompt 应先展示请求体让用户确认 | §3.7 |
|
||
|
||
### 6.5 残留不确定项
|
||
|
||
> 以下是本次核对**未能完全确证**的部分,不要在这些细节上做硬编码假设。
|
||
|
||
| # | 事项 | 状态 | 建议 |
|
||
|---|---|---|---|
|
||
| 1 | `debuggingProjectQuery` 返回的 `projectUuid` 是 number 还是 string | 下游类型为 `Long`,且全局注册了 `BigNumberSerializer`(值超 2^53-1 时输出**字符串**)。源码示例值 `2049298006288687105` 是 19 位雪花 ID → **实际应为字符串**;小 ID 历史数据可能为数字 | 统一**按字符串处理**(比较前归一) |
|
||
| 2 | MyBatis-Plus `Page` 序列化出的完整字段集 | 仅实锤 `records` / `total`(前端代码印证);`size`/`current`/`pages`/`orders` 等为框架常规字段,**未从 jar 逐项确认** | 只依赖 `records` / `total` |
|
||
| 3 | 下游抛 `RuntimeException`(如「生成任务编号失败」)经全局异常处理后的 JSON 结构 | **未确认** | 按 MCP 抛异常处理即可 |
|
||
| 4 | `queryTestUnitListByProjectName` 的 `machineListType` 分支 | MCP 不传该参数,走默认 SQL;另两条分支 SQL 未逐条核对 | 无需关注 |
|
||
| 5 | `debuggingProjectQuery` 的 `ppmQuery` 字段 | **已核实**:恒为 `null`(只作查询条件,不进结果映射) | 不要从返回值读它 |
|
||
| 6 | 值为 `null` 的字段是否会**整键消失** | **已核对**:下游无 `spring.jackson.*` 配置,MIS 共享配置 `application-common.yml` 未设 `default-property-inclusion` → **null 字段会原样输出** | 字段存在,判空即可 |
|
||
|
||
> **另需注意**:`mbv-service-test-unit` 模块里存在一份**同名**的 `/testUnit/queryTestPcByUuids` 实现,
|
||
> 但网关 `/business` 前缀落到的是 **`mbv-service-business`**,以本文档结论为准。
|
||
|
||
---
|
||
|
||
**文档结束** · 生成于 2026-09-22 · 基线 `mis-mcp-server@dev`
|
||
|