
Claude Code SDK #19:Plugins 全解——目录结构 × Manifest Schema × 六类组件,打造可分发的 Claude 扩展包
Plugin 是 Claude Code 的完整扩展打包单元,可以同时携带 Skills、Agents、Hooks、MCP 服务器、LSP 服务器和后台 Monitor,通过 Marketplace 分发安装。本篇完整拆解 Plugin 目录结构(六类组件位置与禁区)、Manifest Schema 全字段(version/userConfig/defaultEnabled/channels 等)、六类组件深度用法、Skills-Directory 自动加载机制、本地开发调试流程,以及提交到官方 Marketplace 的完整步骤,附五条可落地的实践建议。
大多数人把 Claude Code 的能力边界画在内置工具和 CLAUDE.md 这里,但这两条线之间有一个被低估的扩展层:Plugin 系统。一个 Plugin 是一个独立目录,可以同时携带 Skills、Agents、Hooks、MCP 服务器、LSP 服务器和后台 Monitor,通过 Marketplace 分发安装。它不是「一个功能」,是一套打包和共享整套 Claude Code 行为的机制。
本篇把 Plugin 从目录结构到 Manifest Schema 到发布流程彻底拆开,拆出你写第一个可分发 Plugin 需要的全部知识。1
为什么需要 Plugin——Standalone vs Plugin 决策
Claude Code 有两种方式扩展能力:
Standalone 配置(
.claude/ 目录):技能名称短,比如 /hello,只对当前项目有效,无法安装分发,适合个人工作流和快速实验。Plugin(独立目录 + 可选
plugin.json):技能名称带命名空间,比如 /my-plugin:hello,可以发布到 Marketplace、跨项目复用、做版本管理。判断标准很简单:要给同事用、要发社区、要跨多个项目使用,就用 Plugin;只是个人项目的临时脚本,Standalone 更快。
先在
.claude/ 里快速迭代,准备好共享时再通过迁移步骤转 Plugin。Plugin 目录结构全解
一个功能完整的 Plugin 目录长这样:2
my-plugin/
├── .claude-plugin/
│ └── plugin.json # 元数据 Manifest(可选)
├── skills/
│ └── code-review/
│ └── SKILL.md # 模型调用型技能
├── commands/
│ └── deploy.md # 旧式平铺 Markdown 技能(新 Plugin 推荐用 skills/)
├── agents/
│ └── security-reviewer.md # 子 Agent 定义
├── hooks/
│ └── hooks.json # 生命周期事件处理器
├── .mcp.json # MCP 服务器配置
├── .lsp.json # LSP 语言服务器配置
├── monitors/
│ └── monitors.json # 后台 Monitor 配置
├── bin/
│ └── my-tool # 注入 PATH 的可执行文件
└── settings.json # Plugin 激活时应用的默认配置
最常见的坑:把
skills/、agents/、hooks/ 等组件目录放进了 .claude-plugin/ 里面。.claude-plugin/ 只放 plugin.json,其他一律放在 Plugin 根目录。单技能 Plugin 可以把
SKILL.md 直接放在 Plugin 根目录,不需要创建 skills/ 子目录——Claude Code v2.1.142 起自动识别这种布局,Frontmatter 里的 name 字段决定技能调用名。Manifest Schema 完整字段
plugin.json 定义 Plugin 的元数据,name 是唯一必填字段,其他全部可选:| 字段 | 类型 | 作用 |
|---|---|---|
name | string | 命名空间前缀,技能会变成 /name:skill-name |
displayName | string | UI 界面展示名(可含空格,v2.1.143+) |
version | string | Semver 版本号;设置后只在 bump 时推送更新 |
description | string | 在 Plugin 管理器展示的说明 |
author | object | name、email、url |
homepage | string | 文档 URL |
repository | string | 源码仓库 URL |
license | string | 如 MIT |
keywords | array | 搜索标签 |
defaultEnabled | boolean | 默认是否启用,false 让用户主动开启(v2.1.154+) |
版本管理策略:不设
version 字段时,Claude Code 用 git commit SHA 标记版本,每次 push 都算新版本;设了 version 后,只在你手动 bump 时用户才收到更新。发布给外部用户的 Plugin 建议显式设版本。组件路径字段允许自定义目录位置。默认路径「替换型」(
commands、agents、experimental.themes)设置后就不再扫描默认目录;「叠加型」(skills)会在默认 skills/ 之外额外扫描你指定的目录。六类组件深度拆解
Skills 与 Agents
Skills 住在
skills/ 目录,每个技能是一个带 SKILL.md 的子目录。技能名称格式 /plugin-name:skill-name,$ARGUMENTS 占位符接收用户输入:---
---
审查 "$ARGUMENTS" 提供的代码,检查:
1. 代码结构与组织
2. 错误处理
3. 安全隐患
4. 测试覆盖率Agents(子 Agent)住在
agents/ 目录,Markdown 文件。支持的 Frontmatter 字段:name、description、model、effort、maxTurns、tools、disallowedTools、skills、memory、background、isolation(仅支持 "worktree" 值)。安全限制:Plugin 提供的 Agent 不支持
hooks、mcpServers、permissionMode 这三个字段,防止 Plugin 偷偷改变权限模型。Hooks
Plugin 的 Hooks 配置格式与
settings.json 里的 Hooks 完全一致,放在 hooks/hooks.json:{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/format-code.sh"
}
]
}
]
}
}注意
${CLAUDE_PLUGIN_ROOT} 这个变量——Plugin 的 Hooks、MCP 服务器和 Monitor 配置都可以使用这个变量引用 Plugin 自身的目录,解决了路径硬编码的问题。其他可用变量还有 ${CLAUDE_PLUGIN_DATA}、${CLAUDE_PROJECT_DIR} 和 ${user_config.*}。
MCP 服务器
.mcp.json 配置 Plugin 捆绑的 MCP 服务器,语法与项目级 .mcp.json 相同:{
"mcpServers": {
"plugin-database": {
"command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
"env": {
"DB_PATH": "${CLAUDE_PLUGIN_ROOT}/data"
}
}
}
}Plugin 激活时 MCP 服务器自动启动,工具无缝集成进 Claude 的工具集,与用户自定义的 MCP 配置独立管理。
LSP 服务器
.lsp.json 给 Claude 接入语言服务器,提供实时代码诊断、跳转定义、查找引用:{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}关键字段:
command(LSP 二进制,必须在 $PATH)、extensionToLanguage(文件扩展名→语言映射)、diagnostics(是否把诊断信息推送进 Claude 上下文,默认 true)、maxRestarts(崩溃自动重启上限)。LSP Plugin 只配置连接方式,不包含语言服务器二进制本身,用户需要单独安装。官方 Marketplace 已有
pyright-lsp(Python)、typescript-lsp(TypeScript/JS)、rust-analyzer-lsp(Rust)可直接安装。Monitors(后台监视器)
Monitors 是 v2.1.105 引入的实验性组件,让 Plugin 在 Session 期间持续监听日志、文件或外部状态,并把每行 stdout 实时推送给 Claude:
[
{
"name": "error-log",
"command": "tail -F ./logs/error.log",
"description": "应用错误日志",
"when": "on-skill-invoke:debug"
}
]when 字段控制启动时机:"always"(默认,Session 开始时启动)或 "on-skill-invoke:<skill-name>"(首次调用指定技能时才启动)。Monitor 一旦启动,禁用 Plugin 也不会停止它,Session 结束才清理。仅在交互式 CLI Session 中运行,CI/无交互模式下自动跳过。
userConfig 用户可配置值
当 Plugin 需要连接外部服务(API Token、Endpoint 等)时,
userConfig 字段让 Claude Code 在用户启用 Plugin 时弹出配置表单,而不是要求用户手动改 settings.json:{
"userConfig": {
"api_endpoint": {
"type": "string",
"title": "API Endpoint",
"description": "你的团队 API 地址"
},
"api_token": {
"type": "string",
"title": "API Token",
"sensitive": true
}
}
}sensitive: true 的字段走系统钥匙链存储(或 ~/.claude/.credentials.json 备选),不写入 settings.json;钥匙链总容量约 2 KB,保持敏感值精简。配置值通过
${user_config.api_token} 语法注入到 MCP 服务器命令、LSP 配置、Hook 命令和 Monitor 命令中;以环境变量 CLAUDE_PLUGIN_OPTION_API_TOKEN 的形式也传入 Plugin 子进程。安装作用域与 Skills-Directory Plugin
安装 Plugin 时选作用域决定可见范围:
| 作用域 | 配置文件 | 适用场景 |
|---|---|---|
user(默认) | ~/.claude/settings.json | 个人全局 Plugin |
project | .claude/settings.json | 团队共享(提交进版本库) |
local | .claude/settings.local.json | 项目专属,gitignore |
managed | 企业托管 Settings | 只读,更新由管理员控制 |
Skills-Directory Plugin 是一种无需安装步骤的特殊加载方式:在
~/.claude/skills/ 或 .claude/skills/ 下的目录,只要包含 .claude-plugin/plugin.json,下次 Session 就自动以 plugin-name@skills-dir 加载。用 claude plugin init my-tool 可以直接搭架。Project 作用域的 Skills-Directory Plugin 受工作区信任门控制——只有用户接受了该目录的信任对话框才会加载;MCP 服务器需额外单独审批,Monitor 直接不加载。
本地开发与测试
开发阶段用
--plugin-dir 标志绕过安装步骤,直接加载本地目录:claude --plugin-dir ./my-plugin
# 也支持 .zip 包(v2.1.128+)
claude --plugin-dir ./my-plugin.zip
# 多 Plugin 同时加载
claude --plugin-dir ./plugin-one --plugin-dir ./plugin-two修改文件后,在 Session 内运行
/reload-plugins 即可热重载,不需要重启。热重载覆盖 Skills、Agents、Hooks、MCP 服务器和 LSP 服务器的变更;SKILL.md 内容更改在当前 Session 立即生效,无需 reload。claude plugin validate ./my-plugin 在提交前校验结构,加 --strict 把字段名拼写警告升为错误,适合在 CI 里跑。--plugin-url 标志支持直接加载远程 .zip——指向 CI 构建产物的 URL,适合测试已打包但未发布的版本。发布到 Marketplace
Anthropic 维护两个公开 Marketplace:
claude-plugins-official:Anthropic 官方策划,Claude Code 首次启动时自动注册claude-community:社区投稿,需要用户主动添加(/plugin marketplace add anthropics/claude-plugins-community),通过@claude-community前缀安装

提交流程:在 claude.ai 或 Console 提交表单,审核流程会运行
claude plugin validate 加自动安全筛查。通过后 commit SHA 被固定进社区目录,CI 自动 bump。从审核通过到 Marketplace 同步有一天左右延迟。私有发布方案:把 Marketplace 仓库托管在私有 Git repo,通过
strictKnownMarketplaces 或 blockedMarketplaces(管理员 Settings)控制组织内可信来源。五条实践建议
1. 从
claude plugin init 开始,不要手写骨架
claude plugin init my-tool --with skills hooks 一行命令生成带正确目录结构的脚手架,比手动 mkdir 少出错。首次接触 Plugin 系统时,脚手架文件里的注释本身就是文档。2. 始终显式设置
version 字段
省略 version 意味着每次 push 都推送给用户。给内部团队 Plugin 显式设版本,控制更新节奏,避免未完成的变更意外下发。3. 外部服务连接必须走
userConfig
把 API Token 硬编码进 Plugin 目录或通过文档说明让用户手改 settings.json 都是反模式。userConfig + sensitive: true 把 Token 存进系统钥匙链,是 Plugin 分发的正确方式。4. Plugin Hooks 用
${CLAUDE_PLUGIN_ROOT} 引用脚本
Hook 里调用 Plugin 自带的脚本时,一定用 ${CLAUDE_PLUGIN_ROOT}/scripts/xxx.sh 形式,不要写绝对路径。Plugin 被不同用户安装到不同位置,绝对路径会直接导致 Hook 失效。5. 提交前跑
claude plugin validate --strict
把这条命令加进 CI。它会检查目录结构、字段类型和常见拼写错误,比等到用户安装后反馈错误便宜得多。--strict 模式把字段拼错警告升为错误,能在发布前提前抓住 "skils" 这种失误。
このコンテンツについて、さらに観点や背景を補足しましょう。