Plugins & Marketplaces
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page is written against the Claude Code CLI 2.1.283, VS Code 1.139 with the GitHub Copilot Chat
extension, and the GitHub Copilot CLI 1.0.88, all re-verified as current as of 2026-09-28; re-check the
linked docs before relying on an exact field name, since both products change these surfaces often. Every
ai-catalog example is excerpted from the repository at the pinned commit
58fb709
(main).
A plugin is a directory of skills, agents, hooks, MCP servers and other components that Claude Code installs and loads as one unit, instead of a team copying loose skill folders into every project. A marketplace is a git repository or directory that lists plugins and where to fetch each one, so installing and updating a whole set of customizations is one command rather than a manual file copy. Both concepts also now exist, under the same names, on GitHub Copilot — covered at the end of this page.
What a plugin can bundle
A plugin’s component types are the same surfaces the rest of this sub-section covers individually, packaged together:
| Component | Covered in depth on |
|---|---|
Skills |
|
Agents (subagents) |
|
Hooks |
|
MCP servers |
|
Commands (flat |
Once a plugin is enabled, every skill, agent and command it defines that Claude can invoke on its own has its
name and description loaded into context on every turn, in every session where the plugin is enabled — exactly like a project-level skill — so a plugin with many always-on components has a real, ongoing context
cost even in sessions that never use it. Verified against
Claude Code — Plugins overview.
The plugin manifest: .claude-plugin/plugin.json
A plugin’s manifest is optional — without one, Claude Code loads whatever it finds in the
standard directory layout below, and the plugin’s name comes from its
marketplace entry. Write a manifest when the plugin needs metadata, a component outside its default location,
userConfig, or an inline component definition. The manifest lives at .claude-plugin/plugin.json under the
plugin root; every other plugin file (skills/, commands/, hooks/, and so on) sits at the plugin root
itself, not inside .claude-plugin/.
The table below covers every top-level plugin.json field currently documented, verified against
the Claude Code plugin manifest reference:
| Field | Type | What it does |
|---|---|---|
|
string |
A JSON Schema URL for editor autocomplete; Claude Code ignores it at load time. |
|
string |
Required. The plugin’s kebab-case identifier. Every component it defines is namespaced under it, so a skill
|
|
string |
A human-readable name shown in the UI in place of |
|
string |
A version string (not checked against semver). Setting it pins users to that version until it changes; see "Installing, versioning and updates" below. |
|
string |
A short explanation of what the plugin provides. |
|
object |
|
|
string |
A documentation URL. Must parse as a URL or the plugin fails to load. |
|
string |
The source repository URL. Not validated. |
|
string |
An SPDX identifier, e.g. |
|
array of strings |
Discovery tags. |
|
object |
A free-form object for the plugin author’s own data; Claude Code doesn’t read it. |
|
boolean |
Whether the plugin starts enabled when a user hasn’t set it explicitly in |
|
array |
Other plugins that must be enabled for this one to work; each entry is a bare name, |
|
path or array of paths |
Extra directories to scan for skills (each a |
|
path, array of paths, or object map |
Flat |
|
path or array of paths |
Agent |
|
path, object, or array of either |
A |
|
path, object, or array of either |
A |
|
path, object, or array of either |
A |
|
path or array of paths |
Output style files or directories (see
Output Styles, Status Line & More). Replaces the default
|
|
object |
Settings applied while the plugin is enabled; only |
|
object |
Values Claude Code prompts the user for when the plugin is enabled ( |
|
array of objects |
Message channels the plugin provides, each bound to one of its MCP servers. |
A workflows field and an experimental container (themes, monitors, evals) also exist for narrower
cases; see the reference above for their exact shapes. Every component path must start with ./, must resolve
inside the plugin root, and must exist — claude plugin validate ./my-plugin checks both before you ship.
Directory layout
Each component type has a default location under the plugin root, used whenever the manifest doesn’t point somewhere else:
| Component | Default location | Notes |
|---|---|---|
Manifest |
|
Optional. |
Skills |
|
One |
Commands |
|
Flat Markdown command files; prefer |
Agents |
|
Agent Markdown files. |
Hooks |
|
Hook configuration, in the same shape as |
MCP servers |
|
MCP server definitions, in the same shape as a project |
Output styles |
|
Output style Markdown files. |
Executables |
|
Files here are put on the Bash tool’s |
my-plugin/
├── .claude-plugin/
│ └── plugin.json # manifest: name, version, description, ...
├── skills/
│ └── review/
│ └── SKILL.md # runs as /my-plugin:review
├── agents/
│ └── reviewer.md # a subagent Claude can delegate to
├── hooks/
│ └── hooks.json # hooks that run on lifecycle events
└── .mcp.json # adds an MCP server, giving Claude tools
Verified against the plugin manifest reference's standard layout table and the plugins overview's component diagram.
A concrete example: packaging a subset of ai-catalog
ai-catalog has no .claude-plugin/plugin.json and no marketplace.json on main at the pinned commit;
today its 102 iru- skills are distributed by copying .claude/skills/ folders directly into a consuming
repository, and Plugins / Packaging and distributing skills, agents, and CLAUDE.md
describe plugin packaging only in prose. The plugin.json and marketplace.json below are a *new,
illustrative example, written for this page, that would package three of its real, pinned components — the
iru-check-license and iru-check-security skills plus the iru-gate-runner agent — as an installable
plugin. Nothing here ships in ai-catalog today.
ai-catalog-gates pluginai-catalog-gates/
├── .claude-plugin/
│ └── plugin.json
├── skills/
│ ├── iru-check-license/
│ │ └── SKILL.md
│ └── iru-check-security/
│ └── SKILL.md
└── agents/
└── iru-gate-runner.md
{
"name": "ai-catalog-gates",
"displayName": "ai-catalog Quality Gates",
"version": "0.1.0",
"description": "License-header and secret-scanning skills, plus the gate-runner subagent that dispatches to them, from the ai-catalog issue-to-release pipeline.",
"author": {
"name": "Alberto Irurueta",
"url": "https://github.com/albertoirurueta"
},
"homepage": "https://github.com/albertoirurueta/ai-catalog",
"repository": "https://github.com/albertoirurueta/ai-catalog",
"license": "Apache-2.0",
"keywords": ["quality-gate", "license-header", "secret-scanning", "ai-catalog"]
}
skills/iru-check-license/SKILL.md and skills/iru-check-security/SKILL.md here would be verbatim copies of
the pinned files at
iru-check-license/SKILL.md
and
iru-check-security/SKILL.md — both already model: haiku, mechanical-work skills, as
Skills covers for iru-check-license. agents/iru-gate-runner.md
would be a copy of the pinned
iru-gate-runner.md,
whose own frontmatter (tools: Skill, Bash, Read) is unchanged by being packaged this way — a plugin doesn’t
alter a component’s own frontmatter, only where Claude Code finds it and how it’s namespaced. Since no manifest
field here points elsewhere, both directories are picked up by the default skills/ and agents/ scans
described under "Directory layout" above, so the skills and agents keys in plugin.json above are omitted,
not just unset.
A team would list this plugin from its own marketplace:
{
"name": "ai-catalog-gates-marketplace",
"description": "An illustrative marketplace listing a packaged subset of the ai-catalog quality-gate pipeline.",
"owner": {
"name": "Alberto Irurueta",
"url": "https://github.com/albertoirurueta"
},
"plugins": [
{
"name": "ai-catalog-gates",
"source": "./plugins/ai-catalog-gates",
"description": "License-header and secret-scanning skills, plus the gate-runner subagent, from ai-catalog."
}
]
}
marketplace.json’s required top-level fields are `name, owner and plugins; each plugins entry requires
name and source (here a path relative to the marketplace root, since the plugin sits inside the marketplace
directory itself), and may also set any plugin.json field, such as description above, which overrides the
plugin’s own value in listings. Verified against
Claude Code — Create a marketplace and
the marketplace reference. Run
claude plugin validate ./ai-catalog-gates-marketplace before publishing either file — it catches a missing
name, an empty owner.name, a relative source path containing .., and errors inside each relative-source
plugin’s own plugin.json.
Installing, versioning and updates
# register the marketplace (a GitHub repo, git URL, or local path)
/plugin marketplace add albertoirurueta/ai-catalog-gates-marketplace
# install a plugin from it -- <plugin-name>@<marketplace-name>
/plugin install ai-catalog-gates@ai-catalog-gates-marketplace
# from a shell, without starting a session
claude plugin marketplace add albertoirurueta/ai-catalog-gates-marketplace
claude plugin install ai-catalog-gates@ai-catalog-gates-marketplace --scope project
Installing picks a scope: user (every project on this machine), project (everyone working in the
repository, via the committed .claude/settings.json — each collaborator still runs the install command
themselves once), or local (this repository, this machine only). A plugin with a pinned version field stays
on that version until it’s changed; an unpinned plugin from a marketplace with auto-update on refreshes its
on-disk copy after each session start, and a running session keeps the version it already loaded until
/reload-plugins. Anthropic’s official marketplace and marketplaces added from a claude.ai account auto-update
by default; every other marketplace, including a private team one, defaults to auto-update off — update
a plugin explicitly with /plugin → Installed → the plugin → Update now, or claude plugin update
ai-catalog-gates@ai-catalog-gates-marketplace from a shell, or turn auto-update on for the marketplace from
/plugin → Marketplaces. Verified against
Claude Code — Install and manage plugins.
Team distribution via settings
Committing a plugin’s enabledPlugins entry to a project’s .claude/settings.json turns it on for everyone who
opens the repository, and extraKnownMarketplaces registers the marketplace itself so nobody has to run
/plugin marketplace add by hand first. Both keys are verified against
the settings reference's #enabledplugins and
#extraknownmarketplaces entries and work in any settings file (managed, user, project or local), with the
usual precedence between them:
.claude/settings.json{
"extraKnownMarketplaces": {
"ai-catalog-gates-marketplace": {
"source": {
"source": "github",
"repo": "albertoirurueta/ai-catalog-gates-marketplace"
}
}
},
"enabledPlugins": {
"ai-catalog-gates@ai-catalog-gates-marketplace": true
}
}
extraKnownMarketplaces maps a marketplace name to an object with a source (github, git, url, file,
directory, or an inline settings source) and an optional autoUpdate boolean. enabledPlugins maps
plugin-name@marketplace-name to a boolean; a plugin with no entry anywhere falls back to its own
defaultEnabled value. Committing the entry doesn’t download the plugin for collaborators — each still installs
it once — and a plugin an organization’s managed settings force-enables or blocks this way can’t be
re-enabled, disabled or repointed from a lower-precedence settings file. Claude Code honors
extraKnownMarketplaces from a repository’s .claude/settings.json only after the user accepts the workspace
trust dialog for that folder. This is the same distribution shape
Permissions & Settings covers for allow/deny
rules generally.
GitHub Copilot’s equivalent
GitHub Copilot has its own plugin and marketplace system, verified against
GitHub Copilot — About plugins. A Copilot
plugin bundles the same kind of components — custom agents (*.agent.md), skills (SKILL.md under
skills/<name>/), hooks (hooks.json) and MCP/LSP server configurations — into one installable unit, for
Copilot CLI, the Copilot cloud agent, and the GitHub Copilot app. Its manifest is also plugin.json at the
plugin root; Copilot documents two manifest shapes:
-
Agent Plugins 1.0 — an open, cross-vendor schema (
$schema: https://agent-plugins.org/schemas/1.0.0/plugin.schema.json) withname,version,description,author,homepage,repository,license,keywordsand anextensionsobject for client-specific data. Skills (skills/) and MCP servers (mcp.json) sit at fixed locations; Copilot-specific agents, hooks, commands and LSP servers go under acom.github.copilot/directory that other clients ignore. -
Legacy Copilot plugins — no
$schema, with configurable component paths and.mcp.json,.github/mcp.jsonor themcpServersmanifest field for MCP configuration. A legacy manifest can also live at.claude-plugin/plugin.json, among other locations.
A Copilot plugin marketplace is likewise defined by a marketplace.json with name, owner, metadata
(description, version) and a plugins array of {name, description, version, source} entries — close
enough to Claude Code’s shape that GitHub’s own docs allow saving it under a .claude-plugin/ directory as an
alternative to .github/plugin/. Two marketplaces, copilot-plugins and awesome-copilot, are registered by
default.
# register a marketplace (owner/repo on GitHub, a git URL, or a local path)
copilot plugin marketplace add albertoirurueta/ai-catalog-gates-marketplace
# install a plugin from it -- <plugin-name>@<marketplace-name>
copilot plugin install ai-catalog-gates@ai-catalog-gates-marketplace
# list what's installed
copilot plugin list
For team and organization-wide distribution, Copilot’s own configuration reference,
the Copilot CLI plugin
reference, names enabledPlugins and extraKnownMarketplaces as its managed-policy keys too — the same names
Claude Code uses, consistent with both following the shared Agent Plugins 1.0 direction — declared in
~/.copilot/settings.json (personal), a repository’s .github/copilot/settings.json (project, read by both the
CLI and the cloud agent), or an organization’s MDM-managed configuration; a plugin or marketplace a managed
policy pins this way can’t be re-enabled, disabled or repointed locally, exactly as with Claude Code above. That
reference page does not give the full JSON shape of these two keys the way
Claude Code’s settings reference does for its own, so this
page states only what’s confirmed — the key names and their managed-policy behavior — rather than assuming an
identical schema.
VS Code’s own extension surface (installed .vsix packages from the Visual Studio Marketplace) is a separate,
older distribution mechanism for the editor as a whole, not a way to package Copilot’s own
skills/agents/hooks/MCP bundle the way a plugin does; it isn’t covered further here.