63 KiB
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.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*)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 字段)/ ⚠️(透传,未裁剪)
{
"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(该字段只用于查询条件,不参与返回取值) |
返回示例(截取)
{
"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 结构 ✅
[
{
"name": "string", // 项目名称:实际取自下游 portfolioProjectName
"projectUuid": "string" // 项目唯一标识,可直接喂给 queryDriverListNamesByProject
}
]
已核实:下游
ProjectPageInfo没有name字段,所以源码里「portfolioProjectName为空则回退name」的兜底永远不会触发。 实际取值路径只有portfolioProjectName一条;该字段为空的行会被整条丢弃(不返回)。 因此 prompt 中应把name理解为「下游的项目名称(portfolioProjectName)」,不要去找别的名字来源。
返回示例
[
{ "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 结构 ✅
[
{
"driverListVersionUuid": "string", // 驱动列表【版本】唯一标识 —— 给 queryDriverListVersion 用
"driverListName": "string" // 驱动列表名称:实际取自下游 driverListName
}
]
已核实:源码写的是「优先取
nameRemark,为空则回退driverListName」,但下游分页接口的 SQL 根本没查name_remark列, 因此nameRemark在这个链路上恒为 null,回退分支必然生效 —— 返回值里的driverListName实际就是下游的driverListName。 (nameRemark只在单查版本详情、即 §3.4 的返回里才有值。)对调用方而言:只会拿到一个非空的driverListName,直接用它做筛选即可。
返回示例
[
{ "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:
{
"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)② 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 结构 ✅
{
"fileUuid": "string", // ★ 任务下发要用的文件唯一标识
"fileUrl": "string", // 上传后文件服务返回的访问地址
"fileName": "string", // 文件名(取自 objectName 最后一段)
"fileExtensionKey": 0 // 文件扩展名标识;类型不固定(可能是数字/字符串/null),按原样传递即可
}
返回示例
{
"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 必须能区分
① 成功
{
"downloadUrl": "string", // ★ 生成的 preload 更新下载链接
"project": "string", // 实际匹配到的项目名(回显下游下拉里的原值)
"osVer": "string", // 实际匹配到的 OS 版本展示名
"os": "string", // OS 目录名(directory)
"preloadVersion": "string", // 实际使用的 Preload VER
"locationName": "string" // 实际使用的 Location
}
② 失败(三种触发场景,msg 不同,附加字段也不同)
{
"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 |
返回示例
{
"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。
顶层结构
{
"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,可递归)
{
"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)
{
"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)
[
{
"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。
[
{
"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 没有查这一列,恒为nullprompt 里必须写
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 结构
---
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:驱动包下发测试任务(最完整链路)
目标:把「{项目名}」项目下「{驱动列表名匹配词}」的驱动包,下发测试任务。
请严格按顺序执行,每步只用上一步的返回结果,不要跳步或猜 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 更新链接
帮我生成「{项目名}」的 preload 更新链接(OS VER 用 {9.Win11 / 不指定})。
调用 generatePreloadUpdateLink,参数 project = "{项目名}",osVer = "{osVer}"。
判断结果:
- 返回里有 downloadUrl → 成功,把链接给我。
- 返回里有 "success": false →
· 若带 availableProjects,从里面挑最接近的候选,把候选列表给我确认后再重试一次;
· 若带 availableOsVer,同理。
· 不要用同一个错值反复重试。
模板 C:测试机在线状态
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