Guides creation of Claude Code plugins including skills, commands, agents, hooks, MCP servers, and plugin configuration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/plugin-creation-tools:plugin-creationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Create complete Claude Code plugins with any combination of components.
examples/full-featured-plugin/README.mdexamples/full-featured-plugin/commands/review.mdexamples/full-featured-plugin/commands/status.mdexamples/full-featured-plugin/hooks/hooks.jsonexamples/full-featured-plugin/hooks/post-edit.shexamples/full-featured-plugin/hooks/run-hook.cmdexamples/full-featured-plugin/hooks/session-start.shexamples/full-featured-plugin/skills/code-helper/references/patterns.mdexamples/simple-greeter-plugin/README.mdreferences/01-overview/claude-directory.mdreferences/01-overview/component-comparison.mdreferences/01-overview/what-are-agents.mdreferences/01-overview/what-are-commands.mdreferences/01-overview/what-are-hooks.mdreferences/01-overview/what-are-mcp.mdreferences/01-overview/what-are-plugins.mdreferences/01-overview/what-are-skills.mdreferences/02-philosophy/anti-patterns.mdreferences/02-philosophy/core-philosophy.mdreferences/02-philosophy/decision-frameworks.mdCreate complete Claude Code plugins with any combination of components.
| Component | Location | Invocation | Best For |
|---|---|---|---|
| Skills | skills/name/SKILL.md | Model-invoked (auto) | Complex workflows with resources |
| Commands | commands/name.md | User (/command) | Quick, frequently used prompts |
| Agents | agents/name.md | Auto + Manual | Task-specific expertise |
| Hooks | hooks/hooks.json | Event-triggered | Automation and validation |
| MCP | .mcp.json | Auto startup | External tool integration |
references/01-overview/component-comparison.md to decide which components neededWhen creating any plugin, also consider:
.claude/rules/ with modular project rules (path-scoped if needed for different component directories)CONTRIBUTING.md at the plugin root — not a CLAUDE.md. A plugin-root CLAUDE.md is NOT loaded as project context when the plugin is installed; both claude plugin validate and this validator (rule ST03, warn) flag one. To ship instructions Claude reads at runtime, put them in a skill (skills/<name>/SKILL.md); for path-scoped editing rules use .claude/rules/.All plugin documentation should follow lean principles:
references/02-philosophy/core-philosophy.md for full philosophyWhen user says "create plugin", "initialize plugin", "new plugin":
Option A - Use init script:
python scripts/init_plugin.py my-plugin --path ./plugins --components skill,command,hook
Option B - Manual creation:
Create plugin directory structure:
plugin-name/
├── .claude-plugin/
│ └── plugin.json
├── commands/ # if needed
├── agents/ # if needed (recursively scanned — subfolders join the scoped id, e.g. agents/review/security.md → my-plugin:review:security)
├── skills/ # if needed
│ └── skill-name/
│ └── SKILL.md
├── hooks/ # if needed
│ └── hooks.json
└── .mcp.json # if needed
Single-skill minimum layout (v2.1.142+): if the plugin is exactly one skill and nothing else, put SKILL.md at the plugin root with no skills/ subdirectory and no skills field — Claude Code auto-discovers it. See references/08-configuration/plugin-json.md § Important Path Rules item 4.
Copy template from templates/plugin.json.template
Ask user which components they need
When user says "add skill", "create skill", "make skill":
references/03-skills/writing-skillmd.md for structuretemplates/skill/SKILL.md.templateCritical: SKILL.md files are INSTRUCTIONS for Claude, not documentation. Write imperatives telling Claude what to do.
| Documentation (WRONG) | Instructions (CORRECT) |
|---|---|
| "This skill helps with PDF processing" | "Process PDF files using this workflow" |
| "The description field is important" | "Write the description starting with 'Use when...'" |
Consider these optional frontmatter fields:
model: — opus (safe, 1M) or inherit (safe default). Do NOT pin sonnet/haiku on a skill — a skill's model: is an inline current-turn override with no context isolation, so a sub-1M pin overflows when the skill activates from a large conversation (validator rule S14). For cheap heavy work, put it in a Task-dispatched agent instead. See references/03-skills/writing-skillmd.md § Don't pin a skill below the session window.context: fork with agent: <type> for heavy operations that would pollute main contextdisallowed-tools (kebab-case) to hard-remove tools from the pool while the skill runs (e.g. block AskUserQuestion in a background loop). Note the agent equivalent is camelCase disallowedTools — the forms are not interchangeable (rules S15 / A04).disable-model-invocation: true for command-only skills (no auto-trigger)user-invocable: false to hide from / menu (Claude can still invoke via Skill tool)Dynamic context injection: Use !`command` in the skill body to inject runtime state (git status, file contents, etc.) when the skill loads.
Extended thinking: Include "ultrathink" in the skill body for tasks requiring deep reasoning.
When user says "add command", "create command", "slash command":
references/04-commands/writing-commands.mdtemplates/command/command.md.template$ARGUMENTS, $1, $2 for argumentsWhen user says "add agent", "create agent", "make agent":
references/05-agents/writing-agents.mdtemplates/agent/agent.md.templateConsider these agent-specific features:
memory: project for agents that benefit from cross-session learning (architecture decisions, code review patterns)memory: user for personal preferences that carry across projectsmodel: matched to task complexity — haiku for lookup/formatting, sonnet for balanced tasks, opus for complex reasoningtools restriction to minimum needed (reduces cost and attack surface)disallowedTools to block specific tools (e.g., Edit, Write for read-only agents)hooks in agent frontmatter for scoped validation (runs only when that agent is active)Agent teams: For tasks benefiting from multiple perspectives or parallel research, consider agent teams (competing perspectives, hypothesis investigation, parallel tasks). See references/05-agents/agent-patterns.md for team patterns. Requires CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1.
When user says "add hooks", "setup hooks", "event handlers":
references/06-hooks/writing-hooks.mdreferences/06-hooks/hook-events.md for all 30 eventstemplates/hooks/hooks.json.templateSetup - one-time --init-only / --init -p / --maintenance -p preparation. Distinct from SessionStart: Setup does NOT fire on every launch, so a plugin that needs a dependency installed cannot rely on Setup alone — pair with a ${CLAUDE_PLUGIN_DATA} "check on first use, install on miss" pattern.PreToolUse - before tool execution (can block)PostToolUse - after tool execution (formatting, logging). Use the updatedToolOutput JSON return field to rewrite what Claude sees (replaces the older MCP-only updatedMCPToolOutput).PostToolBatch - after a parallel batch resolves (one-shot summary)SessionStart - setup, output directoriesSessionEnd - cleanupUserPromptSubmit - validation, context injection (can block)UserPromptExpansion - intercept direct /skillname invocations (can block)SubagentStart/SubagentStop - agent lifecycleWorktreeCreate/WorktreeRemove - replace default git worktree behavior with custom VCS logic (SVN/Perforce/Mercurial). Input: name via stdin; WorktreeCreate must print the worktree path on stdout, and any non-zero exit aborts creation.PreCompact - inject context before compactionNotification, Stop, TaskCompleted, TeammateIdleAdaptive hooks: Hook stdin JSON includes an effort object ({ "level": ... }) on tool-use-context events; the same level is exported as $CLAUDE_EFFORT to command hooks and the Bash tool. Use it to adapt verbosity, recursion depth, or external-call budget to the user's effort setting.
Exec form vs shell form (v2.1.139+): Command hooks run in exec form when args is set — command resolves as an executable and is spawned directly with each args element passed as one argument, no shell tokenization, no quoting. Prefer exec form for any hook that references a path placeholder (${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PROJECT_DIR}, ${CLAUDE_PLUGIN_DATA}). Omit args to fall back to shell form when you need pipes, &&, or redirects.
No controlling terminal (v2.1.139+): On macOS and Linux, command hooks run without /dev/tty. To surface a message, return systemMessage in JSON stdout; to ring the bell or fire a desktop notification, return terminalSequence (allowlisted OSC sequences). All hook output is capped at 10,000 characters — longer output is replaced with a file-path preview.
Five handler types — choose the right one:
command — shell script, fastest, no LLM cost. Use for logging, file ops, env setup.http — POST event JSON to a webhook (settings.json only). Use for external services.mcp_tool — call a tool on an already-connected MCP server, no shell. Use to file an issue, sync state, log to an external system without spawning a process.prompt — single-turn LLM evaluation, zero script overhead. Use for lightweight validation.agent — multi-turn subagent with tools (Read, Grep, Glob). Experimental upstream — behavior may change.Async execution: Add "async": true on command hooks for background operations (logging, analytics) that shouldn't block the main flow.
MCP tool matching: Use mcp__<server>__<tool> pattern in matchers for PreToolUse/PostToolUse.
Session-remembrance pattern: For plugins that maintain per-project state, /plugin-creation-tools:add-component remembrance-hooks scaffolds a SessionStart + SessionEnd hook pair (plus the install command, /save-session command, and save-session.sh) that survives compaction / /clear / new sessions. Two design rules are non-negotiable: no PostCompact hook (its stdout isn't injected into context — a no-matcher SessionStart covers compaction), and copy save-session.sh into the project (${CLAUDE_PLUGIN_ROOT} doesn't resolve in a project settings.json). See references/06-hooks/remembrance-hooks-pattern.md.
When user says "configure plugin", "setup plugin.json":
references/08-configuration/plugin-json.md for full schemaname$schema (SchemaStore JSON Schema for editor autocomplete), version, description, author, licensecommands (array), agents (array — string form no longer accepted), hooks, mcpServersthemes, monitors) belong under experimental.*. Top-level themes / monitors still load but claude plugin validate warns and a future release will require the nested form. The validator (/plugin-creation-tools:validate) flags top-level usage and offers an auto-migration diff.channels (Telegram/Slack/Discord-style message injection — each entry binds to one of the plugin's mcpServers); bin/ directory auto-discovered (executables there are added to the Bash tool's PATH while the plugin is enabled — chmod +x; useful for CLI helpers users invoke directly, distinct from hooks/ which are event-driven). Plugin-root settings.json supports two keys: agent (activates one of the plugin's agents as the main thread agent) and subagentStatusLine (default status-line config for subagents). See references/08-configuration/plugin-json.md and references/08-configuration/settings.md.Users who want to silence a single plugin skill don't need to uninstall the plugin or edit its SKILL.md. Two escape hatches, in priority order:
skillOverrides setting (.claude/settings.local.json) — four states: on / name-only / user-invocable-only / off. The /skills menu writes this for them. Note: upstream caveat is that skillOverrides does NOT affect plugin-shipped skills — for those, point users at /plugin disable for the whole plugin. Surface this in your README's troubleshooting section./plugin disable <name>@<marketplace> for the entire plugin, scoped per scope (user/project/local).See references/08-configuration/settings.md#skilloverrides for details.
When user says "configure settings", "setup output", "output directory":
references/08-configuration/settings.md for settings hierarchyreferences/08-configuration/output-config.md for output patterns${CLAUDE_PLUGIN_ROOT} - plugin installation directory${CLAUDE_PROJECT_DIR} - project root${CLAUDE_ENV_FILE} - persistent env vars (SessionStart only)When user says "test plugin", "validate plugin":
references/09-testing/testing.mdclaude --debug to see plugin loading/command-name/agents listingWhen user says "package plugin", "publish plugin", "marketplace":
references/10-distribution/packaging.mdmarketplace.json in repository rootBefore creating a component, verify it's the right choice:
| Component | Use When |
|---|---|
| Skill | Complex workflow, needs resources, auto-triggered by context |
| Command | User should trigger explicitly, quick one-off prompts |
| Agent | Specialized expertise, own context window, proactive delegation |
| Hook | Event-based automation, validation, logging |
| MCP | External API/service, custom tools, database access |
The 5-10 Rule: Done 5+ times? Will do 10+ more? Create a skill or command.
references/01-overview/what-are-plugins.md - Plugin overviewreferences/01-overview/what-are-skills.md - Skills overviewreferences/01-overview/what-are-commands.md - Commands overviewreferences/01-overview/what-are-agents.md - Agents overviewreferences/01-overview/what-are-hooks.md - Hooks overviewreferences/01-overview/what-are-mcp.md - MCP overviewreferences/01-overview/component-comparison.md - When to use whatreferences/02-philosophy/core-philosophy.md - Design principlesreferences/02-philosophy/decision-frameworks.md - Decision treesreferences/02-philosophy/anti-patterns.md - What to avoidreferences/03-skills/anthropic-skill-standards.md - Official Anthropic skill standards and checklistreferences/03-skills/skill-patterns.md - Five skill patterns (Sequential, Multi-MCP, Iterative, Context-Aware, Domain-Specific)references/03-skills/ - Skill creation guidesreferences/04-commands/ - Command creation guidesreferences/05-agents/ - Agent creation guidesreferences/06-hooks/ - Hook creation guidesreferences/06-hooks/cross-platform-hooks.md - Windows/macOS/Linux supportreferences/07-mcp/ - MCP overviewreferences/08-configuration/plugin-json.md - Plugin manifest (incl. userConfig schema with type/title fields, themes component path)references/08-configuration/marketplace-json.md - Marketplace config (incl. allowCrossMarketplaceDependenciesOn, claude plugin tag)references/08-configuration/themes.md - Plugin themes (themes/*.json, base + overrides, Ctrl+E user-copy flow)references/08-configuration/settings.md - Settings hierarchy (incl. prUrlTemplate)references/08-configuration/output-config.md - Output configurationreferences/09-testing/testing.md - Testing guide (all components)references/09-testing/debugging.md - Debugging guidereferences/09-testing/cli-reference.md - CLI commands referencereferences/10-distribution/packaging.md - Packaging guidereferences/10-distribution/marketplace.md - Marketplace guidereferences/10-distribution/versioning.md - Version strategyreferences/10-distribution/complete-examples.md - Full plugin examples| Symptom | Likely Cause | Fix |
|---|---|---|
| Plugin doesn't appear after install | Components placed inside .claude-plugin/ instead of plugin root | Move commands/ / agents/ / skills/ / hooks/ to the plugin root. Only plugin.json belongs in .claude-plugin/. |
| Skill exists but Claude never invokes it | Description missing trigger phrase or imperatives | Rewrite to start with "Use when…", include WHAT and WHEN, preserve any PROACTIVELY / MUST / NEVER markers from the prior version. Run skill-quality-reviewer agent to audit. |
| Hook configured but never fires | Wrong event name (case-sensitive) or http handler in hooks/hooks.json | Verify event name is exactly one of the 30 documented in references/06-hooks/hook-events.md. http handlers only work in settings.json — they are silently ignored in hooks.json. Run /plugin-creation-tools:validate. |
Hook spawns on every Bash call but only acts on rm | Filtering inside the script instead of with if | Add if: "Bash(rm *)" to the handler. The matcher fires the event; if is a cheap pre-spawn filter that avoids the "spawn-and-exit-0" anti-pattern. See references/06-hooks/writing-hooks.md#the-if-field. |
mcp_tool hook returns "not connected" on first run | SessionStart / Setup typically fire before MCP servers finish connecting | Expected on first run. Either accept the non-blocking error, or move the call to a later event (PostToolUse, Stop, etc.) where the server is reliably connected. |
Plugin theme doesn't appear in /theme | themes/*.json missing name / base / overrides, or invalid JSON | Run /plugin-creation-tools:validate. See references/08-configuration/themes.md for the schema. |
| Cross-marketplace dependency rejected at install | Root marketplace's marketplace.json is missing allowCrossMarketplaceDependenciesOn | Add the target marketplace name to the root marketplace's allowCrossMarketplaceDependenciesOn array. Trust does not chain — only the root marketplace's allowlist is consulted. See references/08-configuration/marketplace-json.md. |
| Version mismatch errors after release | version drifted between plugin.json and the marketplace entry | Bump both. The validator enforces this. Use claude plugin tag (run from inside the plugin folder) to create the {plugin-name}--v{version} git tag dependents resolve against. |
Frontmatter hooks / mcpServers ignored on a plugin agent | Plugin-packaged agents silently strip hooks / mcpServers / permissionMode for security | Move the hooks to hooks/hooks.json at the plugin root, or scope them via SKILL.md frontmatter. (For agents launched via --agent from project-local .claude/agents/, those fields fire as of v2.1.117+.) |
--debug shows the plugin loading but components missing | Custom commands / agents / outputStyles / experimental.themes / experimental.monitors paths in plugin.json replace defaults — they don't supplement. (skills is the only exception — it adds to the default skills/ directory.) | When you set a custom path for a "Replaces the default" field, the default directory is no longer scanned. Either remove the override or include the default path in the array. v2.1.140+ surfaces the ignored folder in /doctor, claude plugin list, and the /plugin detail view — those tools name the folder being skipped, which is the fastest way to spot a misconfigured manifest. |
For a symptom-first walkthrough of "what state is the runtime actually in," see the upstream Debug Your Config guide (/context, /memory, /doctor, /hooks, /mcp, /skills, /permissions, /status).
Working example plugins in examples/:
examples/simple-greeter-plugin/ - Minimal plugin with one skillexamples/full-featured-plugin/ - Complete plugin with skill, commands, hooksAll templates are in the templates/ directory:
templates/skill/SKILL.md.templatetemplates/command/command.md.templatetemplates/agent/agent.md.templatetemplates/hooks/hooks.json.templatetemplates/hooks/run-hook.cmd.template - Cross-platform hook wrappertemplates/plugin.json.templatetemplates/marketplace.json.templatetemplates/settings.json.templatetemplates/mcp.json.templatescripts/init_plugin.py - Initialize new plugin with selected componentsscripts/init_skill.py - Initialize standalone skillscripts/validate_skill.py - Validate skill structurescripts/package_skill.py - Package skill for distributionnpx claudepluginhub camoa/claude-skills --plugin plugin-creation-toolsCreates, converts, validates, and publishes Claude Code plugins with Agent Skills, hooks, agents, and servers. Automates manifest generation, scanning, structure validation, and marketplace prep.
Orchestrates agentic workflow to create new Claude Code plugins from scratch: prerequisite checks, research, design verification, atomic implementation, validation, documentation.
Guides creation, modification, and debugging of Claude Code plugins with schemas, templates, checklists, validation workflows, and troubleshooting. Activates on .claude-plugin/, plugin.json, commands/, skills/, hooks/.