Published on January 20, 2026 by Dominic Böttger · 10 min read
If you’re working with Claude Code in a team environment, you’ve probably discovered the power of skills and plugins. But here’s the thing: the built-in marketplace is great for general-purpose tools, yet many teams need custom skills tailored to their specific workflows.
This guide walks you through creating and managing a private plugin marketplace - whether hosted on GitHub or used locally from a cloned repository.
What Are Claude Code Plugins?
Before diving into marketplace structure, let’s clarify what we’re building.
Plugins are packages that extend Claude Code’s capabilities. Each plugin can contain:
- Skills: Predefined prompts and workflows that Claude can execute
- Commands: Slash commands for common actions
- Agents: Specialized sub-agents for specific tasks
- Hooks: Event-driven automation triggers
A marketplace is simply a registry that tells Claude Code where to find these plugins and what they contain.
Repository Structure
Here’s the recommended structure for a private plugin marketplace:
my-team-plugins/
├── .claude-plugin/
│ └── marketplace.json # Plugin registry
├── plugins/
│ ├── api-client/
│ │ └── skills/
│ │ └── fetch/
│ │ ├── SKILL.md
│ │ └── scripts/
│ │ └── fetch.py
│ ├── database/
│ │ └── skills/
│ │ └── query/
│ │ ├── SKILL.md
│ │ └── reference/
│ │ └── schema-guide.md
│ └── planner/
│ └── skills/
│ └── tasks/
│ └── SKILL.md
└── README.md
Let’s break down each component.
The Marketplace Registry
The heart of your marketplace is .claude-plugin/marketplace.json. This file tells Claude Code what plugins are available and where to find them:
{
"name": "acme-plugins",
"displayName": "Acme Corp Plugins",
"plugins": [
{
"name": "api-client",
"description": "API client utilities for REST and GraphQL endpoints. Use when working with external APIs.",
"source": "./plugins/api-client",
"skills": ["./skills/fetch"]
},
{
"name": "database",
"description": "Database query tools for PostgreSQL and MySQL. Activate for database operations.",
"source": "./plugins/database",
"skills": ["./skills/query"]
},
{
"name": "planner",
"description": "Task and project planning utilities. Use for managing tasks, sprints, and project workflows.",
"source": "./plugins/planner",
"skills": ["./skills/tasks"]
}
]
}
Key fields:
| Field | Description |
|---|---|
name | Unique identifier for the marketplace (kebab-case) |
displayName | Human-readable name shown in Claude Code |
plugins[].name | Plugin identifier (must match directory name) |
plugins[].description | When to use this plugin - Claude uses this for context |
plugins[].source | Relative path to the plugin directory |
plugins[].skills | Array of skill paths within the plugin |
Plugin Directory Structure
Each plugin lives in its own directory under plugins/. The structure is:
plugins/plugin-name/
└── skills/
└── skill-name/
├── SKILL.md # Required: The skill prompt/instructions
├── scripts/ # Optional: Supporting scripts
│ └── helper.py
└── reference/ # Optional: Reference documentation
└── docs.md
SKILL.md is the only required file. It contains the instructions Claude follows when the skill is invoked. Here’s a simple example:
# API Fetch Skill
When the user asks to fetch data from an API, follow these steps:
1. Determine the HTTP method (GET, POST, PUT, DELETE)
2. Identify required headers and authentication
3. Construct the request using the provided scripts
4. Parse and format the response
## Authentication Handling
For APIs requiring authentication, check for:
- Bearer tokens in environment variables
- API keys in project configuration
- OAuth credentials if applicable
## Example Usage
User: "Fetch the user list from our backend"
Action: Use GET request to /api/users endpoint
Naming Conventions
Getting naming right matters. Claude Code uses a colon-separated naming pattern to identify skills: plugin-name:skill-name.
Understanding the Plugin:Skill Pattern
When you invoke a skill, you reference it using this format:
plugin-name:skill-name
For example, with this directory structure:
plugins/
└── planner/ # Plugin name: "planner"
└── skills/
└── tasks/ # Skill name: "tasks"
└── SKILL.md
The skill is referenced as planner:tasks.
planneris the plugin name (the directory underplugins/)tasksis the skill name (the directory underskills/)
This creates a clear namespace that prevents collisions when multiple plugins exist. You might have:
| Reference | Plugin | Skill | Purpose |
|---|---|---|---|
planner:tasks | planner | tasks | Manage project tasks |
planner:sprints | planner | sprints | Sprint planning |
database:query | database | query | Run database queries |
database:migrate | database | migrate | Database migrations |
Good Naming Examples
planner:tasks # Plugin handles planning, skill manages tasks
api-client:fetch # Plugin is an API client, skill fetches data
database:query # Plugin for database, skill runs queries
docs:generate # Plugin for docs, skill generates them
What to Avoid
Don’t repeat the plugin name in the skill:
planner:planner-tasks # Bad - redundant "planner"
database:database-query # Bad - "database" appears twice
The plugin name already provides context, so the skill name should add new information, not repeat it.
Don’t use generic skill names:
utils:skill # Bad - what does "skill" do?
tools:helper # Bad - too vague
Plugin Naming Guidelines
- Use kebab-case (lowercase with hyphens):
api-client, notapiClientorAPI_Client - Be descriptive but concise:
plannernotproject-task-management-system - Reflect the domain or technology:
msgraph,postgres,slack - Think of it as a namespace: everything under this plugin relates to this domain
Skill Naming Guidelines
- Use action verbs when the skill performs an action:
query,fetch,generate,deploy - Use nouns when the skill manages a resource:
tasks,users,config - Keep it short - one or two words is ideal
- Don’t duplicate information from the plugin name
Real-World Examples
Here’s how naming works for a team with multiple plugins:
# Project management plugin
planner:tasks # Create, update, list tasks
planner:sprints # Manage sprint cycles
planner:reports # Generate progress reports
# Microsoft Graph integration
msgraph:mail # Send and read emails
msgraph:calendar # Manage calendar events
msgraph:users # Query user directory
# Database operations
postgres:query # Run SQL queries
postgres:migrate # Apply migrations
postgres:backup # Backup and restore
# Internal tooling
deploy:staging # Deploy to staging
deploy:production # Deploy to production
Each plugin groups related functionality, and each skill name clearly indicates what it does within that domain.
Registering a Private Marketplace
Now for the practical part: how do you actually use your private marketplace?
Option 1: Local Marketplace (Recommended)
The most reliable approach for private marketplaces is to clone the repository locally and register the local path. This avoids authentication issues and gives you instant updates during development.
First, clone your marketplace repository:
# Clone using SSH (recommended for private repos)
git clone git@github.com:acme-corp/claude-plugins.git ~/Development/claude-plugins
Then add the local path to your Claude Code settings.
For macOS/Linux (~/.claude/settings.json):
{
"extraKnownMarketplaces": {
"acme": {
"source": {
"source": "local",
"directory": "/home/username/Development/claude-plugins"
}
}
}
}
For Windows (%USERPROFILE%\.claude\settings.json):
{
"extraKnownMarketplaces": {
"acme": {
"source": {
"source": "local",
"directory": "C:\\Users\\username\\Development\\claude-plugins"
}
}
}
}
After adding this configuration:
- Restart Claude Code
- Run
/marketplaceto see available plugins - Install plugins with
/install acme:planner
Benefits of local marketplaces:
- Instant updates: Changes to SKILL.md files are reflected immediately
- No network dependency: Works offline
- No credential conflicts: Works with your existing Git/gh CLI setup
- Easy development: Test skills before pushing to the remote repository
To update your plugins, simply pull the latest changes:
cd ~/Development/claude-plugins && git pull
Option 2: GitHub-Hosted Marketplace (Public Repos Only)
For public repositories, you can reference GitHub directly without cloning:
{
"extraKnownMarketplaces": {
"acme": {
"source": {
"source": "github",
"repo": "acme-corp/claude-plugins"
}
}
}
}
Note on private repositories: While the GitHub source option can work with private repos, it may require changes to your Git credential manager configuration. If you’re using the gh CLI with its default credential manager, these changes could cause conflicts. For private repos, the local marketplace approach is simpler and avoids credential headaches.
Creating Your First Skill
Let’s create a practical example. Say your team needs a task management skill. Here’s how to build it.
1. Create the Directory Structure
mkdir -p plugins/planner/skills/tasks
2. Write SKILL.md
# Task Management Skill
Use this skill when the user needs to create, update, or manage project tasks.
## Capabilities
- Create new tasks with title, description, and due date
- List tasks filtered by status, assignee, or project
- Update task status (todo, in-progress, done)
- Assign tasks to team members
## Task Format
Tasks should include:
- **Title**: Brief description (required)
- **Description**: Detailed information (optional)
- **Status**: todo | in-progress | done
- **Assignee**: Team member name or email
- **Due Date**: ISO 8601 format (YYYY-MM-DD)
## Example Interactions
User: "Create a task to update the API documentation"
Action: Create task with title "Update API documentation", status "todo"
User: "Show me all tasks assigned to Sarah"
Action: List tasks filtered by assignee "Sarah"
User: "Mark the login bug task as done"
Action: Update task status to "done"
3. Update marketplace.json
{
"plugins": [
{
"name": "planner",
"description": "Task and project planning utilities. Use when managing tasks, tracking progress, or organizing work.",
"source": "./plugins/planner",
"skills": ["./skills/tasks"]
}
]
}
4. Test It
If using a local marketplace, the skill is immediately available:
You: Create a task to review the PR for the new authentication feature
Claude: [Uses the planner:tasks skill to create the task]
Best Practices
Keep Skills Focused
Each skill should do one thing well. If a skill is getting complex, split it:
plugins/planner/
└── skills/
├── tasks/ # Individual task management
├── sprints/ # Sprint planning and tracking
└── reports/ # Progress reports and analytics
Document for Claude, Not Humans
SKILL.md files are instructions for Claude. Write them as if you’re explaining to a capable assistant:
- Be explicit about edge cases
- Include example inputs and outputs
- Specify error handling expectations
- List any dependencies or prerequisites
Version Your Marketplace
Use Git tags to version your marketplace:
git tag -a v1.2.0 -m "Added planner:sprints skill"
git push origin v1.2.0
This lets teams pin to specific versions if needed.
Include Reference Documentation
For complex domains, add reference material in the reference/ directory:
plugins/planner/skills/tasks/
├── SKILL.md
└── reference/
├── api-docs.md # API documentation
└── examples.md # Usage examples
Claude can reference these files when executing the skill.
Wrapping Up
A private plugin marketplace transforms Claude Code from a general-purpose assistant into a team-specific powerhouse. The initial setup takes about an hour, but the productivity gains compound quickly.
Start small:
- Create one plugin for your most repetitive task
- Test it locally
- Share with your team via GitHub
- Iterate based on feedback
The structure is intentionally simple - just Markdown files and JSON configuration. No build process, no dependencies, no complexity. That’s the point.
Your team’s knowledge, encoded as skills, available to everyone through natural language. That’s the promise, and it delivers.
Resources
Written by Dominic Böttger
← Back to blog