Create and share your own Claude Code plugins with this step-by-step guide.
A Claude Code plugin is just a GitHub repository with a specific directory structure and a manifest file. The manifest tells Claude Code what your plugin includes and how to use it.
Zero-friction publishing
Push your plugin to GitHub and submit the URL for the fastest route to indexing. Auto-discovery also runs regularly, but depends on GitHub Code Search — new or low-activity repositories may take days to appear in GitHub's index.
Also list on the official Anthropic marketplace
Authors who want listing on Anthropic's canonical marketplace can submit via claude.ai/settings/plugins/submit or platform.claude.com/plugins/submit. These are complementary to ClaudePluginHub, not competing.
Here's a typical plugin structure. Only the .claude-plugin/plugin.json manifest is required.
my-awesome-plugin/
├── .claude-plugin/ # Plugin metadata
│ └── plugin.json # Plugin manifest (optional — only "name" is required if present)
├── commands/ # Optional: slash commands (flat .md files)
│ ├── deploy.md
│ └── test.md
├── agents/ # Optional: specialized subagents
│ ├── security-reviewer.md
│ └── test-writer.md
├── skills/ # Optional: skill directories with supporting files
│ └── api-integration/
│ └── SKILL.md
├── output-styles/ # Optional: output style definitions
├── monitors/ # Optional: background monitor configurations
│ └── monitors.json
├── bin/ # Optional: executables added to the Bash tool's PATH when enabled
├── settings.json # Optional: default settings (agent, subagentStatusLine)
├── .mcp.json # Optional: MCP server definitions
├── .lsp.json # Optional: LSP server configurations
├── hooks/ # Optional: lifecycle hooks
│ └── hooks.json
├── README.md # Recommended: usage documentation
└── LICENSE # Recommended: license fileOnly include what you need! A plugin can be as simple as a single manifest file, or as complex as dozens of commands, agents, skills, and integrations.
Component Locations
All component directories (commands/, agents/, skills/, hooks/, output-styles/, monitors/, bin/) and config files (.mcp.json, .lsp.json, settings.json) must be at the plugin root, not inside .claude-plugin/. The manifest file is the only thing inside .claude-plugin/.
The manifest file (.claude-plugin/plugin.json) describes your plugin.
Only name is required. Everything else — including the manifest itself — is optional; Claude Code will auto-discover components from standard directories.
{ "name": "my-formatter" }A slightly richer example with common optional fields:
{
"name": "my-formatter",
"version": "1.0.0",
"description": "Code formatting plugin for multiple languages",
"keywords": ["formatter", "code-quality", "development"]
}name: Plugin identifier (lowercase, hyphens, no spaces) — required.
version:Semantic version (e.g., "1.0.0", "2.1.3"). Claude Code uses this for update detection — if you change code but don't bump version, existing users may not see changes due to caching.
description: Clear, concise description of what your plugin does.
keywords: Array of tags for discovery and categorization.
author, license, homepage, repository: Optional but recommended — these enrich marketplace listings.
{
"name": "devops-suite",
"version": "2.1.0",
"description": "Complete DevOps automation with deployment, monitoring, and alerts",
"keywords": ["devops", "deployment", "ci-cd", "monitoring", "automation"],
"commands": ["./commands/deploy.md", "./commands/rollback.md"],
"agents": ["./agents/infrastructure.md", "./agents/monitoring.md"],
"outputStyles": "./styles/",
"lspServers": "./.lsp.json",
"monitors": "./monitors.json",
"dependencies": [
"helper-lib",
{ "name": "secrets-vault", "version": "~2.1.0" }
],
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/test-runner.sh"
}
]
}
]
},
"mcpServers": {
"aws": {
"command": "npx",
"args": ["@aws-sdk/mcp-server"],
"env": {
"AWS_REGION": "us-east-1"
}
}
}
}This example includes commands, agents, hooks, MCP servers, output styles, LSP servers, monitors, and plugin dependencies. Each component is optional — include only what your plugin needs. Hook types beyond command are supported: http, prompt, and agent.
userConfig)Declare configuration values the user must provide at install time. Claude Code prompts for each value and makes it available throughout the plugin.
{
"userConfig": {
"API_KEY": { "type": "string", "sensitive": true, "description": "API key for service X" },
"REGION": { "type": "string", "default": "us-east-1" }
}
}Values are available as ${user_config.KEY} in MCP/LSP configs, hook commands, and skill/agent content (non-sensitive values only). They are also exported as CLAUDE_PLUGIN_OPTION_<KEY> environment variables. Sensitive values are stored in the system keychain. This replaces the older pattern of asking users to hand-edit settings.json.
channels)Plugins can declare message channels bound to an MCP server to inject content into the conversation — useful for Telegram, Slack, or Discord-style integrations. See the official plugin reference for the full channel schema.
${CLAUDE_PLUGIN_DATA}Alongside ${CLAUDE_PLUGIN_ROOT} (which points at the installed plugin directory), Claude Code exposes ${CLAUDE_PLUGIN_DATA}. It resolves to ~/.claude/plugins/data/<id>/ and survives plugin updates — use it for any state that must persist across version bumps.
Initialize a new public GitHub repository for your plugin. You can use an existing repo too - just add the plugin structure to it.
git init my-awesome-plugin && cd my-awesome-pluginMake the required .claude-plugin directory:
mkdir .claude-pluginCreate .claude-plugin/plugin.json with your plugin metadata. Start simple - you can add more features later.
Add commands, agents, skills, hooks, or MCP servers as needed. Each component is a markdown file with frontmatter:
---
description: Deploy your application to production
---
Deploy the application using the configured deployment strategy.
Include any validation checks and rollback procedures.---
description: Interact with REST APIs
when_to_use: When the user asks to call, test, or document an HTTP API
allowed-tools: [Bash, Read, Write]
---
Expert in making HTTP requests and handling API responses.
Claude will automatically use this when API interaction is needed.Document how to use your plugin. The README is shown on your plugin's detail page in the marketplace.
Commit and push your plugin to GitHub. Make sure the repository is public.
git add . && git commit -m 'Initial plugin release'git push origin mainThat's it! For the fastest processing path, submit your repository URL. Auto-discovery also scans GitHub Code Search regularly, but new repositories may take days to appear in GitHub's search index.
Use clear, lowercase names with hyphens. Good: code-formatter. Avoid: MyPlugin123.
Follow semver (major.minor.patch). Increment the major version for breaking changes, minor for new features, patch for bug fixes.
Use relevant keywords from categories like "development", "productivity", "testing", etc. This helps users discover your plugin.
Document installation, configuration, usage examples, and troubleshooting. Clear docs = happy users.
If you're maintaining a marketplace repository with multiple plugins, you need to understand the relationship between marketplace.json and individual plugin manifests.
Marketplace repositories bundle multiple plugins in a single repo:
my-marketplace/
├── .claude-plugin/
│ └── marketplace.json # Marketplace manifest
├── plugin-one/
│ ├── .claude-plugin/
│ │ └── plugin.json # Required if strict: true
│ └── commands/
├── plugin-two/
│ ├── .claude-plugin/
│ │ └── plugin.json # Required if strict: true
│ └── agents/
└── README.mdImportant: Strict Mode Default
By default, strict: true. This means each plugin directory MUST include .claude-plugin/plugin.json. If you want the marketplace entry to serve as the complete manifest, explicitly set strict: false for that plugin.
/plugin marketplace add ./path before publishingclaude-plugins-official and variants that impersonate Anthropic are blockedFor complete marketplace schema and examples, see the Plugin marketplaces documentation.
Create your plugin, push to GitHub, and submit the URL for fast indexing. Auto-discovery also picks up valid plugins once GitHub indexes them.