Why This Matters#
Ready-made plugins don’t always cover your needs. Creating your own plugin lets you:
- 🎯 Automate repetitive workflows
- 👥 Share tools with your team
- 📦 Package knowledge and practices into a portable format
- 🏪 Publish a plugin for the community
In this lesson, we’ll create a plugin from scratch using materials from the plugin-dev plugin.
Step 1: Create the Folder Structure#
# Create the plugin folder
mkdir -p my-awesome-plugin/.claude-plugin
mkdir -p my-awesome-plugin/commands
mkdir -p my-awesome-plugin/agents
mkdir -p my-awesome-plugin/skills/my-skill
mkdir -p my-awesome-plugin/hooksYou’ll get this structure:
my-awesome-plugin/
├── .claude-plugin/
│ └── plugin.json
├── commands/
├── agents/
├── skills/
│ └── my-skill/
└── hooks/Step 2: Create the Manifest (plugin.json)#
The file .claude-plugin/plugin.json is your plugin’s “passport”:
{
"name": "my-awesome-plugin",
"version": "1.0.0",
"description": "A plugin for automating my workflows",
"author": {
"name": "Your Name",
"email": "you@example.com"
},
"keywords": ["automation", "workflow"]
}Available Manifest Fields#
| Field | Required | Description |
|---|---|---|
name |
✅ Yes | Unique name in kebab-case format |
version |
No | Version in MAJOR.MINOR.PATCH format (e.g., 1.0.0) |
description |
No | Brief description (50–200 characters) |
author |
No | Author name and email |
homepage |
No | Link to documentation |
repository |
No | Link to the code repository |
license |
No | License (e.g., MIT) |
keywords |
No | Tags for search |
Step 3: Create a Command#
A command is a slash command that the user types in Claude Code (e.g., /my-plugin:hello).
Create the file commands/hello.md:
---
name: hello
description: Greets the user and shows project information
---
# Hello Command
Perform the following actions:
1. Greet the user with a friendly message
2. Show the current date and time
3. If there's a README.md file — briefly describe the project
4. Suggest what to start with
Be friendly and positive!Frontmatter — Command Header#
The block between --- and --- is called frontmatter (metadata). It contains:
name— command name (how it will be invoked)description— description (displayed in hints)
Command with Arguments#
Create commands/review-file.md:
---
name: review-file
description: Reviews the specified file for errors and style
---
# File Review
The user wants to review the file: $ARGUMENTS
Perform the following checks:
1. Syntax errors
2. Style inconsistencies
3. Potential security issues
4. Improvement suggestions
Show the result as a structured report.$ARGUMENTS is a special variable that contains the text after the command. If the user types /my-plugin:review-file src/app.js, then $ARGUMENTS will equal src/app.js.
Step 4: Create an Agent#
An agent is a specialized assistant that Claude Code can call to solve a specific task. Unlike a command, an agent works in its own context.
Create the file agents/code-checker.md:
---
name: code-checker
description: Specialized agent for code quality checking
---
# Code Quality Checking Agent
You are a code quality expert. Your task:
1. Analyze the provided code
2. Find potential errors
3. Check best practices compliance
4. Suggest specific improvements
## Working Rules
- Always explain **why** something is a problem
- Provide examples of correct code
- Sort findings by severity: 🔴 critical, 🟡 important, 🟢 recommendationStep 5: Create a Skill#
A skill is a knowledge base that Claude Code automatically loads when relevant. Unlike a command, a skill isn’t invoked directly — Claude accesses it on its own when the topic is relevant.
Create the file skills/my-skill/SKILL.md:
---
name: My coding style skill
description: Use this skill when the user asks to write or review Python code
version: 0.1.0
---
# Python Coding Style
## Rules
1. Use type hints for all functions
2. Docstrings in Google format
3. Maximum line length — 88 characters (Black format)
4. Sort imports with isort
## Example of Good Code
```python
def calculate_total(items: list[dict], tax_rate: float = 0.1) -> float:
"""Calculates the total amount including tax.
Args:
items: List of items with a 'price' field.
tax_rate: Tax rate (default 10%).
Returns:
Total amount with tax.
"""
subtotal = sum(item["price"] for item in items)
return subtotal * (1 + tax_rate)
## Step 6: Add Hooks
Create the file `hooks/hooks.json`:
```json
{
"description": "Hooks for code quality checking",
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "prompt",
"prompt": "Check that the file contains comments and doesn't contain hardcoded passwords or API keys. Return 'approve' if everything is fine or 'deny' with an explanation.",
"timeout": 15
}
]
}
]
}
}Step 7: Test the Plugin#
# Launch Claude Code with our plugin
claude --plugin-dir ./my-awesome-plugin
# Inside Claude Code, try the commands:
> /my-awesome-plugin:hello
> /my-awesome-plugin:review-file src/main.pyFor debugging:
claude --plugin-dir ./my-awesome-plugin --debugComparing Plugin Components#
| Component | How It’s Invoked | Purpose |
|---|---|---|
| Command | /plugin:command |
Specific action at user’s request |
| Agent | Called by Claude automatically | Complex specialized task |
| Skill | Loaded automatically by topic | Background knowledge and rules |
| Hook | Triggered by an event | Automatic check/validation |
Lesson Summary#
- A plugin is created from a folder with a
plugin.jsonmanifest and components - Commands are Markdown files with instructions for Claude, invoked via
/ - Agents are specialized assistants for complex tasks
- Skills are knowledge bases loaded automatically
- Hooks are automatic checks triggered by events
$ARGUMENTSpasses command arguments- Test your plugin with
--plugin-dirand debug with--debug