feat(mcp): 新增运行期失败诊断探针

- 解析 gonavi.log 中 MCP 启动、发现和调用失败信号

- 结合已保存 MCP 服务与工具发现状态输出原因和 nextActions

- 补充系统引导、工具目录、状态标签和回归测试
This commit is contained in:
Syngnat
2026-06-11 22:01:26 +08:00
parent a9eed57cf7
commit 6f4e80c749
12 changed files with 551 additions and 5 deletions

View File

@@ -48,6 +48,31 @@ export const BUILTIN_AI_INSPECTION_MCP_TOOL_INFO: AIBuiltinToolInfo[] = [
},
},
},
{
name: "inspect_mcp_runtime_failures",
icon: "🧯",
desc: "诊断 MCP 启动与调用失败",
detail:
"读取 gonavi.log 中最近的 MCP 启动、工具发现、工具调用和 HTTP MCP 子进程异常,结合当前已保存 MCP 服务与已发现工具,返回失败类型、疑似原因、涉及服务和下一步修复动作。适合用户反馈“新增 MCP 测试失败”“工具发现 0 个”“MCP 工具调用失败”“HTTP MCP 启动失败”时先调用。",
params: "serverName?, keyword?, lineLimit?(默认 160), includeLines?(默认 false)",
tool: {
type: "function",
function: {
name: "inspect_mcp_runtime_failures",
description:
"读取 GoNavi 应用日志中的 MCP 运行期失败信号,归类 MCP 服务启动失败、工具发现失败、工具调用失败和 HTTP MCP 子进程异常,并结合当前 MCP 服务配置与已发现工具数量返回疑似原因和 nextActions。适用于用户提到新增 MCP 测试失败、工具发现 0 个、MCP 工具调用失败、stdio 断开、命令找不到、Docker MCP 退出或 HTTP MCP 启动失败时,先读取该工具,不要只凭弹窗文案猜测。",
parameters: {
type: "object",
properties: {
serverName: { type: "string", description: "可选,只看某个 MCP 服务名或日志中的 server= 名称,例如 GitHub、Browser、DockerFetch" },
keyword: { type: "string", description: "可选,在 MCP 相关日志里继续按关键词过滤,例如 timeout、stdio、permission、401、docker" },
lineLimit: { type: "number", description: "可选,最多读取多少行日志尾部,默认 160最大 200" },
includeLines: { type: "boolean", description: "可选,是否附带脱敏后的 MCP 日志原文行,默认 false需要引用原文时再开启" },
},
},
},
},
},
{
name: "inspect_mcp_authoring_guide",
icon: "🧭",

View File

@@ -86,8 +86,8 @@ export const BUILTIN_TOOL_FLOWS: AIBuiltinToolFlow[] = [
},
{
title: '排查 MCP 接入状态',
steps: 'inspect_mcp_setup -> inspect_ai_runtime',
description: '适合先确认当前配置了哪些 MCP 服务、哪些已启用、外部客户端有没有写入当前 GoNavi 路径,再结合运行时工具列表判断为什么某个工具没暴露出来。',
steps: 'inspect_mcp_setup -> inspect_mcp_runtime_failures -> inspect_ai_runtime',
description: '适合先确认当前配置了哪些 MCP 服务、哪些已启用、外部客户端有没有写入当前 GoNavi 路径,再结合 MCP 运行期失败日志判断为什么某个工具没暴露出来。',
},
{
title: '远程 Agent 接入 GoNavi MCP',
@@ -101,8 +101,8 @@ export const BUILTIN_TOOL_FLOWS: AIBuiltinToolFlow[] = [
},
{
title: '排查 Docker MCP 启动',
steps: 'inspect_mcp_docker_setup -> inspect_mcp_draft -> inspect_mcp_setup',
description: '适合用户按 Docker README 新增 MCP 后发现 0 个工具、容器一启动就退出,或不确定 docker run 参数是否拆对时,先检查 run、-i、镜像名和超时设置。',
steps: 'inspect_mcp_runtime_failures -> inspect_mcp_docker_setup -> inspect_mcp_draft',
description: '适合用户按 Docker README 新增 MCP 后发现 0 个工具、容器一启动就退出,或不确定 docker run 参数是否拆对时,先看运行期失败原因,再检查 run、-i、镜像名和超时设置。',
},
{
title: '查看 MCP 工具参数',

View File

@@ -47,6 +47,14 @@ describe('aiToolRegistry', () => {
expect(info?.tool.function.parameters?.properties?.exposeStrategy?.enum).toContain('cloudflare_tunnel');
});
it('registers the mcp-runtime-failure inspector as a builtin tool', () => {
const info = BUILTIN_AI_TOOL_INFO.find((item) => item.name === 'inspect_mcp_runtime_failures');
expect(info).toBeTruthy();
expect(info?.desc).toContain('启动与调用失败');
expect(info?.tool.function.description).toContain('工具发现失败');
expect(info?.tool.function.parameters?.properties?.serverName?.description).toContain('MCP 服务名');
});
it('registers the mcp-authoring-guide inspector as a builtin tool', () => {
const info = BUILTIN_AI_TOOL_INFO.find((item) => item.name === 'inspect_mcp_authoring_guide');
expect(info).toBeTruthy();
@@ -256,6 +264,7 @@ describe('aiToolRegistry', () => {
expect(tools.some((item) => item.function.name === 'inspect_ai_tool_catalog')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_setup')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_remote_access')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_runtime_failures')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_authoring_guide')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_draft')).toBe(true);
expect(tools.some((item) => item.function.name === 'inspect_mcp_tool_schema')).toBe(true);