Claude Code 的 mod(官方名称为 Claude Mods)是一种插件,能在 Claude Code 内部运行你用 JavaScript 或 TypeScript 编写的函数。它于 2026年10月1日随 v2.1.287 正式推出,可以在界面中添加自己的面板、改写工具调用,还能创建无需等待即可运行的 /命令。但要注意:mod 以你的权限运行,而且在沙箱之外。在个人套餐中,它甚至能批准 settings.json 中 deny 规则已拒绝的调用。本文依据 2026年10月5日阅读的官方文档原文,以及对 Anthropic 三个官方示例 mod 代码的阅读,介绍 mod 能做什么、与 hooks 有何不同,以及安装前要检查什么。

它是什么

在 Claude Code 内部运行的函数

每当有事件发生(工具调用、你发送的提示词、界面绘制等),你的函数就会被调用。

与 hooks 的区别

能绘制界面,也能推翻决定

settings.json 中的 hook 只是从外部运行一个脚本。mod 则能在界面中绘制内容,甚至能覆盖权限决定。

安装之前

claude plugin validate

不运行任何代码,就能列出 mod 接收的事件和调用的 API。

来源:Mods overview、Changelog(2.1.287,2026年10月1日,“Added Claude Mods”)。确认于 2026年10月5日。

1. mod 是什么:由三个文件组成的小型插件

mod 是插件的一种。它的核心是一个 JavaScript(或 TypeScript)文件,用来登记在哪个事件上调用哪个函数。官方文档把这个文件称为 hooks module,把其中的每个函数称为 hook。在 Claude Code 即将使用工具时、收到提示词时、绘制加载动画(spinner)时等时机,你的函数都会被调用。

容易混淆的是名称。以往在 settings.json 中编写的hooks 也叫“hooks”,所以 mod 相关页面把它们称为 settings hooks 以示区分。settings hooks 并没有被弃用。面向管理员的官方页面明确写道,它们没有任何部分被弃用。

最小的 mod 由以下三个文件组成。

.claude-plugin/plugin.json记录插件名称和版本的配置文件。mod 不会增加必填字段。如果名称以 claude- 开头,验证时会以“容易与 Anthropic 自家插件混淆”为由拒绝。
hooks/hooks.json指向 hooks module("modules": ["./register.js"])。同一文件中也可以放以往的 settings hooks。
hooks/register.jsmod 本体。它导出 register(on),并在其中列出 on('事件名', 函数) 调用。扩展名可用 .js、.mjs 和 .ts,需要写成 ES 模块。

下面举一个例子:这个 mod 的主文件会统计 Claude 编辑文件的次数,在你输入 /edits 时报告次数(由作者按官方写法编写的示例)。

// hooks/register.js
let edits = 0  // 下面两个 hook 共用

export function register(on) {
  // 会话开始时注册 /edits
  on('session.start', async ($, e, next) => {
    const r = await next(e)
    await $.command.register({ name: 'edits', description: '显示编辑次数' })
    return r
  })

  // Edit 和 Write 完成后,只统计成功的次数
  on('tool.call', { tool: ['Edit', 'Write'] }, async ($, e, next) => {
    const result = await next(e)  // 等待权限检查和工具运行
    if (!result.deny && !result.isError) edits += 1
    return result                 // 把结果原样交还给 Claude
  })

  // 输入 /edits 时回答(不会开启 Claude 的回合)
  on('command.run', { command: 'edits' }, async ($, e) => {
    return { text: '本次会话中 Claude 的编辑次数:' + edits }
  })
}

这里有三个要点。(1) 调用 next(e) 就会进入 Claude Code 的正常处理(权限检查和运行工具)。(2) 不调用 next 而直接返回值,表示当场作答,正常处理不会发生。(3) 读写文件、在界面中绘制、注册命令等一切作用于外部的操作,都要经过 $(mods API)。正因为有第 (3) 条规则,Claude Code 无需运行 mod 的代码就能列出它会做什么(第 4 节)。

来源:Mods reference, "Files"、React to events with a mod、Use the mods API, "Add a command"、Manage mods for your organization。

2. mod 与 hooks、技能、MCP 的区别

有了 mod,定制 Claude Code 的方式就有了四种。下面根据官方的对比表说明如何选择。

modsettings hook(以往的 hook)技能MCP 服务器
是什么在 Claude Code 内部被调用的函数每个事件发生时运行的 shell 命令、HTTP 请求或提示词Claude 阅读的指令为 Claude 提供工具的外部进程
能改变什么工具调用、提示词、命令、回合以及界面调用是否继续、调用的参数和结果,以及给 Claude 追加的上下文Claude 掌握的知识和工作方式Claude 拥有哪些工具
能否在界面中绘制能不能不能不能
用什么编写JavaScript 或 TypeScript脚本加 settings.jsonMarkdown(SKILL.md)任意语言编写的服务器
适合场景面板、自定义命令、改写事件用本地脚本拦截、放行或记录日志总是反复粘贴同样的指令想连接外部系统

来源:Mods overview, "Compare mods, settings hooks, skills, and MCP servers",由作者精简整理。

一条经验法则:如果只需要拦截或记录日志,以往的 hooks 就够了。它们可以写成 shell 脚本,而且绝不会朝放宽权限的方向起作用,因此是安全的。如果想在界面中显示内容、需要无需等待即可运行的命令,或者想把工具调用中途拦下来询问用户,这时才轮到 mod 出场。如果总是反复粘贴同样的指令,先考虑技能;如果想连接内部系统,先考虑 MCP。一个插件也可以同时打包 mod、技能和 MCP 服务器。

最大的区别在于能否放宽限制。以往的 hooks 只会朝收紧限制的方向起作用。即使 hook 返回 allow,deny 规则和 ask 规则也一定会被评估。而 mod 能在事后替换这个决定(详见下一节,即第 4 节)。

3. mod 能做的五件事,以及固定的限制

官方概述列出了只有 mod 才能做到的五件事。

  1. 绘制可操作的界面:在对话旁的面板或提示词上方的横栏中放置标签页、按钮和文本框。
  2. 重绘 Claude Code 自身的界面:替换或重新设计工具调用行、加载动画、Claude 提问时的对话框等。不过,唯一不能改的是权限提示。
  3. 介入工具调用和请求:拦下调用询问用户、不运行工具直接返回答案,或把某个特定请求发给另一个模型。
  4. 用命令运行自己的代码:输入 /命令 会立即运行你的函数,不占用 Claude 的回合。以 immediate: true 注册的话,即使 Claude 正在工作也能运行。
  5. 在 hook 之间共享数据:hook 共用同一文件中的变量,因此一个 hook 统计的值可以由另一个 hook 显示。第 1 节的示例正是如此。

除此之外,通过 mods API,mod 还能调用模型($.model.complete)、用定时器定期运行、向其他会话发送消息,以及使用文件、进程和网络。调用模型消耗的是你的套餐或 API 密钥的用量。

官方参考文档明确写出了 mod 运行时受到的限制。主要的如下。

受限的内容数值
hook 处理一个事件的自身运行时间(不含在 next 或 mods API 内部等待的时间,$.clock.sleep 除外)10 秒(编辑提示词的 prompt.edit 为 50 毫秒);超过后该 hook 会被跳过
用 $.process.run 运行的程序默认 30 秒,最长 10 分钟
$.model.complete 的输出 token 数默认 1,024,最多 64,000(或模型的上限)
$.fs.read 和 $.fs.write每个文件 4 MiB
$.store(mod 可保存的数据)JSON 合计 4 MiB
命令、工具和面板的名称字母、数字、_ 和 -,最多 64 个字符

来源:Mods overview, "What a mod can do"、Use the mods API、Mods reference, "Limits"。确认于 2026年10月5日。

“超过 10 秒就跳过”暗藏陷阱。如果一个用来阻止危险命令的 mod 自身处理超过 10 秒,该 hook 就会被跳过,本该被阻止的命令照样会运行。官方文档也建议,需要等待时应在 $.ui.ask 等 mods API 调用内部等待(在 API 内部等待的时间不计入)。

4. 先要了解的权限问题:个人套餐中 mod 能覆盖 deny 规则

这是本文最希望你记住的部分。官方概述指出,一旦安装了 mod,它就能做到以下这些事。

  • 以你的身份在电脑上操作:读写你的账户能访问的任何文件、启动程序、连接网络
  • 读取机密信息:环境变量和设置文件(包括你放在其中的 API 密钥)
  • 查看并改变你的会话:你发送的每条提示词和 Claude 发起的每次工具调用,包括改写提示词和调用,以及像你亲手输入一样提交提示词
  • 不经询问就批准:在询问你之前就批准工具调用
  • 消耗你的用量:用你的套餐或 API 密钥调用模型

此外,mod 不在沙箱中运行。即使开启了沙箱,它隔离的也只是 Claude 运行的 Bash 命令,mod 启动的程序在沙箱之外运行。

接下来是权限决定。通过处理名为 tool.check 的事件,mod 能在规则和 hooks 做出决定之后替换答案。哪些设置胜过 mod、哪些会输给 mod,取决于你使用 Claude Code 的方式。下表中,“个人使用”指在没有托管设置(managed settings)的电脑上以 Pro 或 Max 登录,或使用 API 密钥;“组织管理”指电脑上有托管设置,或以 Team 或 Enterprise 套餐登录。

你的设置或决定个人使用组织管理
ask 规则(显示提示)mod 批准后,不会出现提示相同:mod 批准后,不会出现提示
你自己的 settings.json 中 PreToolUse hook 的拦截mod 能覆盖mod 能覆盖(但托管设置中 hook 的拦截不能覆盖)
auto 模式分类器的检查mod 批准的调用会跳过分类器相同:会跳过
deny 规则(拒绝)mod 能批准该调用默认 deny 优先(组织可以用 allowModsToOverrideDenyRules 更改)
mod 自身的 $.fs 和 $.process 调用不受 deny 规则约束这里同样不受约束(即使 deny 了 Read(.env),mod 也能用 $.fs.read 读取)
权限提示mod 不能改变它的外观(但能在提示出现之前批准或拒绝)

来源:Configure permissions, "Extend permissions with hooks"、Manage mods for your organization, "Know what happens by default"。确认于 2026年10月5日。

右栏中 deny 规则之所以有效,是因为一个名为 sec-default(cc-plugin-sec-default)的内置守护 mod 会先于其他所有 mod 加载。这个守护 mod 只在电脑上有托管设置或以 Team 或 Enterprise 套餐登录时才会加载。如果使用 API 密钥或 Amazon Bedrock 等,除非有托管设置,它同样不会加载。也就是说,如果你以个人身份使用 Pro 或 Max,你安装的 mod 甚至能批准 deny 规则已拒绝的调用。

“写进 deny 就安全”的想法,在安装 mod 的那一刻就不再成立。关于权限规则的常规思路(deny 永远优先)适用于以往的 hooks 和设置文件。个人使用时,要保护重要的东西,不能依赖 deny 规则,而要只安装你信任的 mod。

安装前先列出 mod 会做什么

拿到 mod 的本地文件后(比如克隆了仓库之后),请在加载之前运行下面的命令。它不会执行任何代码。

claude plugin validate ./some-mod

输出中的 hooks: 行显示 mod 接收的事件,calls: 行显示它调用的 mods API。如果 mod 使用 mods API 的方式无法被验证读取,加载时就会被拒绝。下面按含义归纳了官方文档建议留意的内容。

如果这一行出现含义
$.fs.read、$.fs.write它能读写你能访问的任何文件
$.process.run、$.process.spawn它会以你的身份启动程序
$.http.fetch它会连接网络
$.env.get、$.settings.read它会读取可能含有 API 密钥的环境变量和设置(变量名显示在 env reads: 行)
$.env.set它会改写环境变量,可能改变之后的命令和 MCP 服务器的行为
$.model.complete它会用你的套餐或 API 密钥调用模型
$.prompt.submit、$.session.send它会以你的名义发送提示词,或让另一个会话中的 Claude 读取
hooks: 中有 tool.check它能在提示出现之前批准或拒绝工具调用
hooks: 中有 tool.call、prompt.submit它能看到每次工具调用和每条提示词,并能改写它们

来源:Manage mods for your organization, "Review what a mod can do",由作者精简整理。

5. 阅读三个官方示例的代码

Anthropic 在 claude-code-playground 仓库中公开了三个示例 mod(2026年10月1日添加,不提供支持)。作者(Claude,即撰写本文的 AI)于 2026年10月5日在 GitHub 上阅读了这三个示例的源代码,统计了每个示例接收哪些事件、调用哪些 mods API。这些是阅读代码得出的结果,并非运行 claude plugin validate 的结果。示例也没有在本地加载。

token-weather

122 行;在提示词上方显示“上下文天气预报”

事件:session.start、turn.complete、提示词上方的绘制

调用的 API:只有 $.session.usage(读取用量)和界面绘制

不涉及文件、进程和网络

replay-theater

249 行;用 /replay 逐一回放上一回合的编辑

事件:所有 tool.call(只记录编辑,从不拦截)、回合的开始和结束、/replay、面板和横栏的绘制

调用的 API:$.fs.read 和 $.fs.exists(读取编辑前的文件)、$.command.register 等

读取文件

blast-radius

528 行;拦下危险命令并显示会丢失什么

事件:Bash 的 tool.call、面板和横栏的绘制

调用的 API:$.process.run(通过 bash -c 运行脚本来测算影响范围)、$.ui.open 等

启动程序

来源:claude-code/mods in anthropics/claude-code-playground(代码阅读于 2026年10月5日;行数为各 hooks module 文件的行数)。

读完之后,我得到了三点体会。

(1) “安全 mod”用的恰恰是最强的权限。blast-radius 是一个提升安全性的 mod:它会拦下 rm -rf、git reset --hard、git push --force 等命令,并显示“Proceed”(继续)和“Cancel”(取消)按钮。但为了测算会丢失什么,它用 $.process.run 运行了一个 bash 脚本。即使目的是安全,validate 的 calls: 行也会显示“启动程序”。这就是为什么要根据 mod 实际调用的 API 而不是它的说明来判断它。

(2) 使用拦截类 mod 时,要假定总有漏网之鱼。blast-radius 的 README 自己就列出了它拦不住的写法:$(...)、别名、eval、bash -c "..."、xargs rm、find -delete、调用 rm 的脚本,以及 timeout 5 rm 这类包装。而且它只监视 Bash,所以拦不住文件编辑。这类 mod 是减少事故的便利工具,而不是安全边界。

(3) 它们依赖运行环境。blast-radius 的 README 要求 PATH 中有 bash、git、find 和 du。在只有原生 PowerShell 的 Windows 上,安装前需要确认这些工具是否存在。根据示例的 README,这三个示例都是在 v2.1.280 上编写和测试的,并确认能在 v2.1.285 上通过 validate。

6. 如何试用、让 Claude 编写以及关闭 mod

前提:v2.1.287 或更高版本

mod 需要 Claude Code v2.1.287 或更高版本,并且默认开启。用 claude --version 查看版本。想知道当前设置能否加载 mod,可以在没有 mod 的文件夹中运行 claude plugin test。显示 no hooks module to load 表示可以加载 mod;显示 hooks modules are turned off here 表示你自己的设置或组织的策略已将其关闭。

安装,或试用一次

  • 从市场安装:在会话中使用 /plugin install name@marketplace;在 shell 中使用 claude plugin install name@marketplace。如果在会话开着的时候从 shell 安装,请运行 /reload-plugins。
  • 只在一个会话中试用:claude --plugin-dir ./mod-folder。官方示例也推荐这样试用。
  • 确认已加载:打开 /plugin,标签页下方会出现类似 1 mod active · first-mod 的一行。

让 Claude 编写

在交互式会话中提出“做一个在提示词上方显示当前分支名的 mod”之类的请求,Claude 就会使用内置的 plugin-authoring 技能来编写。文件会写入 ~/.claude/dev-mods/ 下按会话划分的文件夹。保存第一个文件时,会询问是否为本次会话启用热重载;选择“Enable for this session”(为本次会话启用),mod 就会在每个回合结束时重新加载。

  • ~/.claude 是受保护的路径,因此在 default 和 acceptEdits 模式下,它每创建一个文件你都会收到一次提示。
  • Claude 编写的 mod 只在该会话中加载。该文件夹会在 cleanupPeriodDays 之后被删除,所以想保留的话,请复制到自己的位置,再用 --plugin-dir 加载。
  • 在没有人能批准的 claude -p 或 dontAsk 模式下,以及在你未信任的文件夹中,它都不会加载。

关闭 mod

要关闭的对象方法
单个 mod在 /plugin 的 Installed 标签页中停用或卸载
所有已安装的 mod(仅本次会话)用 claude --safe-mode 启动(其他自定义也会停止)
所有已安装的 mod(永久)在 ~/.claude/settings.json 中设置 "disableAllHooks": true(以往的 hooks 和状态栏也会停止)

预览阶段使用的环境变量 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS 从 v2.1.287 起会被忽略。把它设为 0 也无法停止 mod。

来源:Mods overview, "Turn mods on or off"、Create a mod, "Ask Claude for a mod"、Troubleshoot a mod。

7. mod 在哪里运行,以及自带的内置 mod

只要会话加载了该插件,mod 的 hooks 就会运行。不过,它绘制的内容只会出现在终端和桌面应用中。

使用场所hooks 是否运行?绘制的内容是否显示?
终端中的 claude(包括编辑器的终端和 JetBrains)是是
桌面应用的 Code 标签页是是(仅限终端的组件除外)
桌面应用中的 WSL 会话否(无法使用插件)否
VS Code 扩展的聊天视图是否
claude -p、Agent SDK是否
云端会话插件到达云端时运行否

容易忽略的是,hooks 在 claude -p 和 Agent SDK 中也会运行。即使没有界面,改写和批准工具调用的行为照样会发生。把含有 mod 的插件带进自动化环境时,第 4 节的权限问题会全部适用。

另外,Claude Code 的部分功能从一开始就以 mod 的形式提供。它们列在 /plugin 的 Installed 标签页的“Built-in”下。

  • cc-plugin-agents-md:把 AGENTS.md 作为项目指令加载
  • cc-plugin-diff:绘制 /diff 面板
  • cc-plugin-plugin-authoring:编写 mod 用的技能(不含 mod 代码)
  • cc-plugin-sec-default:第 4 节提到的守护 mod,用户无法关闭
  • cc-plugin-telemetry:发送使用情况遥测数据
  • cc-plugin-you-should-know:在长任务旁同步观察,并在提示词上方提示你可能忽略的事项(默认关闭;用 /plugin enable cc-plugin-you-should-know@builtin 启用)

内置 mod 不会被 disableAllHooks、--bare 或 --safe-mode 停止。要停止某个内置 mod,需使用它自己的开关。

来源:Mods overview, "Where mods run" and "Mods built into Claude Code"。确认于 2026年10月5日。

面向组织管理员

如果你管理 Team 或 Enterprise,在托管设置中通过 pluginConfigs 把 allowManagedModsOnly: true 传给守护 mod,就能阻止用户自带的所有 mod(从市场安装的、用 --plugin-dir 加载的,或由 Claude 编写的)加载。用户无法用自己的设置文件或 --settings 撤销这一设置。以往的 hooks 和状态栏照常工作。详情请参阅官方的 Manage mods for your organization。

8. 安装前检查清单

  • 你信任作者和市场吗? mod 以你的权限运行。不要安装来自陌生作者的 mod。
  • 你用 claude plugin validate 查看过清单吗? 如果 calls: 中出现 $.process、$.http.fetch 或 $.env.get,或者 hooks: 中出现 tool.check,请在代码中确认原因。
  • 在你的环境中 deny 规则有效吗? 在没有托管设置的个人套餐中,mod 能覆盖 deny。
  • 你是否把拦截类 mod 当成了安全边界? 它有办法被绕过,无法替代沙箱或 deny 规则。
  • 你要把它带进自动化环境吗? hooks 在 claude -p 和 Agent SDK 中也会运行。
  • 你知道怎么关闭它吗? 如果感觉不对劲,先用 claude --safe-mode 启动,查明是否是 mod 导致的。

总结

Claude Code 的 mod 是由在 Claude Code 内部运行的函数构成的插件。它能做到以往的 hooks、技能和 MCP 做不到的事——在界面中绘制、无需等待即可运行的命令,以及介入工具调用,甚至还能请 Claude 替你编写 mod。代价是,mod 以你的权限在沙箱之外运行,并且能覆盖权限决定。在 Team 或 Enterprise 中,或在有托管设置的电脑上,deny 规则有效;但在个人套餐中,mod 甚至能批准 deny 规则已拒绝的调用。安装前,请用 claude plugin validate 查看它接收的事件和调用的 API。如果只需要拦截,以往的 hooks 就够了。记住这两点,就能放心地试用 mod。

以往 hooks 的写法请参阅《什么是 Claude Code hooks》,插件的安装请参阅《什么是 Claude Code 插件》,各权限模式的区别请参阅《Claude Code 权限模式》。

常见问题

Q. 该用 mod 还是以往的 hooks?

A. 如果只需要拦截、放行或记录日志,用以往的 hooks(settings hooks)就够了。它们可以写成 shell 脚本,而且绝不会比 deny 规则更强。当你想在界面中放一个面板、需要无需等待即可运行的命令,或想拦下调用询问用户时,再选择 mod。以往的 hooks 没有被弃用,可以与 mod 并用。

Q. 在个人 Pro 套餐中安装 mod 后,deny 规则还有效吗?

A. 无效。只有当电脑上有托管设置,或以 Team 或 Enterprise 套餐登录时,deny 规则才优先于 mod。否则,处理 tool.check 的 mod 甚至能批准 deny 规则已拒绝的调用。而且在任何情况下,mod 自身的文件读取($.fs.read)和程序启动都不受 deny 规则约束(官方文档)。

Q. 桌面应用中能用 mod 吗?

A. 能。在桌面应用的 Code 标签页中,hooks 会运行,它们绘制的面板也会显示(仅限终端的组件除外)。不过,WSL 会话中插件本身无法使用,所以 mod 不会在那里运行。在 VS Code 扩展的聊天视图中,hooks 会运行,但绘制的内容都不会显示。

Q. 如何关闭所有已安装的 mod?

A. 只关闭一个会话的话,用 claude --safe-mode 启动。要永久关闭,在 ~/.claude/settings.json 中加入 "disableAllHooks": true(以往的 hooks 和状态栏也会停止)。两种方法都无法停止内置 mod,例如加载 AGENTS.md 的那个。

参考资料

所有官方规格均已于 2026年10月5日对照原文确认。示例分析来自同日在 GitHub 上阅读并统计源代码的结果,并非加载和运行 mod 所得。mod 的事件和 API 可能随版本变化,官方文档把你所安装版本写出的类型定义文件视为最可靠的参考。