AI活用

claude -p 拒绝 MCP 工具的原因:用 --allowedTools 只允许 5 项操作

claude -p 拒绝 MCP 工具的原因:用 --allowedTools 只允许 5 项操作

早上好。我是まさきん。

家里用的聊天机器人,一直没法往购物清单里写东西。原因是它背后运行的 claude -p 每次都会拒绝 MCP 工具。我对照官方文档查了原因和修法,在这里记一笔。

※本文为发布时的信息。最新条件请以官方网站为准。

POINT
  • claude -p 的无人值守执行中,需要确认的操作会被拒绝
  • --permission-mode acceptEdits 放行的只有文件编辑和一部分文件操作命令
  • MCP 工具要在 --allowedTools 或 permissions.allow 里明确写出才会放行
  • 写法是 mcp__<服务器名>__<工具名>,也可以按服务器为单位指定
  • 我只允许了 Notion 的搜索、获取、查询、创建、更新这 5 项操作

购物清单写不进去

我家有一个全家人一起用的聊天软件机器人。它是我自己做的,背后调用的是 claude -p,也就是以无头方式运行 Claude Code。

我想让这个机器人读写购物清单。购物清单是 Notion 里的一个数据库。家人发一句“帮我买一下这个”,机器人就把它加进清单。我设想的就是这样的用法。

可是试了很多次都写不进去。每次调用 Notion 的工具,都一定被拒绝。在我手边的交互式会话里明明能用,只有经过机器人的时候不行。

原因是没有授权

结论很简单。机器人调用的 claude -p 没有拿到 Notion 连接器的许可。

机器人是用 --permission-mode acceptEdits 运行的,文件编辑会自动放行。所以我一直以为“已经交给它不少权限了”。但 MCP 工具并不在这个范围里。

在我的环境里,无人值守执行时 MCP 工具一定会被拒绝,直到用 --allowedTools 明确写出来为止。这就是这次的出发点。

无人值守时没有人来回答

先把机制理一下。Claude Code 在执行操作前,有时会确认是否允许。交互式会话里,确认会显示在屏幕上,由人来回答。

加了 -p 的执行是非交互模式。官方文档在“Run Claude Code programmatically”这一页做了说明。文档写道,在没有准备好回答确认的对象的 -p 执行中,需要确认的操作会被拒绝。

也就是说,不是“被问到然后停住”,而是“没被问就直接被拒”。在机器人的背后,这个差别就表现为“一定被拒绝”。弄懂机制之后,我才恍然大悟。

权限模式对比

接下来是权限模式。官方的“Choose a permission mode”按模式列出了不需要确认就能执行的范围。

模式不需要确认就能执行的内容官方列举的用途
default仅读取每一项操作都要自己确认的工作
acceptEdits读取、文件编辑、一部分文件操作命令一边检查代码一边推进的工作
plan以读取为主(编辑需要批准)修改之前的调查
auto由分类器审查操作并判断耗时较长的工作
dontAsk仅读取和事先允许的工具范围收得很窄的 CI 和脚本
bypassPermissions几乎全部仅限隔离的容器或虚拟机

default 在界面上显示的名字是 Manual。作为设置值仍然是 default。

模式是地基。在它上面再叠加允许规则和拒绝规则。官方写道,拒绝规则在包括 bypassPermissions 在内的任何模式下都有效。

acceptEdits 放行的范围

acceptEdits 自动放行的是工作目录内的文件编辑。此外 mkdir、mv 这类文件操作命令也会放行。

另一方面,其他的 shell 命令和网络访问不在范围内。官方写道,这些需要 --allowedTools 或 permissions.allow 的规则。自动批准的列表里没有 MCP 工具。

acceptEdits 是“把编辑交出去的模式”,而不是“把外部服务的操作交出去的模式”。我觉得这样理解比较自然。

bypassPermissions 没有生效

其实我在设置文件里写了 bypassPermissions,位置是 ~/.claude/settings.json。所以我一直认定“应该全部都能通过”。但在机器人那里并没有生效。

原因官方写得很清楚。启动时的模式,采用最先匹配到的那一项。

  1. --permission-mode 参数(或 --dangerously-skip-permissions)
  2. 设置文件里的 permissions.defaultMode

CLI 参考里也写着同样的内容。--permission-mode 会覆盖设置文件里的 defaultMode。机器人启动时带着 --permission-mode acceptEdits。所以设置文件里的 bypassPermissions 根本没被用上。

参数和设置文件之间的关系,除了模式以外我没有细查。这里就只当作我自己环境里的事实。

MCP 工具名的写法

写在允许规则里的 MCP 工具名有固定的格式。官方“Configure permissions”里给出的写法如下。

写法对象
mcp__puppeteerpuppeteer 服务器的所有工具
mcp__puppeteer__*同样是该服务器的所有工具(通配符)
mcp__puppeteer__puppeteer_navigate只有 puppeteer 服务器的 puppeteer_navigate
mcp__github__get_*github 服务器中以 get_ 开头的工具

可以按服务器指定,也可以按工具指定。不过允许规则里的通配符有条件,只能用在 mcp__<服务器名>__ 的后面。像 mcp__* 这样连服务器名都模糊掉的许可,文档说会带着警告被忽略。

还有一点要注意的是连接器的名字。Claude Code 自己获取的连接器,工具名的形式稍有不同,据说是 mcp__claude_ai_<服务器名>__<工具名>。先确认实际的名字再写比较稳妥。

用 —allowedTools 明确写出

修法就是把要用的工具在 --allowedTools 里列出来而已。官方的说明是,这个参数用来指定“不需要确认就执行的工具”。

写出来是下面这样。服务器名和工具名只是示例。实际的名字因环境而异,请自行替换。

claude -p "把牛奶加到购物清单里" \
  --permission-mode acceptEdits \
  --allowedTools \
    "mcp__notion__search" \
    "mcp__notion__fetch" \
    "mcp__notion__query" \
    "mcp__notion__create_pages" \
    "mcp__notion__update_page"

我是把这份许可列表放在机器人的代码里。机器人每次调用 claude -p,都传入同一份列表。

也可以写在设置文件里。在 settings.json 的 permissions.allow 中用同样的格式列出。

{
  "permissions": {
    "allow": ["mcp__notion__search", "mcp__notion__fetch"],
    "deny": ["mcp__notion__delete_page"]
  }
}

这里的工具名同样是示例。放在哪一边也许看个人喜好。我觉得能从代码里读出“这个机器人能做什么”更安心,所以放在了代码这一侧。

允许的 5 项操作

如果按服务器整体放行,设置只要 1 行。但我没有这么做。我只允许了 5 项操作 。

操作是否允许在购物清单里的用途
搜索允许查找清单和物品
获取允许读取页面内容
查询允许按条件筛选数据库
创建允许添加新的物品
更新允许修改“下次购买”之类的状态
删除未允许不使用
以上 5 项以外的操作未允许不使用

购物清单的读写,有这 5 项就够了。删除没有放进去。想去掉某个物品时,更新状态就能解决。

加上许可之后,机器人就能用了。家人提出要买的东西,它能放进购物清单的“下次购买”并回报结果。

把交给工具的权限收到只够用的程度,这种感觉和重新审视固定支出很像。手机费也是一样,按实际用量来配,浪费就容易看出来。

无需签约也能获得100积分的资费模拟 试着用乐天移动重新审视手机费

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

把许可收到最小的思路

为什么要收窄?因为机器人的输入并不只来自我一个人。

家人会随意发来各种文字。有口误的时候,也有被理解成别的意思的时候。这时如果连删除都允许了,就无法挽回。只有创建和更新的话,弄错了还能改回来。

把思路列出来,大致如下。

官方还写了规则的判定顺序:deny(拒绝)、ask(确认)、allow(允许)。最先命中的那一条就是结果。所以绝对不想让它用的工具,写进 deny 最可靠。也可以把工具名直接写进 --disallowedTools。据说那样 Claude 就看不到这个工具了。

在处理密钥信息时,同样的“不要只看形式就放心”的感觉也很重要。那部分写在了gitleaks 漏掉 2 处的那篇文章里。

dontAsk 这个选项

读官方文档的时候,还有一个模式让我在意,那就是 dontAsk。

dontAsk 是把所有需要确认的操作一律拒绝的模式。能通过的只有读取和事先允许的内容。官方也给出了面向严格限定许可列表的 CI 的例子。

claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"

我的机器人目前还是 acceptEdits,因为有些场景也想让它编辑文件。不过如果只是操作外部服务,dontAsk 也许更合适。

另外,不指定权限模式的 -p 执行需要留意。启动模式会随环境和版本变化。官方也写着要明确指定想用的模式。

设置步骤

下面是今后要做同样事情时的流程。

  1. 把想让机器人做的操作用文字写出来
  2. 选出这些操作需要的 MCP 工具
  3. 按 mcp__<服务器名>__<工具名> 的格式确认实际的工具名
  4. 列在 --allowedTools 或 permissions.allow 里
  5. 有不想让它用的工具,就写进 deny
  6. 用 claude -p 实际调用,看看有没有被拒绝
  7. 许可列表只在操作增加时才追加

工具名和拒绝的确认方法

工具名靠猜是写不对的。官方介绍了 system/init 这个事件,它出现在 --output-format stream-json 的最开头。里面有模型、工具、MCP 服务器的信息。

拒绝也能从同一份输出里追踪。拒绝会以 permission_denied 这条系统消息出现。据说最后的结果消息里也会以 permission_denials 列出清单。把它留在机器人的日志里,找原因应该会快很多。

常见的失误

注意
  • 认定只要设成 acceptEdits,MCP 工具也会放行
  • 认定设置文件里的 bypassPermissions 比参数更强
  • 工具名靠猜来写,和实际的名字对不上
  • 写了 mcp__* 这种宽泛的许可,却没发现它被忽略了
  • 嫌麻烦,把整个服务器全部放行
  • 在无人值守执行里用 bypassPermissions,变成什么都能通过的状态

前两条正是我自己干过的事。模式名字给人的印象,和实际放行的范围有些出入。

关于 bypassPermissions,官方给了很强的提醒,前提是在隔离的容器或虚拟机里使用。对于家人的输入会原样送达的机器人来说,我觉得不太合适。

开始之前要确认的事

常见问题

Q. 为什么 claude -p 会拒绝 MCP 工具?

-p 是非交互的执行。官方写道,如果没有准备好回答确认的对象,需要确认的操作会被拒绝。在我的环境里,在明确允许 MCP 工具之前一定会被拒绝。

Q. 设成 acceptEdits,MCP 工具也会放行吗?

没有放行。按官方的说明,acceptEdits 自动放行的是文件编辑和一部分文件操作命令。其余的需要 --allowedTools 或 permissions.allow。

Q. 在 settings.json 里写了 bypassPermissions 却不生效。

请确认启动时有没有带 --permission-mode。官方写道,这个参数会覆盖设置文件里的 defaultMode。我的机器人也是卡在这里。

Q. 可以按服务器一次性放行吗?

可以。写成 mcp__<服务器名> 或 mcp__<服务器名>__*,该服务器的全部工具都在范围内。不过删除之类的也会包含进去。我是只把需要的操作逐个写出来。

Q. —allowedTools 和 —tools 有什么区别?

--allowedTools 指定的是不需要确认就执行的工具。--tools 是用来限定可用内置工具的参数。官方写道,--tools 不影响 MCP 工具。

Q. 写了允许规则也有通不过的情况吗?

似乎有。官方写道,组织设为 ask 的连接器工具,允许规则不起作用。被要求必须由用户操作的 MCP 工具也一样。在 dontAsk 模式下,这些会被拒绝。

Q. 加上 —bare 会怎样?

--bare 是省略 MCP 服务器等自动加载的模式。官方写道,MCP 服务器只会连接通过 --mcp-config 传入的那些。认证也以 API 密钥等为前提,所以加之前最好先确认一下。

Q. 有办法明确声明没有人回答确认吗?

官方列出了 --permission-prompts none 这个参数。它会拒绝需要确认的操作,并告诉 Claude 不要重试。据说需要 v2.1.259 及以上版本。我还没有用过。

参考的官方信息

总结

claude -p 拒绝 MCP 工具,是因为没有授权。acceptEdits 是为文件编辑准备的模式。外部服务的操作需要另外明确写出。

许可收到只包含要用的操作比较好。我是从 5 项操作开始的。自制机器人值不值得继续做,这笔账我在Claude Max 使用率的文章里整理过。从通知直接找 AI 商量的做法,也写在了“交给 Claude”按钮的文章里。机器人不动的时候,先看看启动参数吧。

无需签约也能获得100积分的资费模拟 查看乐天移动的资费方案

点击后会跳转到乐天登录页面,登录后即可看到活动内容。

本文包含联盟营销广告。如果您通过本站链接申请相关商品或服务,我们可能会从合作企业获得报酬。此外,运营者是乐天集团的员工,也可能通过员工推荐计划获得报酬。文章内容与评价均基于运营者的真实体验与调查完成,与是否存在广告无关,但请您在阅读前了解上述关系。详情请参阅免责声明与联盟营销说明。 免责声明与联盟营销说明

本文包含机器翻译内容。正式条件请以乐天移动官方网站的多语言页面为准。

如果您对乐天移动的通信区域·信号状况有疑问,可以通过官方的 电波改善调查申请表 进行咨询。

ABOUT THE AUTHOR
まさきん

乐天集团员工·数字营销人(持有FP资格)

40岁出头,双职工家庭、四个孩子的父亲。在乐天集团担任数字营销工作的同时,也活用理财规划师(FP)资格,专注于家庭理财与资产配置。

查看简介

相关文章

RELATED
Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围 AI活用

Gemini(Google AI Pro)家庭共享最多5名家人|设置步骤与共享范围

Google AI Pro除管理员外最多可与5名家人共享。Gemini App和存储空间可以共享,YouTube Premium Lite仅限管理员,Flow的上限由全家分摊。本文根据官方帮助整理了设置步骤和儿童账号的处理方式。

2026.10.13 · 阅读约9分钟
AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变 AI活用

AI订阅扣款日与记账对不上的3个原因|Claude升级后扣款日会改变

Claude在月中升级到Max时,计费周期会重置,当天成为新的扣款日。美元换算日元的汇率在数据到达发卡公司时确定,账单和记账App的同步也会晚几天。本文整理了以收据邮件为准来确定月份的5个步骤。

2026.10.13 · 阅读约10分钟
把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计 AI活用

把freee会计的未处理明细改成每月一次的核销班次:每月5日7:30、分3类、最多15条交给人处理的设计

freee会计里有大约18条未处理明细,连续6次每周检查都原封不动地留着。这里整理一下每月5日早上7:30在家里的Mac上运行的核销班次的设计,以及“能确定的部分每月合并成1个任务、拿不准的明细逐条交给人、上限15条”的界线。

2026.10.12 · 阅读约11分钟
转到乐天移动,最高可获14,000积分 无需签约也能获得100积分的资费模拟 →
立即申请 →