12.5 MCP Inspector 工具链
🎯 学习目标:把 Inspector 用成"能交互调试、也能进 CI 校验"的日常工具 ⏱️ 预计时间:40 分钟 📊 难度等级:⭐⭐⭐(动手为主)
📌 一句话结论:Inspector 是官方调试器,有三种形态——CLI(脚本/CI)、TUI(终端交互)、Web(图形界面)。它最独特的设计是 protocol era:同一个 HTTP 地址,可以按"旧版"或"新版"协议去连,方便你对比行为差异。
🧰 三种形态,怎么选
| 形态 | 适合 | 特点 |
|---|---|---|
| CLI | CI 流水线、shell 一行命令、编码 agent 即时验证服务器改动 | 每次运行只发一个 --method 指定的请求,打印结果后退出 |
| TUI | 在终端里交互式调试 | 全键盘操作,不依赖浏览器 |
| Web | 图形化查看请求/响应/流 | 标签页式界面,最直观 |
💡 三者的服务器连接解析逻辑完全一致:配置文件里的每服务器设置(headers、超时、OAuth、protocol era、roots)在三种形态下都按同样规则生效。
🕰️ 核心概念:Protocol Era
2026-07-28 对协议做了大改,所以 Inspector 把 protocol era(协议时代:legacy 旧 / modern 新,以 2026-07-28 为界)当作一等公民的"每服务器设置",与传输方式正交——同一个 HTTP URL 既能当 legacy 服务器查,也能当 modern 服务器查。
每个服务器带一个 protocolEra,取值 legacy / auto / modern:
| Era | 连接时 Inspector 做什么 |
|---|---|
legacy | 默认值。 直接 initialize,不做任何探测 |
auto | 先探测 server/discover,遇到任何"非 modern"结果就回退到 initialize |
modern | 精确钉住 2026-07-28,不回退,遇到非 modern 服务器就直接失败 |
配置位置:Web 客户端在 Server Settings;catalog/配置文件里是 protocolEra 字段;CLI 与 TUI 从同一份文件读取。
💡 为什么默认是
legacy而不是auto? 调试工具不应该自动探测。对一个沉默的 legacy stdio 服务器发server/discover探测会卡住,还会污染你本就要看的那份 transcript。选auto或modern是一个主动动作,这样你在 Protocol 标签里看到的,就是"你的服务器面对一个按你配置行事的客户端时"会看到的东西。
连接成功后,协商出的 era 会显示在连接头部与 Connection Info 里。modern 连接下,server/discover 还会提供 capabilities(含 extensions)、instructions 与 supportedVersions;服务器名与版本在结果 _meta 的 io.modelcontextprotocol/serverInfo 里。
era 差异速览(同一功能在两种 era 下的不同表现):
| 功能 | Legacy | Modern |
|---|---|---|
| 日志 | 会话级:logging/setLevel 设一次,服务器持续推 notifications/message | logging/setLevel 已移除;改为每请求在 _meta["io.modelcontextprotocol/logLevel"] 上 opt-in |
| 资源订阅 | resources/subscribe,会话级标记 | subscriptions/listen 长连接流,带 stream-status 徽章(Connecting → Listening) |
| Tasks | 靠 capabilities.tasks 显示标签页;tasks/list + 阻塞式 tasks/result | 靠协商的扩展 io.modelcontextprotocol/tasks;只轮询 tasks/get,完成即内联结果 |
| MRTR | 服务器主动发请求(server.elicitInput 等) | 手动逐轮驱动:input_required 在 pending-request 弹窗里等你回答 |
| 会话 | 可能有 Mcp-Session-Id,断开时发 DELETE | 无会话、按请求;不向服务器发 DELETE,断开纯属本地 |
⚠️ legacy 的
collect_elicitation模式在 2026-07-28 连接上会报错,因为该协议版本不允许服务器向客户端发请求。MRTR 是它的现代替代。
💻 CLI 用法详解
每次 CLI 运行:连上服务器 → 用 --method 发一个请求 → 打印结果 → 退出。这正是 CI 与一行命令需要的形态。
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list安装后可直接用 mcp-inspector 二进制;未全局安装则前面加 npx @modelcontextprotocol/inspector。
选择服务器
# stdio:位置参数就是要 spawn 的命令
mcp-inspector --cli node build/index.js --method tools/list
# HTTP
mcp-inspector --cli https://api.example.com/mcp --transport http --method tools/list
# 从配置文件里按名取
mcp-inspector --cli --config ./mcp.json --server myserver --method tools/list⚠️ 配置文件是给一次运行提供 roots 的唯一持久方式:没有 roots 相关的 flag,
--method roots/set只对那一条短命连接生效。为某服务器配置的 roots 会在连接时公布,所以调用roots/list的服务器(如@modelcontextprotocol/server-filesystem用来获知允许目录)能拿到。
支持的 --method
--method | 必需的配套参数 | 说明 |
|---|---|---|
initialize | 无 | 仅连接的探测:返回 {serverInfo, protocolVersion, capabilities, instructions} |
tools/list | 无 | |
tools/call | --tool-name,加 --tool-arg / --tool-args-json | |
resources/list | 无 | |
resources/read | --uri | |
resources/templates/list | 无 | |
prompts/list | 无 | |
prompts/get | --prompt-name、--prompt-args | |
logging/setLevel | --log-level | 仅 legacy;modern 服务器改为按请求 opt-in |
servers/list、servers/show | 无 | 不连任何服务器,只读 catalog |
流式/会话类方法(如 logging/tail)会被拒绝——一个发完就退出的进程无法保持流打开。
传参数:两种方式,语义不同
--tool-arg key=value:会对值做 JSON 解析式强制转换,所以 count=1 变成数字,"012" 变成 12:
mcp-inspector --cli <server> --method tools/call --tool-name mytool \
--tool-arg key=value --tool-arg count=1 --tool-arg 'options={"format":"json"}'--tool-args-json:一次传入整个参数对象,原样传递、不做转换,"012" 仍是字符串 012。两者互斥:
mcp-inspector --cli <server> --method tools/call --tool-name mytool \
--tool-args-json '{"zip":"10001"}'输出格式
--format text(默认):给人看的美化输出--format json:stdout 上输出单个 JSON 对象、无横幅,便于整段管道处理:
mcp-inspector --cli <server> --method tools/list --format json | jq '.result.tools[].name'退出码与错误信封(CI 关键)
每个非零退出都映射到一个稳定的失败类别,调用方可以据此分支,而不必去猜文案:
| 码 | 含义 |
|---|---|
0 | 成功 |
1 | 用法或意外错误(兜底) |
2 | 该工具没有 MCP App(--app-info 探测) |
3 | 服务器要求认证(401/403、WWW-Authenticate、OAuth) |
4 | 服务器不可达(DNS、连接被拒、超时、fetch failed) |
5 | 工具错误:tools/call 返回 isError: true,或工具不存在 |
任何非零退出,CLI 还会向 stderr 写一行 JSON:
{
"error": {
"code": "auth_required",
"message": "Unauthorized",
"status": 401,
"url": "https://api.example/mcp"
}
}因为只有一行,可以用 2>&1 | tail -1 | jq .error 解析。
💡
tools/call即使返回isError: true仍会打印其载荷,但退出码为5——所以&&链不会在失败调用后继续。
脚本里的授权
默认情况下 CLI 会跑和 TUI 一样的 loopback OAuth 流程:开浏览器、等一个 localhost 回调——CI 跑不通。两个 flag 让非交互运行可预测:
| flag | 行为 |
|---|---|
--stored-auth-only | 从不启动交互式 OAuth 或 step-up,从不自动开浏览器;有令牌就用共享存储里的,没有就立即以 auth_required 失败。CI 要的就是它 |
--use-stored-auth | 复用本机 Web Inspector 已取得的令牌,有刷新令牌时先刷新 |
两者都不给、且 stdin/stderr 没有 TTY 时,CLI 会快速失败为 auth_required,而不是傻等十五分钟的回调。
🍳 常用 recipe
在 CI 里验证服务器
set -euo pipefail
# 连不上、或没暴露目标工具,就让构建失败
mcp-inspector --cli --config ./ci-servers.json --server my-server \
--stored-auth-only --method tools/list --format json \
| jq -e '.result.tools | map(.name) | index("get_weather")' > /dev/null按失败类别分支
if out=$(mcp-inspector --cli "$URL" --transport http --method tools/list 2>err.json); then
echo "$out"
else
case $? in
3) echo "需要认证:先跑一次 web inspector 登录" ;;
4) echo "服务器不可达" ;;
*) jq .error < err.json ;;
esac
fi找出所有带 UI 的工具
mcp-inspector --cli "$URL" --transport http --method tools/list --app-info \
| jq -r 'select(.hasApp) | .toolName'不连接、只查 catalog
mcp-inspector --cli --catalog ~/.mcp-inspector/mcp.json --method servers/list
mcp-inspector --cli --catalog ~/.mcp-inspector/mcp.json --method servers/show --server my-server⚠️
servers/show会脱敏带密钥的字段(env值、敏感 header、OAuth client secret),但不会清理 URL 里内嵌的凭据(userinfo 或 query token),也不会清理 stdio 的args。贴 issue 前把原始 URL 和detail字段当作敏感信息。
🧭 排错范式
| 你看到的 | 去哪看 | 大概率原因 |
|---|---|---|
| 请求发出但无响应 | Web 的 Network / Protocol | 传输端点、Mcp-* 头缺失 |
| 登录/授权失败 | Web 的 Authorization | OAuth 配置或 iss 校验(见 12.1) |
| 工具列表里缺了某工具 | Tools 标签的 Excluded 分隔区 | 标了无效的 x-mcp-header(SEP-2243),合规客户端会丢弃它 |
返回 -32022 | Protocol 标签 | 协议版本不受支持;data.supported 里有服务器支持的版本 |
返回 -32020 | Network 标签 | 缺少或错误的镜像 header |
| 日志一条都没有 | Logs 标签 | modern era 下 logLevel 为 off——这是正确行为,不是 bug |
💡 代理:连远程 HTTP/SSE 服务器遵循常规代理变量(
HTTPS_PROXY/HTTP_PROXY/NO_PROXY),无需 Inspector 专属 flag。
📖 官方资料
- 📋 Inspector 总览
- 💻 CLI client
- 🖥️ TUI client
- ⚙️ Configuration and flags
- 🕰️ Protocol eras
- 🍳 Recipes
- 💻 Inspector 代码仓库
🎉 恭喜你走完全书。 从第1章的概念到这里,你已经覆盖了从写一个服务器,到授权、治理、扩展、分发与调试的完整链路。