浏览 MCP与Skills教程与资源

MCP 401 与 403 排查:先识别拒绝请求的是哪一层

分别检查 MCP 端点认证、下游服务授权和网关策略,用响应位置、WWW-Authenticate 与同身份对照请求决定下一步,避免一报错就扩权。

先看错误来自哪里

同一个‘403’,可能根本还没进入 MCP Server

位置常见证据该找谁修
代理、WAF 或访问网关响应是网关 HTML/品牌错误页,Server 没有相应请求记录网络或网关策略;换 API Key 未必有用
MCP HTTP 端点请求本身返回 401/403,可能带 WWW-AuthenticateMCP 连接所用身份、凭证、作用域或 Origin 校验
工具内部的 GitHub/Notion 等下游外层 MCP 调用已完成,工具错误里包含下游 401/403该 Server 访问下游使用的凭证与资源权限
客户端预先拒绝没有真正发出的网络请求,界面显示权限或工具被禁用客户端工具过滤/审批;不等于服务端鉴权失败

先记录请求时间、目标主机、HTTP 状态、错误正文类型和脱敏 request ID。不要把完整 Authorization、Cookie 或授权码复制进问题报告。

读认证挑战

401 是认证分支,403 仍要看具体错误

下面是为了说明字段而构造的 HTTP 片段,不是某台服务器的运行日志。采用 MCP OAuth 的服务应使用为该资源签发的令牌;一个别处可用的 API Key 不会自动成为此 MCP 的令牌。

教学响应片段

无效令牌与缺少 scope

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token"

HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope", scope="documents:read"

documents:read 是用于解释机制的虚构 scope,不是 Notion、GitHub 或 Codex 的配置参数。真实 scope 必须取自该服务的挑战和官方说明,不能照抄这个字符串。

401 分支

先证明确实发送了正确来源的凭证

  1. 01

    辨认服务要求的认证类型

    公开只读服务可能不需要认证;OAuth 服务需走客户端授权;PAT 服务使用对应提供方的令牌。不要把 OpenAI API Key 填入 GitHub MCP,也不要向未知重定向域名发送 Token。

    证据:官方端点与认证说明,而不是工具名称里含有哪个品牌。
  2. 02

    核对客户端实际使用的凭证来源

    若配置引用环境变量,确认启动客户端的进程拥有该变量;GUI 重启后才会继承新的环境。若使用 OAuth,确认当前连接和当前用户对应的授权,避免只在另一个浏览器账号登录。

    只记录变量是否存在、凭证标签和到期信息,不输出令牌值。
  3. 03

    按提供方机制续期或重新授权

    对已过期/已撤销的凭证重新登录或生成新令牌,再更新真实使用位置。JWT 的本地解码只能读声明,不能证明签名有效;opaque token 甚至不能这样查看。

    由服务端对原请求的响应验证,不把本地解码当验证。
  4. 04

    重复同一个最小请求

    身份、资源、动作和参数保持不变。若已从 401 变为工具级无权读取,说明来到下一层,需要继续查资源授权,不能说整个问题已解决。

    保存脱敏的前后响应,不同时换仓库或改业务对象。
403 分支

用同身份的成功/失败对象找出差异

对照结果优先检查不该直接做
同一连接能读测试仓库 A,仓库 B 失败资源所有者、PAT 所选仓库、组织审批和实际资源 ACL生成全仓库管理员 Token 来掩盖差异
同一页面能读,更新失败本次任务是否需要写、Server 是否只读、凭证是否有写权限为一个读取任务打开全部写能力
所有调用突然 403,并有速率限制说明Retry-After、速率响应头、近期并发和服务状态把限流误判成少一个 scope
本地 HTTP Server 返回 Origin 拒绝客户端 Origin 与 Server 允许来源是否匹配关闭所有 Origin 校验;这不是 OAuth scope 问题
权限申请仍在 pending组织审批状态和管理员策略重建相同令牌期望绕过审批
落实到一个产品

GitHub:公开资源成功,不证明私有仓库已获授权

假设同一 github_issues 连接能读取公开 Issue,却读不到你选定的私有 acme/demo-app #42。先确认 owner/repo/#42 的 URL 正确,再检查 fine-grained PAT 的资源所有者、所选仓库、Issues 只读权限和组织批准状态。GitHub 对某些无权私有对象会返回 404,以避免泄露对象是否存在,所以 404 也要放进这个对照。

如果 MCP 外层响应正常,而 issue_read 的工具结果说 GitHub 拒绝了请求,调试重点在下游 GitHub 授权。如果 MCP 地址本身立即 401,先查 Codex 的 bearer_token_env_var。两者使用的错误位置不同,不能仅凭用户界面的一行‘unauthorized’猜根因。

什么时候停止重试

权限缺口不是靠重复请求补出来的

明确的 scope/角色/组织策略拒绝,应先确定任务确实需要对应权限,再走授权流程;同一个无变化请求不停重试既不能扩大权限,还可能触发限流。若客户端在授权后仍用旧令牌,先定位凭证读取位置和缓存,不要留下多份不知谁在使用的 Token。

修复记录只需说明:哪层拒绝、已确认的身份与对象、最小变更、原请求的新结果。没有服务端证据时可写‘疑似网关策略,尚未定位’,不能把 403 一律翻译成‘身份有效但 scope 不够’。

依据与适用范围

本页的一手资料