claude plugin from your shell or a script, or as /plugin and /reload-plugins inside a Claude Code session. This reference gives each command’s flags, defaults, output, and exit codes, along with the two flags that load a plugin for one session.
Run claude plugin --help on your build to confirm which subcommands your version has.
These cases are covered on other pages:
- Install and manage steps, and where
/pluginruns: see Install and manage plugins - What a command changes on disk and which scope takes precedence: see Plugin loading reference
- What an error message means: see Troubleshoot plugins
claude plugin commands
Runclaude plugin <subcommand> from your shell or a script, outside a Claude Code session. These subcommands install and manage plugins without opening the /plugin panel.
claude plugins is an alias for claude plugin.
Every subcommand shares these exit codes, plugin arguments, and scope values:
- Exit codes:
0on success and1on failure.validateadds exit2for an unexpected error, andevaladds the codes listed in its section. - Plugin arguments: a
<plugin>argument is a pluginnameorname@marketplace. When two marketplaces offer the same name, use the qualified form. - Scopes:
--scopetakesuser,project, orlocal, and names the settings file the command writes to.updatealso takesmanaged.
plugin init
Scaffold a new plugin at~/.claude/skills/<name>/. It loads in your next session as <name>@skills-dir with no install step.
new is an alias for init.
For the create, test, and edit workflow that begins with this command, see Create a plugin.
<name> becomes the directory name under ~/.claude/skills/ and the plugin’s name in its manifest.
The command has no flag for another location. To scaffold inside a project instead, see Create a plugin.
Scaffold a plugin with starter skill and hook files:
Created plugin "my-helper" at ~/.claude/skills/my-helper, followed by the id it loads as and the claude plugin disable command that turns it off.
Claude Code exits 1 without writing when it can’t scaffold safely, and the message names the reason. These are common reasons:
- An unknown
--withvalue - An existing scaffold at the target without
--force - A managed setting that blocks skills-directory plugins
plugin install
Install a plugin from a marketplace you’ve added.i is an alias for install.
headersHelper for its download, Claude Code first prints the command and asks Run this command now? [y/N].
Pass
-y from your own terminal to accept the displayed command without the prompt. Here’s what happens without a TTY and when Claude runs the command:
- stdin or stdout isn’t a TTY, and you pass neither
-ynor--accept-command: the install is refused. The output says the command was only displayed, and the exit code is1 - Claude runs the command through its Bash tool:
-yis ignored. Run the command from your own terminal instead
Successfully installed plugin: formatter@my-marketplace (scope: project). When nothing new is installed, the output says why:
- Already installed at that scope: the output is
Plugin "formatter@my-marketplace" is already installed (scope: project)and the exit code is0 - You decline a command-source prompt: the output is
Aborted.and the exit code is1 - You decline a
headersHelperprompt, or it can’t be confirmed without a TTY: the output isAborted — the command was not run.and the exit code is1
JSON result format
When you pass--json to plugin install, the last line of stdout is one JSON object. Parse only that line, because Claude Code prints any command the marketplace declares ahead of it.
Three fields are always present:
command: the subcommand that ran, such asinstalloutcome:okorfailedmessage: a human-readable description of the result
pluginId, scope, and failureCode, appear only when they apply.
The --json option on plugin uninstall, plugin update, plugin enable, and plugin disable prints the same object with that subcommand’s own fields.
A usage error, such as an invalid --scope, prints no result line and exits 1 with the reason on stderr.
Accept a displayed install command
When a--json run displays a marketplace-declared command and doesn’t run it, the failed result also carries a shownCommand object. Its fields include the command as displayed, the plugin it belongs to, and the command’s sha256.
To accept exactly that command, re-run with that sha256 as --accept-command from your own terminal, because the flag has no effect inside a Claude Code session. Requires Claude Code v2.1.271 or later.
The sha256 counts as acceptance for exactly that command, plugin, and marketplace catalog. If any of them changed since the command was displayed, Claude Code doesn’t accept the sha256 and shows the command again. A change that the run’s own marketplace refresh fetches also counts as such a change.
If shownCommand.acceptCommandMatched is false, the sha256 you passed doesn’t match the command now displayed. Review that command before re-running with its sha256.
plugin uninstall
Remove an installed plugin from one scope.remove and rm are aliases for uninstall.
Uninstall a plugin from project scope:
Successfully uninstalled plugin: formatter (scope: project). When the plugin isn’t installed at that scope, the command prints a line that starts Failed to uninstall plugin "formatter@my-marketplace": and exits 1.
plugin enable
Enable a disabled plugin. For a plugin synced from claude.ai, pass<name>@synced as the plugin.
Without
--scope, the command checks your settings files in the order local, project, user, and uses the first scope that mentions the plugin.
If you pass a --scope where the plugin isn’t declared, the command either writes an override or fails:
- A scope that takes precedence over the declaring one: Claude Code writes an override at the scope you passed. For example,
claude plugin disable formatter --scope localturns off a project-enabled plugin for you alone - Any other scope: the command fails with
Plugin "formatter" is installed at project scope, not user. Use --scope project or omit --scope to auto-detect.
Plugin "formatter" is already enabled and exits 1. With --json, the result has "failureCode": "already_in_goal_state" and "alreadyInGoalState": true, so a script can treat that case as success.
When the plugin declares dependencies, Claude Code enables them too. The command fails in these cases:
- A dependency is not installed: enable fails and prints the
claude plugin installcommand for each missing dependency - A dependency is blocked by your organization’s plugin policy: enable fails and names the blocked dependency
- A dependency is set to
falseat a scope with higher precedence than the target scope: enable fails. Enable the dependency at that scope, or pass--scopeto write there
Successfully enabled plugin: formatter (scope: project), naming the scope it detected.
plugin disable
Disable a plugin without uninstalling it. For a plugin synced from claude.ai, pass<name>@synced as the plugin.
Without
--scope, the scope is auto-detected in the same local, project, user order as plugin enable.
If you pass neither a plugin name nor --all, Claude Code prints Please specify a plugin name or use --all to disable all plugins and exits 1. Disabling a plugin that is already disabled prints Plugin "formatter" is already disabled and exits 1, as plugin enable does for an already-enabled plugin.
The command fails for a plugin that is still required:
- Another enabled plugin depends on it: the command fails and names the dependents to disable first
- Your organization requires it as a synced plugin: the command fails and saves nothing
Successfully disabled plugin: formatter (scope: project).
plugin update
Update a plugin to the latest version its marketplace offers. The new version loads in your next session, or after you run/reload-plugins in a running one.
managed is the one scope you can update but not install to. For admin-installed plugins, see Manage plugins for your organization.
Update a plugin:
Checking for updates for plugin "formatter@my-marketplace"…, then the result. When nothing is newer, it prints formatter is already at the latest version (1.0.0). and exits 0.
You can pass a bare plugin name, which the command matches against your installed plugins. When installed plugins from different marketplaces share the name, the command refuses the update and lists the qualified plugin-name@marketplace-name commands to run instead. Updating by bare name requires Claude Code v2.1.246 or later.
plugin list
List installed plugins with their version, scope, and status.
Claude Code groups the human-readable output by how each plugin loads:
Installed plugins:: plugins you installed from a marketplaceSession-only plugins (--plugin-dir / --plugin-url):: plugins loaded by those flags in the same command, as inclaude --plugin-dir ./my-plugin plugin listSkills-directory plugins (.claude/skills/*):: plugins Claude Code found in a skills directorySynced from claude.ai: plugins synced from your claude.ai account
No plugins installed. Use `claude plugin install` to install a plugin.
JSON output
With--json, Claude Code prints an array with one object per installation. Each object carries the fields below. id, version, scope, enabled, and installPath are always present, and the others appear only when they apply.
With
--json --available, Claude Code prints one object instead of an array. Its installed field holds the array of installed-plugin objects, and its available field holds one object per uninstalled marketplace plugin with the fields below.
plugin details
Show a plugin’s component inventory and its projected token cost. The plugin must be loaded: installed, found in a skills directory, or passed with--plugin-dir or --plugin-url in the same command. The <name> is a plugin name or name@marketplace.
--help.
Show what an installed plugin contributes:
Component inventory: the plugin’s skills, agents, hooks, MCP servers, and LSP serversProjected token cost: the always-on tokens the plugin adds to every sessionPer-component (rounded): always-on and on-invoke estimates for each skill, agent, and command. Omitted when the plugin has none
Plugin "formatter" not found. Run `claude plugin list` to see installed plugins, or pass --plugin-dir <path> to load one from disk. and exits 1.
plugin prune
Remove auto-installed dependencies that no installed plugin needs anymore. The command never removes a plugin you installed yourself.autoremove is an alias for prune.
Preview what a prune would remove:
(dry run — nothing removed). With none to remove, it prints a line that starts Nothing to prune.
Without --dry-run, the command removes the orphaned dependencies only after you confirm at the prompt or pass -y.
The exit code is 0 whatever you answer at the prompt.
What prune does depends on whether a terminal is attached and whether you pass -y:
plugin eval
Run a plugin’s eval cases and report scored results. Requires Claude Code v2.1.269 or later. Each case is a prompt plus graders. Claude Code runs it several times in an isolated session with only the target plugin loaded, and by default also without the plugin so the report shows the difference. See Test plugins with evals for the case format, graders, results, and CI usage.target defaults to the current directory and takes any of these forms:
- A plugin directory
- A single
prompt.mdorcase.yamlfile - An installed plugin as
nameorname@marketplace name@skills-dir
--tag, --allow-tools, and --json. Each of these options takes the words that follow it as its value, so a target written after one of them is read as a tag, a tool name, or the JSON output path instead of as the target.
This table lists the options most runs use. Run claude plugin eval --help for the complete set, including --case, --tag, --output-dir, --report, --allow-real-servers, --keep-temp, and --verbose.
The exit code reports how the run ended. To act on it in a pipeline, see Run evals in CI.
plugin eval init
Create an eval suite for the plugin in the current directory. Requires Claude Code v2.1.269 or later. See Create your first eval suite.- Reads the plugin
- Asks you what it should do well
- Proposes cases and graders
- Writes the case files
- Runs the cases and reviews the grades with you to check that the graders score the way you would
--bare, or without a terminal, the command writes a blank single-case template instead. When Claude runs the command from inside a Claude Code session, the command prints the interview instructions for that session to follow rather than writing a template.
The optional name is a case name. It’s required with --bare or without a terminal, because the command writes the blank template for that case. The interview doesn’t need one.
The command accepts these options:
plugin tag
Create an annotated git tag named<name>--v<version> for a plugin release. Before tagging, the command checks that the plugin’s plugin.json and any marketplace entry that lists it agree on the version.
For when to tag a release, see Publish a plugin.
[path] is the plugin directory, defaulting to the current directory. The command finds the marketplace entry by walking up from that directory to a .claude-plugin/marketplace.json that lists the plugin.
Preview the tag for a plugin in a marketplace checkout:
- The plugin name
- The version and which file it came from
- The matching marketplace entry, when there is one
- The tag name
- The
git tagandgit pushcommands it would run
--dry-run, Claude Code prints Created tag formatter--v1.0.0 and either Pushed to origin or the push command to run yourself. If the push fails, the tag is still created locally and the command exits with an error.
The command exits 1 and prints the reason when it can’t tag safely. Common reasons are:
- No
versioninplugin.jsonor the marketplace entry - The tag already exists
- The working tree is dirty
plugin validate
Validate a plugin manifest, a marketplace manifest, or the skills, agents, and commands in a directory, and exit with a code a CI job can act on. For the create, test, and edit workflow, see Create a plugin. For what the validator checks in each manifest, see the plugin manifest reference and the marketplace reference.
Validate a plugin before committing it:
Validate a directory
The<path> is a manifest file or a directory. Given a directory, Claude Code picks what to validate by what it finds there:
.claude-plugin/marketplace.json, when it exists- Otherwise
.claude-plugin/plugin.json - Otherwise the component files, chosen by the directory’s name. Validating component files without a manifest requires Claude Code v2.1.233 or later:
- A directory named
skills,agents, orcommands: the files inside it - A directory named
.claude: theskills,agents, andcommandsdirectories inside it - Any other directory: those three directories under its
.claude
- A directory named
- A linked
skills,agents, orcommandsdirectory under the plugin or.clauderoot: Claude Code warns that nothing in it was read. - A linked entry inside a
skills,agents, orcommandsdirectory: Claude Code skips it and warns, per directory, how many entries it skipped that a session would load. - The
skills,agents, orcommandsdirectory you name is itself a symlink, or its parent.claudedirectory is: Claude Code reports an error and checks nothing in it. Name the real directory instead.
- A
SKILL.mdat the plugin root: when you runclaude plugin validateagainst a plugin directory, Claude Code doesn’t check aSKILL.mdat the plugin root - A
CLAUDE.mdat the plugin root: in a plugin run, Claude Code also warns about aCLAUDE.mdat the plugin root - Plugin files in a marketplace run: from a marketplace directory, Claude Code doesn’t open the plugins’ skill, agent, command, or hook files. To find errors in those files, validate each plugin directory
Output and exit codes
Claude Code prints the file it validated, any errors and warnings with their paths, and a verdict line. The exit code follows the verdict:
With
--json, Claude Code writes the report to stdout as one JSON object with these top-level fields:
success: the same verdict the exit code givesstrict: whether the run treated warnings as errorstarget: the resolved path Claude Code validatedmanifest: the manifest’s own result, ornullfor a run without a manifestcontents: per-file results, each naming itsfileand carryingerrors,warnings, andnotesarrays
2, the command writes nothing to stdout. The error message goes to stderr.
claude plugin marketplace commands
Runclaude plugin marketplace <subcommand> from your shell to add, list, refresh, and remove the marketplaces you install plugins from.
- Exit codes: these subcommands follow the exit-code convention of the plugin commands
- Scopes: their
--scopeflag has no-sshort form
plugin marketplace add
Add a marketplace from a GitHub repository, a git URL, a hostedmarketplace.json, or a local path, and declare it in a settings file.
After you add it, Claude Code installs any dependencies that your installed plugins were missing.
<source> takes any of the forms in the table below, and its form decides the source type and how Claude Code fetches the marketplace. For the resulting source object, see the marketplace reference.
For a host whose clone URLs don’t carry the
.git suffix, such as AWS CodeCommit, add the marketplace as a git entry in extraKnownMarketplaces instead. Claude Code clones a git entry whether or not its URL ends in .git.
Claude Code also clones a gitlab.com URL with nested subgroups, such as https://gitlab.com/group/subgroup/project.
Add a marketplace and share it with the project:
Successfully added marketplace: your-marketplace (declared in project settings), using the name from the marketplace’s own manifest. A repeat add or an invalid source prints one of these results instead:
- Marketplace already on disk: the output is
Marketplace 'your-marketplace' already on disk — declared in project settingsand the exit code is0 - Unrecognized source: the output is
Invalid marketplace source format. Try: owner/repo, https://..., or ./pathand the exit code is1 - Bare host such as
gitlab.example.com/team/plugins: the add fails as an invalidowner/reposhorthand, and the message tells you to addhttps://or use a local path
From claude.ai: section of claude plugin marketplace list:
--claudeai, the command refuses --scope and --sparse. The marketplace is hosted for your account, not declared in a settings file, so you can’t share it through a project’s .claude/settings.json.
plugin marketplace list
List every marketplace you’ve added, with its source.
Claude Code prints
Configured marketplaces: and one Source: line per marketplace, or No marketplaces configured.
With --json, Claude Code prints an array with one object per marketplace, carrying the fields below. Every field is a string.
An added claude.ai marketplace has no local clone, so its entry carries its claude.ai identifiers,
marketplaceId and organizationUuid, in place of installLocation. It also carries scope when one is recorded, and status.
If your terminal sessions sync plugins from your claude.ai account, the text listing ends with a From claude.ai: section. That section names the marketplaces claude.ai lists for your account that you haven’t added, both git-based and hosted. It requires Claude Code v2.1.273 or later.
To add a marketplace from that section, see Add a marketplace from claude.ai.
The --json output covers configured marketplaces only and leaves the section out.
plugin marketplace remove
Remove a marketplace’s declaration from your settings.rm is an alias for remove.
<name> is the marketplace name that plugin marketplace list shows, not the source you passed to add.
Remove a marketplace from every scope:
Successfully removed marketplace: your-marketplace, adding (from project settings) when you scoped it. If you scope to a settings file that doesn’t declare the marketplace, the command fails with Marketplace 'your-marketplace' is not declared in project settings. Omit --scope to remove it from all scopes.
plugin marketplace update
Refresh one marketplace, or every marketplace, from its source to fetch new plugins and versions. A marketplace added with a branch or tagref updates to the latest commit of that ref, not the repository’s default branch.
--help.
Refresh one marketplace:
Successfully updated marketplace: your-marketplace. When you omit the name, it prints a count such as Successfully updated 2 marketplaces. With no marketplaces added, it prints No marketplaces configured and exits 0.
/plugin in a session
Inside an interactive session,/plugin opens the plugin panel. Each subcommand opens the panel on a tab, runs an action there, or prints a result inline. /plugins and /marketplace are aliases for /plugin.
You can run these commands only in an interactive terminal session. In a non-interactive run such as claude -p, Claude Code replies that /plugin isn’t available in this environment.
For which surfaces have /plugin, how to install without it, and what each panel tab shows, see Install and manage plugins.
A <plugin> is a plugin name or name@marketplace.
The table below lists every session form. The shell subcommands init, update, details, prune, eval, and eval init have no session form.
If you name a plugin that isn’t installed in the current project in
/plugin enable, disable, uninstall, or configure, Claude Code prints Plugin "<plugin>" is not installed in this project instead of acting.
/reload-plugins
Apply pending plugin changes to the running session without restarting it. Pending changes are plugins you installed, updated, enabled, disabled, or edited on disk since the session started. When you close the/plugin panel with pending changes you made in it, Claude Code runs /reload-plugins for you. Run it yourself after plugin changes that happen outside the panel, such as a claude plugin command you ran in another terminal.
Reload summary
Claude Code reloads every active plugin and prints one summary line,Reloaded: N plugins · N skills · N agents · N hooks · N plugin MCP servers · N plugin LSP servers, omitting the plugin MCP server count in a session without an interactive terminal. When any plugin failed, the summary adds N errors during load. Run /plugin for details.
The skills count covers every skill a plugin provides, both its commands/ entries and its SKILL.md skills. The agents count is the number of agents loaded in the session, including ones that don’t come from plugins.
When a reloaded plugin’s dependencies are missing, Claude Code installs them, reloads again, and appends (+ N dependencies: <names>) resolved to the summary.
Reloads that change MCP tools
When the reload would add or remove a plugin MCP server or theLSP tool, and that change would invalidate the prompt cache, Claude Code doesn’t apply the reload. It prints a line such as This reload changes MCP tools (<server>) — your next message will re-read the whole conversation instead of using the cache. Run /reload-plugins --force to apply. Pass --force to apply it anyway.
Sessions without an interactive terminal
/reload-plugins also runs in sessions without an interactive terminal, such as the desktop app, the Agent SDK, and non-interactive mode with -p. Requires Claude Code v2.1.260 or later.
In those sessions, the command runs only when you type it into the session yourself, such as in the -p prompt or the desktop app’s prompt box. When it arrives another way, such as through Remote Control or a message relayed from Slack, the command replies /reload-plugins isn't available over a remote connection in this session. and reloads nothing.
The reload in those sessions doesn’t connect or disconnect plugin MCP servers. Those changes take effect in your next session.
Flags that load a plugin for one session
Twoclaude flags load a plugin for one session only, without installing it. Both are repeatable.
Plugin authors use them to test a plugin before publishing. For the load-edit-reload workflow, see Develop without a marketplace.
A plugin that either flag loads is a session-only plugin.
claude plugin list shows it as <name>@inline with scope session, but only when the same flag precedes the subcommand. For example, run claude --plugin-dir ./my-plugin plugin list.
When a session-only plugin shares a name with an installed plugin, Claude Code loads the session-only copy for that session and skips the installed one. The installed copy loads instead if you disabled the session-only copy with claude plugin disable <name>@inline, or if managed settings lock that plugin name. For the precedence, see Plugin loading reference.
An administrator can reject both flags, and folders named in the CLAUDE_CODE_PLUGIN_DIRS variable, with the managed disableSideloadFlags setting. Claude Code then prints that the flag is disabled by your organization’s managed settings and exits 1 without starting.
From the Agent SDK, the plugins option is the equivalent of --plugin-dir.
Next steps
- Install and manage plugins: the same operations as steps, with what you see at each one
- Plugin loading reference: what each command changes on disk and which scope takes effect
- Troubleshoot plugins: install, marketplace, load, and validation error messages with their fixes
- Plugin manifest reference: the fields
claude plugin validatechecks