Skip to content

12.5 MCP Inspector 工具链

🎯 学习目标:把 Inspector 用成"能交互调试、也能进 CI 校验"的日常工具 ⏱️ 预计时间:40 分钟 📊 难度等级:⭐⭐⭐(动手为主)

📌 一句话结论:Inspector 是官方调试器,有三种形态——CLI(脚本/CI)、TUI(终端交互)、Web(图形界面)。它最独特的设计是 protocol era同一个 HTTP 地址,可以按"旧版"或"新版"协议去连,方便你对比行为差异。

🧰 三种形态,怎么选

形态适合特点
CLICI 流水线、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。选 automodern 是一个主动动作,这样你在 Protocol 标签里看到的,就是"你的服务器面对一个按你配置行事的客户端时"会看到的东西。

连接成功后,协商出的 era 会显示在连接头部与 Connection Info 里。modern 连接下,server/discover 还会提供 capabilities(含 extensions)、instructionssupportedVersions;服务器名与版本在结果 _metaio.modelcontextprotocol/serverInfo 里。

era 差异速览(同一功能在两种 era 下的不同表现):

功能LegacyModern
日志会话级:logging/setLevel 设一次,服务器持续推 notifications/messagelogging/setLevel 已移除;改为每请求_meta["io.modelcontextprotocol/logLevel"] 上 opt-in
资源订阅resources/subscribe,会话级标记subscriptions/listen 长连接流,带 stream-status 徽章(Connecting → Listening)
Taskscapabilities.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 与一行命令需要的形态。

bash
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list

安装后可直接用 mcp-inspector 二进制;未全局安装则前面加 npx @modelcontextprotocol/inspector

选择服务器

bash
# 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/listservers/show不连任何服务器,只读 catalog

流式/会话类方法(如 logging/tail)会被拒绝——一个发完就退出的进程无法保持流打开。

传参数:两种方式,语义不同

--tool-arg key=value:会对值做 JSON 解析式强制转换,所以 count=1 变成数字,"012" 变成 12

bash
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。两者互斥

bash
mcp-inspector --cli <server> --method tools/call --tool-name mytool \
  --tool-args-json '{"zip":"10001"}'

输出格式

  • --format text(默认):给人看的美化输出
  • --format json:stdout 上输出单个 JSON 对象、无横幅,便于整段管道处理:
bash
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

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 里验证服务器

bash
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

按失败类别分支

bash
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 的工具

bash
mcp-inspector --cli "$URL" --transport http --method tools/list --app-info \
  | jq -r 'select(.hasApp) | .toolName'

不连接、只查 catalog

bash
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 的 AuthorizationOAuth 配置或 iss 校验(见 12.1)
工具列表里缺了某工具Tools 标签的 Excluded 分隔区标了无效的 x-mcp-header(SEP-2243),合规客户端会丢弃它
返回 -32022Protocol 标签协议版本不受支持;data.supported 里有服务器支持的版本
返回 -32020Network 标签缺少或错误的镜像 header
日志一条都没有Logs 标签modern era 下 logLeveloff——这是正确行为,不是 bug

💡 代理:连远程 HTTP/SSE 服务器遵循常规代理变量(HTTPS_PROXY / HTTP_PROXY / NO_PROXY),无需 Inspector 专属 flag。

📖 官方资料


🎉 恭喜你走完全书。第1章的概念到这里,你已经覆盖了从写一个服务器,到授权、治理、扩展、分发与调试的完整链路。

🏠 返回教程首页📖 回看 12.1 OAuth 2.1 授权体系🔁 协议版本演进

内容依据 MCP 官方规范整理 · 规范以 官方文档 为准