Marketplace Manager
Guidelines for authoring, appending, and distributing plugin marketplace catalogs.
Step 1: Initialize the Marketplace
To create a new marketplace:
- Create directory: Create a dedicated git repository or local path for the catalog.
- Create config directory: Create a
.claude-plugin/directory at the root. - Create catalog file: Create a
marketplace.jsonfile inside.claude-plugin/. - Add basic setup metadata (name must be kebab-case):
{ "name": "my-marketplace", "owner": { "name": "My Name", "email": "optional@example.com" }, "plugins": [] }
Reserved names (blocked by Claude Code):
claude-code-marketplace,claude-code-plugins,claude-plugins-official,anthropic-marketplace,anthropic-plugins,agent-skills,knowledge-work-plugins,life-sciences. Names that impersonate official marketplaces (e.g.official-claude-plugins) are also blocked.
Step 2: Add Plugin Entries
To add entries to your marketplace plugins list:
- Define the
name(kebab-case). - Specify the
source— choose the type that matches your hosting:
Source Types
Same-repo subdirectory (monorepo — verified working)
{ "source": "./plugins/my-plugin-folder" }
Path is resolved relative to the marketplace root (the directory containing .claude-plugin/), not from .claude-plugin/ itself. Must start with ./.
Note: Relative paths only work when the marketplace is added via Git (GitHub, GitLab, git URL). If added via a direct URL to
marketplace.json, relative paths fail — usegithub,npm, orurlsources instead.
GitHub repository
{ "source": { "source": "github", "repo": "owner/repo", "ref": "v2.0.0", "sha": "a1b2c3d..." } }
ref and sha are optional. Omit to use the default branch.
Monorepo subdirectory via sparse clone (avoids fetching whole repo)
{ "source": { "source": "git-subdir", "url": "https://github.com/owner/repo", "path": "plugins/my-plugin" } }
Note: field is path (not subdir), and the key is source (not type). Also accepts GitHub shorthand or SSH URLs.
npm package
{ "source": { "source": "npm", "package": "@scope/my-plugin", "version": "^1.0.0", "registry": "https://registry.npmjs.org" } }
version defaults to latest; registry defaults to the public npm registry.
Non-GitHub git host
{ "source": { "source": "url", "url": "https://gitlab.com/owner/repo.git", "ref": "main" } }
The .git suffix is optional — Azure DevOps and AWS CodeCommit URLs without it work fine.
Set
strictmode (always set this explicitly — never rely on the default):Value Requires Behavior true(default when omitted)Plugin must have its own plugin.jsonplugin.jsonis authoritative; marketplace entry supplements itfalsePlugin must NOT have a plugin.jsonthat declares componentsMarketplace entry IS the entire definition Both failure modes cause the entire plugin to silently fail to load:
strict: true(or omitted) + noplugin.json→ load failure (authority source missing)strict: false+ plugin has aplugin.jsondeclaring components → conflict = load failure
Best practice for monorepo plugins: Always set
"strict": trueexplicitly and ensure your plugin directory has a.claude-plugin/plugin.json. Never omitstrictand assume the default will work.Optional: use
metadata.pluginRootto shorten relative source paths. Setting"pluginRoot": "./plugins"lets you write"source": "formatter"instead of"source": "./plugins/formatter".Optional: pin a version. Warning: do not set
versionin both the marketplace entry and the plugin'splugin.json—plugin.jsonwins silently and the marketplace version is ignored. For relative-path plugins, set version in the marketplace entry. For all other sources, set it inplugin.json.Plugin Manifest Schema Requirements (MANDATORY):
- Every plugin's
.claude-plugin/plugin.jsonMUST adhere to the clean, minimal metadata schema:{ "name": "my-plugin", "version": "0.1.0", "description": "What the plugin does", "author": { "name": "richfrem", "email": "connect.richfrem@gmail.com" }, "repository": "https://github.com/richfrem/agent-plugins-skills", "license": "MIT", "keywords": ["plugin-tag"] } - Prohibited fields:
.claude-plugin/plugin.jsonmust NEVER containskills,agents,hooks, orcommandsarrays (these are auto-discovered by Claude Code and rejected by validators). - Setting
"author": "string"causes Claude Code to fail withauthor: Invalid input: expected object, received stringduring/plugin install. - No duplicate top-level keys in
plugin.jsonormarketplace.json.
- Every plugin's
Plugin Author Note: In hooks or server configs, use
${CLAUDE_PLUGIN_ROOT}(read-only install path) and${CLAUDE_PLUGIN_DATA}(persistent state directory) instead of absolute host paths.
Step 3: Validate Before Publishing
Run validation to catch schema errors before consumers see them:
/plugin validate .
# or via CLI:
claude plugin validate .
Validator checks: plugin.json, skill/agent/command frontmatter, hooks/hooks.json syntax and schema.
Common errors:
| Error | Solution |
|---|---|
File not found: .claude-plugin/marketplace.json |
Create the file with required fields |
Duplicate plugin name "x" |
Give each plugin a unique name |
plugins[0].source: Path contains ".." |
Use paths without .. |
YAML frontmatter failed to parse |
Fix YAML syntax in the skill/agent file |
Step 4: Distribution
Publishing to GitHub (verified — Claude Code 2.1.81+)
- Create
.claude-plugin/marketplace.jsonat the repo root (not inside a subdirectory). - Commit and push to the default branch (
main). - Claude Code fetches from the default branch — the PR must be merged before consumers can install.
Consumers register the marketplace with:
/plugin marketplace add owner/repo
Example: /plugin marketplace add richfrem/agent-plugins-skills
On success, Claude Code responds: Successfully added marketplace: <name>
Known non-working subcommands (Claude Code 2.1.81):
/plugin marketplace browse— returns no content, not a supported subcommand- Use
/plugin listor/plugin helpto discover what subcommands are available in your version
Step 5: Install Plugins (Consumer)
After adding the marketplace, install any listed plugin by name:
/plugin install <name>
This opens an interactive Plugins panel (not plain text output) showing:
- Plugin name and source marketplace
- Description pulled from
marketplace.json - Scope picker: user scope (all repos) / project scope (collaborators on this repo) / local scope (this repo only)
Scope flags (if using CLI directly):
/plugin install <name>— user scope (default)/plugin install <name> --scope project— team shared/plugin install <name> --scope local— machine local
Note: The command returns no stdout — the install UI renders in the Plugins panel, not the terminal.
After install, run /reload-plugins to activate immediately without restarting. Output format:
Reloaded: N plugins · N skill · N agents · N hooks · N plugin MCP servers · N plugin LSP server
Plugin Manager TUI (/plugin)
Running /plugin with no arguments opens the full plugin manager with tabs:
- Plugins — browse all available
- Discover — explore by category
- Installed — manage active plugins
- Marketplaces — view/manage registered marketplaces
- Errors — installation or load errors
Marketplaces Tab
Shows each registered marketplace with:
• claude-plugins-official * ← * = built-in/pinned
anthropics/claude-plugins-official
117 available • 2 installed • Updated 3/22/2026
• my-marketplace-id
owner/repo
27 available • 1 installed • Updated 3/22/2026
Keybindings: Enter select · u update · r remove
Installed Plugin Detail View
Selecting an installed plugin shows:
plugin-name @ marketplace-id
Scope: project
Version: 2.0.0
<description>
Author: Author Name
Status: Enabled
Installed components:
• Skills: skill-a, skill-b
Options: Disable plugin · Mark for update · Update now · Uninstall · View repository · Back to plugin list
Team & Enterprise Distribution
Auto-install for a team (.claude/settings.json)
{
"extraKnownMarketplaces": {
"my-marketplace-id": {
"source": {
"source": "github",
"repo": "owner/repo"
}
}
},
"enabledPlugins": {
"my-plugin@my-marketplace-id": true
}
}
extraKnownMarketplaces is a keyed object (not an array) where the key is the marketplace ID (kebab-case). enabledPlugins is also a keyed object using the format "plugin-name@marketplace-id": true. Both make the marketplace and plugin available by default for every team member.
Lock to approved marketplaces only (enterprise)
strictKnownMarketplaces in managed settings restricts which sources users can add:
{ "strictKnownMarketplaces": [] } // complete lockdown
{ "strictKnownMarketplaces": [{ "source": "github", "repo": "acme/approved" }] } // allowlist
{ "strictKnownMarketplaces": [{ "source": "hostPattern", "hostPattern": "^github\\.example\\.com$" }] } // regex on host
{ "strictKnownMarketplaces": [{ "source": "pathPattern", "pathPattern": "^/opt/approved/" }] } // regex on path
Note: this is a policy gate only — it does NOT register marketplaces. Pair with extraKnownMarketplaces to pre-register allowed ones.
Pre-populate plugins in containers / CI
export CLAUDE_CODE_PLUGIN_SEED_DIR=/path/to/pre-installed-plugins
# Seed directory mirrors ~/.claude/plugins structure (known_marketplaces.json, marketplaces/, cache/)
# Seed entries are read-only — auto-updates disabled for seeded marketplaces
# To layer multiple seed dirs, separate with : (Unix) or ; (Windows)
Release channels
Point two marketplace entries at different ref values of the same repo:
{ "name": "stable-tools", "plugins": [{ "name": "my-plugin", "source": { "source": "github", "repo": "acme/plugin", "ref": "stable" } }] }
{ "name": "latest-tools", "plugins": [{ "name": "my-plugin", "source": { "source": "github", "repo": "acme/plugin", "ref": "latest" } }] }
Each ref's plugin.json must declare a different version — same version = Claude Code treats them as identical and skips the update.
Marketplace Management Commands (Consumer)
/plugin marketplace list # list all registered marketplaces
/plugin marketplace update <name> # refresh catalog from remote
/plugin marketplace remove <name> # remove (also uninstalls its plugins)
/plugin install <plugin>@<marketplace> # install (user scope default)
/plugin disable <plugin>@<marketplace> # disable without uninstalling
/plugin enable <plugin>@<marketplace> # re-enable
/plugin uninstall <plugin>@<marketplace> # remove completely
claude plugin install <plugin> --scope project # install at specific scope
Shortcuts: /plugin market = /plugin marketplace, rm = remove.
Environment Variables
| Variable | Purpose |
|---|---|
CLAUDE_CODE_PLUGIN_SEED_DIR |
Pre-populate plugins for containers/CI |
CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS |
Git clone/pull timeout in ms (default: 120000) |
GITHUB_TOKEN / GH_TOKEN |
Auth for private GitHub marketplace repos (auto-updates) |
GITLAB_TOKEN / GL_TOKEN |
Auth for private GitLab repos |
BITBUCKET_TOKEN |
Auth for private Bitbucket repos |
FORCE_AUTOUPDATE_PLUGINS=true |
Keep plugin auto-updates on when DISABLE_AUTOUPDATER is set |
SkillsMP.com (Open SKILL.md Ecosystem Marketplace)
skillsmp.com auto-indexes open-source SKILL.md skills from GitHub daily.
Requirements to Get Indexed
- Public GitHub repo with
SKILL.mdfiles containingname+descriptionfrontmatter - Add GitHub topic tags:
claude-skillsand/orclaude-code-skill - Wait up to 24 hours for the daily sync
TODO: CHECK INDEXING - Topics added to
richfrem/agent-plugins-skillson 2026-03-22. Verify at skillsmp.com after 2026-03-23.
Watch Out
Skills at plugins/<plugin>/skills/<skill>/SKILL.md (4 levels deep) may not be crawled. If not indexed after first sync, add a top-level skills/ directory mirroring the skill folders.
Step 6: Universal Marketplace Compatibility (Gemini)
To ensure your repository is installable as a native extension suite in the Gemini CLI, you must provide a manifestation file in the root directory.
1. gemini-extension.json
The manifest defines the identity and behavior of the extension:
{
"name": "my-extension-id",
"version": "1.0.0",
"description": "Universal Agent Plugins & Skills extension.",
"contextFileName": "GEMINI.md"
}
2. GEMINI.md
The contextFileName (usually GEMINI.md) serves as the "Instruction Profile" for the session.
- Consolidated rules (coding conventions, discipline).
- Specific personas or logic for the plugins in the suite.
- If missing, Gemini may fail to load the extension instructions.
Gemini Installation Command
gemini extensions install https://github.com/owner/repo
References & Examples
- references/marketplace-schema.md - Struct, vars, and strict overrides.
- examples/marketplace.json - Working sample with GitHub lookup.