Claude Code is a CLI tool that lives in your terminal and helps you write code, but its real power comes from plugins. A plugin can add custom slash commands, hook into Claude’s lifecycle events, and integrate with external services via MCP. In this guide, we build a plugin from scratch.
What Is a Claude Code Plugin?
A Claude Code plugin is a package that extends Claude Code’s functionality. It lives in a directory structure that Claude Code recognizes and loads automatically. Plugins can add slash commands that run when you type a forward-slash, hooks that fire on specific events like file saves or session starts, and MCP servers that give Claude access to external tools.
The Plugin Directory Structure
Every Claude Code plugin follows a standard directory layout. At minimum, you need a plugin directory with a commands folder and a hooks folder. The commands folder contains markdown files that define slash commands. The hooks folder contains shell scripts that run on specific lifecycle events.
Creating Your First Plugin
Step 1: Set Up the Directory
Create a new directory for your plugin. Name it something descriptive like my-claude-tools. Inside, create two folders: commands/ and hooks/. You may also add a README.md to document what your plugin does.
Step 2: Add a Slash Command
Create a markdown file in the commands directory. Name it with the command name, like review.md. This file becomes the /review command in Claude Code.
The markdown file contains instructions that Claude follows when the command is invoked. You can include system prompts, templates, or even reference external scripts. The command file is just markdown that Claude reads as instructions.
Step 3: Register the Plugin
Tell Claude Code about your plugin directory. In your Claude Code settings or via the CLI, add the path to your plugin directory. Claude Code scans the directory on startup and loads any commands and hooks it finds.
Building Custom Slash Commands
Slash commands are the most visible part of a plugin. They appear in Claude Code’s command menu and execute when you type their name.
Command File Format
Each command is a markdown file in the commands directory. The filename (without .md) becomes the slash command name. The file content is the instruction set Claude follows when the command runs.
Good command files are specific and actionable. Instead of “help me review code,” write “Review the modified files for security vulnerabilities, performance issues, and style consistency. Check for SQL injection, XSS vulnerabilities, and hardcoded secrets.”
Argument Forwarding
You can pass arguments after a slash command. For example, /review auth.js passes auth.js as an argument to the review command. In your command markdown, reference $ARGUMENTS to receive whatever the user types after the command.
Adding Hooks to Plugin Events
Hooks are shell scripts that run automatically when specific events occur in Claude Code. They let you automate actions like linting after edits, running tests after code changes, or sending notifications when a session ends.
Available Hook Events
Claude Code fires hooks on events like PreToolUse (before a tool runs), PostToolUse (after a tool runs), SessionStart (when a session begins), SessionEnd (when a session ends), and others. You can register a hook for any of these events in your plugin’s hooks directory.
Writing a Hook Script
A hook is a shell script that receives JSON input via stdin describing the event. Your script processes this input and returns a JSON response. For a lint hook, you might run ESLint on modified files and return any errors Claude should address.
Pro Hint
Start with simple hooks. A PostToolUse hook that runs a linter is a great first project. Once you understand the event data format, you can build more complex hooks that conditionally block actions, modify tool inputs, or trigger external workflows. See our advanced patterns in Claude Code Patterns: Subagents, Worktrees, Orchestration.
Integrating MCP Servers
MCP servers extend Claude’s capabilities beyond code manipulation. Through MCP, Claude can interact with databases, APIs, file systems, and any service that exposes a tool interface. Your plugin can include or reference MCP server configurations.
Adding MCP to Your Plugin
Create an mcp.json file in your plugin directory. This file tells Claude Code which MCP servers to load when your plugin is active. You can reference pre-built MCP servers or point to custom ones your team maintains.
For guidance on building your own MCP servers, see our complete guide on building custom MCP servers for Hermes Agent. The principles apply directly to MCP servers used with Claude Code plugins.
Testing and Debugging Your Plugin
After creating your plugin, test it thoroughly. Start Claude Code, type your slash command, and verify it works as expected. If a hook is not firing, check that the script is executable (chmod +x on Unix systems) and that the event name matches Claude Code’s expected format.
Use verbose logging in your hook scripts. Print the input JSON to a log file so you can see exactly what event data Claude is sending. This makes debugging much faster.
Plugin Best Practices
Keep Commands Focused
Each slash command should do one thing well. If your command is trying to review code, format files, and run tests all at once, split it into separate commands. Focused commands are easier to maintain and more predictable for users.
Document Everything
Include a README.md in your plugin directory that explains what each command does, what arguments it accepts, and what hooks are registered. This helps other team members use your plugin and helps you remember how it works when you return to it months later.
Handle Errors Gracefully
Your hook scripts will encounter errors. Missing files, network timeouts, permission issues. Always include error handling and return meaningful error messages that Claude can relay to the user.
| Plugin Component | File Location | Purpose |
|---|---|---|
| Slash commands | commands/*.md | Custom CLI commands for Claude Code |
| Hooks | hooks/*.sh | Event-triggered automation scripts |
| MCP config | mcp.json | External tool integrations |
| README | README.md | Plugin documentation |
Frequently Asked Questions
A Claude Code plugin is a directory-based package that extends Claude Code with custom slash commands, lifecycle hooks, and MCP server integrations. Plugins live in directories that Claude Code scans and loads automatically.
Create a markdown file in your plugin’s commands directory. Name the file after your command (e.g., review.md becomes /review). The markdown content is the instruction set Claude follows when the command is invoked.
Yes, through MCP (Model Context Protocol) servers. Configure MCP servers in an mcp.json file in your plugin directory. MCP servers let Claude interact with databases, APIs, and any external service.
Hook scripts go in the hooks directory of your plugin. Each script is a shell script that runs on specific lifecycle events like PreToolUse, PostToolUse, SessionStart, or SessionEnd.
Yes. Commit your plugin directory to your team’s shared repository. Team members add the plugin path to their Claude Code configuration, and the plugin becomes available to everyone on the team.
Plugins work on any platform where Claude Code runs: macOS, Linux, and Windows (via WSL). Hook scripts must be written for the target platform’s shell environment.