Claude Code mod:它是什么,以及我们给每个代理都装上的那个 mod
mod 是一种让 JavaScript 在 Claude Code 内部运行的插件。它能做什么、由哪三个文件组成、如何加载和测试,以及我们给每个代理都装上的那个 mod。
2026 年 10 月 1 日,Claude Code 2.1.287 发布,更新日志只有一行:“Added Claude Mods”。四天后,AgentsRoom 开始把我们的一个 mod 加载进它运行的 Claude 代理里。
本文讲清楚 mod 是什么,它能做哪些旧扩展点做不到的事,如何编写、加载和测试一个 mod,以及我们在 AgentsRoom 启动的每个 Claude 代理里装上一个 mod 学到了什么。关于 Claude Code 的事实均来自其文档和更新日志,阅读日期为 2026 年 11 月 9 日,所装版本为 Claude Code 2.1.318。
简短回答。 mod 是一个带 hooks module 的 Claude Code 插件。hooks module 是一个 JavaScript 或 TypeScript 文件,事件发生时,Claude Code 会在自己的进程里调用它的函数。函数可以放行事件、修改事件,或者代替 Claude Code 应答。mod 就是这样绘制面板、添加命令,或者在 shell 命令运行前把它拦下。
mod 是什么
Claude Code 早就有插件:一个在 .claude-plugin/plugin.json 放了清单的文件夹,把技能、子代理、settings hook 和 MCP 服务器打包在一起,作为一个整体安装。mod 是插件能装的又一样东西。当插件的 hooks/hooks.json 在 modules 键下指定一个代码文件时,Claude Code 会加载这个文件,并调用它导出的 register 函数。这时这个插件就叫 mod。
在 register 里,每次调用 on(event, hook) 都会把一个函数挂到一个事件上:工具运行前的 tool.call、你发送提示词时的 prompt.submit、session.start、斜杠命令对应的 command.run、Claude Code 绘制屏幕某一部分时的 ui.render,等等。每个 hook 都会收到三样东西:
$,mods API:mod 在自身代码之外能做的一切,比如$.ui、$.command、$.fs、$.process或$.http。e,事件本身,是普通数据:对一次工具调用来说,就是工具名和它的参数。next,把事件传给其他 mod,再交给 Claude Code 自己的行为,并返回结果。
hook 怎么处理 next,决定了接下来发生什么。返回 next(e),你只是旁观。用修改过的 e 副本调用 next,你就改写了事件。不调用 next、直接返回你自己的结果,你就替它应答了:工具根本不会运行,或者 Claude Code 自己的绘制不会发生。
文档也把这些函数叫作 hook。它们不是你写在 settings.json 里的那种 hook,后者如今被 Claude Code 称为 settings hook。
mod、settings hook、技能还是 MCP 服务器
这四者有重叠,而 mod 是其中最重的。选能完成任务的最轻的那个。
| 你想要 | 用 |
|---|---|
| 给 Claude 一些你总在聊天里反复粘贴的指令 | 技能(SKILL.md) |
| 给 Claude 能触达外部系统的工具 | MCP 服务器 |
| 用你现有的脚本拦截、放行或记录一个事件 | settings hook |
| 在提示词上方绘制面板或横条、添加无需 Claude 轮次就能运行的命令、改写或应答一次工具调用、在事件之间保持状态 | mod |
一个插件可以同时装下这四样,所以 mod 可以和它配合的技能、MCP 服务器一起发布。
mod 的三个文件
my-mod/
├── .claude-plugin/
│ └── plugin.json
└── hooks/
├── hooks.json
└── register.ts
plugin.json 是常规的插件清单:名称、版本、描述。hooks.json 指向代码,{ "modules": ["./register.ts"] },写一个相对于该文件的路径。register.ts 就是 hooks module。Claude Code 直接加载 .js 和 .ts,不需要打包器,也没有构建步骤,唯一允许的裸导入是 claude-code,用于类型和几个辅助函数。
我们发布的 mod:这个文件是谁改的?
AgentsRoom 在同一个仓库上运行多个编码代理,并在「更改」标签页里显示哪个代理改了哪个文件,这样你就能单独审查并提交每个代理的工作。用 Claude 的 Edit 和 Write 工具写的文件很好办:Claude Code 会通过 settings hook 报告它们。用 shell 命令写的文件就不行了。sed -i、heredoc、codemod 或 rm 都不经过任何文件工具。
在有 mod 之前,我们靠猜。AgentsRoom 读取代理的会话记录,得知每条 Bash 命令何时开始、何时结束,再拿文件的修改时间去对这些时间窗口。大多数时候管用,但有三种说得出名字的失败:
- 被删除的文件没有修改时间,所以删除从来没被归属;
- 像
grep这样的只读命令也会打开一个时间窗口,代理在这期间可能写了任何东西; - 它依赖会话记录的格式,而 Claude Code 可以随意改变这个格式。
mod 消除了猜测。我们的 agentsroom-changes mod 为两个 shell 工具挂钩 tool.call。命令运行前一刻,它给仓库拍一张快照(git status,加上每个有改动路径的大小和修改时间);运行后一刻,再拍一张。有差异的路径就是这条命令改动的内容,删除也包括在内,mod 通过一个本地 HTTP 端点把它们发给 AgentsRoom 桌面应用。被 Claude Code 自己标记为只读的调用不认领任何文件。
下面是精简后的 hook。完整文件有 177 行,大部分是快照及其上限的处理。
import type { Register } from 'claude-code';
const SHELL_TOOLS = new Set(['Bash', 'PowerShell']);
export const register: Register = (on) => {
on('tool.call', async ($, e, next) => {
if (!SHELL_TOOLS.has(e.tool)) return next(e);
const ready = await prepare($).catch(() => null); // agent id, repo root, snapshot
if (!ready) return next(e); // outside AgentsRoom: do nothing
const callId = e.tool_use_id;
post($, ready.agentId, { kind: 'start', callId });
const ran = await next(e); // the command runs here
const wroteNothing = ran.deny !== undefined || ran.isReadOnly === true;
await reportEnd($, { ...ready, callId }, wroteNothing)
.catch(() => post($, ready.agentId, { kind: 'end', callId, paths: [] }));
return ran; // Claude sees the normal result
});
};
桌面应用把 mod 复制到自己的文件夹里,并且只在已安装的 Claude Code 为 2.1.287 或更新版本时,用 claude --plugin-dir <that folder> 启动每个 Claude 代理。我们在 2026 年 10 月 5 日的 AgentsRoom 1.201.0 中发布了它。
发布过程中学到的
mod 绝不能让用户损失一次工具调用。 我们的 hook 挡在 Claude 运行的每条 shell 命令前面。它一旦抛错或等待网络,Claude 的工作就会停下。每一步都有保护,每次发往桌面应用的请求都是发出即不管,我们唯一接受的等待是两次 git status 快照,每次上限 15 秒。丢掉一次请求只损失一次归属,绝不会损失命令本身。
不需要你的时候,什么都别做。 mod 会读取 AgentsRoom 为它的代理设置的一个环境变量。如果没有这个变量,比如有人把文件夹复制到了自己的环境里,每个 hook 都会直接走 next(e)。
用 --plugin-dir 加载的文件夹会被监视。 文件夹里的文件一变,Claude Code 就会重新加载 mod,而每次重新加载都会再运行一次 register。这决定了我们的安装方式:桌面应用只在内容变化时才写 mod 文件,因为每次启动代理都无脑重写一遍,会让每个已经打开的 Claude 控制台都重新加载这个 mod。
做好 API 会变的准备。 事件和方法可能在版本之间变化,文档自己也这么说。从 --plugin-dir 加载 mod 时,Claude Code 会把当前运行版本的类型声明写进 .claude-plugin/types/;我们以它为准做类型检查,而不是以某个网页为准。而且如果某个版本不再加载我们的 mod,也不会坏掉什么:mod 永远不会报告就绪,AgentsRoom 就退回原来的会话记录方法。
自己写一个
有两种入门方式。
让 Claude 来写。 在交互式 Claude Code 会话里描述你想要的 mod(“在提示词上方显示当前 git 分支”)。Claude 会使用内置技能 plugin-authoring,把 mod 写进这次会话的一个文件夹,Claude Code 会问你一次是否启用 Claude 写的 mod。答应之后,mod 会在这一轮结束时加载,之后每一轮改动它都会重新加载。
自己写这三个文件,然后:
claude --plugin-dir ./my-mod # load it for one session, hot reload on save
claude plugin validate ./my-mod # what Claude Code reads from it, without running it
claude plugin test # run the mod's *.test.ts files, no session needed
claude plugin validate 会打印一行 hooks:,列出你的模块处理的事件,再打印一行 calls:,列出它调用的每个 mods API 方法。如果你本想处理的某个事件不在其中,Claude Code 也不会调用那个 hook。静态分析有规则:每次调用都写完整($.ui.toast(...),绝不写 const ui = $.ui),事件名以字符串字面量传入,只通过相对路径导入你自己的文件。
要分享一个 mod,就把它当作插件来对待:直接发送文件夹,或者把它列进一个插件市场(一个带 .claude-plugin/marketplace.json 的仓库),别人就能用 /plugin install <name>@<marketplace> 安装。
现在就能读的 mod
- Claude Code 内置:
/plugin,Installed 标签页,Built-in 区域。其中包括/diff面板,以及把AGENTS.md当作项目指令读取的加载器,Anthropic 把它们的源码连同测试公开在 anthropics/claude-code 仓库的mods文件夹里。同样内置、但要你启用才会打开的是 You should know,一个旁路代理,会指出你或 Claude 可能漏掉的东西。 - Anthropic 的示例,在 claude-code-playground 仓库里:绘制在提示词上方的上下文窗口预测,一个拦下有风险的 shell 命令并展示它会改动什么的守卫,以及一条逐步回看上一轮编辑的
/replay命令。 - 我们的,上文已介绍:一个完全没有界面、只有一个
tool.callhook 的 mod。如果你需要的是数据而不是面板,这是个值得照抄的形态。
安装别人的 mod 之前
mod 没有沙箱隔离。它以你的权限运行:可以读写你的文件,读取你的环境变量和设置(包括 API 密钥),启动程序,发起网络请求,看到每一条提示词和每一次工具调用,还能在询问你之前就批准一次工具调用。即使你开启了 Claude Code 的沙箱,它覆盖的也是 Claude 运行的 Bash 命令,而不是 mod 启动的进程。
所以安装前先读一读。克隆这个 mod,对文件夹运行 claude plugin validate:hooks: 和 calls: 两行会告诉你它监听什么、触达什么,而不运行任何东西。一个只在提示词上方画横条的 mod,没有理由调用 $.http 或 $.process。要停掉你安装的所有 mod,可以用 --safe-mode 启动单次会话,或者在 ~/.claude/settings.json 里设置 "disableAllHooks": true。
mod 在哪里运行
| 你在哪里运行 Claude Code | hook 是否运行 | mod 绘制的内容是否显示 |
|---|---|---|
终端里的 claude | 是 | 是 |
| Claude Desktop 应用的 Code 标签页(WSL 会话除外) | 是,从 2.1.286 起 | 是 |
| VS Code 扩展 | 是 | 从扩展 2.1.299 起 |
claude -p 和 Agent SDK | 是 | 否 |
| 云端会话 | 是,前提是插件能到达该会话 | 否 |
会绘制内容的 mod 应当检查自己运行在哪里,在什么都不绘制的地方退回到文本。
在 AgentsRoom 中
你不用安装任何东西:从 Claude Code 2.1.287 起,每个 Claude 代理启动时都带着这个 mod,「更改」标签页会在执行操作的代理旁边,显示它的每条 shell 命令创建、修改或删除的文件。在更旧的 Claude Code 上,AgentsRoom 照旧从会话记录里匹配 shell 写入。
同样的思路也在其他能支持的 CLI 中运行:oh-my-pi 有一个遵循同样约定的扩展,其他 CLI 则照旧用以前的方式匹配 shell 写入。如果你想更深入地利用 Claude Code 在每一步暴露的信息,我们的 Claude Code hook 指南介绍了与 mod 并列的 settings hook。
常见问题
Claude Code 里的 mod 是什么?
mod 是一个包含 hooks module 的 Claude Code 插件。hooks module 是一个 JavaScript 或 TypeScript 文件,每当发生某件事,比如一次工具调用、一条提交的提示词或屏幕某一部分要绘制时,Claude Code 都会在自己的进程里调用它的函数。每个函数都可以放行事件、修改事件,或者自己处理它。正因如此,mod 才能绘制面板、添加命令,或者拦下一条有风险的 shell 命令。
使用 mod 需要哪个版本的 Claude Code?
终端里需要 Claude Code 2.1.287 或更高版本,它于 2026 年 10 月 1 日发布,更新日志里写着“Added Claude Mods”。Claude Desktop 应用的 Code 标签页从 2.1.286 起支持。在 VS Code 扩展里,hook 可以运行,而要显示 mod 绘制的内容,需要扩展 2.1.299 或更高版本。运行 claude --version 即可查看。
mod 和 Claude Code hook 有什么区别?
写在 settings.json 里的 hook 会在事件触发时,在 Claude Code 外部运行一条 shell 命令、一个 HTTP 请求或一条提示词。mod 的 hook 是在 Claude Code 内部运行的函数。它们能做 settings hook 做不到的事:在界面上绘制、添加无需 Claude 轮次就能运行的斜杠命令、改写一次工具调用或不运行工具直接给出应答,以及在 hook 之间共享状态。
安装 Claude Code mod 安全吗?
mod 没有沙箱隔离。它以你的权限运行,可以读取你的文件和环境变量、启动程序、发起网络请求,并批准一次工具调用。只安装你信任的作者写的 mod,并且先对文件夹运行 claude plugin validate:它会在不运行 mod 的情况下,列出 mod 挂钩的事件和它发起的调用。
在哪里能找到 Claude Code mod 的示例?
Anthropic 在 anthropics/claude-code 仓库的 mods 文件夹里公开了部分内置 mod 的源码,比如 /diff 面板和 AGENTS.md 加载器,并在 anthropics/claude-code-playground 仓库里提供示例 mod。本文介绍的 AgentsRoom mod 是第四类示例:一个没有界面、只有一个 tool.call hook 的 mod。
可以关闭 mod 吗?
可以。在 /plugin 的 Installed 标签页里停用单个 mod,用 --safe-mode 启动单次会话,或者在 ~/.claude/settings.json 里把 disableAllHooks 设为 true,就能停掉你安装的所有 mod,连同你的 settings hook 一起。--safe-mode 和 disableAllHooks 不会停掉内置 mod:它们要在 /plugin 里逐个关闭。
下载 AgentsRoom
在一个窗口中运行你所有项目的所有 AI 代理。
配套应用:随时随地监控你的 Agent
使用 Claude、Codex、Antigravity CLI 或其他 AI 提供商。
把 Bug 和需求直接发送到您的公开待办清单。
继续阅读
一次 Claude Code 会话会触发 30 个 hook 事件。只有 3 个能回话。
Claude Code hook 事件的完整清单:每个事件何时触发、其中哪 15 个能阻断,以及那条悄悄吞掉大部分 hook 输出的 stdout 规则。一份在数千次代理会话的生产环境中跑出来的实战参考。
阅读全文减少 MCP 令牌消耗:我们如何把工具定义削减 60%
代理能调用的每个 MCP 工具,都是模型可能在每次请求时读取的一段 JSON。我们的工具大约有 95,000 个令牌。本文介绍如何在两分钟内测量你自己的工具,我们在不删除任何工具的前提下削减了什么,以及防止它再次膨胀的预算检查。
阅读全文写代码用哪个 AI 最好?1,200 位开发者实际启动的模型
28 天内 205,366 次代理启动:Opus 第一,GPT-6.1 Sol 第二,一半账号用的是我们默认推荐的模型。这些数字能证明什么,又不能证明什么。
阅读全文
