Skip to main content
Claude Code 插件由多个组件构建而成,例如 skills、agents、hooks 和 MCP 服务器。每个组件在插件中都有一个默认文件夹,在 .claude-plugin/plugin.json 中有一个可选的清单键来替换或添加到该文件夹,以及用户看到的名称。有关每个键的完整字段表,请参阅清单参考。 使用此页面向已加载的插件添加组件。 添加组件后,在运行中的会话中运行 /reload-plugins 或启动新会话,以便 Claude Code 加载它。要在加载前检查组件的文件,请从插件目录在 shell 中运行 claude plugin validate .。
这些情况在其他页面上有介绍:

浏览插件目录

浏览器显示了一个示例插件 my-plugin,它在其默认位置拥有每种组件的一个副本:
  • 一个审查 skill 和一个 about 命令
  • 一个 security-review 子代理
  • 一个在 Claude 编辑文件后格式化文件的 hook,以及它调用的 scripts/ 文件夹
  • 一个日志监视器
  • 一个输出样式和一个颜色主题
  • 一个 route-audit 工作流
  • 一个 hello-plugin 可执行文件
  • 默认设置
  • 一个本地 MCP 服务器和一个 Go 语言服务器
每个文件都是其格式的最小有效示例,用于展示形状而不是实用性:真实的 skill 或 agent 包含完整的说明,通常还有支持文件,真实的 hook 或监视器执行真实的工作。浏览器后的部分使用与浏览器相同的文件作为示例,并链接到更完整的文件。选择一个文件或文件夹来阅读其用途、查看其内容,并找到涵盖它的部分。

添加每种组件

下面的每个部分涵盖一种组件:其文件在插件中的位置、一个验证的示例、插件加载后用户看到的内容,以及改变默认位置的清单键。添加您的插件需要的那些;没有一个是必需的。

Skills

一个 skill 是一个 SKILL.md 文件,当其描述与任务匹配时 Claude 可以加载它。用户也可以将其作为命令运行。将每个 skill 保存在 skills/ 下的自己的目录中:
给 SKILL.md 一个 description,以便 Claude 知道何时使用它:
skills/review/SKILL.md
加载插件后,/my-plugin:review 运行 skill。命令名称和谁可以调用它遵循这些规则:
  • 命令名称:/<plugin>:<directory>,所以 my-plugin 中的 skills/review/SKILL.md 是 /my-plugin:review。如果您在 frontmatter 中设置 name,它替换最后一段,插件前缀保持不变。请参阅skill 如何获得其命令名称
  • 谁调用它:Claude、用户或两者,由 frontmatter 控制。请参阅控制谁调用 skill
您也可以将 skills 放在默认 skills/ 目录之外:
  • 其他目录:在 skills 清单键中列出它们。它们添加到默认 skills/ 扫描,而不是替换它,不像 commands 和 agents
  • 插件根目录中的单个 skill:没有 skills/ 目录且没有 skills 清单键,插件根目录中的 SKILL.md 加载为一个 skill。在其 frontmatter 中设置 name,因为否则市场安装会根据其缓存目录而不是您的插件命名 skill
要在插件中包含说明,请将其写成 skill。Claude Code 不加载插件根目录中的 CLAUDE.md,claude plugin validate 警告 CLAUDE.md at the plugin root is not loaded as project context。 对于 frontmatter 字段和支持文件,请参阅 Skills。

命令

命令是用户按名称运行的单个 Markdown 文件,例如 /my-plugin:about。
命令是较旧的格式,skills 对新工作已经取代它们。skill 以相同的方式按名称运行,它也可以在其目录中携带支持文件。为您从 .claude/commands/ 移动的文件保留 commands/。
将命令保存在 commands/<file>.md,它变成 /<plugin>:<file>。子目录添加一个段,所以 commands/db/migrate.md 是 /my-plugin:db:migrate。 命令文件采用与 skills 相同的 frontmatter。

在清单中定义命令

只有当您想将命令文件保留在 commands/ 之外的某个地方,或在 plugin.json 中定义一个短命令而不需要单独的 Markdown 文件时,您才需要这样做。设置 commands 清单键,Claude Code 读取它而不是扫描 commands/。该键采用路径、路径数组或将每个命令名称映射到 source 文件或内联 content 的对象。 此清单内联定义 /my-plugin:about,没有 Markdown 文件:
.claude-plugin/plugin.json
加载插件并在会话中运行 /my-plugin:about 以确认它已加载。 对于完整的键语法,请参阅 commands。

Agents

一个子代理是一个单独的助手,拥有自己的说明和上下文窗口,Claude 可以将任务委托给它。agents/ 下的每个 Markdown 文件定义一个:
agents/security-reviewer.md
此 agent 被命名为 my-plugin:security-reviewer,用户可以显式调用它使用 @agent-my-plugin:security-reviewer。名称形式是 <plugin>:<name>,其中 <name> 来自 frontmatter,或当没有时来自文件名。 agents 清单键替换 agents/ 扫描。

在子文件夹中组织 agents

您可以将插件 agent 文件放在 agents/ 的子文件夹中。Claude Code 递归加载它们并用冒号连接插件名称、每个子文件夹名称和文件名以形成 agent 的作用域名称。例如,my-plugin 中的 agents/review/security.md 加载为 my-plugin:review:security。两个设置改变该名称:
  • Frontmatter name:它仅替换文件名,所以 agents/review/security.md 中的 name: audit 加载为 my-plugin:review:audit
  • 清单 agents 字段:您在那里列出的文件加载时不带子文件夹名称,所以 "agents": "./custom/review/security.md" 加载为 my-plugin:security

插件 agents 中的 Frontmatter 字段

插件 agent 的 frontmatter 遵循这些规则:
  • 支持的字段:name、description、model、effort、maxTurns、tools、disallowedTools、skills、memory、background、omitClaudeMd、isolation、color 和 experimental 的 cacheTtl 键。唯一有效的 isolation 值是 "worktree"。请参阅支持的 frontmatter 字段了解每个字段的作用
  • 忽略的字段:permissionMode、hooks、mcpServers 和 initialPrompt。agent 文件不能自己添加 hooks 或 MCP 服务器,所以改为添加这些作为插件 hooks 和 MCP 服务器
  • 不解析的 Frontmatter:agent 仍然加载,每个字段都被忽略。它根据文件命名,其描述读作 Agent from my-plugin plugin。在 shell 中运行 claude plugin validate 来找到这些文件
对于每个字段的作用和优先级规则,请参阅 Subagents。

Hooks

一个 hook 在 Claude Code 生命周期中的某个点自动运行某些内容,例如在每次文件编辑后:shell 命令、HTTP 请求、MCP 工具调用、对模型的提示或子代理。将插件的 hooks 保存在插件根目录的 hooks/hooks.json 中,在顶级 "hooks" 键下,形状与 settings.json 中的 hooks 对象相同。这让您可以复制现有的设置 hook 而不改变。 此 hook 在每次 Write 或 Edit 后运行一个捆绑脚本:
hooks/hooks.json
将脚本保存在 scripts/format.sh 并使其可执行。 加载插件并要求 Claude 编辑文件。退出 0 的 PostToolUse hook 在记录中显示任何内容,所以用调试日志或脚本本身改变的内容确认它运行。 hooks/hooks.json 和 hooks 清单键中的 Hooks 都加载。对于每个事件及其有效负载,请参阅 Hook 事件。

插件 hooks 何时触发

插件的 hooks 不等待使用插件的一个 skills 或命令。Claude Code 在会话加载插件时注册它们,从那时起它们在其事件上触发。要限制 hook 何时运行,缩小其 matcher。 如果 hook 从不触发,请参阅不触发的 hooks。

环境、引用和匹配 MCP 工具

hook 的环境、${CLAUDE_PLUGIN_ROOT} 的引用和插件自己的 MCP 工具的匹配器工作如下:
  • 环境:每个 hook 进程在其环境中接收 CLAUDE_PLUGIN_ROOT 和 CLAUDE_PLUGIN_DATA,加上每个用户配置值的 CLAUDE_PLUGIN_OPTION_<KEY>,所以您的脚本可以从那里读取它们
  • 引用:当 command 没有 args 时,它通过 shell 运行,所以用双引号包装 ${CLAUDE_PLUGIN_ROOT} 路径,如 Hooks 下的 hooks/hooks.json 示例所做的那样,以保持扩展的路径为一个 shell 单词。当您改为传递 args 时,每个元素作为一个参数传递,没有 shell,不需要引用。请参阅 exec 形式和 shell 形式
  • 匹配插件自己的 MCP 工具:来自此插件声明的 MCP 服务器的工具被命名为 mcp__plugin_<plugin>_<server>__<tool>,所以在匹配器中写那个完整名称。仅在服务器名称上的匹配器从不触发。请参阅匹配 MCP 工具

MCP 服务器

MCP 服务器从外部系统为 Claude 提供工具。在插件根目录的 .mcp.json 中声明它,形状与项目 .mcp.json 相同。此 .mcp.json 声明一个名为 db 的服务器:
.mcp.json
您也可以省略 mcpServers 包装器并将 db 放在文件的顶级。 加载插件并运行 /mcp 以确认服务器显示为 plugin:my-plugin:db。 claude plugin validate 检查 .mcp.json 并报告 Claude Code 在加载时会丢弃的服务器条目为错误。需要 Claude Code v2.1.281 或更高版本。 对于坏条目在加载时显示的位置,请参阅不启动的 MCP 服务器。 mcpServers 清单键采用内联服务器映射、JSON 文件的路径或这些的数组。当清单服务器与 .mcp.json 中的一个同名时,清单服务器替换它。

到达 claude.ai 和 Cowork 中的用户

本地 stdio 服务器,例如 MCP 服务器 下的 db 服务器,在 Claude Code 和在 Claude Desktop 应用中在您的机器上运行的 Cowork 会话中运行,但不在 claude.ai 上。要到达那里的用户,通过其 https:// URL 引用远程服务器,claude.ai 和 Cowork 作为连接器提供给用户。

服务器名称、工具名称和重新加载

服务器的名称、变量替换和重新加载行为遵循这些规则:
  • 服务器名称:plugin:<plugin>:<server>,所以 my-plugin 中的 db 服务器在 /mcp 中是 plugin:my-plugin:db。使用相同的形式在 mcp_tool hook 中命名服务器
  • 工具名称:mcp__plugin_<plugin>_<server>__<tool>,所以该 db 服务器上的 query 工具是 mcp__plugin_my-plugin_db__query。这是在权限规则和 hook 匹配器中使用的名称
  • 替换:${CLAUDE_PLUGIN_ROOT} 和其他路径变量在 command、args 和 env 中被替换。args 中不需要引用,因为每个元素作为一个参数传递
  • 重新加载:当用户运行 /reload-plugins 并且重新加载应用时,配置未改变的服务器保持其连接。配置改变的服务器重新连接,您删除的服务器断开连接

包含打包的 MCPB 服务器

mcpServers 键也接受打包的服务器作为 MCPB 文件,其扩展名是 .mcpb 或较旧的 .dxt。将键指向文件,作为插件内的路径或 https:// URL:
.claude-plugin/plugin.json
服务器从包的清单中的 name 获取其名称。 对于传输和身份验证,请参阅 MCP。

LSP 服务器

LSP 服务器为 Claude 提供诊断和代码导航。如果官方代码智能插件已经涵盖您的语言,安装那个而不是写一个。否则在插件根目录的 .lsp.json 中声明服务器:
.lsp.json
文件直接将每个服务器名称映射到其配置,没有围绕映射的包装对象。command 是二进制的名称,其参数在 args 中。extensionToLanguage 需要至少一个扩展名,每个以 . 开头。 claude plugin validate 不读取此文件。当任何条目无效时,整个文件在加载时被跳过,Invalid LSP server config for ".lsp.json" 出现在 /plugin Errors 标签中。 您的插件配置连接但不安装服务器二进制,每个文件扩展名获得一个服务器:
  • 缺少二进制:Claude Code 从用户的 PATH 按名称启动 command。当二进制不存在时,服务器启动失败,claude --debug 记录 LSP server <name> failed to start
  • 扩展冲突:当两个启用的服务器声称相同的扩展名时,首先注册的处理这些文件,另一个不用于它们,无论服务器来自一个插件还是两个。/plugin Errors 标签显示警告 LSP server "<name>" is not used for <ext> files
lspServers 清单键采用相同的映射内联、JSON 文件的路径或这些的数组,其服务器添加到 .lsp.json 中的那些。当清单服务器与 .lsp.json 中的一个同名时,清单服务器替换它。 对于 transport、超时、重启和其他字段,请参阅 lspServers。 将日志输出发送到 stderr,而不是 stdout。Claude Code 仅将服务器的 stdout 读取为协议消息,并接受最多 64 KiB 的消息头和最多 32 MiB 的消息正文。 Claude Code 断开超过任一限制或向 stdout 写入非协议输出的服务器,并将断开连接计为 restartOnCrash 和 maxRestarts 的崩溃。当您使用 --debug 运行时,Claude Code 将命名原因的错误写入调试日志。

可执行文件

插件根目录中 bin/ 中的文件在启用插件时位于 Bash 工具的 shell 的 PATH 上,所以 Claude 可以将它们作为裸命令运行。添加一个可执行脚本:
bin/hello-plugin
使用 chmod +x bin/hello-plugin 使其可执行并加载插件。当您要求 Claude 运行 hello-plugin 时,Bash 工具结果显示脚本的输出。 插件 bin/ 目录在用户自己的 PATH 条目之后,所以插件不能影响 git、ls 或另一个系统命令。 claude.ai 和 Cowork 不安装具有顶级 bin/ 目录的插件,包括您通过 claude.ai 组织设置分发的那个。

默认设置

要设置在启用插件时应用的默认值,在插件根目录添加 settings.json,或将相同的对象内联放在 settings 清单键中。两个键生效,agent 和 subagentStatusLine,所有其他键都被丢弃。 设置 agent 以将插件自己的一个 agents 作为主线程运行:
settings.json
加载插件并启动会话。Claude 然后在主对话中使用 security-reviewer agent 的系统提示和模型回答。 对于键控制的所有内容,请参阅 agent 设置。 当相同的键在多个地方设置时,这些规则决定哪个值应用:
  • 文件优于清单:当两者都存在且 settings.json 设置至少一个支持的键时,settings.json 应用,清单的 settings 被忽略
  • 用户设置优于插件默认值:跨设置源,插件默认值是最低层,所以用户自己在 ~/.claude/settings.json 中的 agent 覆盖您的
  • 两个插件设置相同的键:最后加载的插件的值应用,claude --debug 记录 overrides setting
对于 subagentStatusLine 形状,请参阅子代理状态行。

主题和输出样式

插件可以包含颜色主题和输出样式。两者都显示在与用户自己相同的选择器中。对于任一个,设置清单键替换文件夹扫描。 插件主题是只读的,所以当用户在 /theme 中编辑一个时,编辑被保存为他们自己的主题目录中的副本。 此主题在深色预设上重新着色提示符强调和错误文本:
themes/dracula.json

频道

一个频道让外部系统(例如聊天应用)将消息发送到会话中。在插件中,频道是 MCP 服务器之一加上一个 channels 条目,将其绑定并可以提示其自己的配置。此清单将频道绑定到 telegram 服务器并要求机器人令牌:
.claude-plugin/plugin.json
server 必须匹配 mcpServers 中的键。每个频道的 userConfig 采用与顶级 userConfig 键相同的形状。 对于服务器必须实现的内容以及用户如何启用频道插件,请参阅频道参考中的打包为插件。对于字段表,请参阅 channels。

监视器

监视器是在整个会话中在后台运行的 shell 命令。它打印的内容作为通知到达 Claude,所以 Claude 可以对日志或状态更改做出反应,而无需被要求观看它。将条目保存在 monitors/monitors.json 中:
monitors/monitors.json
命令在 shell 中运行,在会话启动的工作目录中。 监视器的命令在它启动的位置和它可以引用的内容中受到限制:
  • 仅交互式会话:插件监视器在交互式会话中启动,从不在带 -p 标志的非交互式模式中。它们也仅在 Monitor 工具可用的地方启动
  • 无用户配置:command 获取路径变量和环境中的 ${ENV_VAR},但从不获取 ${user_config.*}。引用一个的监视器不启动,监视器进程也不接收 CLAUDE_PLUGIN_OPTION_<KEY>
  • 中途禁用:如果您在会话中途禁用插件,Claude Code 不停止已经运行的监视器。它们在会话结束时停止
experimental.monitors 清单键采用相同的数组内联或 JSON 文件的路径,并代替 monitors/monitors.json 读取。 对于 when 触发器和其他字段,请参阅 monitors。

要求用户提供配置值

在 userConfig 清单键中声明您的插件需要的值,以便用户不自己编辑 settings.json。每个选项显示在一个对话框中,其 title 作为标签,其 description 在下方。 为令牌或密码设置 "sensitive": true。对话框然后掩盖输入,值存储在安全存储中而不是 settings.json。 此清单要求端点和令牌:
.claude-plugin/plugin.json

配置对话框何时出现

对话框仅在交互式 /plugin 界面中出现。当用户执行以下任何操作时,它为任何尚未设置的选项打开:
  • 在 /plugin 中安装插件
  • 在会话内运行 /plugin install <plugin>@<marketplace>
  • 从 /plugin 中的 Installed 标签启用插件
要在任何时间打开相同的对话框,用户运行 /plugin configure <plugin>@<marketplace>。 claude plugin install shell 命令从不提示 userConfig 值。要从 shell 设置值,将每个值作为 --config KEY=VALUE 传递。当选项保持未设置时,命令打印一个 userConfig options not yet set 行,命名两种设置它们的方式。userConfig 对话框从不出现引用该行。 对于选项字段、每个值存储的位置、组件如何引用保存的值以及哪些字段拒绝 ${user_config.*},请参阅用户配置。

引用插件路径和存储数据

您不知道您的插件将被安装在哪里,所以通过这些变量而不是固定路径引用其文件和数据。它们在 skill、命令和 agent 内容、hook 和监视器命令以及 MCP 和 LSP 服务器配置中被替换。它们也被导出到 hook、MCP 和 LSP 进程:
  • ${CLAUDE_PLUGIN_ROOT}:插件的安装目录。每个版本都有自己的缓存目录,所以当插件更新时路径改变。不要在那里写状态
  • ${CLAUDE_PLUGIN_DATA}:一个在更新中存活的目录,用于 node_modules、虚拟环境和缓存。它解析为 ~/.claude/plugins/data/<id>/ 并在首次引用时创建
  • ${CLAUDE_PROJECT_DIR}:项目根目录,hooks 接收的相同值
在数据目录路径中,<id> 是插件标识符,每个字符除了字母、数字、_ 和 - 被替换为 -,所以 my-plugin@my-marketplace 变成 my-plugin-my-marketplace。 在 Windows 上,替换的路径使用正斜杠,所以 shell 不将反斜杠读取为转义。

将依赖项安装到数据目录

对于市场安装的插件,Claude Code 在缓存插件时自动安装符合条件的 Node.js 包依赖项,所以您可能不需要自己安装它们。当您这样做时,此 SessionStart hook 在首次运行时将 node_modules 安装到 ${CLAUDE_PLUGIN_DATA} 中,并在更新改变 package.json 后再次安装:
hooks/hooks.json
在第一个会话后,~/.claude/plugins/data/<id>/node_modules 存在。MCP 服务器然后可以在其 env 中设置 NODE_PATH 为 ${CLAUDE_PLUGIN_DATA}/node_modules。对于哪些字段替换哪个变量,请参阅环境变量。

后续步骤