Plugins
Plugins extend Claude Code with modular packages that bundle commands, skills, agents, output styles, hooks, MCP servers, LSP servers, channels, and settings. They are installed from a marketplace, loaded via CLI flag, or bundled as built-ins.
.claude-plugin/plugin.json.
Everything else is optional and auto-detected by directory convention.
Plugin Sources & Storage
| Source | ID Format | Description |
|---|---|---|
| Marketplace | plugin@marketplace | Installed from a marketplace repository |
| Session | (path-based) | Loaded via --plugin-dir CLI flag |
| Built-in | plugin@builtin | Bundled with Claude Code (currently none registered) |
Storage locations
# Cached plugin files
~/.claude/plugins/cache/{marketplace}/{plugin}/{version}/
# Enabled plugins list
~/.claude/settings.json → enabledPlugins: [...]
# Per-plugin options
~/.claude/settings.json → pluginConfigs: {...} Plugin Directory Structure
my-plugin/
├── .claude-plugin/
│ ├── plugin.json # Manifest (REQUIRED)
│ └── marketplace.json # For publishers
├── commands/ # Slash commands (auto-detected)
│ ├── build.md
│ └── deploy.md
├── agents/ # Custom agents (auto-detected)
│ └── test-runner.md
├── skills/ # Skills (auto-detected)
│ └── my-skill/
│ └── SKILL.md
├── output-styles/ # Output styles (auto-detected)
│ └── concise.md
├── hooks/
│ └── hooks.json # Hook configurations
└── .mcp.json # MCP servers (optional) The manifest at .claude-plugin/plugin.json is the only required file. Claude Code auto-detects capabilities from standard directories without manifest declarations.
Auto-detected directories
commands/ Any .md files → slash commands agents/ Any .md files → custom agent types skills/ Dirs containing SKILL.md → skills output-styles/ Any .md files → output styles hooks/hooks.json Hook configurations .mcp.json MCP server configurations Plugin Manifest (plugin.json)
Complete schema
{
"name": "my-plugin",
"version": "1.0.0",
"description": "What this plugin does",
"author": {
"name": "Author Name",
"email": "[email protected]",
"url": "https://example.com"
},
"homepage": "https://example.com/plugin",
"repository": "https://github.com/org/plugin",
"license": "MIT",
"keywords": ["testing", "deployment"],
"dependencies": [
"other-plugin",
"dep-plugin@other-marketplace"
],
"commands": { ... },
"agents": [ ... ],
"skills": [ ... ],
"outputStyles": [ ... ],
"hooks": { ... },
"mcpServers": { ... },
"lspServers": { ... },
"channels": [ ... ],
"userConfig": { ... },
"settings": { ... }
} Metadata fields
| Field | Req. | Description |
|---|---|---|
| name | Yes | kebab-case, no spaces |
| version | No | Semver (e.g. "1.2.3") |
| description | No | Short description |
| author | No | name required if object present |
| license | No | SPDX identifier |
| keywords | No | Search keywords |
| dependencies | No | "name" or "name@marketplace" |
Plugin Capabilities (9 Types)
Commands
Slash commands like /build, /deploy.
"commands": {
"build": {
"source": "./commands/build.md",
"description": "Build the project",
"argumentHint": "[target]",
"model": "claude-sonnet-4-6",
"allowedTools": ["Bash", "Read"]
},
"about": {
"content": "# About\nInline content.",
"description": "Show plugin info"
}
} Also accepts: single path string or array of paths.
Agents
Custom AI agent types with their own tools and model.
"agents": [
"./agents/test-runner.md",
"./agents/reviewer.md"
] Agent .md files use the same frontmatter format as user-defined agents (tools, model, disallowedTools).
Skills
Skill directories containing SKILL.md.
"skills": [
"./skills/my-skill",
"./skills/another-skill"
] Auto-detected: any directory in skills/ containing SKILL.md.
Output Styles
Custom response formatting.
---
name: Concise
description: Short, direct responses
keepCodingInstructions: true
forceForPlugin: false
---
Respond in 1-2 sentences. No preamble. forceForPlugin: true overrides user settings when the plugin is active.
Hooks
Supports all 27 hook events. Three declaration formats:
// Inline object
"hooks": { "PostToolUse": [...] }
// File reference
"hooks": "./hooks/extra.json"
// Array mixing both
"hooks": [
"./hooks/formatting.json",
{ "Stop": [...] }
] MCP Servers
External tool integrations. Special variables available:
"mcpServers": {
"my-server": {
"type": "stdio",
"command": "node",
"args": ["`${plugin_root}`/server.js"],
"env": {
"API_KEY": "`${user_config.API_KEY}`"
}
}
} Also accepts: ./file.json, ./server.mcpb, or remote URL.
LSP Servers
Language server protocol for code intelligence.
command — start command (required)extensionToLanguage — file ext → lang ID (required)transport — stdio / socketrestartOnCrash / maxRestartsstartupTimeout / shutdownTimeout (ms)Channels
Messaging channels for KAIROS assistant mode.
"channels": [{
"server": "my-chat-server",
"displayName": "Team Chat",
"userConfig": {
"CHANNEL_ID": {
"type": "string",
"title": "Channel ID"
}
}
}] server must match a key in mcpServers. MCP server must declare claude/channel capability.
Settings
Configuration overrides when the plugin is enabled.
"settings": {
"agent": {
"my-agent": {
"tools": ["Read", "Grep"],
"model": "haiku"
}
}
} Currently only the "agent" key is supported. Merged into the settings cascade when enabled.
User Configuration (userConfig)
Plugins can define options prompted at enable time. Values are injected as $`${user_config.KEY}` in MCP/LSP configs, hooks, and skill content — and as CLAUDE_PLUGIN_OPTION_KEY env vars in hook commands.
Schema example
"userConfig": {
"API_KEY": {
"type": "string",
"title": "API Key",
"description": "Your API key",
"required": true,
"sensitive": true // stored in Keychain
},
"MAX_RESULTS": {
"type": "number",
"title": "Max Results",
"default": 10,
"min": 1,
"max": 100
},
"VERBOSE": {
"type": "boolean",
"default": false
},
"PROJECT_DIR": { "type": "directory" },
"CONFIG_FILE": { "type": "file" }
} Config option types
| Type | Input | Extra fields |
|---|---|---|
| string | Text input | multiple (array) |
| number | Numeric | min, max |
| boolean | Toggle | — |
| directory | Path picker | — |
| file | File picker | — |
Storage
settings.json → pluginConfigs[pluginId].options.credentials.jsonMarketplace System
Plugin source formats
| Type | Format |
|---|---|
| Relative path | "./plugins/my-plugin" |
| NPM | { "source": "npm", "package": "@org/plugin", "version": "^1.0" } |
| Pip | { "source": "pip", "package": "my-plugin" } |
| Git URL | { "source": "url", "url": "https://...", "ref": "main" } |
| GitHub | { "source": "github", "repo": "owner/repo", "ref": "v1.0" } |
| Git subdirectory | { "source": "git-subdir", "url": "...", "path": "plugins/my" } |
Anti-impersonation
Marketplace names are validated against known registries. A marketplace cannot impersonate another marketplace's plugins. Cross-marketplace dependencies require explicit allowCrossMarketplaceDependenciesOn.
extraKnownMarketplaces in settings.json
{
"extraKnownMarketplaces": [
{
"type": "github",
"repo": "org/plugins",
"ref": "main"
},
{
"type": "url",
"url": "https://plugins.example.com/marketplace.json"
},
{
"type": "npm",
"package": "@org/marketplace"
},
{
"type": "directory",
"path": "/local/marketplace"
},
{
"type": "settings",
"name": "inline-marketplace",
"plugins": [
{ "name": "my-plugin", "source": "./path" }
]
}
]
} Installation & Loading Flow
Installation (10 steps)
Loading on startup (5 steps)
Caching & auto-update
Plugins are version-checked on startup. Cache supports ZIP mode. If forceRemoveDeletedPlugins: true in the marketplace, removed plugins are auto-disabled.
/plugin Command
Aliases: /plugins, /marketplace
| Command | Description |
|---|---|
| /plugin | Open interactive plugin management menu |
| /plugin install [name@marketplace] | Install a plugin from marketplace |
| /plugin manage | Manage installed plugins (enable/disable/configure) |
| /plugin uninstall <name> | Remove a plugin |
| /plugin enable <name> | Enable a disabled plugin |
| /plugin disable <name> | Disable a plugin |
| /plugin validate [path] | Validate a plugin manifest |
| /plugin marketplace add <source> | Add a marketplace source |
| /plugin marketplace remove <name> | Remove a marketplace source |
| /plugin marketplace update [name] | Update marketplace index |
| /plugin marketplace list | List configured marketplaces |
Permissions & Enterprise Policies
Policy controls
| Setting | Description |
|---|---|
| allowedPlugins | Allowlist of permitted plugins (name or name@marketplace) |
| deniedPlugins | Denylist — always takes precedence over allowlist (fail-closed) |
| strictPluginOnlyCustomization | Lock surfaces (e.g., mcp) to plugin-only — user-configured MCP servers blocked |
Plugin MCP server naming
plugin:<pluginName>:<serverName> Deduplicated against manually-configured servers — manual wins. Plugin MCP servers follow the same permission system as regular MCP tools.
Plugin ID format
// String
"my-plugin@my-marketplace"
// Object with options
{
"id": "my-plugin@my-marketplace",
"version": "^1.0.0",
"required": true,
"config": { "API_KEY": "value" }
} Both parts validated: [a-z0-9][-a-z0-9._]*
src/plugins/bundled/index.ts currently registers
zero built-in plugins. The infrastructure exists for migrating bundled skills to user-toggleable
plugin form, but as of the current source the built-in registry is empty.