尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于MCP Server构建AI可查询的错误知识库:从协议到实践

基于MCP Server构建AI可查询的错误知识库:从协议到实践 把一段崩溃日志直接扔给大模型它往往会回你一句“这可能是网络问题”——这个场景很多开发者已经熟悉到麻木。原因倒也不难理解大模型不是一个精确的检索系统它对具体异常的理解来自训练数据里的概率分布而不是你当前项目的真实上下文。它更擅长告诉你“大概可以往哪个方向排查”而不是告诉你“这个错误码在你的技术栈里到底意味着什么”。所以当看到“An MCP server that knows what that error message means”这个项目时我认为值得关注的不是“又一个查错误码的小工具”而是它背后代表的一种范式转变把错误排查知识变成 AI 可以直接调用的工具能力而不是靠提示词硬套。这篇文章我会拆开讲清楚一件事为什么“错误信息理解”特别适合做成 MCP Server以及如果你也打算实现一个从协议理解、环境准备、核心代码、规则库设计、客户端接入到效果验证的完整路径是什么。读完你不仅能看懂这类项目大概是怎么做的还能照着思路搭出一个属于你自己团队、甚至属于你自己的错误知识库版本。1. 这篇文章真正要解决的问题先说说大多数开发者每天都在经历的事情。你在终端里启动服务报错信息长这样Error: EACCES: permission denied, open /var/log/your-app/app.log你大概率知道这是权限问题但如果是更晦涩的ORA-28547: connection to server failed, probable Oracle Net admin error或者failed to start login server: 以一种访问权限不允许的方式做了一个访问套接字尝试这时候你通常会打开搜索引擎或者把错误信息粘贴给 AI。但实际体验往往是错误信息本身就不是给人看的。很多报错来自底层框架它只告诉你有异常不告诉你业务场景。搜索引擎命中率不稳定。全局唯一、冷门的错误码搜索出来的可能只有一条 Stack Overflow 帖子而且不一定适配你的版本。大模型只会“一本正经地胡说八道”。你贴一段 token exchange failed 的日志它可能给你分析十分钟网络代理配置最后发现错误原因是目标环境不支持该地区访问。这第三个痛点恰恰是 MCP Server 最能改变的地方。直接问大模型本质上是让模型“凭空推理”。而通过 MCP Server 查询本质上是让模型“先查表再回答”。推理能力负责把查询结果组织成自然语言检索能力负责给出准确答案。所以这篇文章的核心判断是错误信息解读这种任务真正可靠的做法不是让 AI 猜而是给 AI 配一个可查询、可更新、可积累的错误知识库。MCP Server 就是这个知识库和 AI 客户端之间的“标准插头”。2. MCP 协议基础模型上下文协议到底在做什么MCP 的全称是 Model Context Protocol模型上下文协议。它由 Anthropic 在 2024 年底开源目的是解决一个很实际的问题大模型应用不能只靠训练数据它需要访问外部数据源和工具但每个客户端都自己开发一套工具接入方式成本和混乱程度都太高。把 MCP 类比成 USB 接口更容易理解。如果没有 USB你每买一个外设都要给电脑焊一根专用线缆。MCP 做的事情就是统一了 AI 客户端和外部工具之间的接口标准。一个完整的 MCP 架构包含三层MCP 客户端宿主程序 | | MCP 协议stdio / HTTPSSE | MCP Server | | API / 文件 / 数据库 / 内部服务 | 错误知识库、日志系统、监控平台、代码仓库...所谓“宿主程序”Host就是 Claude Desktop、Cursor、VS Code、Dify 这类支持 MCP 的应用。它负责接收用户的自然语言决定是否调用某个工具并把工具返回的结果组织成最终回答。MCP Server 可以暴露三类能力能力类型作用举例Tool工具让模型执行外部操作查询错误码、查询数据库、调用搜索引擎Resource资源让模型读取结构化数据读取配置文件、读取项目文档Prompt提示词给模型提供可复用的模板代码评审模板、日志分析模板对于一个“懂得错误信息含义”的 MCP Server核心能力就是 Tool提供一个lookup_error工具接受错误码或错误关键词返回该错误的技术栈归属、可能原因和解决方案。这里还有一个容易被忽略的设计点MCP 支持多种传输方式。本地开发常用 stdio也就是通过标准输入输出通信远程服务可以用 HTTPSSE 或 Streamable HTTP。这意味着你可以把错误知识库部署成公司内部服务每个开发者的 AI 客户端都可以连上来而不是每个人各自维护一份错误文档。3. 整体架构设计从“让 AI 猜”到“让 AI 查”理解了 MCP 协议之后我们再来看这类项目的整体架构。一个“错误信息查询 MCP Server”从职责上可以拆成三层第一层MCP 协议层。这一层负责接收 AI 客户端的请求校验参数返回结构化结果。开发者不需要每次都自己实现协议细节直接使用官方 SDK 即可。第二层错误解析层。这一层是核心逻辑所在。它接收一段错误消息提取错误码或关键词再结合技术栈信息匹配知识库中的规则。第三层知识库层。这一层是数据来源。起步阶段可以是一个 JSON 文件以后可以升级成 SQLite、MySQL甚至是搜索引擎前的向量数据库。这三层之间的关系可以用下面这段文本流程描述用户粘贴错误日志 ↓ AI 客户端识别出“这是一个错误查询请求” ↓ 调用 lookup_error 工具传入错误码/关键词 ↓ MCP Server 解析参数匹配本地知识库 ↓ 返回结构化结果错误含义、原因分析、解决步骤 ↓ AI 结合用户的上下文生成可读的回答这里有一个关键点AI 客户端负责判断“什么时候该查”MCP Server 负责给出“准确的答案”。用户不需要记住错误知识库里有哪几条规则只需要把报错贴给 AIAI 会根据工具描述自动决定是否调用。4. 环境准备与项目初始化下面进入实操环节。我们以 TypeScript 为例从零搭一个最简可用的 MCP Server。如果你更熟悉 Python也可以参考官方 Python SDK核心思路完全一致。首先确认本机环境Node.js 16 或更高版本建议使用 LTS 版本具体版本以你实际安装为准。npm 或 pnpm、yarn 任一包管理器。一个趁手的编辑器VS Code 即可。项目目录和依赖按下面步骤创建。mkdir error-helper-mcp cd error-helper-mcp npm init -y npm install modelcontextprotocol/sdk zod npm install -D typescript types/node tsx这里解释一下依赖modelcontextprotocol/sdk是 MCP 官方 TypeScript SDK。zod用于声明工具的输入参数 schemaMCP 客户端会根据这个 schema 决定如何传参数。typescript和tsx用于编译和本地调试运行。然后初始化 TypeScript 配置npx tsc --init最终的目录结构建议如下error-helper-mcp/ ├── src/ │ ├── index.ts # MCP Server 入口 │ ├── errors.ts # 错误查询逻辑 │ └── knowledge-base.ts # 错误知识库数据 ├── package.json └── tsconfig.json这样设计的好处是入口文件只负责注册工具查询逻辑放独立模块知识库数据单独维护。后续如果要从文件切换成数据库只需要改 knowledge-base 这一层MCP 工具注册部分完全不用动。5. 核心代码实现最简可用的错误查询 MCP Server这一节我们写三个文件知识库数据、查询逻辑、Server 入口。5.1 定义错误知识库先定义一个知识库数据结构。为了演示方便这里直接放在 TypeScript 文件里实际项目可以抽成 JSON 或数据库。// 文件路径src/knowledge-base.ts export interface ErrorEntry { /** 错误码尽量保持全局唯一 */ code: string; /** 技术栈标签例如 nodejs、mysql、oracle */ stack: string[]; /** 错误关键词用于模糊匹配 */ keywords: string[]; /** 错误含义 */ description: string; /** 可能原因列表 */ causes: string[]; /** 解决步骤 */ solutions: string[]; /** 参考文档链接 */ references?: string[]; } export const errorKnowledgeBase: ErrorEntry[] [ { code: EACCES, stack: [nodejs, linux], keywords: [permission denied, access denied], description: 当前用户没有足够的权限来访问指定文件或目录。, causes: [ 运行 Node.js 进程的用户对文件没有读写权限, 文件或目录所有者与当前用户不一致, ], solutions: [ 检查文件权限使用 ls -l 查看所有者, 使用 sudo 运行命令但要确认命令来源可信, 为应用单独创建服务用户并给该用户授权, ], references: [https://nodejs.org/docs/], }, { code: ORA-28547, stack: [oracle, database], keywords: [oracle net admin error, connection to server failed], description: Oracle 客户端与服务器之间的网络连接失败通常是 Oracle Net 组件配置或版本不匹配导致。, causes: [ sqlnet.ora 或 tnsnames.ora 配置错误, Oracle 客户端版本与数据库服务器版本不兼容, ], solutions: [ 检查 sqlnet.ora 中的连接参数, 确认客户端和服务器端 Oracle 版本兼容性, 查看监听服务是否启动, ], }, { code: TOKEN_EXCHANGE_FAILED, stack: [auth, api], keywords: [token exchange failed, token endpoint], description: 令牌交换失败通常是 OAuth/OIDC 流程中授权码或客户端凭证无效。, causes: [ 授权码已过期或已被使用, 客户端密钥配置错误, 回调地址与注册的不一致, 服务端对请求来源区域有限制, ], solutions: [ 重新发起授权流程获取新的授权码, 检查客户端配置中的 client_secret, 确认回调地址精确匹配, 查看服务端是否有区域限制策略, ], }, ];从知识库结构可以看出每一种错误都包含两层信息一是机器可匹配的字段错误码、关键词、技术栈二是 AI 可理解的字段含义、原因、解决方案。MCP Server 的查询逻辑本质上就是机器匹配和语义理解的结合。5.2 实现查询逻辑接下来写查询函数。这里采用一个比较务实的策略先按错误码精确匹配再按关键词模糊匹配最后用技术栈过滤。// 文件路径src/errors.ts import { errorKnowledgeBase, ErrorEntry } from ./knowledge-base.js; export interface LookupParams { /** 错误码或错误消息片段 */ query: string; /** 可选的技术栈标签 */ stack?: string; } export function lookupError(params: LookupParams): ErrorEntry[] { const query params.query.trim().toLowerCase(); const stack params.stack?.trim().toLowerCase(); if (!query) { return []; } // 第一次匹配错误码精确匹配 const exactMatches errorKnowledgeBase.filter((entry) entry.code.toLowerCase() query ); // 第二次匹配错误码包含匹配 const codeMatches exactMatches.length 0 ? errorKnowledgeBase.filter((entry) entry.code.toLowerCase().includes(query) ) : []; // 第三次匹配关键词匹配 const keywordMatches exactMatches.length 0 codeMatches.length 0 ? errorKnowledgeBase.filter((entry) entry.keywords.some((keyword) query.includes(keyword.toLowerCase())) ) : []; // 合并结果并去重 const combined [...exactMatches, ...codeMatches, ...keywordMatches]; const deduplicated Array.from( new Map(combined.map((item) [item.code, item])).values() ); // 如果指定了技术栈进一步过滤并优先返回 if (stack) { const stackFiltered deduplicated.filter((entry) entry.stack.some((s) s.toLowerCase().includes(stack)) ); if (stackFiltered.length 0) { return stackFiltered; } } return deduplicated; }这段逻辑并不复杂但有一个设计值得注意“匹配失败”本身就是重要信息。当知识库里没有命中任何规则时MCP Server 返回空数组AI 客户端就能明确告诉用户“这个错误没有收录建议人工排查后再沉淀进知识库”。而不是让大模型硬编一个看起来合理的答案。5.3 注册 MCP 工具最后是 MCP Server 入口。这里使用官方 SDK 中比较通用的 API因为 SDK 版本仍在迭代具体方法名以你安装的版本为准但整体结构是不变的。// 文件路径src/index.ts import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; import { lookupError } from ./errors.js; const server new McpServer({ name: error-helper, version: 0.1.0, }); server.tool( lookup_error, 根据错误码或错误消息片段查询错误含义、原因和解决方案, { query: z.string().describe(错误码或错误消息例如 EACCES 或 ORA-28547), stack: z .string() .optional() .describe(可选的过滤条件例如 nodejs、oracle、mysql), }, async (params) { const results lookupError({ query: params.query, stack: params.stack, }); if (results.length 0) { return { content: [ { type: text, text: 知识库中未找到该错误的直接匹配记录。建议先通过日志上下文人工排查确认后将规则补充到知识库。, }, ], }; } const formatted results.map((entry) { return [ 错误码${entry.code}, 技术栈${entry.stack.join(, )}, 含义${entry.description}, 可能原因, ...entry.causes.map((cause) - ${cause}), 解决方案, ...entry.solutions.map((solution) - ${solution}), ].join(\n); }); return { content: [ { type: text, text: 查到 ${formatted.length} 条相关记录\n\n${formatted.join(\n\n)}, }, ], }; } ); const transport new StdioServerTransport(); await server.connect(transport);代码看起来不长但它完成了一个完整的闭环接收 AI 客户端的工具调用请求、解析参数、查询知识库、返回结构化 Markdown 文本。AI 拿到这段文本后会结合用户原来的报错上下文生成一段自然语言的排查建议。5.4 编译与启动TypeScript 项目可以先编译再运行也可以直接用 tsx 调试。# 方式一编译后运行 npx tsc node dist/index.js # 方式二tsx 直接运行开发调试更省事 npx tsx src/index.ts因为使用了 stdio 传输这个程序不能像普通服务那样在终端里直接看到输出。它等待的是标准输入上的 JSON-RPC 请求需要借助 MCP Inspector 或客户端来测试。6. 规则库设计决定这个工具价值的不是代码而是数据代码写完后这个项目的价值重心就从“怎么写”转移到了“存了什么”。一个错误知识库如果只有三条规则价值约等于零如果有三百条经过验证的规则就是一个团队级的排查资产。规则库设计有四个要点。第一筛选高频错误。不要一开始就追求全面覆盖。观察团队一个月内的报错记录把出现频率最高的前 20 个错误收录进来比盲目收录 200 个冷门错误更有价值。第二字段要同时满足“机器匹配”和“AI 语义”。机器匹配靠错误码和关键词AI 语义靠 description、causes、solutions。只写关键词没有含义解释AI 拿到结果也组织不出高质量回答。第三解决方案要“可执行、可验证”。好的解决方案不是“检查网络配置”这种笼统建议而是给出具体命令、具体配置项以及如何验证是否生效。例如解决方案 1. 执行 adb reverse tcp:8080 tcp:8080将设备端口映射到本地 2. 重新启动应用并观察日志 3. 如果仍然失败使用 netstat -ano 检查端口占用第四为“未命中”设计回退策略。当 AI 查询不到结果时它应该明确告诉用户“知识库未收录”而不是硬编答案。这样错误知识库才能持续收敛——每个未命中都是下一次补充规则的机会。7. 接入 MCP 客户端Claude Desktop 与编辑器场景MCP Server 写好后需要接入支持 MCP 的客户端。这里以 Claude Desktop 为例其他客户端的配置位置可能不同但配置结构是类似的。找到客户端的配置文件。Claude Desktop 的配置路径通常是macOS~/Library/Application Support/Claude/claude_desktop_config.jsonWindows%APPDATA%\Claude\claude_desktop_config.json在配置文件中加入{ mcpServers: { error-helper: { command: npx, args: [tsx, /absolute/path/to/error-helper-mcp/src/index.ts] } } }注意command和args需要根据你的环境调整。如果 node_modules 安装在项目本地也可以指定完整的 node 路径和脚本路径。重启客户端后你可以输入一段包含错误信息的描述观察客户端是否自动调用lookup_error工具。正常情况下AI 客户端会在回答中提示“已通过 error-helper 查询错误信息”并给出 Tool 返回的结构化内容。对于 Cursor、VS Code 等编辑器通常是在 MCP 配置界面中添加同样的 JSON 配置。不同的客户端对 stdio 启动方式的参数要求可能略有差异如果不确定可以查看客户端文档中的 MCP 配置说明。8. 效果验证用 MCP Inspector 测试工具调用没有接入客户端之前MCP Inspector 是调试 MCP Server 最方便的工具。它相当于一个可视化调试面板可以直接看到 Server 注册了哪些工具、工具接收了什么参数、返回了什么结果。在项目根目录运行npx modelcontextprotocol/inspector npx tsx src/index.ts如果当前环境对 npx 嵌套解析有问题可以先安装 tsx 到全局再运行npm install -g tsx npx modelcontextprotocol/inspector tsx src/index.ts启动后Inspector 会提供一个本地网页地址用浏览器打开即可看到 MCP Server 的工具列表。选择lookup_error工具填入参数{ query: ORA-28547, stack: oracle }点击执行预期返回结果中包含错误码、技术栈、含义、可能原因和解决方案。同样可以测试未命中场景{ query: UNKNOWN_ERROR_XYZ }预期返回文本是“知识库中未找到该错误的直接匹配记录”。如何判断成功主要看三点MCP Inspector 能正常列出lookup_error工具。输入参数带 schema 校验缺失必填参数时客户端会提示。返回结果是结构化的content数组而不是启动时的报错堆栈。如果 MCP Server 本身有逻辑错误Inspector 会直接显示服务端的异常堆栈这是第一时间的定位线索。9. 常见问题与排查思路在实际搭建过程中最容易遇到的几个问题如下问题现象可能原因排查方式解决方案客户端启动后找不到 MCP Server配置路径错误或命令启动失败查看客户端日志确认配置文件是否被加载检查配置中的绝对路径先手动在终端执行启动命令验证工具调用返回超时stdio 输出被无关日志污染查看启动命令是否有 console.log 输出移除 MCP Server 中的调试日志stdout 只能用于协议通信TypeScript 类型报错SDK 版本 API 差异查看 node_modules 中 SDK 的实际导出以当前 SDK 版本为准调整 import 和工具注册方法客户端能连接但工具不调用工具描述不够清晰AI 不知道何时调用在聊天中直接问客户端“你能查错误码吗”优化工具描述明确说明适用场景和参数含义查询结果不完整知识库命中率低检查匹配逻辑是否覆盖错误码前缀增加包含匹配和关键词匹配策略补充规则其中最容易踩坑的是第二个stdio 传输模式下MCP Server 的 stdout 是协议通道。任何多余的 console.log 都会污染协议数据导致客户端解析失败。调试时要用 console.error 输出诊断信息或者直接使用文件日志。10. 最佳实践与工程建议从“一个能跑的 Demo”到“一个能用的团队工具”中间还差几个工程决策。错误知识库和代码一起版本管理。知识库本身就是最重要的资产和代码一起进 Git 仓库可以保证每次修改都有历史记录也方便团队 review。匹配失败要埋点。当用户查询一个知识库没有收录的错误时记录下查询关键词和技术栈。这些数据是知识库扩充的第一手资料。不要让 AI 直接执行解决方案中的命令。即使 MCP Server 返回了带有命令的解决步骤AI 客户端能“显示”命令也不代表它应该自动执行。尤其涉及改配置、改文件权限、操作数据库时必须保留人工确认环节。从“单机版”演进到“服务版”。本地 JSON 知识库适合个人学习团队场景建议把 MCP Server 部署成远程服务通过 HTTP 暴露工具。这样知识库只需要在服务端维护一份所有开发者的 AI 客户端共享同一个错误语义层。定义清晰的数据来源和可靠度。每条错误规则的来源可以是官方文档、真实排障记录或社区高票答案。建议给每条记录增加一个来源标记例如官方文档优先社区答案标明参考链接避免后续维护时无法判断信息可靠度。11. 总结与后续方向这个出现在 HN 上的 MCP Server 项目本质上是在做一件事把错误信息从无人维护的“报废字符串”变成 AI 可查询的结构化知识。它的价值不在于用上了多复杂的模型或算法而在于选对了一个足够痛的场景并采用了一个足够标准的接入方式。如果你正在尝试类似方向我的建议是先不要急着设计复杂架构用这篇文章里的最小代码跑通“用户贴报错 - AI 调用工具 - 返回结构化方案”的闭环然后花时间积累知识库。前 50 条规则可能会有些枯燥但到 200 条的时候你会发现 AI 对你们团队报错的理解已经远远超过了一个普通开发者的记忆范围。下一步可以考虑的方向包括知识库接入向量检索支持碎片化错误日志的语义匹配将 MCP Server 部署成公司内部 HTTP 服务让所有开发者共享把每次排障过程自动沉淀为新规则形成持续演进的错误知识闭环。判断这类项目是否优秀最终看的不是工具数量而是你愿不愿意让它成为你日常工作流的一部分。
返回列表