跳到正文
ccmods.app

如何开发 Claude Code Mod

从空文件夹到别人一条命令就能安装的 mod。下面的示例已在 Claude Code 2.1.296 上用 claude plugin validate 和 claude -p 实测。

作者 ccmods.app 编辑部 · 更新于

Mod 由什么组成?

一个 mod 就是带 hooks module 的 Claude Code plugin。hooks module 是一个 JavaScript 或 TypeScript 文件,导出 register 函数;Claude Code 加载时调用它,你在里面用 on(事件, hook) 登记要处理的事件。

每个 hook 都会收到三个参数:$(mods API,例如 $.ui、$.command)、e(事件内容)、next(交给下层 plugin 和 Claude Code 自身处理)。不调用 next 直接返回,就表示由你来回答这个事件。

你想做的事用到的 hook 或接口
打开 pane 或在输入框上方放一条 bandui.render(Pane / AbovePrompt)、$.ui.open
重绘 Claude Code 自己的界面ui.render(如 Spinner、工具行)
拦截、改写或观察工具调用tool.call
改写提示词或系统提示词prompt.submit、prompt.compose
添加即时斜杠命令$.command.register + command.run
状态栏、toast 通知$.ui.status、$.ui.toast
调用模型、读写文件、运行进程$.model、$.fs、$.process

最快的方法是什么?

直接让 Claude 写。Claude Code 内置 plugin-authoring skill:在会话里描述你想要的 mod(例如「测试失败时弹一个 toast」),Claude 会写好代码并提示开启热重载。详见 官方 Create a mod 文档。

手写一个 Hello World

这个 mod 添加 /hello 命令,并在状态栏统计工具调用次数。目录结构:

hello-mod/
├── .claude-plugin/
│   ├── plugin.json
│   └── marketplace.json   ← makes the repo installable
└── hooks/
    ├── hooks.json
    └── register.js
.claude-plugin/plugin.json
{
  "name": "hello-mod",
  "version": "0.1.0",
  "description": "Counts tool calls and adds a /hello command",
  "author": {
    "name": "your-github-name"
  }
}
hooks/hooks.json
{ "modules": ["./register.js"] }
hooks/register.js
// Shared by every hook in this file. Resets when the mod reloads.
let toolCalls = 0

export function register(on) {
  // Add the /hello command when a session starts.
  on('session.start', async ($, e, next) => {
    await $.command.register({ name: 'hello', description: 'Say hello and show the tool call count' })
    return next(e)
  })

  // Answer /hello right away, without a Claude turn.
  on('command.run', { command: 'hello' }, async () => {
    return { text: `Hello from hello-mod! Claude has made ${toolCalls} tool calls this session.` }
  })

  // Count each tool call and show the count in the status line.
  on('tool.call', async ($, e, next) => {
    toolCalls += 1
    $.ui.status(`tool calls: ${toolCalls}`)
    return next(e)
  })
}

/hello 的 hook 没有调用 next,直接返回 { text },所以命令立即执行、不消耗 Claude 回合;tool.call 的 hook 计数后调用 next(e),工具照常运行。

怎样在本地测试?

先校验,再用 --plugin-dir 加载。

$ claude plugin validate ./hello-mod
$ claude --plugin-dir ./hello-mod

在会话中输入 /hello。交互式会话会监听该文件夹,保存文件即重新加载 mod。hook 抛错会被跳过而不是中断会话,用 claude --debug 查看原因。自动化测试:写 *.test.ts 并运行 claude plugin test ./hello-mod,见 Test a mod。

怎样发布到 GitHub?

在 plugin.json 旁边加一个 marketplace 文件,仓库本身就能被安装:

.claude-plugin/marketplace.json
{
  "name": "hello-mod",
  "description": "A hello world Claude Code mod",
  "owner": {
    "name": "your-github-name"
  },
  "plugins": [
    {
      "name": "hello-mod",
      "source": "./"
    }
  ]
}

推送为公开仓库后,任何人都可以这样安装:

$ claude plugin install hello-mod --marketplace your-github-name/hello-mod

发布前检查清单

  • claude plugin validate 无报错。
  • 插件名不要以 claude-、anthropic-、cc-plugin- 开头,这些前缀是保留的,校验会失败。
  • README 写清楚安装命令、mod 会访问什么(文件、网络、模型额度)、需要哪些 API key 或外部工具。
  • 拦截性质的 hook(会拒绝工具调用的守卫)加 .catch,否则 hook 出错时被守卫的操作会照常执行。
  • 添加 LICENSE 文件。

怎样被 ccmods.app 收录?

我们收录通过 claude plugin validate 且有 README 的 mod,并定期在 GitHub 上搜索新项目。想更快被收录,提交一个 issue 附上仓库链接即可。

继续深入:Mods reference 列出全部事件、方法和元素;也可以参考已收录的 界面类 mod 和 工具调用类 mod 的源码。