.mcp.json 中定义的 MCP 服务器在 claude mcp list 里出现 “Pending approval” 状态时,唯一合规的解法是:在该目录交互式启动 claude,先接受工作区信任对话框,再在 /mcp 面板里逐个批准。这一步操作同时触发工作区信任检查——仓库提交的所有”自动批准”配置在未信任目录里一律被忽略。
一、Pending approval 是怎么产生的
克隆一份仓库到本地,如果它根目录带了 .mcp.json,里面写着 mcpServers 的命令或 URL,这些服务器不会自动连接。设计这一关的理由很直接:.mcp.json 的字段本质是可执行 shell 命令,不加拦截意味着 git clone 之后陌生进程就无声启动了。
| 状态标记 | 含义 | 是否可连接 |
|---|---|---|
| 正常 | 已通过审批并连上 | 是 |
| ⏸ Pending approval | 等待用户在交互式会话中批准 | 否 |
| ✗ Rejected | 已被显式拒绝 | 否 |
| 401 / 403 | 远程服务器需 OAuth 鉴权 | 待登录 |
Pending approval 这一行的语义不是”配置写错了”,而是”配置没被这台机器的人审批过”。从 v2.1.196 起,审批状态只从三类来源读取:本地未提交的 .claude/settings.local.json、用户级 ~/.claude/settings.json、以及交互式会话中的人工批准记录。仓库里提交到 .claude/settings.json 的 enableAllProjectMcpServers 或 enabledMcpjsonServers 在未受信任的目录里一律被忽略。
二、解锁 Pending approval 的标准流程
要把 ⏸ 状态变成可连接,必须走工作区信任 + 逐个审批这两道闸。命令本身很短,但顺序不能换:
- 进入项目根目录的交互式 Claude 会话:
cd /path/to/your-repo && claude; - 首次运行会弹”是否信任本目录”对话框,选”Yes, proceed”完成工作区信任;
- 在交互式会话中输入
/mcp,进入 MCP 状态面板; - 逐个批准需要启用的服务器(每个 Pending 项对应一个交互式确认);
- 退出后再次运行
claude mcp list,Pending 标记应消失,状态进入正常或鉴权待补全。
# 1) 触发信任对话框
cd ~/work/your-repo
claude
# 弹出 "Do you trust the files in this folder?" → 选 1
# 2) 退出后查看状态
claude mcp list
# github: ... - ⏸ Pending approval (run `claude` to approve)
# 3) 再进交互式,按 /mcp 逐个批准
claude
# 输入 /mcp → 选批准
三、这一步会触发的安全检查
接受工作区信任对话框会同步触发一整套安全检查,目标是让”仓库提交的内容不能自己批准自己”。
- 工作区信任键值落盘:以 git 仓库根目录(或非仓库场景的启动目录)为键,信任结果被持久化,下次进同目录不再弹窗;
- 能力授予键过滤:提交到仓库的
permissions.allow、enableAllProjectMcpServers、enabledMcpjsonServers在未信任目录里被读取但被丢弃,避免克隆即生效; - 健康检查准入:被批准的服务器才会被发起连接与健康探测;Pending 状态下即便 token 已导出也不会去拉进程;
- 鉴权态分离:远程 MCP 收到 401/403 时,
/mcp面板提供 OAuth 入口,鉴权失败不会被静默回退到无凭证调用。
整个流程的核心原则是:仓库自带的配置文件不能批准自己引入的服务器,必须由本地用户亲自点头。v2.1.196 之后的工作区信任检查被前置到 settings 解析之前,正是为这一原则兜底。
四、命令行无法单独”批准”的两个原因
很多团队协作时会问:能不能写一个 CI 命令直接 claude mcp approve?答案是不能,原因有两点。
| 命令 | 是否需要工作区信任 | 是否可单独批准 |
|---|---|---|
claude mcp list |
否(只读状态) | 否 |
claude mcp get |
否(只读状态) | 否 |
claude mcp add |
否(仅写入配置) | 否 |
交互式 claude + /mcp 面板 |
是 | 是 |
claude mcp reset-project-choices |
否 | 否(只重置) |
list / get / add 都是非交互的、不带信任上下文的命令;批准动作本质上是”用户在交互式 UI 上对某条规则点头”,这必须由触发信任对话框之后的人工操作完成。reset-project-choices 只是把审批状态清回 Pending,不会替用户做新的批准。
五、团队协作的推荐实践
仓库中只提交”意图”而不提交”自动批准”是社区里被反复验证的方案。.claude/settings.json 里只写 enabledMcpjsonServers: ["jira", "sentry"] 这种声明性列表,真正的连接留给每个开发者在本机走一遍信任 + 审批流程。这样既保留了”团队统一知道项目要用哪些 MCP”,又避免了”克隆即生效”的安全风险。
// .claude/settings.json(提交到仓库,团队共享)
{
"enabledMcpjsonServers": ["github", "sentry"]
}
本地调试或临时覆盖时,把真审批写到 .claude/settings.local.json(gitignore 默认不跟踪),这样切分支、换开发机都不会污染团队共识。/mcp 面板里看到的所有 Pending 项,批准的也只是当前机器当前工作区。
到这里,”Pending approval 怎么解锁 + 背后触发的安全检查”就完整了:先在交互式会话里接受工作区信任,再在 /mcp 面板逐项批准,期间能力授予键被过滤、健康检查才被允许发起、鉴权态独立处理。
常见问题(FAQ)
Q1:claude mcp list 里直接看到 Pending,能不能在终端里批准?
不能。批准必须在交互式 claude 会话内、接受信任对话框后通过 /mcp 面板完成。
Q2:提交到仓库的 enableAllProjectMcpServers: true 为什么没生效?
仓库自带的能力授予键在未信任目录里被读取但被丢弃,必须本地用户先完成工作区信任。
Q3:误拒了某个 MCP 服务器怎么恢复?
运行 claude mcp reset-project-choices 把审批清空,再走一遍信任 + 审批流程即可。