Zum Inhalt springen

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.

Bundled as a unit

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 FileInvocation 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.