Plugin architecture
A plugin is a directory containing a.claude-plugin/plugin.json manifest. At startup, Claude Code loads plugins from each configured marketplace, caches them locally, and merges their contributions into the active session.
Plugin IDs
Every plugin is identified by{name}@{marketplace}. Built-in plugins that ship with Claude Code use the sentinel marketplace builtin: e.g. my-plugin@builtin. Marketplace plugins use the marketplace’s registered name.
Scopes
Plugins can be installed at three scopes (defined inservices/plugins/pluginOperations.ts):
| Scope | Settings file | Who sees it |
|---|---|---|
user | ~/.claude/settings.json | You, across all projects |
project | .claude/settings.json | Everyone with the repo |
local | .claude/settings.local.json | You, in this project only |
managed scope exists for organization-provisioned plugins installed via managed-settings.json. These can be updated but not uninstalled by users.
The /plugin command
Run /plugin to open the interactive plugin manager. Available subcommands:
my-plugin) or fully qualified (my-plugin@marketplace). The @marketplace qualifier is required if a plugin with the same name exists in multiple marketplaces.
Installing plugins
Add a marketplace (if needed)
If the plugin is not in a marketplace you have already configured, add it first:Or add it via
/plugin install https://example.com/marketplace.json.Install the plugin
settings.json, and caches the plugin files locally.Installation order of operations
FrompluginOperations.ts:installPluginOp:
- Search materialized marketplaces for the plugin entry
- Write settings (declares intent — this is the atomic action)
- Cache plugin files and record the version hint
Managing plugins
Enable / disable
Disabling a plugin keeps it installed but removes its contributions from the session:Uninstall
settings.json and marks the cached version as orphaned. If this was the last scope using the plugin, stored options and secrets are also deleted (deletePluginOptions, deletePluginDataDir).
Update
installed_plugins_v2.json. The running session is unaffected — changes take effect on restart.
Disable all
Built-in plugins
Built-in plugins are registered at startup viaregisterBuiltinPlugin() (plugins/builtinPlugins.ts) and appear in a dedicated “Built-in” section of the /plugin UI. They do not live on disk — their path is the sentinel value "builtin".
~/.claude/settings.json under enabledPlugins. The defaultEnabled field on the definition controls the initial state.
Built-in plugins can contribute:
- Skills — slash commands available via the
Skilltool - Hooks — lifecycle hooks (pre/post tool use, session start, etc.)
- MCP servers — additional MCP server connections
Creating a plugin
Add skills (optional)
Skills are markdown files that define slash commands. Place them in a
skills/ directory inside the plugin. Each file becomes a /skill-name command.Add hooks (optional)
Hooks are executable scripts that run at lifecycle events. Reference them in your manifest under the
hooks key.Add MCP servers (optional)
Declare MCP servers in
plugin.json under mcpServers. Claude Code connects to them when the plugin is enabled.Plugin scoping and precedence
When the same plugin is declared at multiple scopes, the most specific scope wins:findPluginInSettings in pluginOperations.ts searches local first, then project, then user. This lets you override a team-wide project-scoped plugin with a local-only preference without modifying the shared settings.json.
Organization policy
Administrators can block specific plugins via managed settings. Blocked plugins cannot be installed or enabled:isPluginBlockedByPolicy (utils/plugins/pluginPolicy.ts) and is enforced during both install and enable operations.
Background installation
On startup,PluginInstallationManager.ts reconciles declared marketplaces with the materialized state in the background. New marketplaces are cloned; changed sources are re-fetched. The REPL shows a spinner for each pending marketplace. After reconciliation:
- New installs trigger an auto-refresh so the plugins are available immediately
- Updates only set a
needsRefreshflag and show a notification to run/reload-plugins