Skip to main content
每次 CLI 运行都会连接到服务器,调用你通过 --method 指定的单个请求,打印结果并退出。这使其非常适合 CI 流水线、Shell 单行命令,以及需要立即验证服务器更改的编程代理。
如果需要针对同一服务器运行多条命令,或执行跨越同一会话的流程(任务、订阅、elicitation),请使用mcpdo 连接客户端,它只连接一次,并在命令之间保持连接。
以下示例使用已安装的 mcp-inspector 二进制文件。如果未进行全局安装,请像上面一样,在每条命令前加上 npx @modelcontextprotocol/inspector。

选择服务器

CLI 接受一个位置命令(stdio)、一个 --server-url(HTTP/SSE),或从目录或配置文件中选择一个命名服务器:
当服务器来自文件时,其每个服务器的设置(请求头、超时、OAuth、协议时代和根目录)会应用于连接,解析方式与 TUI 和 Web 客户端完全一致。--header 标志会覆盖该次运行中文件中的请求头,同时保留其超时和 OAuth 设置。 后续示例会将你所使用的上述任一形式,以及其 --transport 或 --config/--server 标志,缩写为 <server>。
**配置文件是为一次运行提供 根目录的唯一持久方式:**没有 roots 标志,CLI 也没有 roots/set 方法。为服务器配置的根目录会在连接时公布,因此调用 roots/list 的服务器(例如 @modelcontextprotocol/server-filesystem,它会调用该方法来了解其允许访问的目录)可以获取这些根目录。
请参阅配置和标志,了解 --catalog 与 --config、-- 分隔符以及通用的服务器选择标志。

方法

仅限流或会话的方法(例如 logging/tail)会被拒绝,因为退出的进程无法保持流处于打开状态。

传递参数

--tool-arg 接受 key=value,并在值可解析时通过 JSON 解析进行强制类型转换,因此 count=1 和 zip=10001 都会发送数字。无效 JSON(如 zip=012 或裸词)会作为字符串发送;随后字符串会转换为工具输入 schema 为该属性声明的类型,因此对数值型 zip 使用 zip=012 仍会发送 12:
--tool-args-json 一次性接受整个参数对象,并跳过 key=value 解析,因此 {"zip":"10001"} 会发送字符串 "10001" 而不是数字。schema 转换仍适用于字符串值,因此只有当 schema 将该属性声明为字符串(或未声明类型)时,它才会保持字符串。两者不能同时使用:

输出

--format text(默认)以便于人类阅读的格式美化输出。--format json 会在 stdout 上输出单个 JSON 对象,不包含任何横幅信息,因此整个输出可以直接通过管道传递:

探测 MCP 应用

--app-info 会报告某个工具是否附带 MCP 应用 UI(包括其 ui:// 资源、CSP 和权限),而不会调用该工具,这样流水线就能在调用任何工具之前决定是否需要浏览器:
退出代码用于区分不同结果:带有应用的工具退出码为 0,不带应用的工具退出码为 2,而缺少的工具退出码为 5,因此拼写错误不会被误认为“没有应用”。探测失败(无法读取 UI 资源、resourceUri 格式错误)会记录在 resourceError 字段中,而不会中止操作,因此单个有问题的工具不会导致整个列表处理失败。 CLI 无法渲染 App,因此默认不会在 initialize 时声明 MCP Apps 扩展。如果服务器只向声明支持 App 的客户端公开应用工具,它会看起来没有应用(退出码为 2)。添加 --advertise-apps 可让本次运行声明该扩展。
tools/list --app-info 始终输出 NDJSON(每个工具一行),无论 --format 的值是什么;--format json 只会重新组织 tools/call --app-info 的单工具输出。

退出代码和错误信封

每个非零退出代码都对应一个稳定的失败类别,因此调用方无需抓取文本即可根据_原因_进行分支处理: 对于任何非零退出,CLI 还会向 stderr 写入单行 JSON:
由于它只有一行,调用方可以使用 2>&1 | tail -1 | jq .error 对其进行解析。 信封始终包含 code 和 message,如果已知还会包含 cause(如 DNS 失败等底层错误)、status(HTTP 状态)和 url。URL 查询字符串中的机密信息会被遮盖。code 是稳定的失败名称,例如 auth_required、unreachable、tool_not_found、tool_is_error、no_app、schema_unportable、store_unavailable、oauth_state_unrecognized,以及兜底的 error。 返回 isError: true 的 tools/call 仍会打印其负载,但会以 5 退出,因此失败调用不会继续执行 && 链。

脚本中的授权

默认情况下,CLI 运行的回环 OAuth 流程与 TUI 相同:它会打开浏览器,并等待 CI 作业无法完成的 localhost 回调。以下两个标志可让非交互式运行变得可预测:
  • --stored-auth-only:永不启动交互式 OAuth 或升级验证,也永不自动打开浏览器。如果共享存储中存在令牌,则使用这些令牌;否则立即失败并返回 auth_required。这是 CI 所需的标志。
  • --use-stored-auth:复用 Web Inspector 已在此计算机上获取的令牌;如果存储了刷新令牌,则先刷新令牌。它按 URL 查找令牌,因此需要同时提供 --server-url。
如果两个标志都未使用,且 stdin 或 stderr 没有 TTY,CLI 会快速失败并返回 auth_required,而不是在无人完成回调的情况下挂起十五分钟。 请参阅授权,了解完整流程、从 Web 到 CLI 的交接,以及 --print-handoff。

配方

在 CI 中验证服务器

CI 门禁

三个标志可以将检查转为非零退出,并分别使用独立的退出码,让作业区分失败原因:
  • --strict(配合 tools/list):在 stderr 上完整报告工具 schema 可移植性问题(路径、问题和建议修复),如果存在错误级别问题则以 6 退出。不使用该标志时,tools/list 只打印一行计数;使用 --format json 时,发现结果会以 schemaFindings 字段折叠到输出中。
  • --verify(配合 skills/list 或 skills/get):执行 SEP-2640 符合性和摘要检查,为每个技能在 stdout 上写入一份 JSON 报告;发现违规时以 7 退出,如果读取限制阻止检查所有技能则以 8 退出。使用 --skill-catalog-max-skills 和 --skill-catalog-max-bytes 设置限制。
  • --require-digests(配合 --verify):当技能未播发任何摘要时以 9 退出,而不是将其报告为无法验证并以 0 退出。

根据失败类别进行分支处理

对每个具有 UI 的工具执行冒烟测试

在不连接的情况下检查目录

servers/show 会隐藏包含机密信息的字段(env 值、敏感标头、 OAuth 客户端机密),但不会清除嵌入服务器 url(用户信息或查询令牌) 或 stdio args 中的凭据。在将原始 URL 和 detail 字段粘贴到 issue 之前,请将其视为敏感信息。

编辑目录

servers/add、servers/edit 和 servers/remove 会在不连接任何对象的情况下写入目录。它们使用与 Web 客户端服务器列表相同的代码,因此 env 值和客户端密钥会像从 UI 写入时一样进入机密信息存储,运行中的 Web 客户端也会发现这些更改。
只有可写目录(--catalog、MCP_CATALOG_PATH 或默认目录)可以被写入;--config 会被拒绝。使用内存机密信息存储时,如果写入操作提供了 -e 值(或执行了 --rename),也会被拒绝,因为这些机密信息会在运行退出时丢失。

代理

与远程 HTTP/SSE 服务器的连接遵循约定的代理变量:HTTPS_PROXY / HTTP_PROXY(及其小写形式)用于选择代理,NO_PROXY 用于排除指定主机。无需使用 Inspector 专用标志,代理代理器会延迟加载,因此不使用代理运行时不会产生额外开销。Web 客户端的后端同样如此。