--- name: box-factory-plugin-design description: Interpretive guidance for designing Claude Code plugins. Helps you understand plugin architecture, marketplace distribution, and when plugins are the right pattern. Use when creating or reviewing plugins. --- # Plugin Design Skill This skill provides interpretive guidance and best practices for creating Claude Code plugins. **ALWAYS fetch current official documentation before creating plugins** - this skill helps you understand what the docs mean and how to create excellent plugins. ## Required Reading Before Creating Plugins Fetch these docs with WebFetch every time: - **** - Plugin overview and quickstart - **** - Complete specifications - **** - Distribution patterns ## Core Understanding ### Plugins Are Packaging, Not Functionality **Key insight:** Plugins don't add new capabilities to Claude Code. They package existing extension points (commands, agents, skills, hooks, MCP servers) for distribution. **What this means:** - Plugins bundle components together - The value is distribution and discoverability - Components work the same inside or outside plugins - You're organizing and sharing, not creating new primitives **Decision test:** If you're asking "should this be a plugin?", you're asking the wrong question. Ask "should I package these existing components for sharing?" ### Critical Directory Structure (Official Specification) **The #1 mistake** that causes plugins to install but not work: ``` ✅ Correct: plugin-name/ ├── .claude-plugin/ │ └── plugin.json ← Only metadata here ├── commands/ ← At plugin root ├── agents/ ← At plugin root ├── skills/ ← At plugin root └── hooks/ ← At plugin root ❌ Wrong (won't work): plugin-name/ └── .claude-plugin/ ├── plugin.json ├── commands/ ← Won't be found! └── agents/ ← Won't be found! ``` **Official docs say:** "All other directories (commands/, agents/, skills/, hooks/) must be at the plugin root, not inside `.claude-plugin/`." ### Skills Directory Structure Skills use subdirectories with a `SKILL.md` file: ``` skills/ ├── skill-one/ │ ├── SKILL.md ← Skill definition │ └── helpers.py ← Supporting files (optional) └── skill-two/ └── SKILL.md ``` ## Plugin Manifest (plugin.json) - Official Specification Located at `.claude-plugin/plugin.json`: ### Required Fields - **name**: Unique identifier in kebab-case (e.g., "deployment-tools") ### Optional Metadata Fields We Use | Field | Type | Purpose | |-------|------|---------| | version | string | Semantic versioning (e.g., "2.1.0") | | description | string | Brief plugin purpose explanation | | repository | string | Source code location | ### Optional Metadata Fields We NEVER Use | Field | Type | Purpose | |-------|------|---------| | author | object | Author details: `{name, email, url}` | | homepage | string | Documentation URL | | license | string | License identifier (MIT, Apache-2.0, etc.) | | keywords | array | Discovery tags for categorization | ### Component Path Fields (Optional) Override default locations: - **commands**: Additional command files/directories (string or array) - **agents**: Agent markdown files (string or array) - **hooks**: Hook configuration path or inline JSON - **mcpServers**: MCP server configuration path or inline JSON **Note:** Custom paths *supplement* default directories, they don't replace them. **Best practice:** Always include `description` and `version` even though they're optional - improves discoverability and user trust. Do NOT include `author`, `repository`, `homepage`, `license`, or `keywords` unless explicitly specified. ## Advanced Features (Official Specification) ### Environment Variables Use `${CLAUDE_PLUGIN_ROOT}` in paths to reference the plugin's absolute directory. ### Custom Component Paths Specify additional locations for components: ```json { "name": "my-plugin", "commands": ["./extra-commands", "./legacy/commands"], "agents": "./custom-agents" } ``` All paths must be relative to plugin root and start with `./` ### Inline Component Configuration Define hooks or MCP servers directly in plugin.json instead of separate files: ```json { "name": "my-plugin", "hooks": { "PreToolUse:Bash": "./hooks/bash-guard.sh" }, "mcpServers": { "custom-server": { "command": "node", "args": ["./server.js"] } } } ``` ### MCP Server Configuration (Best Practices) **CRITICAL:** When configuring MCP servers in plugins, follow these security and maintainability patterns. #### Always Use External Configuration Files **✅ CORRECT - External file:** ```json // plugin.json { "name": "my-plugin", "mcpServers": "./.mcp.json" } ``` ```json // .mcp.json (at plugin root) { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" } } } ``` **❌ WRONG - Inline configuration:** ```json { "name": "my-plugin", "mcpServers": { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "" } } } } ``` **Why external files are better:** - Separation of concerns (metadata vs configuration) - Easier to edit MCP config independently - Cleaner plugin.json focused on plugin metadata - Matches user expectations from standalone MCP setups #### Always Use Environment Variable References **✅ CORRECT - Environment variable reference:** ```json { "server-name": { "command": "server-binary", "env": { "API_KEY": "${API_KEY}", "AUTH_TOKEN": "${AUTH_TOKEN}", "DATABASE_URL": "${DATABASE_URL}" } } } ``` **❌ WRONG - Hardcoded empty strings:** ```json { "server-name": { "env": { "API_KEY": "", "AUTH_TOKEN": "", "DATABASE_URL": "" } } } ``` **❌ VERY WRONG - Hardcoded actual secrets:** ```json { "server-name": { "env": { "API_KEY": "sk_live_abc123..." } } } ``` **Why environment variables are critical:** - **Security**: Never commit secrets to git history - **Portability**: Different users/environments have different credentials - **Standard practice**: `${VAR_NAME}` is the established MCP pattern - **Documentation clarity**: Shows what env vars are required #### Document Required Environment Variables **In your README, always include:** ```markdown ## MCP Server Setup This plugin includes the [Server Name] MCP server. ### Prerequisites - [Tool requirements, e.g., Node.js, Python] - [Service account or API access] ### Configuration 1. Obtain credentials: - Visit [credential URL] - Create [token/API key] with `scope1`, `scope2` permissions 2. Set environment variables: ```bash export API_KEY="your_key_here" export AUTH_TOKEN="your_token_here" ``` 3. The MCP server will start automatically when the plugin is enabled ``` **Required documentation elements:** - Prerequisites (tools, accounts, permissions) - How to obtain credentials with specific scopes/permissions - Exact environment variable names to set - Example export commands - When the server starts (usually: when plugin enabled) #### Common MCP Server Types **GitHub:** ```json { "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" } } } ``` **Filesystem:** ```json { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"], "env": {} } } ``` **Database:** ```json { "database": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres"], "env": { "DATABASE_URL": "${DATABASE_URL}" } } } ``` **Custom server using plugin root:** ```json { "custom": { "command": "${CLAUDE_PLUGIN_ROOT}/servers/custom-server", "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"], "env": { "CUSTOM_API_KEY": "${CUSTOM_API_KEY}" } } } ``` #### MCP Configuration Checklist Before publishing plugin with MCP servers: **Security:** - ✓ All secrets use `${ENV_VAR}` references (never hardcoded) - ✓ No empty string placeholders for secrets - ✓ No actual credentials in git history - ✓ .env files in .gitignore if used for local testing **Structure:** - ✓ MCP configuration in external file (`.mcp.json` or custom path) - ✓ Path in plugin.json is relative and starts with `./` - ✓ Valid JSON syntax in MCP configuration file **Documentation:** - ✓ README explains how to obtain credentials - ✓ Required scopes/permissions documented - ✓ Environment variable names clearly listed - ✓ Example export commands provided - ✓ Troubleshooting section for common issues **Testing:** - ✓ Verified MCP server starts with plugin enabled - ✓ Tested with actual credentials in environment - ✓ Confirmed required tools/dependencies work ## Marketplace Distribution (Official Specification) ### Marketplace.json Structure Located at `.claude-plugin/marketplace.json`: **Required fields:** - **name**: Marketplace identifier (kebab-case) - **owner**: Maintainer information object - **plugins**: Array of plugin entries **Plugin entry fields:** ```json { "name": "plugin-name", "source": "./plugins/plugin-name", "description": "Optional override", "strict": true } ``` ### Source Types **Local path (development):** ```json "source": "./plugins/my-plugin" ``` **GitHub repository:** ```json "source": { "source": "github", "repo": "owner/repo" } ``` **Git URL:** ```json "source": { "source": "url", "url": "https://gitlab.com/user/plugin.git" } ``` ### The `strict` Field - **`strict: true`** (default): Plugin must have its own `plugin.json` - **`strict: false`**: Marketplace entry serves as complete manifest **Use `strict: false` when:** Packaging third-party content without modifying it. ## Decision Framework ### When to Create a Plugin **Create plugin when:** - You have multiple related components (commands + agents + hooks) - You want to share with team/community - You need versioning and distribution - You want one-command installation (`/plugin install`) **Don't create plugin when:** - Single command/agent (just share the file) - Personal workflow (no distribution need) - Rapid iteration (plugins add packaging overhead) - Testing concepts (develop components first, package later) ### Plugin Scope Philosophy (Best Practices) **Good plugin scope:** - Focused purpose (testing suite, security scanner, docs generator) - Related components work together - Clear value proposition - Composable with other plugins **Bad plugin scope:** - "Everything for development" (too broad) - Unrelated utilities thrown together - Duplicates core functionality - Conflicts with other plugins ## Development Workflow (Best Practices) The docs show the mechanics. Here's the philosophy: 1. **Build components first** - Create and test commands/agents individually 2. **Test without packaging** - Use `.claude/` directories for iteration 3. **Package when ready** - Add plugin.json and organize structure 4. **Validate locally** - Use `claude plugin validate .` command 5. **Create test marketplace** - Local marketplace with absolute paths 6. **Install and test** - `/plugin marketplace add ./path/to/marketplace` 7. **Iterate** - Fix issues, restart Claude Code, test again 8. **Document** - Write comprehensive README 9. **Publish** - Push to GitHub, share marketplace **Key insight:** Don't start with plugin structure. Build components, then package them. ## Testing Commands (Official Specification) **Validate plugin structure:** ```bash claude plugin validate . ``` Checks JSON syntax and directory structure. **Add local marketplace for testing:** ```bash /plugin marketplace add ./absolute/path/to/marketplace ``` **Install from local marketplace:** ```bash /plugin install plugin-name@marketplace-name ``` **Verify installation:** Check `/help` for newly installed commands and agents. ## Common Pitfalls (Best Practices) ### Pitfall #1: Components in Wrong Directory **Problem:** Putting commands/agents inside `.claude-plugin/` **Why it fails:** Claude Code only looks at plugin root for components **Solution:** Keep `.claude-plugin/` for metadata only, put all components at root ### Pitfall #2: Premature Pluginification **Problem:** Creating plugin for single command or concept **Why it fails:** - Overhead of marketplace setup - Harder to iterate quickly - Users just want the file - More complex to maintain **Better:** Share the markdown file directly, create plugin later if collection grows ### Pitfall #3: Kitchen Sink Plugin **Problem:** "All my utilities" plugin with unrelated components **Why it fails:** - Unclear purpose - Users only want subset - Hard to maintain and version - Discovery problems **Better:** Focused plugins (testing tools, git helpers, docs generators) ### Pitfall #4: Missing Documentation **Problem:** Plugin without README or usage examples **Why it fails:** - Users don't know what's included - No installation instructions - No troubleshooting guidance - Low adoption **Solution:** Comprehensive README with: - Installation steps - Component list with examples - Required dependencies - Troubleshooting section - Changelog ### Pitfall #5: Ignoring Semantic Versioning **Problem:** Breaking changes in minor/patch versions **Why it fails:** Users expect: - `1.0.0 → 1.0.1` - Bug fixes only, safe to auto-update - `1.0.0 → 1.1.0` - New features, backward compatible - `1.0.0 → 2.0.0` - Breaking changes, needs migration **Solution:** Follow semver strictly, document breaking changes ## Marketplace Organization (Best Practices) ### Embedded vs External Plugins **Embedded (monorepo approach):** ``` marketplace/ ├── .claude-plugin/marketplace.json └── plugins/ ├── plugin-one/ └── plugin-two/ ``` **Pros:** - Single source of truth - Atomic updates - Easier testing **Cons:** - Monorepo management overhead - Slower independent development **External (distributed approach):** ```json { "plugins": [ { "name": "plugin-one", "source": { "source": "github", "repo": "org/plugin-one" } } ] } ``` **Pros:** - Independent versioning - Faster iteration - Individual repos easier to manage **Cons:** - Dependency coordination - Potential version conflicts ### Team Distribution Strategy **Official mechanism:** Configure `.claude/settings.json` at repository level: ```json { "extraKnownMarketplaces": ["owner/marketplace-repo"], "enabledPlugins": ["plugin-name@marketplace-name"] } ``` **Best practices to consider:** - Test plugins thoroughly before team rollout - Document required environment variables - Have rollback plan if plugin breaks - Establish approval process for new plugins - Communicate plugin updates to team ## Plugin Quality Checklist Before publishing: **Structure (from official docs):** - ✓ Valid `plugin.json` at `.claude-plugin/plugin.json` - ✓ Components at plugin root (not in `.claude-plugin/`) - ✓ Proper directory names (commands, agents, skills, hooks) - ✓ `claude plugin validate .` passes - ✓ Relative paths start with `./` **Metadata (best practices):** - ✓ Descriptive name (kebab-case) - ✓ Clear description (what problem it solves) - ✓ Semantic versioning - ✓ Author info (for support) - ✓ Repository link (for issues/PRs) - ✓ Keywords for discovery **Documentation (best practices):** - ✓ Comprehensive README - ✓ Installation instructions - ✓ Usage examples for each component - ✓ Required dependencies documented - ✓ Troubleshooting section - ✓ Changelog **Design (best practices):** - ✓ Focused scope (clear purpose) - ✓ No duplication of core functionality - ✓ Components complement each other - ✓ Tested locally before publishing ## Example: High-Quality Plugin Manifest **Basic (what docs show):** ```json { "name": "my-plugin", "description": "A plugin", "version": "1.0.0" } ``` **Issues:** - ❌ Vague description **Excellent (applying best practices):** ```json { "name": "python-testing-suite", "version": "1.0.0", "description": "Comprehensive Python testing tools with pytest integration, coverage reporting, and failure analysis", "repository": "https://github.com/username/python-testing-suite", } ``` **Improvements:** - ✅ Specific description (what it does, how it helps) - ✅ (optional, but okay)Repository for issues and PRs ## Documentation References These are the authoritative sources. Fetch them before creating plugins: **Plugin creation:** - - Overview and quickstart **Complete specifications:** - - All schemas and patterns **Distribution:** - - Marketplace setup **Component specifications:** - Reference agent-design, slash-command-design skills for component details **Remember:** Official docs provide structure and features. This skill provides best practices and patterns for creating excellent plugins.