授权

社区译文;来源: MCP 80041ab0

远程 MCP 服务器通常需要授权。Inspector 在全部三种客户端中都实现了完整的授权流程,并将获得的 token 保存在磁盘上共享,从而使一次登录可在所有客户端中使用。

流程,端到端

连接并被拒绝

Inspector 连接到服务器 URL。服务器返回 401。如果响应带有 WWW-Authenticate 头,它会指向受保护资源的元数据 URL(resource_metadata),以及可选的请求所需 scope。

发现授权服务器

Inspector 获取服务器的受保护资源与授权服务器元数据,以了解端点和支持的授权类型。

注册或标识客户端

Inspector 通过已配置的机制向授权服务器标识自身:动态客户端注册、预注册的静态客户端(--client-id / --client-secret)、客户端 ID 元数据文档(--client-metadata-url),或企业托管 IdP。

在浏览器中授权

Inspector 打开授权 URL。你登录并同意。

接收回调

授权服务器重定向到 Inspector 的回调 URL,并携带授权码。

交换并重试

用授权码换取 token,持久化 token 后重试最初的连接请求。对于会话中途的挑战,CLI 会自动重试被拒绝的请求,Web 客户端会要求你重试该操作。

回调 URL

Web 应用在自己的 URL 上监听 OAuth 回调,而 CLI 和 TUI 则共用第二个回调 URL:

界面默认回调 URL原因
Web<origin you opened the Inspector at>/oauth/callback,默认 http://127.0.0.1:6274/oauth/callback主应用服务器本身已有 HTTP 监听器。可从 Server Settings 中的 Redirect URI 字段复制精确值。
CLIhttp://127.0.0.1:6276/oauth/callback专用的 loopback 监听器,避免与正在运行的 Web Inspector 冲突。
TUIhttp://127.0.0.1:6276/oauth/callback与 CLI 共用同一个监听器。

在使用 CLI 或 TUI 前,必须在需要预注册重定向 URI 的 IdP 上注册 http://127.0.0.1:6276/oauth/callback。默认值的设计是可预测的:注册一次即可复用。

对于 CLI 和 TUI,可用 --callback-url 或 MCP_OAUTH_CALLBACK_URL 覆盖它。Web 的回调始终跟随页面的 origin,因此 localhost 和 127.0.0.1 在 Web 中也会产生不同的重定向 URI。

回调 URL 必须绑定 loopback 主机:localhost、127.0.0.0/8 或 [::1]。 监听器通过明文 http 接收授权码,因此非 loopback 主机会被拒绝并报错,且没有 flag 可覆盖此限制。 如果你的浏览器运行在另一台机器上,可将回调端口转发过去,或改用 Web Inspector 完成登录: --print-handoff(下文)会为 Web Inspector 的端口打印 portForwardCmd。

重定向 URI 必须完全匹配你在授权服务器上的注册。即使到达的是同一个监听器,http://localhost:6276/... 和 http://127.0.0.1:6276/... 对授权服务器来说也是不同的 URI。

同一时刻只有一个进程能占用默认端口;第二个并发流程会因 EADDRINUSE 失败。如果你的授权服务器支持动态重定向 URI 注册,可为每个实例使用不同的固定端口,或使用 http://127.0.0.1:0/oauth/callback 让操作系统分配临时端口。

凭据存储位置

文件内容
~/.mcp-inspector/storage/oauth.json非机密的 OAuth 状态(发现元数据、PKCE verifier、已授予的 scope、公共客户端 ID),按规范化后的服务器 URL 键入。写入时仅限所有者访问。
~/.mcp-inspector/storage/client.json安装级客户端设置(客户端元数据 URL、企业 IdP)。与 Web 客户端的 Client Settings 对话框写入的是同一个文件。
catalog 文件 中服务器的 oauth 块每个服务器的客户端 ID/secret、scope、是否为企业托管、以及step-up策略。

oauth.json 的解析顺序:MCP_INSPECTOR_OAUTH_STATE_PATH,然后 MCP_STORAGE_DIR 下的 oauth.json(参见环境变量),最后才是默认路径。三种客户端的解析方式完全相同。命令行的 --client-id / --client-secret / --client-metadata-url 会覆盖 client.json。

机密本身(access token、refresh token、注册访问 token、IdP 会话 token)并不存放在 oauth.json 中,而是进入机密存储——当钥匙串可用时就是操作系统钥匙串。MCP_INSPECTOR_PERSIST_TOKENS 用于限制保留哪些已获取的 token:all(默认)、access(不保留 refresh token)或 none(每次运行都重新授权)。参见机密存储变量。

会话中途重新授权

服务器可以在会话中途用 401 或 403 insufficient_scope 拒绝_单个_请求,Inspector 会处理这两种情况而不会断开连接:

  • 重新授权:token 过期或被撤销。Inspector 解析 WWW-Authenticate 挑战并重新执行授权流程,然后重试失败的请求。
  • Step-up:该请求需要当前 token 所不具备的 scope。Inspector 会为当前已持有的 scope 与请求所需 scope 的并集重新授权,因此新 token 将同时覆盖旧 token 的权限以及新请求所需的 scope。

在 Web 客户端,会出现 Re-authentication required 横幅;对于 step-up 则会打开 Additional permissions required 对话框,列出所需 scope,你可以点击 Authorize 确认。每个服务器的 Insufficient-scope response 设置可以关闭 step-up,使 403 直接作为错误返回。在 CLI 中,step-up 会在 stderr 上提示:

Proceed with step-up authorization? [y/N]

回答 y 继续。可通过管道输入(echo y | ...),只要输入以换行结尾或 stdin 关闭即可。N 或在无回答的情况下 EOF 会拒绝。若非 TTY 的 stdin 在 5 秒内未发送任何内容,则会以 auth_required 失败,这与显式拒绝是不同的情况。企业托管的 step-up 会静默重新颁发 token,无需提示。

非交互与 CI 运行

交互式 OAuth 要求在 stdin 或 stderr 上有 TTY,或者设置 MCP_AUTO_OPEN_ENABLED=true。将 stderr 重定向到管道(如 2>&1 | tee)仍可工作,因为 stdin 仍是 TTY。当两者都不满足时(这是 CI 的常见情况),CLI 会快速失败并返回 auth_required,而不是等待长达十五分钟无人完成的回调。

对于 CI,应显式指定:

mcp-inspector --cli "$URL" --transport http --stored-auth-only --method tools/list

--stored-auth-only 永远不会启动交互式 OAuth 或 step-up,也不会打开浏览器。它会使用共享存储中已有的 token(如果存在),否则立即失败。

从 Web 客户端移交到 CLI

常用场景:人在这台机器的 Web Inspector 中完成了 OAuth,现在需要脚本使用该 token。

Flag行为
--use-stored-auth读取 --server-url 对应的已存储认证信息并注入 Authorization: Bearer。如果存储了 refresh token,会先运行刷新授权并注入新的 token,同时持久化轮换后的 token。当没有匹配项时以退出码 3(no_stored_token)退出,并列出已存储的服务器 URL。
--wait-for-auth <sec>轮询状态文件,直到 --server-url 对应的 token 出现后再注入。超时(<sec> 秒)时以退出码 3(auth_wait_timeout)退出。适用于将登录过程移交给人工后再等待的场景。
--list-stored-auth打印 { oauthStatePath, storedServerUrls } 并退出,不进行连接。
--print-handoff为 --server-url 打印 JSON 块(deepLink、portForwardCmd、oauthStatePath、apiToken)并退出;这是远程脚本驱动浏览器端所需的全部信息。
--relogin连接前删除该服务器 URL 对应的已存储 OAuth 状态,并在授权服务器上撤销授权(可用 --no-revoke 跳过)。仅适用于 HTTP/SSE。

典型的远程 VM 流程。假设 VM 上正运行 Web Inspector,且已知 MCP_INSPECTOR_API_TOKEN 并在下方 shell 中导出该值;否则 handoff 中的 deepLink 将不带 autoConnect token,Web 客户端会拒绝它。

# On the VM: print what the human needs in order to complete OAuth in their browser
mcp-inspector --cli --server-url https://api.example/mcp --print-handoff

# Then block until the token lands, and run the call with it
mcp-inspector --cli --transport http --server-url https://api.example/mcp \
  --wait-for-auth 120 --method tools/list

handoff 块中的 deepLink 会直接导航浏览器到已连接的 Inspector;参见深层链接。

由于已存储条目不记录过期时间,使用 --use-stored-auth 时每次都会用 refresh token 执行刷新授权。对于轮换型(一次性)refresh token,这会带来两个窄范围的失败窗口:两个并发调用可能竞态争抢同一个状态文件;以及在刷新成功与写回之间崩溃会导致轮换后的 token 未被保存。两种情况都不太常见,可在 Web 客户端重新授权来恢复。

检查授权状态

  • Web:Connection Info 面板会显示授权状态、客户端注册类型、客户端 ID、已授予的 scope 和 access token,并提供 Clear OAuth state and disconnect 按钮用于清除当前服务器的 OAuth 状态。清除时默认会撤销授权,除非服务器的 Revoke tokens on clear 设置关闭。
  • TUI:Auth 标签页(a)显示相同字段,并以相同方式清除状态。
  • CLI:--list-stored-auth 显示磁盘上的内容,--relogin 则会撤销并丢弃它,然后重新开始授权流程。