MCP HTTP 授权与 REST API 鉴权的关系
用同一个 Bearer Token 请求模型解释远程 MCP 和 REST 的协议差异,以及 PAT、OAuth 与 stdio 的授权边界。
[!info] related notes
- 所属 MOC: mcp-moc
- 相关概念: oauth2、oauth-authorization-code-pkce、oauth-client-registration-methods
- 易混淆概念:
- 相关资源:
MCP HTTP 授权与 REST API 鉴权的关系
范围
这里讨论通过 HTTP 传输访问受保护 MCP Server 时的鉴权模型,并对比普通 REST API;不讨论“模型如何选择调用工具”的推理层,不把本地 stdio MCP 假装成远程 HTTP 服务。
核心结论
MCP 并没有重新发明 Token 鉴权。普通 REST API 和受保护的 HTTP MCP 都可以使用:
Authorization: Bearer <access-token>
区别主要在业务协议:REST 常通过 URL / HTTP method 暴露操作;MCP 使用统一的 JSON-RPC 消息和标准工具发现/调用方法(如 tools/list、tools/call)。授权通过之后,MCP Server 才将工具调用映射到其业务服务。
两条最小调用链
普通 REST
GET /api/v1/goals + Bearer
→ 验证 Token
→ 验证用户对 Goal 的权限
→ JSON response
远程 MCP
POST /mcp + Bearer
JSON-RPC method: tools/call, name: goal_search
→ 验证 Token 与 resource/scope
→ 验证工具调用与业务归属
→ MCP tool result
以上省略了 MCP 2026-07-28 协议版本、方法镜像等完整 transport headers,实际实现必须遵循所选协议版本;这只是认证与业务边界模型,不是可直接复制运行的最完整 wire transcript。
先拿到 Token:PAT 与 OAuth 是两种不同车道
Personal Access Token
用户登录 Web 后创建 scoped PAT,人工把它放入本地 Agent 配置。Agent 后续直接以 Bearer 请求 MCP;服务端仍要检查有效期、scope、账户状态、撤销、resource audience 和业务归属。PAT 通常没有标准 OAuth 浏览器授权/Refresh Token 交互。
OAuth 委托授权
当客户端没有可用凭据时,受保护 HTTP MCP 按规范返回 401 和带 protected-resource metadata 定位的 WWW-Authenticate。客户端发现授权服务器、获得 client_id、通过授权码 + PKCE 让用户登录及 consent,然后拿到 Access Token。后续每次 MCP HTTP 请求仍然携带普通 Bearer Token,不是每次都弹浏览器。
如果身份无效/Token 过期,通常是 401;Token 有效但 scope 不足,通常是 403 insufficient_scope,并可以引导申请更小范围的权限。Token 必须为目标 MCP resource 签发,不能将其它站点登录 Token 原样转发。
本地 stdio MCP 不是同一个网络模型
通过 stdio 与本机进程通信的 MCP Server 通常从环境变量、启动配置或本地受控渠道获取凭据,不要求套用远程 HTTP OAuth discovery。MCP 协议存在 ≠ 一定存在 HTTP 服务器或 OAuth 登录页。
易混淆点
- 在 MCP 中,“Host / MCP Client / MCP Server”是协议软件角色;在 OAuth 中,“Client / Authorization Server / Resource Server”是授权角色;同一程序可以映射到两套角色,名字相同不代表逻辑完全一样。
- OAuth 解决“如何委托并获得限权凭据”;REST/MCP 解决“如何表达和执行请求”。它们不是对立技术。
- 用户身份与资源级 owner permission 不能只靠 tool 名称或模型口头声明。
- 首次浏览器授权与日常 HTTP 请求要分清时序。
学习检查
- 把一个 REST GET 换成 MCP
tools/call,鉴权层最核心的相同点是什么? - 什么情况下客户端才需要打开浏览器授权?
- 401 和 403 分别说明什么?
- 为什么一个 GitHub 登录 Session Token 不应该直接作为 MemoFlow MCP Access Token?
- 为什么
stdio模式不应硬套远程 HTTP OAuth 规范?