Plugin Structure
Anatomy of a Plugin
At its core, a plugin is a directory with a fixed structure. The heart is the plugin.json file in the .claude-plugin/ folder -- it identifies the directory as a plugin and contains the metadata.
Directory Structure
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Manifest (required)
├── skills/
│ ├── review.md # Skill definitions
│ └── deploy.md
├── agents/
│ └── security-agent.md # Agent definitions
├── hooks/
│ └── hooks.json # Hook configuration
├── .mcp.json # MCP server configuration
└── settings.json # Plugin settings
Only .claude-plugin/plugin.json is mandatory. All other folders and files are optional -- you only use what your plugin needs.
The plugin.json Manifest
The manifest is your plugin's business card:
{
"name": "my-security-plugin",
"version": "1.0.0",
"description": "Security toolkit with vulnerability scans and code reviews",
"author": {
"name": "Your Name"
}
}
The name must be unique -- it becomes the namespace prefix for all skills and agents in the plugin.
Click a layer
The complete package: plugin.json manifest defines name, version, namespace, and bundled components.
my-plugin/ with plugin.json
Reusable workflows as Markdown files. Triggered via /slash commands.
/review, /deploy, /test
Specialized subagent configurations with their own model, tools, and instructions.
review-agent.md, test-agent.md
Automation hooks and MCP server configurations installed with the plugin.
PostToolUse hooks, local MCP servers
Namespace Isolation in Detail
Namespace isolation is the feature that makes plugins safe and conflict-free. Every skill in the plugin automatically gets the prefix /plugin-name::
| Skill File | Invocation in Chat |
|---|---|
skills/review.md | /my-security-plugin:review |
skills/deploy.md | /my-security-plugin:deploy |
This means: Even if three different plugins each define a skill named review, there's no collision. Each one is uniquely addressable through its fully qualified name.
iWhy Namespaces Matter
Without namespaces, installing a new plugin could potentially overwrite existing skills. Namespace isolation guarantees that plugins never interfere with each other -- just like modules in Python or packages in Java.
Security Restrictions
Plugins are treated as less trusted than your local configuration. Therefore, strict restrictions apply to plugin subagents:
- No
hooks-- Plugin agents cannot define their own hooks - No
mcpServers-- Plugin agents don't get direct MCP access - No
permissionMode-- Plugin agents cannot set their own permission level
These fields are simply ignored in agent definitions within plugins.
!Workaround if Needed
If you need to give a plugin agent MCP access or hooks, copy the agent definition to .claude/agents/ in your project. There it's treated as a local, trusted configuration and all fields are respected. This is a deliberate decision -- you take responsibility for security.
Testing and Loading Plugins
During development, you load your plugin locally without installing it:
# Load plugin from local directory
claude --plugin-dir ./my-plugin
This command starts Claude Code and integrates the plugin directly from the specified directory. Changes to the plugin take effect after a reload:
/reload-plugins
*Development Workflow
The typical workflow when developing plugins: Terminal 1 for Claude Code with --plugin-dir, Terminal 2 for changes to the plugin code. After each change, a /reload-plugins in the Claude Code terminal -- and you immediately see the result.
Plugin Settings
The settings.json in the plugin root can define default settings:
{
"model": "opus-4",
"permissions": {
"allow": ["Read", "Grep", "Glob"],
"deny": ["Bash"]
}
}
These settings are treated as suggestions -- the local project configuration always takes precedence.
Summary
A plugin is a clearly structured package with a manifest, skills, agents, hooks, and MCP configuration. Namespace isolation prevents conflicts, and security restrictions ensure that plugins don't receive uncontrolled permissions. In the next section, we'll look at how MCP integration works in detail.