跳到正文
FunCoding

搜索

搜索文档、智能体、博客、Skill 和 MCP

托管和维护插件市场

把插件市场发布到用户能访问的地方、为私有市场授权、发布更新和改名而不破坏已有安装:托管方式、下载限制、私有访问、更新与版本、发布渠道、改名与移除、归档下载认证。

托管市场,就是把你的 marketplace.json 目录放在别人能用 /plugin marketplace add 添加的地方,让他们安装其中的插件,并在你推送后持续收到你的改动。本页面向运营市场的人。还没写目录文件时,从「创建市场」开始;管理员要在组织机器上要求、限制或预装市场,见「为组织管理插件」。

托管你的市场

可以托管在 GitHub、其他 git 主机、作为托管的 marketplace.json URL,或放在共享文件系统的目录里。把对应你托管位置的添加命令发给用户,并告诉他们机器上需要什么:

托管位置用户在 Claude Code 会话里运行用户需要
GitHub/plugin marketplace add your-org/your-marketplacegit,私有仓库还需要「为私有市场授权」里说明的访问权
GitLab、Bitbucket、GitHub Enterprise Server 或其他 git 主机/plugin marketplace add https://gitlab.example.com/team/plugins.gitgit 和从其机器访问该主机的能力;发完整 URL,因为 owner/repo 简写总是指 github.com
托管的 marketplace.json URL/plugin marketplace add https://plugins.example.com/marketplace.json对该 URL 的 HTTPS 访问;目录本身不需要 git
共享文件系统上的目录/plugin marketplace add /Volumes/shared/claude-plugins对该路径的读权限

要固定 GitHub 或 git URL 市场的某个分支或标签,让用户追加 #<ref>,如 your-org/your-marketplace#stable。成功添加会打印 Successfully added marketplace: your-marketplace,Claude Code 从你 marketplace.json 的 name 字段取这个名字,而不是仓库名。用户随后用条目的 name 和市场的 name 安装插件,如 /plugin install code-formatter@your-marketplace。

为仓库里所有人注册市场:要与在某仓库工作的所有人共享市场,在那里从 shell 运行一次 claude plugin marketplace add your-org/your-marketplace --scope project 并提交它写入的 .claude/settings.json。

URL 托管的市场避免相对路径条目:用户把你的市场作为裸 marketplace.json URL 添加时,Claude Code 只下载那一个文件;plugins 数组里 source 是 ./plugins/formatter 这样相对路径的条目,在安装时会失败。

托管文件的下载限制:用户把你的市场作为 marketplace.json URL 添加,或安装 archive 来源的条目时,Claude Code 从你的服务器下载文件,超出这些限制就会失败:

文件最大下载服务器响应时间重定向
url 市场来源的 marketplace.json5 MiB10 秒重定向到不同源时必须用 https://,且不能指向环回、链路本地或云元数据主机,所以从 https:// 重定向到 http:// 会失败
archive 插件来源的 zip256 MiB120 秒最多五次;每个重定向目标必须用 https://,且不能指向环回、链路本地或云元数据主机

被重定向到不同源的请求不带你在市场来源或插件条目上配置的任何请求头。归档下载后,如果 zip 超出这些解压限制,安装会失败:条目数(文件和目录)100,000;任一单个文件解压后 512 MiB;解压后总大小 1 GiB;压缩比(解压后内容为 zip 大小的 50 倍)。

在共享目录里原地编辑插件:用户从共享目录添加你的市场时,Claude Code 直接从该目录读取相对路径来源的插件而不复制,用户在下次启动会话或运行 /reload-plugins 时看到你的编辑,无需更新。不要把插件文件放进 Git LFS:用户添加托管在 git 仓库里的市场或安装它列出的基于 git 的插件时,Claude Code 把那个仓库克隆到他们的机器上,克隆从不下载 LFS 内容。用符号链接在市场内共享文件:要在你的插件与同一市场的其他部分之间共享文件,在插件目录里创建符号链接。Claude Code 把插件复制进缓存时,按目标解析的位置处理每个链接:在插件自己的目录内就保留为缓存里的相对符号链接;在同一市场的别处就被解引用,目标内容被复制到缓存里(这让元插件的 skills/ 目录可以链接到市场里其他插件定义的 skills);在市场之外则出于安全被跳过。从本地路径或默认 copy 模式的 command 来源安装的插件,Claude Code 只保留解析在插件自己目录内的符号链接。例如(Windows 上从提升权限的命令提示符用 mklink /D 或启用开发者模式):

ln -s ../../shared-plugin/skills/foo ./skills/foo

通过组织设置分发

在 Team 或 Enterprise 套餐上,你也可以通过 claude.ai 的 Organization settings > Plugins & skills 分发市场,而不是托管在用户自己添加的地方。组织同步对仓库的要求比 /plugin marketplace add 更严:在 github.com 和 gitlab.com 上市场仓库必须是私有或内部;组织同步只接受部分插件来源类型;claude.ai 会拒绝带顶层 bin/ 目录的插件并同步市场的其余部分(错误消息以 Plugin contains a top-level bin/ directory 开头),把可执行文件放到 scripts/ 等其他目录。

为私有市场授权

用户添加、安装或更新你的市场时,Claude Code 在他们的机器上运行 git,关闭交互提示,依赖该机器已有的凭据;Claude Code 自己没有 git 令牌。克隆走 SSH 还是 HTTPS,取决于你发给用户的添加命令的形式:

  • GitHub owner/repo:Claude Code 探测 ssh -T git@github.com,探测成功就通过 SSH 克隆;探测失败或 SSH 克隆本身失败时通过 HTTPS 克隆
  • git@host:path.git:SSH
  • https://example.com/repo.git:HTTPS

告诉用户每种协议在他们机器上需要什么:SSH 的密钥必须无需口令提示就能工作(例如已加载到 ssh-agent),主机必须已在 known_hosts 里;HTTPS 时 Claude Code 保持用户的 git 凭据助手启用但禁止它提示,助手已存储的凭据可用,需要它询问的则失败(在 GitHub 上 gh auth login 再 gh auth setup-git 会存一个)。GitHub Enterprise Server 主机,用户需要从其机器访问该主机的 git 权限。如果你改为通过 claude.ai 的 Organization settings > Plugins & skills 分发,用户的 git 凭据不参与。

服务没有 git 主机账号的用户

没有 git 主机账号的用户可以添加你以 marketplace.json URL 或共享目录提供的市场,但只能安装他们也能触及其条目来源的插件;指向私有 github 仓库的条目仍然需要他们有账号。这些条目来源不需要 git 账号:archive(通过 HTTPS 下载的 zip,用户既不需要 git 也不需要账号,只需要对该 URL 的网络访问;需要 v2.1.224 或更高版本;用 sha256 固定每个归档,使 Claude Code 拒绝被改动的下载);公开 git 仓库(条目给出 https:// URL 时,Claude Code 无凭据地通过 HTTPS 克隆公开的 url 或 git-subdir 来源)。对同一网络里的团队,共享文件系统上的 directory 市场也无需 git 账号,用户只需要路径的读权限。

后台自动更新如何处理凭据

后台自动更新是 Claude Code 在会话开始后对市场和已安装插件的无人值守刷新,你的市场默认关闭,直到用户或管理员打开。对私有市场开启时,检查新提交的后台检查使用用户配置的 git 凭据助手且从不提示:SSH 远程由加载在 ssh-agent 里的密钥认证;有已存凭据的 HTTPS 远程由无需提示就能提供已存凭据的助手认证(Git Credential Manager、macOS Keychain 助手和 git-credential-store 在持有该主机的凭据后都是这样);需要提示的助手的 HTTPS 远程无法在后台回答,更新静默失败,现有检出保持原位,用户的插件继续用上次同步的状态工作。检查之后:检出已是最新则保持原样;检查发现新提交,或因无法访问/认证远程而失败,Claude Code 会重新克隆市场并用新克隆替换现有检出(如果克隆失败,现有检出保持原位)。要让私有市场保持最新,用户可以:存储凭据(先登录凭据助手让它持有该主机的凭据,GitHub 上运行 gh auth login 再 gh auth setup-git),或在后台检查无法访问或认证远程时保留检出——设置 CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1,Claude Code 保留现有检出而不尝试重新克隆。仅在环境里设置 GITHUB_TOKEN 或其他提供商令牌本身不会让后台检查认证成功,令牌要通过凭据助手(如读取 GH_TOKEN 和 GITHUB_TOKEN 的 gh CLI 助手)才生效。

在全公司推行

向公司推行插件涉及你(市场所有者)、控制托管设置的管理员,以及每个使用 Claude Code 的人。没有管理员也可以推行,那样每个人自己添加市场并安装插件。

谁做什么
你,市场所有者把目录放在只有公司能读的仓库里,发送对应你托管位置的添加命令,说明每个人机器上需要什么
管理员在托管设置里用 extraKnownMarketplaces 和 enabledPlugins 为所有人注册市场并打开其插件,并在那里设置 autoUpdate
每个人需要对私有 git 仓库的读权限,凭据已存在机器上;没有管理员时还要自己运行添加和安装命令

对没有 git 主机账号的人,有这几种触达方式:不需要 git 账号的条目来源、预填的插件目录(见「给容器和 CI 做种子」)、claude.ai 组织设置(用户的 git 凭据不参与)。

让用户保持最新

你的改动通过后台自动更新(为你的市场开启后)或用户自己更新插件到达他们。两种情况下,用户只有在插件的计算版本改变时才会得到新副本。

开启自动更新:你的市场默认关闭后台自动更新,marketplace.json 里没有字段能打开它,要由用户或管理员打开:告诉用户在 /plugin 的 Marketplaces 里选中你的市场并选 Enable auto-update;或请管理员在托管设置里你的市场的 extraKnownMarketplaces 条目上设 "autoUpdate": true,这样对收到这些设置的所有人都开启。没有自动更新时,用户在会话里运行 /plugin marketplace update <name> 或在 shell 里运行 claude plugin update <plugin>@<name> 来收到你的改动。

发布新版本:要给用户发布新版本,改插件的 version;只有插件的计算版本与用户已有的不同,用户才会得到新副本,该版本先取自 plugin.json,再取自市场条目。用户从作为本地目录添加的市场里原地加载的插件不受 version 控制,它在每次会话启动时加载你当前的文件。对其他每种安装(原地加载或 command 来源除外),要么每次发布都提高 version,要么省略它:每次发布都提高 version 时,用户停留在缓存副本上直到字符串改变,如果你设了 "version": "1.0.0" 并推送新提交而不改它,用户收不到;省略 version,用户就跟踪你的提交(plugin.json 和市场条目里都不要写)。不要同时在 plugin.json 和市场条目里设 version,否则 Claude Code 会不加警告地用 plugin.json 的值,claude plugin validate 会把不一致报告为 Entry declares version "<a>" but <path>/plugin.json says "<b>"。

把用户固定在一个版本:一个市场同一时间只提供每个插件的一个版本,所以通过选择每个条目指向什么来固定版本:插件条目上的 ref 和 sha(对 github、url 或 git-subdir 来源,ref 指分支或标签,sha 指提交);添加命令上的 #<ref>(添加 your-org/your-marketplace#stable 的用户得到目录的那个分支或标签);<plugin>--v<version> 标签(依赖的版本范围对这些标签解析)。

改变 command 来源的命令:如果你改了 command 来源的 command 或切换它的 mode,每个用户要先接受新命令,Claude Code 才会运行;Claude Code 只运行用户在安装或上次更新插件时接受的那条精确命令。用户的市场副本获取到改动后,该用户会看到:不再有后台运行(命令的每会话一次运行对该用户停止,所以工具的新输出到不了他);/plugin 的 Errors 标签页出现一个条目,显示新命令和要运行的 claude plugin update 命令。告诉用户在终端运行该条目显示的命令,Claude Code 会向他们展示新命令并请求接受。

运行发布渠道

要提供稳定和早期访问两条轨道,托管两个条目指向同一插件不同 ref 的市场,让每个用户添加自己想要的那个。Claude Code 没有发布渠道的概念,一个市场同一时间只提供每个插件的一个版本。两个 marketplace.json 要有不同的 name(Claude Code 按 name 识别市场,用户不能同时注册两个同名市场)。用这两个目录,添加 stable-tools 的用户从 stable 分支安装 code-formatter,添加 latest-tools 的用户从 latest 安装:

{
  "name": "stable-tools",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": { "source": "github", "repo": "your-org/code-formatter", "ref": "stable" } }
  ]
}

另一个目录同理,name 为 latest-tools、ref 为 latest。给两个 ref 不同的 plugin.json 版本,或省略 version 让提交 SHA 来区分;更新靠比较版本检测,所以 ref 移动而版本没变会让用户停留在缓存副本上。要把渠道分配给用户组而不是让用户选择,管理员给每个组对应的 extraKnownMarketplaces 条目。

改名或移除插件

插件的 name 是它的标识符:用户在 enabledPlugins 和 pluginConfigs 设置键以及 /plugin install 里引用它,所以改名会破坏每个现有安装。想改变用户在 /plugin 里看到的标签而不破坏任何东西,在 plugin.json 里设置 displayName 并保持 name 不变。

用 renames 映射迁移用户

必须改 name 时,在 marketplace.json 里加顶层 renames 映射,让 Claude Code 迁移现有用户而不是报告 Plugin "<name>" not found in marketplace;从 plugins 里移除条目时也一样。把每个旧名映射到当前名,或插件已消失时映射到 null:

{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": "./plugins/code-formatter" }
  ],
  "renames": {
    "formatter": "code-formatter",
    "legacy-linter": null
  }
}

推送后,仍启用旧名的用户会看到:改名的条目,插件以新名加载,claude plugin list 和 /plugin 里的插件详情显示一次 Renamed to "code-formatter" in the "your-marketplace" marketplace,Claude Code 把 enabledPlugins 里的旧键重写为新键;null 条目,旧键从这些范围里被删除,用户看到 Removed from the "your-marketplace" marketplace;在托管设置里启用的,插件仍以新名加载,但 Claude Code 无法重写托管设置,所以通知会反复出现,直到管理员更新那里的 enabledPlugins。对用户从 git 仓库或 URL 添加的市场,改名后的插件会报告 Plugin "<name>" not cached at <path>,直到用户在会话里运行一次 /plugin install code-formatter@your-marketplace。把 renames 当作只增不减的历史:所有人迁移后也保留旧条目;再次改名时添加第二个条目而不是编辑第一个,因为 Claude Code 从最旧的名字顺链接跟踪。编辑映射后在 shell 里运行 claude plugin validate .,它会拒绝循环的链,或不以 null 或 plugins 里的名字结尾的链,报告 renames.<name>: chain does not resolve。

从用户机器上卸载被移除的插件

想把被移除的插件从用户机器上卸载而不是留着副本,在 marketplace.json 顶层设置 "forceRemoveDeletedPlugins": true。没有这个字段,被移除的插件保持已安装并报告 Plugin "<name>" not found in marketplace。设置后,Claude Code:把用户从你市场安装的内容与条目和 renames 映射对比,既没列出也没改名的插件视为已移除;从用户、项目和本地范围卸载每个已移除的插件(只由托管设置安装的插件保持原位);在 /plugin 里的 Flagged 标题下列出每个已移除插件,状态为 Removed from marketplace。

认证归档下载

要认证 archive 下载(如从私有注册表下载),设置 Claude Code 随之发送的 HTTP 请求头。可以在两处设置 headers:市场的 url 来源(你注册该市场时用的 url 来源,如 extraKnownMarketplaces 条目),或插件的条目(v2.1.238 或更高版本,在 marketplace.json 条目里 source 旁边设置)。任一处,当值是短期的(如注册表按需生成的令牌)时,设置 headersHelper 命令而不是 headers:Claude Code 运行命令并把它打印的 JSON 对象作为那处的请求头发送。你选的位置决定哪些下载得到请求头以及 Claude Code 何时运行命令:

位置得到请求头的下载何时运行那里设置的 headersHelper
市场 url 来源市场 URL 同源(相同协议、主机和端口)上的归档下载在每次获取该市场的 marketplace.json 之前和该源上每次归档下载之前
插件条目仅该条目自己的下载仅在用户单独安装或更新那一个插件并接受该命令时

两处设置了同名请求头时,Claude Code 发送条目的值;同一位置内,命令打印的请求头覆盖 headers 里列出的同名请求头。

给插件条目加 headersHelper

这个条目在 source 旁边设置 headersHelper,还设置了 "strict": false(Claude Code 对设置了 headersHelper 的 marketplace.json 条目的要求):

{
  "name": "my-plugin",
  "description": "Formatting commands for internal services",
  "strict": false,
  "source": {
    "source": "archive",
    "url": "https://registry.example.com/plugins/my-plugin-2.1.0.zip"
  },
  "headersHelper": "/opt/bin/mint-registry-token.sh"
}

检查条目:在 shell 里运行 claude plugin install my-plugin@your-marketplace,Claude Code 会向你展示命令和归档 URL,并在你接受后下载 zip。

编写 headersHelper 命令

无论设在市场 url 来源还是插件条目上,命令都要满足:命令文本至多 500 个可打印 ASCII 字符,且没有连续四个或更多空格;输出在 stdout 打印一个由请求头名和字符串值组成的 JSON 对象,并在 10 秒内以 0 退出;shell 和工作目录由 sh(Windows 上是 cmd.exe)运行,工作目录是配置目录(~/.claude 或 CLAUDE_CONFIG_DIR),所以要给绝对路径或 PATH 上的命令;Claude Code 移除的变量:命令设在 marketplace.json 条目或项目的 .claude/settings.json、.claude/settings.local.json 里时,Claude Code 会从环境里移除每个名字看起来像凭据的变量;Claude Code 设置的变量:url 来源命令有 CLAUDE_CODE_MARKETPLACE_URL 和 CLAUDE_CODE_MARKETPLACE_NAME,条目命令有 CLAUDE_CODE_PLUGIN_NAME 和 CLAUDE_CODE_PLUGIN_ARCHIVE_URL。生成 bearer 令牌的命令打印形如这样的对象:

{"Authorization": "Bearer eyJhbGciOiJSUzI1NiJ9"}

何时跳过命令或丢弃输出

出现以下任一情形时,headersHelper 命令不运行,或 headers 或命令输出里的请求头被丢弃:命令失败(退出码非零、运行超过 10 秒、或打印的不是字符串值的 JSON 对象,则该命令所服务的获取或下载不会发生);市场 URL 不以 https:// 开头(该 url 来源的命令不运行,请求只带它 headers 字段里列出的请求头);重定向离开源(下载被重定向到归档 URL 的源之外时,重定向后的请求不带来自市场 url 来源或插件条目的任何 headers 值或命令输出);条目设置了路由或身份请求头(Claude Code 从条目的 headers 和命令输出里丢弃 Host、Cookie、X-Forwarded-* 这类请求路由和客户端身份名称,保留 Authorization 这类认证名称);命令设在 --add-dir 目录的设置里(命令被忽略,url 来源和内联插件条目都一样,只发送该文件的 headers);托管设置阻止命令(把 disableCommandPluginSources 设为 true 会阻止 headersHelper 命令,allowManagedHooksOnly 也会阻止,除非 disableCommandPluginSources 被显式设为 false)。

用户如何接受 headersHelper 命令

用户每次单独安装或更新那一个插件时接受插件条目的命令:在 /plugin 里插件自己的视图,或用 claude plugin install 或 claude plugin update;Claude Code 会展示命令和归档 URL。在非交互 shell 里传 --yes 来接受命令;要只接受之前某次 --json 运行展示的那条命令,传 --accept-command 并带上那次运行报告的 sha256。