Skip to main content

Practical Guide

AI-assisted

Create Claude Code plugins from scratch: complete development workflow, Marketplace publishing, team collaboration setup, and troubleshooting guide

Quick Recap

In the previous article, we explored the core concepts of Plugins: they are Claude Code's mechanism for packaging and distributing workflows, combining Commands, Skills, Agents, Hooks, and other components into a single unit for team sharing and community distribution. This article takes a hands-on approach, walking you through the complete process from creation to publishing.

Creating Your First Plugin

Step 1: Create the Directory Structure

mkdir my-first-plugin
mkdir my-first-plugin/.claude-plugin
mkdir my-first-plugin/commands

Step 2: Create the Plugin Manifest

Define your plugin's metadata in .claude-plugin/plugin.json:

{
  "name": "my-first-plugin",
  "description": "My first Claude Code plugin",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}

Step 3: Add Slash Commands

Create Markdown files in the commands/ directory. Each file corresponds to a command:

commands/hello.md:

---
description: Send a friendly greeting to the user
---

# Hello Command

Please greet the user warmly and ask what you can help them with today.

Step 4: Test the Plugin

Use the --plugin-dir flag to load your local plugin for testing:

claude --plugin-dir ./my-first-plugin

Run the command in Claude Code:

/my-first-plugin:hello

Step 5: Add Command Arguments

Commands support receiving user-provided arguments. Update hello.md:

---
description: Send a personalized greeting to a specific user
---

# Hello Command

Please warmly greet the user named "$ARGUMENTS" and ask what you can help them with today.

If the user didn't provide a name, use "friend" as the default.

Test the command with arguments:

/my-first-plugin:hello Alice

Supported argument placeholders:

  • $ARGUMENTS - All user input
  • $1, $2, $3 - Individual arguments

Adding More Components

Adding Skills

Create a skills/ directory. Each Skill is a folder containing a SKILL.md file:

my-first-plugin/
├── skills/
│   └── code-review/
│       └── SKILL.md

skills/code-review/SKILL.md:

---
name: code-review
description: Review code for quality, security, and maintainability
---

When reviewing code, check the following aspects:

1. **Code organization**: Is the structure clear?
2. **Error handling**: Are exceptions properly handled?
3. **Security concerns**: Are there any security vulnerabilities?
4. **Test coverage**: Is critical logic covered by tests?

Output format:
- Critical issues (must fix)
- Warnings (should fix)
- Suggestions (nice to have)

Adding Subagents

Create an agents/ directory:

agents/code-reviewer.md:

---
name: code-reviewer
description: Professional code review agent for quality inspection
tools: Read, Grep, Glob, Bash
---

You are an experienced code review expert.

When invoked:
1. Run git diff to see recent changes
2. Analyze modified files
3. Provide structured review feedback

Review checklist:
- Code readability and naming conventions
- Error handling and edge cases
- Security vulnerabilities (e.g., injection, sensitive data exposure)
- Performance optimization opportunities

Adding Hooks

Hooks let you automatically run scripts when specific events occur. Create hooks/hooks.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format-code.sh"
          }
        ]
      }
    ]
  }
}

Important: Use the ${CLAUDE_PLUGIN_ROOT} environment variable to reference files within your plugin directory, ensuring paths resolve correctly regardless of where the plugin is installed.

Create the corresponding script scripts/format-code.sh:

#!/bin/bash
# Format code
cd "$CLAUDE_PROJECT_DIR" && make format 2>/dev/null || true

Remember to set execution permissions:

chmod +x scripts/format-code.sh

Adding MCP Servers

If your plugin needs to connect to external systems, create .mcp.json:

{
  "mcpServers": {
    "plugin-database": {
      "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
      "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
      "env": {
        "DB_PATH": "${CLAUDE_PLUGIN_ROOT}/data"
      }
    }
  }
}

Complete Plugin Structure

A fully-featured Plugin might look like this:

my-plugin/
├── .claude-plugin/
│   └── plugin.json           # Plugin manifest
├── commands/
│   ├── review.md             # Code review command
│   ├── deploy.md             # Deployment command
│   └── test.md               # Testing command
├── agents/
│   ├── code-reviewer.md      # Code review agent
│   └── debugger.md           # Debugging agent
├── skills/
│   └── code-standards/
│       └── SKILL.md          # Coding standards knowledge
├── hooks/
│   └── hooks.json            # Event hook configuration
├── scripts/
│   ├── format-code.sh        # Code formatting script
│   └── run-tests.sh          # Test runner script
├── .mcp.json                  # MCP configuration
├── LICENSE
├── README.md
└── CHANGELOG.md

The corresponding plugin.json:

{
  "name": "dev-toolkit",
  "version": "1.0.0",
  "description": "Developer toolkit: an all-in-one solution for code review, testing, and deployment",
  "author": {
    "name": "Your Team",
    "email": "team@example.com"
  },
  "homepage": "https://github.com/you/dev-toolkit",
  "repository": "https://github.com/you/dev-toolkit",
  "license": "MIT",
  "keywords": ["development", "code-review", "deployment"],
  "commands": "./commands/",
  "agents": "./agents/",
  "skills": "./skills/",
  "hooks": "./hooks/hooks.json",
  "mcpServers": "./.mcp.json"
}

Publishing to the Marketplace

What Is the Marketplace

The Marketplace is the distribution hub for Plugins. Think of it as a "plugin store" — users can install your published plugins with a simple command.

Creating a Marketplace Configuration

Create .claude-plugin/marketplace.json in your GitHub repository:

{
  "name": "my-marketplace",
  "owner": {
    "name": "Your Name",
    "email": "you@example.com"
  },
  "plugins": [
    {
      "name": "dev-toolkit",
      "source": "./plugins/dev-toolkit",
      "description": "Developer toolkit",
      "version": "1.0.0"
    },
    {
      "name": "doc-generator",
      "source": {
        "source": "github",
        "repo": "you/doc-generator-plugin"
      },
      "description": "Documentation generation tool"
    }
  ]
}

Plugin Source Types

The Marketplace supports multiple source types:

Relative path (plugins within the same repository):

{
  "name": "my-plugin",
  "source": "./plugins/my-plugin"
}

GitHub repository:

{
  "name": "github-plugin",
  "source": {
    "source": "github",
    "repo": "owner/plugin-repo"
  }
}

Any Git repository:

{
  "name": "git-plugin",
  "source": {
    "source": "url",
    "url": "https://gitlab.com/team/plugin.git"
  }
}

Publishing Workflow

  1. Create a GitHub repository

  2. Push your code:

    git init
    git add .
    git commit -m "Initial release"
    git push origin main
  3. Users add your Marketplace:

    /plugin marketplace add your-username/your-repo
  4. Users install plugins:

    /plugin install dev-toolkit@your-marketplace

Installing and Managing Plugins

Via the Interactive Menu

/plugin

This opens an interactive interface where you can browse, install, enable, and disable plugins.

Via the Command Line

Add a Marketplace:

/plugin marketplace add owner/repo           # GitHub
/plugin marketplace add https://example.com/marketplace.json  # URL
/plugin marketplace add ./local-marketplace  # Local

Install plugins:

# Install to user scope (default)
/plugin install formatter@my-marketplace

# Install to project scope (shared with team)
/plugin install formatter@my-marketplace --scope project

# Install to local scope (gitignored)
/plugin install formatter@my-marketplace --scope local

Other management commands:

/plugin enable <plugin>      # Enable a plugin
/plugin disable <plugin>     # Disable a plugin
/plugin uninstall <plugin>   # Uninstall a plugin
/plugin update <plugin>      # Update a plugin

Validating Plugins

Verify your plugin configuration before publishing:

claude plugin validate .

Or within Claude Code:

/plugin validate .

Team Collaboration Setup

Sharing Plugin Configuration in a Project

Commit the plugin configuration to version control so team members automatically get it:

.claude/settings.json:

{
  "extraKnownMarketplaces": {
    "company-tools": {
      "source": {
        "source": "github",
        "repo": "your-org/claude-plugins"
      }
    }
  },
  "enabledPlugins": {
    "code-formatter@company-tools": true,
    "deployment-tools@company-tools": true
  }
}

After team members clone the project, these plugins will be automatically available.

Enterprise Marketplace Restrictions

For enterprise environments that require strict control, you can restrict allowed Marketplaces in managed settings:

{
  "strictKnownMarketplaces": [
    {
      "source": "github",
      "repo": "company/approved-plugins"
    }
  ]
}

Set it to an empty array [] to completely disable external plugins.

CLI Command Reference

CommandDescription
/pluginOpen the interactive management interface
/plugin install <name>@<marketplace>Install a plugin
/plugin uninstall <name>Uninstall a plugin
/plugin enable <name>Enable a plugin
/plugin disable <name>Disable a plugin
/plugin update <name>Update a plugin
/plugin validate .Validate the plugin configuration in the current directory
/plugin marketplace add <source>Add a Marketplace
/plugin marketplace listList added Marketplaces
/plugin marketplace updateUpdate the Marketplace cache
/plugin marketplace remove <name>Remove a Marketplace

Best Practices

Development Best Practices

  1. Keep Skills focused: Each Skill should do one thing well — avoid catch-all designs
  2. Write clear descriptions: Help Claude understand when to use your components
  3. Test with your team first: Validate internally before distributing to the community
  4. Document version changes: Record every version's changes in CHANGELOG.md

Directory Structure Best Practices

  • Place commands/, agents/, skills/ in the plugin root directory
  • Only put plugin.json inside the .claude-plugin/ directory
  • Use ${CLAUDE_PLUGIN_ROOT} to reference files within the plugin
  • Never use ../ to access files outside the plugin

Hooks Best Practices

  1. Scripts must be executable: chmod +x script.sh
  2. Use a shebang to declare the interpreter: #!/bin/bash
  3. Use the ${CLAUDE_PLUGIN_ROOT} variable to ensure correct paths
  4. Test scripts independently before integrating them into Hooks

Version Management Best Practices

Follow Semantic Versioning:

  • MAJOR (1.0.0 → 2.0.0): Breaking changes
  • MINOR (1.0.0 → 1.1.0): New features (backward compatible)
  • PATCH (1.0.0 → 1.0.1): Bug fixes (backward compatible)

Troubleshooting

ProblemPossible CauseSolution
Plugin doesn't loadMalformed plugin.jsonValidate with claude plugin validate
Command not showingIncorrect directory structureEnsure commands/ is in the root, not inside .claude-plugin/
Hooks not triggeringScript not executableRun chmod +x script.sh
Path not foundUsing relative pathsSwitch to ${CLAUDE_PLUGIN_ROOT}
MCP server failsEnvironment variables not setCheck path configuration in .mcp.json

Migrating from Existing Configuration

If you already have configurations under the .claude/ directory, follow these steps to migrate them into a Plugin:

  1. Create the Plugin structure:

    mkdir my-plugin/.claude-plugin
  2. Create plugin.json:

    {
      "name": "my-plugin",
      "description": "Plugin migrated from existing configuration",
      "version": "1.0.0"
    }
  3. Copy existing files:

    cp -r .claude/commands my-plugin/
    cp -r .claude/agents my-plugin/
    cp -r .claude/skills my-plugin/
  4. Migrate Hooks: Copy the hooks configuration from .claude/settings.json to hooks/hooks.json

  5. Test:

    claude --plugin-dir ./my-plugin

Learning Resources

Official Documentation

ResourceLinkDescription
Plugins Referencecode.claude.com/docsPlugin reference documentation
Create Pluginscode.claude.com/docsPlugin creation guide
Best PracticesAnthropic EngineeringOfficial best practices
Agent Skills Standardagentskills.ioOpen standard specification

Official Repositories

ResourceLinkDescription
anthropics/skillsGitHubOfficial Skills repository
anthropics/claude-plugins-officialGitHubOfficial plugin catalog
Docker MCP ToolkitWebsite200+ prebuilt MCPs

Community Resources

ResourceLinkDescription
claude-plugins.devWebsiteCommunity registry and CLI
awesome-claude-pluginsGitHubCollection of 243 plugins
awesome-claude-codeGitHubBest practices compilation
wshobson/agentsGitHub99 agents + 15 orchestrators
jeremylongshore tutorialGitHubHundreds of plugins + Jupyter tutorials

Looking Ahead

The Plugin system represents a quantum leap in Claude Code's extensibility. As the community grows, we can expect to see:

  • A richer plugin ecosystem: Covering a wide range of development scenarios and workflows
  • Enterprise-grade features: More comprehensive permission management and auditing capabilities
  • Cross-platform compatibility: The open Skills standard has already been adopted by multiple vendors

Now is the perfect time to get involved. Start with simple commands, gradually add Skills and Hooks, and ultimately build a complete workflow solution.

If you want to learn more about the Subagent component that Plugins can include, read What Are Claude Code Subagents.

Comments

Table of Contents

Practical Guide | Yu's Cyber Desk