最近在给团队维护一个内部 MCP Server,每次版本更新前我都会用官方 Inspector 做一轮“只读体检”。MCP Server 这层东西很有意思,它本身不产数据,也不直接执行业务逻辑,而是把 Tools、Resources、Prompts 这些能力包装成标准协议,让 AI 客户端能像调接口一样调用它们。也正因为多了这层协议转换,很多问题不是逻辑错,而是协议格式、资源定位、参数定义这些细节出状况,线上暴露一个就是一个故障。所以上线前用 Inspector 逐项验证协议握手、工具定义、资源读取和提示词模板,是成本最低的一道防线。
这篇文章不聊太深的设计哲学,就讲我实际检查时做的事:怎么看协议层有没有对齐,怎么逐个验证 Tools、Resources、Prompts,以及这半年踩过哪些坑。适合正在写 MCP Server、或者准备把 AI 工具链接入内部系统的同学参考。内容偏实战,按照“理解概念 → 动手检查 → 排查问题 → 建立清单”的顺序展开。
1. 为什么要给 MCP Server 做“上线前体检”
1.1 MCP Server 到底解决了什么问题
先对齐一个基本认知。MCP(Model Context Protocol,模型上下文协议)解决的是 AI 模型怎么安全、标准化地访问外部能力的问题。以前每个人做 AI Agent 都要自己设计一套工具调用规范,A 项目定义callTool(name, params),B 项目定义一个/invoke接口,AI 客户端接到这些五花八门的 API 根本没法统一处理。MCP 把“工具调用”“资源读取”“提示词模板”这些能力抽象成一套标准协议,服务端实现这套协议,任何支持 MCP 的客户端都能理解它。
MCP Server 就是这套协议的服务端实现。它本身不是一个业务系统,而是一个“翻译层”:把内部的数据库查询、外部 API、文档检索、业务函数等能力,包装成标准的 Tools、Resources、Prompts。AI 客户端通过协议发现这些能力,并在合适的时机调用它们。
但这带来了一个新的复杂点:你的业务逻辑可能没错,但只要协议层没有严格遵守规范,客户端就发现不了、调用不对、甚至直接报错。这类错误在传统 API 调试里不太常见,因为传统 API 是你定义好了 JSON 格式,两边都按这个格式写代码;而 MCP 的客户端是“自动发现”你的能力定义,如果定义不规范,自动化的链路就会断。
1.2 检查的难点在哪:协议层和应用层
很多人第一次写 MCP Server 时,习惯性地只测“功能能不能跑通”,比如写了个查询订单的工具,本地调一下返回正常,就觉得可以上线了。问题是,功能跑通只能说明“你的 Server 内部逻辑没问题”,并不能说明“你的 Server 与任意 MCP 客户端之间的协议交互没问题”。
这两个层面完全是两回事。应用层是你自己代码里的事,比如查询数据库、调 API、拼装结果;协议层是你和 AI 客户端之间的约定,包括 handshake 时返回什么 capabilities、Tools 的 JSON Schema 怎么写、Resources 的 URI 稳不稳定、Prompts 的参数名是否和描述一致。后者才是 MCP Server 区别于普通 API 服务的核心难点。
我见过不少项目,Server 单独测一切正常,但接到真实客户端就傻眼:有的客户端要求所有 Tool 返回值里必须是content数组,你在数组里塞了个自定义字段,客户端就解析不出来;有的客户端在发起请求时会先调用resources/list,如果你的 Server 在这个方法上报错,所有客户端都会认为你不可用。这些都不是“功能 bug”,而是“协议 bug”,必须在环境里用标准工具验证。
1.3 为什么选 Inspector 做只读检查
MCP 官方提供了一个调试工具,就叫 Inspector。它的作用是用一个图形界面连接你的 MCP Server,把协议交互过程完整暴露出来:连接建立之后,你能看到 Server 声明了哪些 capabilities、暴露了哪些 Tools、Resources、Prompts,还可以手动触发一次协议调用并查看完整请求返回内容。
我把它称为“只读体检”,主要是说两件事。第一,Inspector 本身不会修改你的 Server 代码,也不会上线任何东西,它只做一个观察者;第二,它对 Server 的绝大多数操作是“列表”“读取”“查看定义”,不会自动执行任何危险动作。唯一可能触发真实行为的是你在界面上手动点某个 Tool 的 Call 按钮,这个操作由你控制,所以整体风险可控,非常适合在上线前做一轮不污染数据的预检。
当然,你可能会问:官方 SDK 里不是有测试客户端吗?自己写个脚本也能调。确实可以,但 Inspector 的价值在于“图形化 + 协议日志透明 + 内置验证工具”。它能让你像看浏览器开发者工具一样,逐条查看协议报文,定位问题在哪一个环节。脚本测试适合回归,Inspector 适合排查和人工审查,两者结合才最稳。
2. 拆解四个检查对象:协议、Tools、Resources、Prompts
2.1 协议层:握手、初始化、能力协商
MCP 的协议层像一个“入职流程”。客户端连上 Server 之后,第一件事不是直接调工具,而是先打招呼:客户端发送initialize请求,告诉 Server 自己支持的协议版本;Server 返回自己的版本、能力列表、实现信息;然后双方再发一个initialized通知,确认可以开始干活。
这个阶段最容易出的问题就是版本不匹配。MCP 协议版本有一个字符串标识,比如2024-11-05这种日期格式。如果 Client 端 SDK 比较新、Server 端 SDK 比较旧,或者反过来,两边在版本协商上就可能出问题。规范的 Server 应该在自己的 capabilities 里明确声明支持哪些功能,还要用正确的方式告诉客户端:我支持工具但不支持资源订阅,我支持提示词但不支持流式响应。
用 Inspector 检查时,重点关注两个地方。第一是initialize响应的capabilities字段,看看哪些能力被声明了;第二是后续每次请求响应里,是否都带有正确的 JSON-RPC 消息结构。很多问题其实不是功能逻辑问题,而是协议字段不完整、类型不对、甚至返回了非 JSON 内容,这类错误在 Inspector 里一眼就能看到。
2.2 Tools:AI 能调用的“双手”
Tools 是 MCP 里最核心的能力,也是开发者最先接触的概念。简单理解,Tools 就是暴露给 AI 的函数。AI 不能直接执行代码,它会根据用户的指令和上下文,决定“要不要调用某个工具”“传什么参数”,然后由 MCP Server 去执行,把结果返回给 AI。
每个 Tool 由几个关键字段组成:name(工具名,必须唯一且符合命名规范)、description(描述这个工具是做什么的、什么时候用)、inputSchema(一个 JSON Schema,描述这个工具需要哪些参数、参数类型是什么、哪些必填)。这仨字段任何一个写得不清楚,AI 都可能“看不懂”你的工具。
name别乱起,尽量用下划线分隔的英文小写,比如query_order,不要带空格、中文、特殊符号。description要写清楚“什么时候该用、什么时候不该用”,因为 AI 是靠文本来理解工具用途的,描述太笼统会导致它明明能调你的工具却不调。inputSchema则是 AI 生成参数的依据,字段名、类型、必填性、枚举值,都要写准确,否则 AI 会传错参数。
上线前检查 Tools,核心是看三层:定义是否合规、参数能否通过 Schema 校验、实际调用是否能返回结构化结果。Inspector 会把 Server 声明的所有 Tools 列出来,你可以逐个打开看定义,也可以直接填参数试调用,非常直观。
2.3 Resources:AI 能读取的“资料库”
Resources 是 MCP 里容易被忽略、但线上出问题最多的部分。它表示可被 AI 读取的上下文数据,有点像是给模型提供的“资料库”。和 Tools 不同,Resources 不执行动作,只是提供内容。AI 读取一个 Resource,就像人打开一份文档,内容被塞进上下文,供模型理解。
每个 Resource 一般有uri、name、description和可选的mimeType。URI 是它的唯一标识,常见的有file:///path/to/file、https://example.com/doc,也可以定义自定义 scheme,比如doc://order/123。客户端会在需要时用resources/read请求读取这个 URI 对应的内容。
Resources 最容易出问题的地方是 URI 的稳定性和读取权限。假如你的 Resource URI 里带时间戳或者临时拼接标识,AI 拿到一个 URI 之后,过几分钟再去读就失效了,这种体验非常差。再比如同一个资源既能被 A 客户端读取、又要供 B 客户端订阅,如果权限控制不清晰,就会偶发“读到了但内容为空”的情况。
用 Inspector 检查 Resources,重点看三件事:resources/list返回的列表是否完整且稳定、每个 URI 是否能正常被resources/read读取、返回的mimeType和内容格式是否一致。这个环节没有太多花哨操作,核心就是“列表里有什么,读取就一定能读到”。
2.4 Prompts:AI 的“标准话术模板”
Prompts 是 MCP 里偏“保守”但很实用的能力。它不是自动运行的工具,而是一组可复用的提示词模板。客户端可以根据场景,向 Server 请求某个 Prompt 模板,然后拿到一段结构化的对话消息,再把这段消息塞给模型或对话系统。
一个 Prompt 包含name、description和arguments参数定义。比如你创建一个叫summarize_doc的 Prompt,参数是doc_uri,客户端请求后,Server 返回一段消息模板:“请总结以下文档 {doc_uri} 的内容……”这样就把提示词逻辑收敛在 Server 端,客户端不用硬编码提示词,也方便统一管理和更新。
Prompts 线上常见问题包括模板里的参数名和arguments定义不一致、缺少描述导致客户端不知道什么时候用这个模板、返回的消息格式不符合对话结构等。Inspector 的 Prompts 页签会让你看到这个 Prompt 接收哪些参数、参数是什么类型,还能实际渲染一次,看最终生成的消息长什么样,非常方便排查模板问题。
3. 实操走一遍:Inspector 从启动到全绿的关键步骤
3.1 启动 Inspector 并连接本地 Server
先讲最常用的本地连接方式。MCP Server 最常见的是 stdio 模式:Server 是一个通过标准输入输出通信的进程,客户端去拉起这个进程,然后在一个管道里交换消息。Inspector 支持这种模式,启动之后你需要在它的界面里填上“启动 Server 的命令”和“工作目录”。
具体操作是这样。项目根目录下,先确保你的 MCP Server 已经能被命令行启动,比如node dist/index.js或python main.py。然后用 npx 启动 Inspector:
npx @modelcontextprotocol/inspector启动后浏览器打开 http://localhost:6274,左侧会有一个连接配置区。Transport Type 选 stdio,然后在 Command 填node,Arguments 填dist/index.js,如果有环境变量也可以填在 Env 里。填完后点 Connect。
这里有个很容易踩的坑:很多人的 Server 是 TypeScript 写的,跑之前没编译,导致填了node dist/index.js之后进程直接就退出。建议先手动在终端跑一次这个命令,确认进程能常驻、没有立即退出的现象,再填到 Inspector 里。不然你根本分不清是 Inspector 的问题还是 Server 启动的问题。
如果你想检查的 Server 跑在远端,还可以用 SSE 或者 HTTP 传输模式。这时 Inspector 的 Transport Type 选 SSE 或 Streamable HTTP,填上远程地址就行。这个模式适合检查已经部署在测试环境的 Server,不用把代码拉下来。
3.2 逐步验证协议交互
连接成功后,Inspector 主界面会展示一个完整的请求日志列表。每次客户端发送 JSON-RPC 请求、Server 返回响应,都会以时间线的方式列出来。这一步是检查协议层最关键的入口。
第一次连上时,你应该立刻能看到一条initialize请求和对应响应。点开响应,检查几个关键点:
protocolVersion是否是你预期的版本;capabilities里有没有声明tools、resources、prompts;如果你只实现了 Tools,那能力列表里就只有tools,这是正常的;serverInfo里name和version能不能准确标识你的服务。
接着看notifications/initialized通知,如果这条没有出来,说明客户端和 Server 的握手流程不完整,之后很多调用可能都不生效。
日志区还有过滤功能,你可以只看请求、只看响应、或者只看错误消息。建议把错误打开,因为很多 Server 在正常流程里会夹杂一些非致命错误,比如某个 resource 读取失败,但 Server 并没有终止。这些错误如果不逐一排查,上线后可能变成定时炸弹。
3.3 逐个检查 Tools 定义并试调用
协议握手没问题后,切到 Tools 页签。Inspector 会自动调用tools/list,把你的 Server 上所有工具列出来。这时候先别急着试调用,先把列表完完整整看一遍。
检查顺序我一般按三步走。第一步看数量对不对:你预期暴露 5 个工具,列表里是不是刚好 5 个,有没有多出一些忘了删的调试工具。第二步逐个点开工具定义,核对name、description、inputSchema。重点看 inputSchema 里的字段名、类型、是否 required,以及 description 是否足够清晰。第三步,选几个核心工具,做一次真实调用。
试调用时要注意参数填写。Inspector 会让你输入一个符合 Schema 的 JSON 对象,比如:
{ "order_id": "20240815001", "include_detail": true }点击运行后,观察返回结果。正常的 Tool 返回应该包含content数组,每条 content 是一个结构化对象,最常用的是{"type": "text", "text": "查询结果..."}。如果你返回了自定义格式,比如直接返回{"code": 0, "data": ...}放在 content 外面,很多客户端会解析不到,这个在 Inspector 里能立刻看到。
再强调一下安全:Inspector 本身只读,但 Tool 的 Call 是真实执行。如果这个工具会写数据库、发消息、甚至扣费,上线前试调用时要小心。我的做法是给这类危险工具加一个环境开关,在测试环境里用一个 mock 版本,或者传入一个专门的测试参数,确保不会影响真实数据。
3.4 验证 Resources 的读取链路
切到 Resources 页签,Inspector 会调用resources/list给你展示所有 Server 声明的资源。这里有一个常见现象:如果你没有实现 Resources 相关方法,这个页签会显示空列表,没关系,说明你的 Server 不提供资源能力;但如果你明明实现了,列表却是空的,那就要查服务端代码里listResources的返回了。
列表展示后,重点做两件事。第一,逐个检查 URI 的格式和数量。URI 必须是稳定唯一的,我建议实际用手点一遍每个资源,试试能不能正常读取。第二,观察读取结果。点开某个资源后,Inspector 会发送resources/read请求,并把返回的内容显示出来。检查返回内容的格式:如果声明了application/json,那内容应该是 JSON;如果声明了text/plain,那随意。
特别提醒:有些 Server 的 Resource 内容是动态生成的,比如根据当前时间返回不同数据,但 URI 一样。这种情况本身没问题,但如果你发现“同样的 URI,上一次读取成功,这一次读取超时”,那就要考虑是不是动态生成逻辑里有耗时的外部依赖。Inspector 日志里会显示每条请求的耗时,看到耗时异常偏高的资源,上线前一定要优化。
3.5 检查 Prompts 的模板与参数
Prompts 页签的操作逻辑和 Tools 类似,但目的不同。Tools 的检查重点是“调用结果是否正确”,Prompts 的检查重点是“模板渲染出来是什么样”。
进入页签后,你会看到prompts/list返回的所有提示词模板。打开一个模板,能看到它定义的参数。比如一个 Prompt 叫generate_meeting_summary,参数有meeting_id,类型是 string,必填。你可以在 Inspector 里填上参数,然后点渲染,它会发出prompts/get请求,返回一组合法消息。
检查这个返回消息时,重点看三块。第一是消息的角色序列是否合理,通常是一个 system 或 user 消息;第二是模板里插值后的文本是否通顺,有没有留下没替换的{xxx}占位符;第三是参数类型和描述是否与模板里的用法吻合。如果模板里用了{date}但参数定义里根本没有 date,客户端发送请求时不知道要传这个参数,最后就渲染不出来。
如果你没实现 Prompts 能力,页签同样是空的。但要注意,Inspector 的空列表和“方法未实现”的错误提示,展示方式不太一样。看到页签为空别急着下结论,去日志区看看有没有类似Method not found: prompts/list的报错,如果有,说明你的 Server SDK 版本可能不支持 Prompts,需要升级。
4. 常见问题与排查技巧实录
4.1 连接不上:先分清 stdio 和 HTTP
要我说,Inspector 的报错信息里,十次有八次是“连接不上”引发的后续连锁反应。很多人看到红色错误提示就慌了,其实排查思路很简单:先确认你用的传输方式对不对。
如果你的 Server 是本地进程,默认用 stdio。这个时候检查两点:命令行能不能手动启动成功;启动后进程是不是一直在运行。一旦进程打印一行日志就退出,Inspector 自然会显示连接失败或者一连接就断开。我遇到最多的原因就是路径不对:当前工作目录不是项目根目录,导致dist/index.js找不到。
如果你的 Server 是远程部署,确认你填的是 SSE 或 Streamable HTTP 的地址,而不是业务接口地址。有些框架会把 MCP 端点挂在/mcp路径下,如果你填了根路径/,也会连不上。先拿 curl 试一下端点是否可达:
curl -X POST http://your-server/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'能收到响应,再去 Inspector 里连,基本就没问题。
4.2 工具定义“合法但不可用”:schema 与序列化问题
有一种很隐蔽的问题:Server 端的工具定义看着没问题,schema 也是标准 JSON Schema,但 AI 客户端调用时总是传错参数,或者调用返回后 AI 读不懂结果。
这一类问题的根源往往在“类型解析”上。我给你举一个真实例子:有个工具返回的数据里包含一个嵌套对象,定义时写的是type: "object",但实际返回的时候,代码把对象转成了字符串。从协议角度看,字段类型和真实值不一致,客户端解析自然出错。
另一个常见的坑是 JSON Schema 里忘了加additionalProperties: false。如果 Server 内部对参数做了严格校验,AI 多传了一个未定义的字段,请求就会被拒绝。但更常见的情况是 AI 看到字段名“差不多”就传了,如果 schema 不约束,多余字段会被忽略,导致核心逻辑拿不到正确参数。我建议在关键工具上把additionalProperties设为 false,同时在描述里写明“除下列参数外不要传其他字段”。
用 Inspector 排查这类问题,不要只看“调用是否成功”,还要把请求参数原样复制出来,看 AI 实际传的参数和你 Schema 的匹配度。如果 AI 总是漏掉某个必填参数,大概率是你 description 没写清楚,或者参数名有歧义。改 description 比改代码更管用。
4.3 资源读取偶发失败:URI 稳定性与权限
Resources 的偶发失败,最让运维头疼。它不是 100% 失败,而是时好时坏,这种问题用 Inspector 反而最容易复现:因为你可以反复点同一个资源的 Read,多试几次看失败率。
如果是“读一次成功、读一次失败”,优先怀疑 Server 端的缓存或权限逻辑。有些 Server 在第一次读取时会走一次外部接口拿数据并缓存,第二次直接从缓存返回;但只要缓存过期,下一次读取就会再次触发外部接口,外部接口慢或挂了,读取就失败。
另一个和权限相关:许多内部系统会在 Resource 读取接口上做鉴权,比如要求 Header 里带 token。输入 Inspector 连接信息时没配好 header,就会导致部分需要认证的资源读取失败。排查时可以看响应状态码,如果返回 401、403,基本就是认证问题;如果返回 500 或超时,才是服务端逻辑问题。
最后提醒一下:Resources 的mimeType要设置准确。你声明这是text/markdown,结果返回内容是一段二进制乱码,客户端拿去做上下文反而会污染模型理解。上线前至少要把每个资源读出来的内容用肉眼扫一遍。
4.4 提示词调用报错:参数名拼写与缺省值
Prompts 的报错相对好排查,因为它本质是“模板字符串 + 参数替换”。Inspector 的报错信息如果提示Missing required argument: xxx,先回去看模板定义里arguments列表,是不是有这个参数名?是不是大小写对不上?
这里有个细节容易踩坑:模板定义里参数名用的是meetingId(驼峰),但模板字符串里引用的是meeting_id(下划线),渲染时就会替换不到。你也许觉得这不会发生,但多人协作的项目里,定义模板和实现模板的人不是同一个,这种低级错误真的很常见。
还有一种情况是参数有默认值。Inspector 渲染时如果你不传,它通常走的是“不带默认值”的逻辑,所以你会看到报错。但真实客户端可能永远会带上这个参数,所以遇到“Inspector 报错但线上没报错”,也别觉得奇怪。更可靠的方式是:如果真的设计了可选参数,在模板里用条件渲染或给默认值做兜底,保证缺省时消息依然通顺。
4.5 上线前检查清单(速查表)
这一套跑下来步骤有点多,我整理成了一张速查表,方便每次发版前对照打勾。
| 检查项 | 操作位置 | 通过标准 |
|---|---|---|
| 协议版本协商 | Inspector 日志initialize响应 | 协议版本匹配,无报错 |
| 能力声明 | initialize响应capabilities | 已声明 tools/resources/prompts |
| 工具列表完整性 | Tools 页签 | 工具数量、名称、描述符合预期 |
| 工具 Schema 合法性 | Tools 每个定义的 inputSchema | JSON Schema 合法,字段类型正确 |
| 核心工具试调用 | Tools 页签填写参数并 Call | 返回内容为 content 数组,无异常 |
| 资源列表完整性 | Resources 页签 | URI 数量与格式正确 |
| 资源读取成功率 | Resources 逐个 Read | 连续两次读取成功 |
| 提示词参数匹配 | Prompts 页签渲染 | 参数替换正确,无占位符残留 |
| 错误日志 | Inspector 日志过滤 Error | 无非致命错误堆积 |
| 危险工具隔离 | 代码审查 | 写操作工具有测试开关或 mock |
这个表不是给老板看的,是给自己看的。每次发版前花二十分钟跑一遍,能挡住大部分线上问题。
5. 从上线前检查到上线后监控:我的几点体会
5.1 把检查沉淀成脚本
Inspector 适合做人工审查,但纯靠人工会有两个问题:一是慢,二是容易漏。所以我现在把 Inspector 能发现的问题分成了两类:一类是必须人工判断的,比如描述是否准确、模板是否通顺;另一类是可以自动化的,比如工具列表数量是否变化、Schema 是否合法、Resources 能否读取。
后一类我已经沉淀成了一个小的回归脚本,用 MCP SDK 自带测试工具 + 自定义断言,每天定时跑一次。脚本只做 list 和 read,不执行任何 Tool 的 call,所以非常安全。一旦发现某个资源读取失败,或者某个工具的 Schema 有语法错误,立刻告警,不用等上线才发现。
这么做之后,Inspector 的角色变成了“发版前的人工终审”工具,而不是唯一的检查手段。自动化保证基线不出错,人工保证体验层面不出问题,两边互补,效果最好。
5.2 日志设计要一开始就做对
我在帮朋友排查一个线上 MCP Server 问题时,最大的障碍不是它调不通,而是它不打印任何有用的日志。所有 MCP 方法都包在最外层,只输出一个统一异常,根本不知道是哪一个方法挂了,也不知道请求参数是什么。最后只能靠 Inspector 一点一点试,排查效率极低。
如果你的 Server 还在开发阶段,趁早做好日志设计。至少在三个地方打日志:请求入口(哪个方法、请求 ID、参数摘要)、外部 IO 调用(调用了什么服务、耗时多少)、异常分支(异常堆栈、请求上下文)。这样线上出了问题,你能快速定位,而不是让用户帮你抓包。
Inspector 的日志区能把你本地复现的各种请求都记录下来,但那是“本地诊断日志”,不是线上运行日志。两者都要有,但我个人觉得后者更关键,因为线上的真实请求模式千奇百怪,本地很难完全模拟。
5.3 一些真实教训
最后分享几个真实踩过坑的片段,希望你能绕开。
第一个教训:工具的 description 真的是“AI 能不能正确使用工具”的关键。我有一个天气查询工具,description 只写了“查询天气”,结果 AI 在用户问“明天该穿什么”时死活不调它,因为描述没告诉它“可以根据天气信息推断穿衣建议”。后来我把 description 扩写成“当用户询问天气、气温、穿衣建议、出行安排时使用,输入城市名和日期”,调用率立刻上来了。这个东西不是玄学,是 AI 的文本理解机制决定的。
第二个教训:别以为 Resources 就不是代码。我曾经手写了一个返回 PDF 元数据的 Resource,自测时内容正常,但线上客户端一直报错,最后发现是因为mimeType声明了application/pdf,但返回内容实际是 base64 编码的 JSON,客户端按 PDF 解析当然失败。资源链路也要讲“契约”,不只是 Tools 才讲。
第三个教训:上线前检查不要只在发版当天做。有一次我连续改了很多代码,上线前一天用 Inspector 跑了一遍,发现一切正常;第二天又改了一个小字段,没重新跑,直接发布。结果那个小字段刚好是某个 Tools 的inputSchema里必填参数的类型,从 string 改成了 integer,AI 客户端还按 string 传,线上立刻报错。从那以后,我强迫自己把“任何代码变更后都跑一遍 Inspector 全量检查”变成肌肉记忆。
我个人现在的习惯是:无论改动多小,发版前至少跑一轮tools/list+resources/list+ 核心工具试调用,全程不超过二十分钟。这个习惯帮我挡住过很多次线上故障,也让我对 MCP Server 的协议细节保持敏感。Inspector 本身不复杂,复杂的是你愿不愿意在每个版本上线前,花这二十分钟安静地看一遍协议日志。