Plugins

This documentation was generated with the assistance of AI. Please report any inaccuracies.

A plugin is not a fourth kind of instruction alongside CLAUDE.md, skills, and agents — it’s how any combination of those (plus slash commands, hooks, and MCP server configs) gets packaged, versioned, and installed as one unit, instead of copied file by file into each repository’s .claude/ directory.

What a plugin bundles

A single plugin directory can carry:

  • Skills (skills/<name>/SKILL.md, same shape as Creating and updating skills and agents describes)

  • Custom agents (agents/<name>.md)

  • Slash commands and hooks (hooks/hooks.json — event handlers that react to Claude Code lifecycle events)

  • MCP and LSP server configuration (.mcp.json, .lsp.json)

  • Background monitors, default settings, and executables added to PATH (bin/)

Everything the plugin contributes is namespaced under its own name (e.g. a skill from a my-org-tools plugin is invoked as /my-org-tools:some-skill), so installing several plugins can’t silently collide on a shared skill/agent/command name the way copy-pasting loose files could.

Directory layout

my-plugin/
├── .claude-plugin/
│   └── plugin.json        # manifest: name, version, author, description
├── skills/
│   └── some-skill/
│       └── SKILL.md
├── agents/
│   └── some-agent.md
├── hooks/
│   └── hooks.json
├── .mcp.json
├── .lsp.json
├── monitors/
│   └── monitors.json
├── bin/
└── settings.json

Only plugin.json belongs inside .claude-plugin/ — skills/, agents/, hooks/, etc. are siblings of .claude-plugin/, not nested inside it.

Marketplaces

A marketplace is a catalog of installable plugins — a marketplace.json served from a git repository, another remote URL, or a local path. Two commands drive it:

/plugin marketplace add <owner/repo, git URL, or path to marketplace.json>
/plugin install <plugin-name>@<marketplace-name>

Both public and private marketplaces work the same way:

  • Public — Anthropic curates an official marketplace, and a separate community marketplace accepts public submissions. Useful for generally-applicable skills/agents not specific to any one organization.

  • Private/internal — an organization can host its own marketplace in a private git repository and point /plugin marketplace add at it, giving every repository in the org the same install command without that repository needing public visibility. This is the natural home for the kind of skill this catalog defines (release process, PR review conventions) once it needs to reach more than one repository — see Packaging and distributing skills, agents, and CLAUDE.md for when that step is actually worth taking.

This catalog’s own marketplace

This catalog is itself a marketplace named ai-catalog (.claude-plugin/marketplace.json, generated from tools/plugins.json). It splits the 196 skills into iru-core (the stack-independent pipeline: iru-issue, iru-explore, iru-plan, iru-code, PR and release skills, ticket intake, license and security checks, documentation, the repository bootstrap front door, and the three agents), iru-knowledge, and one plugin per stack (iru-java, iru-springboot, iru-quarkus, iru-dotnet, iru-typescript, iru-nestjs, iru-nextjs, iru-react-native, iru-php, iru-python, iru-android, iru-swift, iru-kmp, iru-rust, iru-go, iru-cli). Every stack plugin depends on iru-core, and a few depend on a sibling stack whose gates they reuse (iru-springboot and iru-quarkus on iru-java; iru-nestjs, iru-nextjs and iru-react-native on iru-typescript; iru-cli on iru-rust, iru-go, iru-swift and iru-dotnet). Every edge is one that a Skill() call in the dependent plugin proves (tools/generate-marketplace.py fails on an uncovered cross-plugin call); iru-kmp only mentions the Android and Swift skills in prose, so it has no edge to them.

claude plugin marketplace add albertoirurueta/ai-catalog
/plugin install iru-core@ai-catalog
/plugin install iru-java@ai-catalog

Things that differ from copying the files:

  • Skill names. A skill from a plugin is listed and can be invoked in its namespaced form, for example /iru-java:iru-java-test. The bare /iru-java-test (and Skill({skill: "iru-java-test"}) inside other skills) keeps working because every skill name in the catalog is unique, so none of the cross-references had to change. Keep the iru- prefix on anything you add so that stays true.

  • Agent names. Agents are reachable only by their namespaced name in plugin mode: iru-core:iru-gate-runner, iru-core:iru-isolated-skill-executor and iru-core:iru-change-summarizer. The skills that dispatch agents explain this rule, and each agent’s body repeats it (subagent_type: "iru-gate-runner" when installed under .claude/agents/, "iru-core:iru-gate-runner" as a plugin).

  • iru-core alone is not enough for the stack-dependent front doors. /iru-setup-repository hands off to the iru-setup-<stack>-repository orchestrator of the detected project type, and /iru-code dispatches each task to the iru-<key>-code-one-task-group skill of the task’s language key; both live in the stack plugins. With only iru-core installed they report the missing skill instead of bootstrapping or implementing, so install the matching stack plugin (for example iru-java) alongside it. Likewise iru-typescript routes React Native tasks to iru-react-native, which must be installed for them. These calls are recorded as optional_calls in tools/plugins.json rather than as dependencies (a dependency from iru-core to every stack would be circular, and the calls are conditional on the stack).

  • Headless mode. claude -p denies the Skill tool for skills that declare allowed-tools; pass --allowedTools=Skill (together with whatever else the run needs) when running a catalog skill non-interactively. In plugin mode also pass --add-dir <plugin directory> (the plugin’s cached checkout under ~/.claude/plugins/): without it a headless run refuses to read the skill’s templates/ and reference/ files, which sit outside the working directory, and the skill stops at that read.

  • Disk use. Each installed plugin caches a full copy of the repository, because the plugins select skills from the unchanged .claude/skills/ tree rather than from per-plugin directories. The measured cost is large: two plugins installed from a directory marketplace took 231 MB (tools/baseline/sample-runs-after.md), and a git-source install still copies every tracked file, which today includes docs/node_modules (6,310 tracked files). Dependencies multiply it: installing iru-cli pulls in six plugins. Untracking docs/node_modules is a separate follow-up that would shrink every copy.

  • Copying still works. Nothing about the plugins changes the files: copying a skill directory into another repository’s .claude/skills/ (Packaging and distributing skills, agents, and CLAUDE.md) is still supported, and every skill keeps all its templates and references under its own directory.

See Splitting the catalog in the performance guide for why the catalog is split by stack rather than by purpose, and what one stack’s install saves in the skill listing.

Getting updates when a new release is published

Installing a plugin is not a one-time copy — it stays linked to the marketplace it came from, and that marketplace is how updates reach it once its author publishes a new version:

  • Official Anthropic marketplaces auto-update by default: Claude Code refreshes the marketplace catalog and updates any installed plugin to its latest version at startup, with no action needed. A third-party or local-development marketplace has auto-update disabled by default — check for and pull new versions explicitly with:

    /plugin marketplace update <marketplace-name>

    This is the same command whether the marketplace lives in a public repository or a private, organization-internal one (Packaging and distributing skills, agents, and CLAUDE.md) — there’s no separate per-plugin update command, since an update is a marketplace-wide refresh rather than a single plugin’s action.

  • Updates apply silently, then prompt you to activate them. Neither the auto-update path nor /plugin marketplace update shows a changelog or diff before replacing the installed files. Once a plugin has actually changed, Claude Code shows a notification prompting you to run:

    /reload-plugins

    to pick up the new version within your current session — until that’s run, the session keeps using whatever version was already loaded.

  • Check what’s installed with /plugin (the interactive manager’s "Installed" tab, which shows each plugin’s scope and last-updated date) or /plugin list / claude plugin list from the shell. There is no separate command to preview whether a newer version exists without applying it — running /plugin marketplace update both checks and applies in one step.

  • Pinning a specific version isn’t a per-user control. Installing/updating tracks whatever the marketplace currently points to; the closest thing to a pin is the marketplace being added against a fixed git ref (/plugin marketplace add <url>#<tag-or-branch>), which is an administrator decision about the marketplace, not something each installer chooses individually. If a team needs every repository to advance to a new plugin version deliberately rather than picking it up automatically, host the marketplace privately with auto-update off and treat /plugin marketplace update as the explicit "take the new release now" action — the same rollout discipline as bumping a dependency version, rather than letting it drift silently across machines.

Creating one

Scaffold a new plugin with:

claude plugin init <name>

which creates the .claude-plugin/plugin.json manifest and a starter skill directory. During development, test it in place without publishing or installing it via:

claude --plugin-dir ./my-plugin

As with skills and agents (Creating and updating skills and agents), the fastest way to fill in the actual skill/agent content once the plugin shell exists is to ask Claude Code to draft it, grounded in whatever similar skill or agent already exists — either elsewhere in the plugin or in a repository adopting it.

See also