Plugins从入门到精通(中)
公众号名称:朱昆鹏AI手记
作者名称:朱昆鹏mm
发布时间:2026-05-25 15:21
一.前言
《Plugins 从入门到精通》中篇来了,咱们继续
- 上篇:讲解Plugins基础概念、目录结构和基本使用
- 中篇(当前阅读):讲解Plugins 的 manifest 完整字段、Marketplace 机制和高级配置
- 下篇:从源码角度来补充理解Plugins 的加载、缓存与运行机制
上篇我们讲了 Plugin 的”骨架”——目录怎么放、 plugin.json 长啥样、Marketplace 是什么 中篇我们要往里塞”血肉”——每一个字段到底怎么用,怎么写一个完整可用的插件
二.plugin.json 完整字段详解
上篇我们只列出了几个常用字段,那只是”皮”,真正发挥威力靠的是后面这些”内功”
根据源码 src/utils/plugins/schemas.ts 里的 PluginManifestSchema, plugin.json 一共支持 元数据 + 9 大类配置
1.元数据字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | ✅ | 插件名,kebab-case,不允许空格 |
version | string | ❌ | semver 版本(1.2.3) |
description | string | ❌ | 简介 |
author | object | ❌ | { name, email?, url?} |
homepage | string | ❌ | 必须是合法 URL |
repository | string | ❌ | 源码仓库地址 |
license | string | ❌ | SPDX 标识(MIT / Apache-2.0) |
keywords | array | ❌ | 关键字数组,用于市场检索 |
dependencies | array | ❌ | 依赖的其他插件(apt 风格) |
这一部分和 NPM 的 package.json 几乎一一对应,写起来不会陌生
2.commands —— 自定义斜杠命令
最常用的扩展点 默认情况下,插件目录下的 commands/ 子目录里的 .md 文件会被自动识别为命令
方式一:默认目录(什么都不用配)
my-plugin/
└── commands/
├── deploy.md →/my-plugin:deploy
└── format.md →/my-plugin:format
方式二:在 manifest 中显式声明额外路径
{
"name":"my-plugin",
"commands":"./extra/extra-cmd.md"
}
支持三种格式:
- 单个路径:
"./extra-cmd.md" - 数组:
["./cmd-a.md","./cmd-b.md"] - 对象映射(推荐,可以加丰富元信息):
json "commands":{"about":{"source":"./README.md","description":"查看插件介绍","argumentHint":"[版本号]","model":"haiku","allowedTools":["Read","Bash"]}}
对象映射的好处是,每个命令可以单独指定默认模型、参数提示、允许工具等
命名规则:插件名 + ”:” + 命令名 →
/:比如插件dev-tools里的deploy.md会变成/dev-tools:deploy
3.agents —— 自定义 AI 代理
代理(Agent)是 Claude Code 里”子 AI”的概念 每个 agent 是一个 .md 文件,定义专门干一件事的小助手
my-plugin/
└── agents/
└── code-reviewer.md
也可以在 manifest 显式声明:
{
"agents":["./agents/special-agent.md"]
}
加载后,AI 在对话中可以通过 Task tool 调用 agent 委托子任务
4.skills —— 插件附带的 Skills
Plugin 可以打包 Skills,命名格式 :
my-plugin/
└── skills/
├── code-review/
│ └── SKILL.md →/my-plugin:code-review
└── deploy-check/
└── SKILL.md →/my-plugin:deploy-check
也可以在 manifest 指定额外的 skills 目录:
{
"skills":["./extra-skills"]
}
Skills 的详细写法可以看《Skills 从入门到精通》三部曲
5.hooks —— 生命周期钩子
这是 Plugin 最强大的能力之一 hook 可以让你在 Claude 执行某个操作的前后自动跑你的脚本
默认目录: hooks/hooks.json
{
"description":"代码提交前自动跑 lint",
"hooks":{
"PreToolUse":[
{
"matcher":"Bash",
"hooks":[
{
"type":"command",
"command":"${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh"
}
]
}
]
}
}
根据源码 src/utils/plugins/loadPluginHooks.ts,目前支持的 hook 事件多达 29 种:
| 事件 | 触发时机 |
|---|---|
PreToolUse | 工具执行前 |
PostToolUse | 工具执行后 |
PostToolUseFailure | 工具执行失败后 |
PermissionDenied | 权限被拒绝 |
PermissionRequest | 权限请求时 |
Notification | 通知触发 |
UserPromptSubmit | 用户提交提问 |
SessionStart | 会话开始 |
SessionEnd | 会话结束 |
Stop | 会话停止 |
StopFailure | 停止失败 |
SubagentStart | 子代理启动 |
SubagentStop | 子代理停止 |
PreCompact | 上下文压缩前 |
PostCompact | 上下文压缩后 |
Setup | 初始化 |
TeammateIdle | 队友空闲 |
TaskCreated | 任务创建 |
TaskCompleted | 任务完成 |
Elicitation | 信息征询 |
ConfigChange | 配置变更 |
WorktreeCreate | Worktree 创建 |
WorktreeRemove | Worktree 移除 |
InstructionsLoaded | 指令加载 |
CwdChanged | 工作目录变更 |
FileChanged | 文件变更 |
是不是有点眼花?记不住没关系,常用的就 4 个:
PreToolUse—— 工具执行前(最常用,比如拦截危险命令)PostToolUse—— 工具执行后(最常用,比如自动格式化)SessionStart—— 启动时(注入欢迎信息、环境检查)Stop—— 结束时(清理、审计)
6.mcpServers —— MCP 服务器
MCP(Model Context Protocol)是让 AI 调用外部工具的协议 插件可以打包自己的 MCP 服务器
{
"mcpServers":{
"my-mcp":{
"command":"node",
"args":["${CLAUDE_PLUGIN_ROOT}/server/index.js"],
"env":{
"API_KEY":"${user_config.api_key}"
}
}
}
}
也支持以下几种来源:
| 格式 | 说明 |
|---|---|
"./mcp.json" | 引用外部 JSON 配置文件 |
"./bundle.mcpb" | 引用 MCPB 打包文件 |
{"server-name":{...}} | 内联配置 |
[...] | 数组形式,混合多种来源 |
注意默认情况下 .mcp.json 文件也会被自动加载,不写 manifest 也行
7.lspServers —— LSP 语言服务器
LSP(Language Server Protocol)让 AI 像 IDE 一样能做代码补全和跳转
{
"lspServers":{
"my-language":{
"command":"my-lsp-server",
"args":["--stdio"],
"extensionToLanguage":{
".myext":"my-language"
},
"transport":"stdio"
}
}
}
支持 stdio 和 socket 两种通信方式
8.outputStyles —— 输出风格
可以定义 AI 输出的风格 比如让 AI 用”简洁版”或者”详细版”回答
my-plugin/
└── output-styles/
├── concise.md # 简洁风格
└── verbose.md # 详细风格
9.userConfig —— 用户配置
这是一个特别有用的字段 它允许插件作者声明”我需要用户提供哪些信息”,安装时会弹窗让用户填
{
"userConfig":{
"api_key":{
"type":"string",
"title":"API 密钥",
"description":"用于访问 XXX 服务的 API Key",
"required":true,
"sensitive":true
},
"timeout":{
"type":"number",
"title":"超时时间",
"description":"请求超时秒数",
"default":30,
"min":1,
"max":300
},
"enable_log":{
"type":"boolean",
"title":"启用日志",
"default":false
},
"workspace_dir":{
"type":"directory",
"title":"工作目录"
}
}
}
支持的类型有 5 种:
string—— 字符串(支持multiple:true开启数组)number—— 数字(可指定min/max)boolean—— 布尔值directory—— 目录路径file—— 文件路径
重点:sensitive 字段
如果一个配置标记了 "sensitive":true:
- 输入时自动遮罩显示
- 存储到安全存储(macOS keychain / .credentials.json),不会进入 settings.json
- 在 Skill / Agent 内容中不会展开(避免敏感信息进入模型上下文)
这一招让插件安全地接入 API Key变得非常优雅
怎么在插件里读取用户配置?
通过 ${user_config.KEY} 模板变量,可以在以下地方使用:
- MCP 服务器的 command / args / env
- LSP 服务器配置
- Hook 命令
- Skill / Agent 内容(但 sensitive 字段会被屏蔽)
10.channels —— IM 频道接入
这是一个比较新的字段,让插件可以注册自己为”消息频道” 比如 Telegram、Slack、飞书的 IM 接入
{
"channels":[
{
"server":"my-telegram-mcp",
"displayName":"Telegram",
"userConfig":{
"bot_token":{"type":"string","title":"Bot Token","sensitive":true},
"owner_id":{"type":"string","title":"Owner ID"}
}
}
]
}
server 必须指向 manifest 里 mcpServers 中已声明的某个 MCP 服务器
11.settings —— 注入设置
允许插件合并一些设置到 Claude Code 的设置体系中 但是出于安全考虑,目前只允许 agent 这一个白名单字段
三.模板变量
写插件经常会用到”动态路径”,比如指向插件自己的脚本 根据源码 src/utils/plugins/pluginOptionsStorage.ts,Plugin 提供了 3 类模板变量:
1.${CLAUDE_PLUGIN_ROOT}
插件的安装目录(版本化路径)
# 比如某个插件实际安装在
~/.claude/plugins/cache/my-market/my-plugin/1.2.0/
# 那么 ${CLAUDE_PLUGIN_ROOT} 就指向上面这个目录
⚠️ 注意:这个路径会在插件更新时变化(每次更新创建新的版本目录),所以不要把用户数据放到这里
2.${CLAUDE_PLUGIN_DATA}
插件的持久化数据目录
~/.claude/plugins/data//
特点:
- 在插件更新时保持不变
- 只在最后一次卸载时才删除
- 用来存配置、缓存、用户数据
3.${user_config.KEY}
用户配置变量,对应 manifest 里 userConfig 声明的字段
"command":"${CLAUDE_PLUGIN_ROOT}/scripts/run.sh",
"env":{
"API_KEY":"${user_config.api_key}",
"DATA_DIR":"${CLAUDE_PLUGIN_DATA}"
}
4.${VAR} —— 一般环境变量
任何标准的环境变量都可以用 ${VAR} 引用 解析顺序是:plugin 变量优先 → user_config 变量 → 系统环境变量
四.Marketplace 详解
上篇我们简单提了 Marketplace,这里我们深入讲一下
1.官方 Marketplace 一览
根据源码 src/utils/plugins/schemas.ts 里的 ALLOWED_OFFICIAL_MARKETPLACE_NAMES,Anthropic 维护着 8 个官方市场:
| 名称 | 用途 |
|---|---|
claude-code-marketplace | Claude Code 通用市场 |
claude-code-plugins | Claude Code 插件市场 |
claude-plugins-official | 官方插件 |
anthropic-marketplace | Anthropic 综合市场 |
anthropic-plugins | Anthropic 插件 |
agent-skills | Agent 技能市场 |
life-sciences | 生命科学领域 |
knowledge-work-plugins | 知识工作市场 |
这些名字是保留字,只有来自 github.com/anthropics/ 的仓库才能使用,防止第三方仿冒
2.marketplace.json 完整结构
{
"name":"my-marketplace",
"owner":{
"name":"团队名称",
"email":"contact@example.com",
"url":"https://example.com"
},
"metadata":{
"description":"我们团队的内部插件市场",
"version":"1.0.0",
"pluginRoot":"./plugins"
},
"plugins":[
{
"name":"java-best-practices",
"source":"./plugins/java-best-practices",
"description":"Java 开发最佳实践",
"category":"language",
"tags":["java","backend","best-practices"]
},
{
"name":"jira-mcp",
"source":{
"source":"npm",
"package":"@my-org/jira-mcp",
"version":"^1.0.0"
},
"category":"integration"
},
{
"name":"shared-tools",
"source":{
"source":"github",
"repo":"my-org/shared-tools",
"ref":"v2.1.0"
}
}
],
"allowCrossMarketplaceDependenciesOn":["other-market"],
"forceRemoveDeletedPlugins":true
}
3.插件来源 (PluginSource) 6 种类型
根据源码 PluginSourceSchema,每个插件可以来自 6 个地方:
| Source | 配置 | 适用 |
|---|---|---|
| 相对路径 | "./plugins/foo" | 同仓库内的插件 |
github | { source:'github', repo:'owner/repo',ref?, sha?} | GitHub 整仓 |
git | { source:'git', url:'...',ref?, sha?} | 任意 Git 仓库 |
git-subdir | { source:'git-subdir', url, path,ref?, sha?} | Monorepo 子目录 |
npm | { source:'npm',package, version?, registry?} | NPM 包 |
pip | { source:'pip',package, version?, registry?} | Python 包 |
亮点: git-subdir
如果你的插件放在一个大 monorepo 的子目录里,用 git-subdir 可以只克隆子目录,省带宽 底层用的是 git sparse-checkout,对超大仓库(比如几个 GB 的)非常友好
4.7 种 Marketplace 来源
上篇也提过,市场本身也支持 7 种来源类型 这里把 7 种全列出来对比:
//1.GitHub仓库(最常用)
{"source":"github","repo":"owner/repo"}
//2.任意Git URL
{"source":"git","url":"https://gitlab.com/x/y.git"}
//3.直接给 JSON URL
{"source":"url","url":"https://x.com/m.json"}
//4. NPM 包(市场分发)
{"source":"npm","package":"@org/marketplace"}
//5.本地文件
{"source":"file","path":"/path/to/marketplace.json"}
//6.本地目录
{"source":"directory","path":"/path/to/dir/"}
//7. settings.json 内联(最骚的)
{
"source":"settings",
"name":"my-inline",
"plugins":[
{"name":"x","source":{...}}
]
}
第 7 种 settings 来源特别有意思——你可以直接在 settings.json 里写一个虚拟市场,不用单独建一个 marketplace.json 文件,特别适合临时尝试
5.插件依赖 dependencies
Plugin 之间可以声明依赖关系,类似 apt 包管理
{
"name":"advanced-deployer",
"dependencies":[
"git-helper",
"docker-tools@official-market"
]
}
依赖规则(根据 dependencyResolver.ts):
- 裸名(不带
@xxx)会默认从声明插件所在的市场解析 - 带
@market的需要跨市场授权 - 默认禁止跨市场依赖(防止信任泄漏)
- 想跨市场,需要在根市场 marketplace.json 里写:
json "allowCrossMarketplaceDependenciesOn":["other-market"]
依赖采用 apt 风格:仅保证”依赖项存在并启用”,不是模块导入
6.自动更新
根据 pluginAutoupdate.ts,Plugin 系统支持后台自动更新:
- 默认:官方市场开启自动更新(除了
knowledge-work-plugins) - 非官方市场默认不自动更新
- 启动时检查并下载新版本,但需要重启 Claude Code 才生效
- 用户可以手动开关:
bash /plugin marketplace update # 手动更新所有 /plugin marketplace update # 更新指定市场
五.三方插件库推荐
讲完原理,来推荐几个实战中比较有口碑的 Plugin 仓库(注:随着时间推移地址可能变化)
1.官方插件市场
# 添加官方市场
/plugin marketplace add anthropics/claude-plugins-official
里面是 Anthropic 官方维护的一批通用插件,安全有保障,首推
2.Agent Skills
/plugin marketplace add anthropics/agent-skills
更偏向通用 Agent 能力的市场,里面打包了一堆”AI 助理”性质的插件
3.Knowledge Work Plugins
/plugin marketplace add anthropics/knowledge-work-plugins
针对知识工作者(写作、研究、咨询、PM 等)的专项插件市场
4.各社区/团队的插件库
- Superpowers —— 社区里比较火的一套”超能力”插件
- gstack —— 一套基于 Plugin 的开发工作流(在本项目代码里可以看到很多 gstack 命令)
- superclaude / sc: —— Multi-Agent 编排插件包
5.怎么挑插件?
我自己挑插件的几个原则:
- 看作者 —— Anthropic 官方 > 知名开源团队 > 个人项目
- 看更新频率 —— 三个月以内有提交比较稳妥
- 看 issue —— 看看坑多不多,能不能修
- 看 manifest 干不干净 —— 有完整的 description、author、homepage 的更靠谱
- 看权限范围 —— 含 hooks 的插件优先看 hook 脚本内容,别盲装
六.开发一个完整插件的流程
最后用一个端到端的示例串起本篇所有知识点
假设我们要做一个 git-helper 插件:
- 提供
/git-helper:status斜杠命令 - 在每次会话开始时打印仓库状态
- 接入一个 git-mcp 服务器
- 安装时让用户配置一个工作区路径
第一步:建目录
mkdir -p git-helper/{.claude-plugin,commands,hooks,scripts}
第二步:写 plugin.json
{
"name":"git-helper",
"version":"1.0.0",
"description":"智能 Git 助手插件",
"author":{
"name":"你",
"email":"you@example.com"
},
"license":"MIT",
"keywords":["git","vcs","helper"],
"userConfig":{
"workspace":{
"type":"directory",
"title":"工作区路径",
"description":"默认查询的仓库根目录",
"required":true
}
},
"mcpServers":{
"git-mcp":{
"command":"node",
"args":["${CLAUDE_PLUGIN_ROOT}/scripts/git-mcp.js"],
"env":{
"WORKSPACE":"${user_config.workspace}",
"DATA_DIR":"${CLAUDE_PLUGIN_DATA}"
}
}
}
}
第三步:写命令 commands/status.md
---
description:查看 git 仓库状态
allowed-tools:Bash
---
帮我执行`git status`并解释当前仓库的状态
第四步:写 hook hooks/hooks.json
{
"description":"会话开始时打印仓库状态",
"hooks":{
"SessionStart":[
{
"matcher":"*",
"hooks":[
{
"type":"command",
"command":"git -C ${user_config.workspace} status --short"
}
]
}
]
}
}
第五步:验证
/plugin validate ./git-helper
如果 manifest 合法,会输出 ✅
第六步:本地测试
# 启动时加上 --plugin-dir 参数加载本地插件
claude --plugin-dir ./git-helper
测试无误后,把目录推到 GitHub,写一个 marketplace.json 就能让别人安装了
七.结尾
读完本篇,我建议你按这个顺序练手:
- 从官方市场装一个真实插件(比如
claude-plugins-official里随便挑一个),观察它的目录结构 - 写一个最简化的
git-helper(按上面流程做) - 试着加一个
PreToolUsehook,拦截一下 Bash 命令 - 用
${user_config.xxx}接入一个真实的 API Key
下篇我会从源码角度带大家走一遍 Plugin 的”一生”:
- Plugin 怎么被启动加载?
loadAllPlugins干了啥? - Marketplace 是怎么从 GitHub 克隆到本地缓存的?
- 版本化缓存 (
cache////) 怎么工作? - Hooks 怎么从 plugin 注册到全局事件系统?
- MCP / LSP 服务器怎么被启动?
我们明天再会吧~
往期推荐



内容效果不满意?点此反馈