AgentSkillsCN

plugin-maker

创建、验证并维护 Claude Code 插件。当用户希望创建插件、添加插件、开发插件、构建插件,或提及插件的创建时,可使用此技能。此外,当您需要为现有插件添加命令、代理、技能或钩子,配置 plugin.json 清单文件,或调试插件发现机制时,也可使用此技能。

SKILL.md
--- frontmatter
name: plugin-maker
description: Create, validate, and maintain Claude Code plugins. Use when the user wants to create a plugin, add a plugin, make a plugin, build a plugin, or mentions plugin creation. Also use when adding commands, agents, skills, or hooks to existing plugins, configuring plugin.json manifests, or debugging plugin discovery.
allowed-tools: Read Write Edit Bash Glob Grep

Plugin Maker

Create discoverable Claude Code plugins that bundle commands, agents, skills, hooks, and MCP configurations.

Core Principles

  1. Plugins bundle components: A plugin is a container for related commands, agents, skills, hooks, and MCP configs
  2. Manifest-driven discovery: The .claude-plugin/plugin.json file makes the plugin discoverable
  3. Convention over configuration: Standard directory names enable automatic component discovery
  4. Plugins vs Skills: Use plugins when bundling multiple component types; use standalone skills for single capabilities

Plugin Structure

Warning: Do not place plugin.json directly in the plugin directory. It must be inside the .claude-plugin/ subdirectory for the plugin to be discovered.

code
my-plugin/
├── .claude-plugin/
│   └── plugin.json          # Required: manifest file (MUST be here)
├── README.md                 # Recommended: documentation
├── commands/                 # Slash commands (*.md)
│   ├── my-command.md
│   └── help.md
├── agents/                   # Subagent definitions (*.md)
│   └── my-agent.md
├── skills/                   # Skills (subdirs with SKILL.md)
│   └── my-skill/
│       └── SKILL.md
├── hooks/                    # Hook configurations
│   ├── hooks.json
│   └── handler.py
├── .mcp.json                 # MCP server configuration
└── .lsp.json                 # LSP server configuration

Quick Template: plugin.json

Every plugin requires .claude-plugin/plugin.json:

json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Brief description of what this plugin does"
}

Optional author field for attribution:

json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Brief description of what this plugin does",
  "author": {
    "name": "Your Name",
    "email": "you@example.com"
  }
}

Creating a Plugin

Step 1: Create Directory Structure

bash
mkdir -p ./my-plugin/.claude-plugin
mkdir -p ./my-plugin/commands

Step 2: Create plugin.json

Create .claude-plugin/plugin.json with required fields:

json
{
  "name": "my-plugin",
  "description": "What this plugin does"
}

Step 3: Add Components

Add the components your plugin needs (see Component Quick Reference below).

Step 4: Test with --plugin-dir

Use the --plugin-dir flag to test your plugin without installing it:

bash
claude --plugin-dir ./my-plugin

This loads your plugin for the current session only, allowing rapid iteration.

Step 5: Validate Structure

bash
# Check manifest exists and is valid JSON
cat ./my-plugin/.claude-plugin/plugin.json | jq .

# List all components
ls -la ./my-plugin/

Step 6: Test Discovery

Ask Claude to use your plugin's commands or agents to verify discovery works.

Component Quick Reference

Commands (commands/*.md)

Slash commands users invoke explicitly. Plugin commands are namespaced as /plugin-name:command-name.

yaml
---
description: What this command does
argument-hint: [optional-args]
allowed-tools: ["Read", "Write", "Bash"]
---

# Command Name

Instructions for Claude when this command is invoked.

The user's input is available as $ARGUMENTS.

**Advanced argument access:**
- `$ARGUMENTS` - Full argument string
- `$1`, `$2`, `$3` - Individual arguments (space-separated)

Fields:

FieldRequiredDescription
descriptionYesShown in /help and command completion
argument-hintNoHint text for arguments (e.g., [file-path])
allowed-toolsNoRestrict available tools (JSON array)
disable-model-invocationNoIf true, only explicit /command triggers it
modelNoOverride model: inherit, sonnet, opus, haiku

Agents (agents/*.md)

Specialized subagents for parallel or delegated work.

yaml
---
name: my-agent
description: Use this agent when analyzing code for security issues. Examples: <example>Context: User asks about security\nuser: "Check this file for vulnerabilities"\nassistant: "I'll analyze with the security agent"</example>
model: sonnet
color: yellow
tools: ["Read", "Grep", "Glob"]
---

You are an expert at [specific task].

## Your Role

Detailed instructions for the agent...

Fields:

FieldRequiredDescription
nameYesAgent identifier (lowercase, hyphens)
descriptionYesWhen to use. Include Examples tags: <example>Context: ...\nuser: "..."\nassistant: "..."</example>
modelNoinherit, sonnet, opus, haiku
colorNoVisual indicator: yellow, blue, green, etc.
toolsNoArray of available tools

Triggering Tip: Use <example> tags in descriptions for complex use cases. Include context, user message, and assistant response to guide invocation.

Skills (skills/skill-name/SKILL.md)

Model-invoked capabilities that Claude activates based on context. Plugin skills are namespaced as /plugin-name:skill-name.

yaml
---
name: my-skill
description: What this skill does. Use when user mentions [trigger terms].
---

# Skill Name

Instructions...

Hooks (hooks/hooks.json)

Event-driven automation scripts. Use for validation, context injection, and workflow automation.

Hook Types:

  • Prompt-based (recommended): LLM-driven decisions with "type": "prompt"
  • Command-based: Bash scripts with "type": "command"
json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "prompt",
        "prompt": "Validate file write safety. Check: path traversal, credentials. Return 'approve' or 'deny'."
      }]
    }],
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "prompt",
        "prompt": "Verify task completion: tests run, build succeeded. Return 'approve' or 'block'."
      }]
    }]
  }
}

Available Events:

EventTrigger
PreToolUseBefore any tool executes
PostToolUseAfter a tool executes
UserPromptSubmitWhen user submits a prompt
StopWhen Claude wants to stop
SubagentStopWhen subagent wants to stop
SessionStartSession begins
SessionEndSession ends
PreCompactBefore context compaction
NotificationUser notification sent

Important: Use ${CLAUDE_PLUGIN_ROOT} for paths in hook commands.

See Hook Development Guide for comprehensive patterns.

MCP Configuration (.mcp.json)

Integrate Model Context Protocol servers for additional tools:

json
{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/mcp-server/index.js"],
      "env": {
        "NODE_ENV": "production"
      }
    }
  }
}

Server types: stdio, SSE, HTTP, WebSocket. Tools appear as mcp__plugin-name__tool-name.

Plugin Settings (.claude/plugin-name.local.md)

Store per-project configuration with YAML frontmatter:

markdown
---
enabled: true
strict_mode: false
max_retries: 3
---

# Plugin Configuration

Settings documentation here.

Usage:

  • Read from hooks, commands, and agents
  • Control plugin behavior per-project
  • Store state and configuration
  • Should be in .gitignore

See Plugin Settings Guide for parsing techniques and patterns.

LSP Configuration (.lsp.json)

Configure Language Server Protocol servers for enhanced editor support:

json
{
  "lspServers": {
    "my-lsp": {
      "command": "my-language-server",
      "args": ["--stdio"],
      "filetypes": ["mylang"]
    }
  }
}

Fields:

FieldRequiredDescription
commandYesThe LSP server executable
argsNoCommand-line arguments
filetypesYesFile extensions to activate for

Plugin Locations

LocationPurpose
--plugin-dir ./pathDevelopment/testing (primary workflow)
~/.claude/plugins/Personal plugins (installed)
.claude/plugins/Project plugins (committed to git)

When to Create a Plugin

Standalone Skill vs Plugin Comparison

FeatureStandalone SkillPlugin
Simplest optionOne SKILL.md fileMultiple files/directories
CommandsNoYes
Multiple skillsNoYes
AgentsNoYes
HooksNoYes
MCP serversNoYes
LSP serversNoYes
NamespacingNone/plugin-name:*
DistributionCopy filePackage directory

Create a plugin when:

  • You need multiple component types (commands + agents, skills + hooks, etc.)
  • You want to bundle and distribute related functionality
  • Your team needs shared tooling with consistent behavior

Don't create a plugin when:

  • You only need a single skill (use standalone skill instead)
  • You only need a single command (consider a skill or CLAUDE.md instruction)
  • The functionality is project-specific and simple

Naming Conventions

ItemConventionExample
Plugin directorylowercase-hyphenatedmy-plugin
plugin.json namematches directory"name": "my-plugin"
Commands directoryplural commands/not command/
Agents directoryplural agents/not agent/
Skills directoryplural skills/not skill/
Hooks directorysingular hooks/with hooks.json inside

Quick Reference

Create:

bash
mkdir -p ./my-plugin/.claude-plugin

Test during development:

bash
claude --plugin-dir ./my-plugin

Validate manifest:

bash
cat ./my-plugin/.claude-plugin/plugin.json | jq .

Install plugin:

bash
cp -r ./my-plugin ~/.claude/plugins/

List installed plugins:

bash
ls ~/.claude/plugins/*/
ls .claude/plugins/*/

Additional Resources