llms.txt@08-Plugins-Skills · git:20261001.bf1f66b · 2026-10-01 · sha256 11d563782269a280

llms.txt@08-Plugins-Skills git:20261001.bf1f66bF

Immutable. This exact content never changes and is served at /api/v1/blob/11d563782269a280.

# Plugins & Skills

> Every page below, concatenated. Each section gives the page title, its upstream source and its path in this repository.

---

## Commit Push Pr

Source: https://github.com/anthropics/claude-code/blob/main/.claude/commands/commit-push-pr.md
Path: 08-Plugins-Skills/claude-code-claude-commands-commit-push-pr.md

## Context

- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`

## Your task

Based on the above changes:

1. Create a new branch if on main
2. Create a single commit with an appropriate message
3. Push the branch to origin
4. Create a pull request using `gh pr create`
5. You have the capability to call multiple tools in a single response. You MUST do all of the above in a single message. Do not use any other tools or do anything else. Do not send any other text or messages besides these tool calls.

---

## New Sdk App

Source: https://github.com/anthropics/claude-code/blob/main/plugins/agent-sdk-dev/commands/new-sdk-app.md
Path: 08-Plugins-Skills/claude-code-plugins-agent-sdk-dev-commands-new-sdk-app.md

You are tasked with helping the user create a new Claude Agent SDK application. Follow these steps carefully:

## Reference Documentation

Before starting, review the official documentation to ensure you provide accurate and up-to-date guidance. Use WebFetch to read these pages:

1. **Start with the overview**: https://docs.claude.com/en/api/agent-sdk/overview
2. **Based on the user's language choice, read the appropriate SDK reference**:
   - TypeScript: https://docs.claude.com/en/api/agent-sdk/typescript
   - Python: https://docs.claude.com/en/api/agent-sdk/python
3. **Read relevant guides mentioned in the overview** such as:
   - Streaming vs Single Mode
   - Permissions
   - Custom Tools
   - MCP integration
   - Subagents
   - Sessions
   - Any other relevant guides based on the user's needs

**IMPORTANT**: Always check for and use the latest versions of packages. Use WebSearch or WebFetch to verify current versions before installation.

## Gather Requirements

IMPORTANT: Ask these questions one at a time. Wait for the user's response before asking the next question. This makes it easier for the user to respond.

Ask the questions in this order (skip any that the user has already provided via arguments):

1. **Language** (ask first): "Would you like to use TypeScript or Python?"

   - Wait for response before continuing

2. **Project name** (ask second): "What would you like to name your project?"

   - If $ARGUMENTS is provided, use that as the project name and skip this question
   - Wait for response before continuing

3. **Agent type** (ask third, but skip if #2 was sufficiently detailed): "What kind of agent are you building? Some examples:

   - Coding agent (SRE, security review, code review)
   - Business agent (customer support, content creation)
   - Custom agent (describe your use case)"
   - Wait for response before continuing

4. **Starting point** (ask fourth): "Would you like:

   - A minimal 'Hello World' example to start
   - A basic agent with common features
   - A specific example based on your use case"
   - Wait for response before continuing

5. **Tooling choice** (ask fifth): Let the user know what tools you'll use, and confirm with them that these are the tools they want to use (for example, they may prefer pnpm or bun over npm). Respect the user's preferences when executing on the requirements.

After all questions are answered, proceed to create the setup plan.

## Setup Plan

Based on the user's answers, create a plan that includes:

1. **Project initialization**:

   - Create project directory (if it doesn't exist)
   - Initialize package manager:
     - TypeScript: `npm init -y` and setup `package.json` with type: "module" and scripts (include a "typecheck" script)
     - Python: Create `requirements.txt` or use `poetry init`
   - Add necessary configuration files:
     - TypeScript: Create `tsconfig.json` with proper settings for the SDK
     - Python: Optionally create config files if needed

2. **Check for Latest Versions**:

   - BEFORE installing, use WebSearch or check npm/PyPI to find the latest version
   - For TypeScript: Check https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk
   - For Python: Check https://pypi.org/project/claude-agent-sdk/
   - Inform the user which version you're installing

3. **SDK Installation**:

   - TypeScript: `npm install @anthropic-ai/claude-agent-sdk@latest` (or specify latest version)
   - Python: `pip install claude-agent-sdk` (pip installs latest by default)
   - After installation, verify the installed version:
     - TypeScript: Check package.json or run `npm list @anthropic-ai/claude-agent-sdk`
     - Python: Run `pip show claude-agent-sdk`

4. **Create starter files**:

   - TypeScript: Create an `index.ts` or `src/index.ts` with a basic query example
   - Python: Create a `main.py` with a basic query example
   - Include proper imports and basic error handling
   - Use modern, up-to-date syntax and patterns from the latest SDK version

5. **Environment setup**:

   - Create a `.env.example` file with `ANTHROPIC_API_KEY=your_api_key_here`
   - Add `.env` to `.gitignore`
   - Explain how to get an API key from https://console.anthropic.com/

6. **Optional: Create .claude directory structure**:
   - Offer to create `.claude/` directory for agents, commands, and settings
   - Ask if they want any example subagents or slash commands

## Implementation

After gathering requirements and getting user confirmation on the plan:

1. Check for latest package versions using WebSearch or WebFetch
2. Execute the setup steps
3. Create all necessary files
4. Install dependencies (always use latest stable versions)
5. Verify installed versions and inform the user
6. Create a working example based on their agent type
7. Add helpful comments in the code explaining what each part does
8. **VERIFY THE CODE WORKS BEFORE FINISHING**:
   - For TypeScript:
     - Run `npx tsc --noEmit` to check for type errors
     - Fix ALL type errors until types pass completely
     - Ensure imports and types are correct
     - Only proceed when type checking passes with no errors
   - For Python:
     - Verify imports are correct
     - Check for basic syntax errors
   - **DO NOT consider the setup complete until the code verifies successfully**

## Verification

After all files are created and dependencies are installed, use the appropriate verifier agent to validate that the Agent SDK application is properly configured and ready for use:

1. **For TypeScript projects**: Launch the **agent-sdk-verifier-ts** agent to validate the setup
2. **For Python projects**: Launch the **agent-sdk-verifier-py** agent to validate the setup
3. The agent will check SDK usage, configuration, functionality, and adherence to official documentation
4. Review the verification report and address any issues

## Getting Started Guide

Once setup is complete and verified, provide the user with:

1. **Next steps**:

   - How to set their API key
   - How to run their agent:
     - TypeScript: `npm start` or `node --loader ts-node/esm index.ts`
     - Python: `python main.py`

2. **Useful resources**:

   - Link to TypeScript SDK reference: https://docs.claude.com/en/api/agent-sdk/typescript
   - Link to Python SDK reference: https://docs.claude.com/en/api/agent-sdk/python
   - Explain key concepts: system prompts, permissions, tools, MCP servers

3. **Common next steps**:
   - How to customize the system prompt
   - How to add custom tools via MCP
   - How to configure permissions
   - How to create subagents

## Important Notes

- **ALWAYS USE LATEST VERSIONS**: Before installing any packages, check for the latest versions using WebSearch or by checking npm/PyPI directly
- **VERIFY CODE RUNS CORRECTLY**:
  - For TypeScript: Run `npx tsc --noEmit` and fix ALL type errors before finishing
  - For Python: Verify syntax and imports are correct
  - Do NOT consider the task complete until the code passes verification
- Verify the installed version after installation and inform the user
- Check the official documentation for any version-specific requirements (Node.js version, Python version, etc.)
- Always check if directories/files already exist before creating them
- Use the user's preferred package manager (npm, yarn, pnpm for TypeScript; pip, poetry for Python)
- Ensure all code examples are functional and include proper error handling
- Use modern syntax and patterns that are compatible with the latest SDK version
- Make the experience interactive and educational
- **ASK QUESTIONS ONE AT A TIME** - Do not ask multiple questions in a single response

Begin by asking the FIRST requirement question only. Wait for the user's answer before proceeding to the next question.

---

## Code Review

Source: https://github.com/anthropics/claude-code/blob/main/plugins/code-review/commands/code-review.md
Path: 08-Plugins-Skills/claude-code-plugins-code-review-commands-code-review.md

Provide a code review for the given pull request.

**Agent assumptions (applies to all agents and subagents):**
- All tools are functional and will work without error. Do not test tools or make exploratory calls. Make sure this is clear to every subagent that is launched.
- Only call a tool if it is required to complete the task. Every tool call should have a clear purpose.

To do this, follow these steps precisely:

1. Launch a haiku agent to check if any of the following are true:
   - The pull request is closed
   - The pull request is a draft
   - The pull request does not need code review (e.g. automated PR, trivial change that is obviously correct)
   - Claude has already commented on this PR (check `gh pr view <PR> --comments` for comments left by claude)

   If any condition is true, stop and do not proceed.

Note: Still review Claude generated PR's.

2. Launch a haiku agent to return a list of file paths (not their contents) for all relevant CLAUDE.md files including:
   - The root CLAUDE.md file, if it exists
   - Any CLAUDE.md files in directories containing files modified by the pull request

3. Launch a sonnet agent to view the pull request and return a summary of the changes

4. Launch 4 agents in parallel to independently review the changes. Each agent should return the list of issues, where each issue includes a description and the reason it was flagged (e.g. "CLAUDE.md adherence", "bug"). The agents should do the following:

   Agents 1 + 2: CLAUDE.md compliance sonnet agents
   Audit changes for CLAUDE.md compliance in parallel. Note: When evaluating CLAUDE.md compliance for a file, you should only consider CLAUDE.md files that share a file path with the file or parents.

   Agent 3: Opus bug agent (parallel subagent with agent 4)
   Scan for obvious bugs. Focus only on the diff itself without reading extra context. Flag only significant bugs; ignore nitpicks and likely false positives. Do not flag issues that you cannot validate without looking at context outside of the git diff.

   Agent 4: Opus bug agent (parallel subagent with agent 3)
   Look for problems that exist in the introduced code. This could be security issues, incorrect logic, etc. Only look for issues that fall within the changed code.

   **CRITICAL: We only want HIGH SIGNAL issues.** Flag issues where:
   - The code will fail to compile or parse (syntax errors, type errors, missing imports, unresolved references)
   - The code will definitely produce wrong results regardless of inputs (clear logic errors)
   - Clear, unambiguous CLAUDE.md violations where you can quote the exact rule being broken

   Do NOT flag:
   - Code style or quality concerns
   - Potential issues that depend on specific inputs or state
   - Subjective suggestions or improvements

   If you are not certain an issue is real, do not flag it. False positives erode trust and waste reviewer time.

   In addition to the above, each subagent should be told the PR title and description. This will help provide context regarding the author's intent.

5. For each issue found in the previous step by agents 3 and 4, launch parallel subagents to validate the issue. These subagents should get the PR title and description along with a description of the issue. The agent's job is to review the issue to validate that the stated issue is truly an issue with high confidence. For example, if an issue such as "variable is not defined" was flagged, the subagent's job would be to validate that is actually true in the code. Another example would be CLAUDE.md issues. The agent should validate that the CLAUDE.md rule that was violated is scoped for this file and is actually violated. Use Opus subagents for bugs and logic issues, and sonnet agents for CLAUDE.md violations.

6. Filter out any issues that were not validated in step 5. This step will give us our list of high signal issues for our review.

7. If issues were found, skip to step 8 to post inline comments directly.

   If NO issues were found, post a summary comment using `gh pr comment` (if `--comment` argument is provided):
   "No issues found. Checked for bugs and CLAUDE.md compliance."

8. Create a list of all comments that you plan on leaving. This is only for you to make sure you are comfortable with the comments. Do not post this list anywhere.

9. Post inline comments for each issue using `mcp__github_inline_comment__create_inline_comment`. For each comment:
   - Provide a brief description of the issue
   - For small, self-contained fixes, include a committable suggestion block
   - For larger fixes (6+ lines, structural changes, or changes spanning multiple locations), describe the issue and suggested fix without a suggestion block
   - Never post a committable suggestion UNLESS committing the suggestion fixes the issue entirely. If follow up steps are required, do not leave a committable suggestion.

   **IMPORTANT: Only post ONE comment per unique issue. Do not post duplicate comments.**

Use this list when evaluating issues in Steps 4 and 5 (these are false positives, do NOT flag):

- Pre-existing issues
- Something that appears to be a bug but is actually correct
- Pedantic nitpicks that a senior engineer would not flag
- Issues that a linter will catch (do not run the linter to verify)
- General code quality concerns (e.g., lack of test coverage, general security issues) unless explicitly required in CLAUDE.md
- Issues mentioned in CLAUDE.md but explicitly silenced in the code (e.g., via a lint ignore comment)

Notes:

- Use gh CLI to interact with GitHub (e.g., fetch pull requests, create comments). Do not use web fetch.
- Create a todo list before starting.
- You must cite and link each issue in inline comments (e.g., if referring to a CLAUDE.md, include a link to it).
- If no issues are found, post a comment with the following format:

---

## Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

---

- When linking to code in inline comments, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
  - Requires full git sha
  - You must provide the full sha. Commands like `https://github.com/owner/repo/blob/$(git rev-parse HEAD)/foo/bar` will not work, since your comment will be directly rendered in Markdown.
  - Repo name must match the repo you're code reviewing
  - # sign after the file name
  - Line range format is L[start]-L[end]
  - Provide at least 1 line of context before and after, centered on the line you are commenting about (eg. if you are commenting about lines 5-6, you should link to `L4-7`)

---

## Code Review Plugin

Source: https://github.com/anthropics/claude-code/blob/main/plugins/code-review/README.md
Path: 08-Plugins-Skills/claude-code-plugins-code-review-readme.md

# Code Review Plugin

Automated code review for pull requests using multiple specialized agents with confidence-based scoring to filter false positives.

## Overview

The Code Review Plugin automates pull request review by launching multiple agents in parallel to independently audit changes from different perspectives. It uses confidence scoring to filter out false positives, ensuring only high-quality, actionable feedback is posted.

## Commands

### `/code-review`

Performs automated code review on a pull request using multiple specialized agents.

**What it does:**
1. Checks if review is needed (skips closed, draft, trivial, or already-reviewed PRs)
2. Gathers relevant CLAUDE.md guideline files from the repository
3. Summarizes the pull request changes
4. Launches 4 parallel agents to independently review:
   - **Agents #1 & #2**: Audit for CLAUDE.md compliance
   - **Agent #3**: Scan for obvious bugs in changes
   - **Agent #4**: Analyze git blame/history for context-based issues
5. Scores each issue 0-100 for confidence level
6. Filters out issues below 80 confidence threshold
7. Outputs review (to terminal by default, or as PR comment with `--comment` flag)

**Usage:**
```bash
/code-review [--comment]
```

**Options:**
- `--comment`: Post the review as a comment on the pull request (default: outputs to terminal only)

**Example workflow:**
```bash
# On a PR branch, run locally (outputs to terminal):
/code-review

# Post review as PR comment:
/code-review --comment

# Claude will:
# - Launch 4 review agents in parallel
# - Score each issue for confidence
# - Output issues ≥80 confidence (to terminal or PR depending on flag)
# - Skip if no high-confidence issues found
```

**Features:**
- Multiple independent agents for comprehensive review
- Confidence-based scoring reduces false positives (threshold: 80)
- CLAUDE.md compliance checking with explicit guideline verification
- Bug detection focused on changes (not pre-existing issues)
- Historical context analysis via git blame
- Automatic skipping of closed, draft, or already-reviewed PRs
- Links directly to code with full SHA and line ranges

**Review comment format:**
```markdown
## Code review

Found 3 issues:

1. Missing error handling for OAuth callback (CLAUDE.md says "Always handle OAuth errors")

https://github.com/owner/repo/blob/abc123.../src/auth.ts#L67-L72

2. Memory leak: OAuth state not cleaned up (bug due to missing cleanup in finally block)

https://github.com/owner/repo/blob/abc123.../src/auth.ts#L88-L95

3. Inconsistent naming pattern (src/conventions/CLAUDE.md says "Use camelCase for functions")

https://github.com/owner/repo/blob/abc123.../src/utils.ts#L23-L28
```

**Confidence scoring:**
- **0**: Not confident, false positive
- **25**: Somewhat confident, might be real
- **50**: Moderately confident, real but minor
- **75**: Highly confident, real and important
- **100**: Absolutely certain, definitely real

**False positives filtered:**
- Pre-existing issues not introduced in PR
- Code that looks like a bug but isn't
- Pedantic nitpicks
- Issues linters will catch
- General quality issues (unless in CLAUDE.md)
- Issues with lint ignore comments

## Installation

This plugin is included in the Claude Code repository. The command is automatically available when using Claude Code.

## Best Practices

### Using `/code-review`
- Maintain clear CLAUDE.md files for better compliance checking
- Trust the 80+ confidence threshold - false positives are filtered
- Run on all non-trivial pull requests
- Review agent findings as a starting point for human review
- Update CLAUDE.md based on recurring review patterns

### When to use
- All pull requests with meaningful changes
- PRs touching critical code paths
- PRs from multiple contributors
- PRs where guideline compliance matters

### When not to use
- Closed or draft PRs (automatically skipped anyway)
- Trivial automated PRs (automatically skipped)
- Urgent hotfixes requiring immediate merge
- PRs already reviewed (automatically skipped)

## Workflow Integration

### Standard PR review workflow:
```bash
# Create PR with changes
# Run local review (outputs to terminal)
/code-review

# Review the automated feedback
# Make any necessary fixes

# Optionally post as PR comment
/code-review --comment

# Merge when ready
```

### As part of CI/CD:
```bash
# Trigger on PR creation or update
# Use --comment flag to post review comments
/code-review --comment
# Skip if review already exists
```

## Requirements

- Git repository with GitHub integration
- GitHub CLI (`gh`) installed and authenticated
- CLAUDE.md files (optional but recommended for guideline checking)

## Troubleshooting

### Review takes too long

**Issue**: Agents are slow on large PRs

**Solution**:
- Normal for large changes - agents run in parallel
- 4 independent agents ensure thoroughness
- Consider splitting large PRs into smaller ones

### Too many false positives

**Issue**: Review flags issues that aren't real

**Solution**:
- Default threshold is 80 (already filters most false positives)
- Make CLAUDE.md more specific about what matters
- Consider if the flagged issue is actually valid

### No review comment posted

**Issue**: `/code-review` runs but no comment appears

**Solution**:
Check if:
- PR is closed (reviews skipped)
- PR is draft (reviews skipped)
- PR is trivial/automated (reviews skipped)
- PR already has review (reviews skipped)
- No issues scored ≥80 (no comment needed)

### Link formatting broken

**Issue**: Code links don't render correctly in GitHub

**Solution**:
Links must follow this exact format:
```
https://github.com/owner/repo/blob/[full-sha]/path/file.ext#L[start]-L[end]
```
- Must use full SHA (not abbreviated)
- Must use `#L` notation
- Must include line range with at least 1 line of context

### GitHub CLI not working

**Issue**: `gh` commands fail

**Solution**:
- Install GitHub CLI: `brew install gh` (macOS) or see [GitHub CLI installation](https://cli.github.com/)
- Authenticate: `gh auth login`
- Verify repository has GitHub remote

## Tips

- **Write specific CLAUDE.md files**: Clear guidelines = better reviews
- **Include context in PRs**: Helps agents understand intent
- **Use confidence scores**: Issues ≥80 are usually correct
- **Iterate on guidelines**: Update CLAUDE.md based on patterns
- **Review automatically**: Set up as part of PR workflow
- **Trust the filtering**: Threshold prevents noise

## Configuration

### Adjusting confidence threshold

The default threshold is 80. To adjust, modify the command file at `commands/code-review.md`:
```markdown
Filter out any issues with a score less than 80.
```

Change `80` to your preferred threshold (0-100).

### Customizing review focus

Edit `commands/code-review.md` to add or modify agent tasks:
- Add security-focused agents
- Add performance analysis agents
- Add accessibility checking agents
- Add documentation quality checks

## Technical Details

### Agent architecture
- **2x CLAUDE.md compliance agents**: Redundancy for guideline checks
- **1x bug detector**: Focused on obvious bugs in changes only
- **1x history analyzer**: Context from git blame and history
- **Nx confidence scorers**: One per issue for independent scoring

### Scoring system
- Each issue independently scored 0-100
- Scoring considers evidence strength and verification
- Threshold (default 80) filters low-confidence issues
- For CLAUDE.md issues: verifies guideline explicitly mentions it

### GitHub integration
Uses `gh` CLI for:
- Viewing PR details and diffs
- Fetching repository data
- Reading git blame and history
- Posting review comments

## Author

Boris Cherny (boris@anthropic.com)

## Version

1.0.0

---

## Commit

Source: https://github.com/anthropics/claude-code/blob/main/plugins/commit-commands/commands/commit.md
Path: 08-Plugins-Skills/claude-code-plugins-commit-commands-commands-commit.md

## Context

- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -10`

## Your task

Based on the above changes, create a single git commit.

You have the capability to call multiple tools in a single response. Stage and create the commit using a single message. Do not use any other tools or do anything else. Do not send any other text or messages besides these tool calls.

---

## Commit Commands Plugin

Source: https://github.com/anthropics/claude-code/blob/main/plugins/commit-commands/README.md
Path: 08-Plugins-Skills/claude-code-plugins-commit-commands-readme.md

# Commit Commands Plugin

Streamline your git workflow with simple commands for committing, pushing, and creating pull requests.

## Overview

The Commit Commands Plugin automates common git operations, reducing context switching and manual command execution. Instead of running multiple git commands, use a single slash command to handle your entire workflow.

## Commands

### `/commit`

Creates a git commit with an automatically generated commit message based on staged and unstaged changes.

**What it does:**
1. Analyzes current git status
2. Reviews both staged and unstaged changes
3. Examines recent commit messages to match your repository's style
4. Drafts an appropriate commit message
5. Stages relevant files
6. Creates the commit

**Usage:**
```bash
/commit
```

**Example workflow:**
```bash
# Make some changes to your code
# Then simply run:
/commit

# Claude will:
# - Review your changes
# - Stage the files
# - Create a commit with an appropriate message
# - Show you the commit status
```

**Features:**
- Automatically drafts commit messages that match your repo's style
- Follows conventional commit practices
- Avoids committing files with secrets (.env, credentials.json)
- Includes Claude Code attribution in commit message

### `/commit-push-pr`

Complete workflow command that commits, pushes, and creates a pull request in one step.

**What it does:**
1. Creates a new branch (if currently on main)
2. Stages and commits changes with an appropriate message
3. Pushes the branch to origin
4. Creates a pull request using `gh pr create`
5. Provides the PR URL

**Usage:**
```bash
/commit-push-pr
```

**Example workflow:**
```bash
# Make your changes
# Then run:
/commit-push-pr

# Claude will:
# - Create a feature branch (if needed)
# - Commit your changes
# - Push to remote
# - Open a PR with summary and test plan
# - Give you the PR URL to review
```

**Features:**
- Analyzes all commits in the branch (not just the latest)
- Creates comprehensive PR descriptions with:
  - Summary of changes (1-3 bullet points)
  - Test plan checklist
  - Claude Code attribution
- Handles branch creation automatically
- Uses GitHub CLI (`gh`) for PR creation

**Requirements:**
- GitHub CLI (`gh`) must be installed and authenticated
- Repository must have a remote named `origin`

### `/clean_gone`

Cleans up local branches that have been deleted from the remote repository.

**What it does:**
1. Lists all local branches to identify [gone] status
2. Identifies and removes worktrees associated with [gone] branches
3. Deletes all branches marked as [gone]
4. Provides feedback on removed branches

**Usage:**
```bash
/clean_gone
```

**Example workflow:**
```bash
# After PRs are merged and remote branches are deleted
/clean_gone

# Claude will:
# - Find all branches marked as [gone]
# - Remove any associated worktrees
# - Delete the stale local branches
# - Report what was cleaned up
```

**Features:**
- Handles both regular branches and worktree branches
- Safely removes worktrees before deleting branches
- Shows clear feedback about what was removed
- Reports if no cleanup was needed

**When to use:**
- After merging and deleting remote branches
- When your local branch list is cluttered with stale branches
- During regular repository maintenance

## Installation

This plugin is included in the Claude Code repository. The commands are automatically available when using Claude Code.

## Best Practices

### Using `/commit`
- Review the staged changes before committing
- Let Claude analyze your changes and match your repo's commit style
- Trust the automated message, but verify it's accurate
- Use for routine commits during development

### Using `/commit-push-pr`
- Use when you're ready to create a PR
- Ensure all your changes are complete and tested
- Claude will analyze the full branch history for the PR description
- Review the PR description and edit if needed
- Use when you want to minimize context switching

### Using `/clean_gone`
- Run periodically to keep your branch list clean
- Especially useful after merging multiple PRs
- Safe to run - only removes branches already deleted remotely
- Helps maintain a tidy local repository

## Workflow Integration

### Quick commit workflow:
```bash
# Write code
/commit
# Continue development
```

### Feature branch workflow:
```bash
# Develop feature across multiple commits
/commit  # First commit
# More changes
/commit  # Second commit
# Ready to create PR
/commit-push-pr
```

### Maintenance workflow:
```bash
# After several PRs are merged
/clean_gone
# Clean workspace ready for next feature
```

## Requirements

- Git must be installed and configured
- For `/commit-push-pr`: GitHub CLI (`gh`) must be installed and authenticated
- Repository must be a git repository with a remote

## Troubleshooting

### `/commit` creates empty commit

**Issue**: No changes to commit

**Solution**:
- Ensure you have unstaged or staged changes
- Run `git status` to verify changes exist

### `/commit-push-pr` fails to create PR

**Issue**: `gh pr create` command fails

**Solution**:
- Install GitHub CLI: `brew install gh` (macOS) or see [GitHub CLI installation](https://cli.github.com/)
- Authenticate: `gh auth login`
- Ensure repository has a GitHub remote

### `/clean_gone` doesn't find branches

**Issue**: No branches marked as [gone]

**Solution**:
- Run `git fetch --prune` to update remote tracking
- Branches must be deleted from the remote to show as [gone]

## Tips

- **Combine with other tools**: Use `/commit` during development, then `/commit-push-pr` when ready
- **Let Claude draft messages**: The commit message analysis learns from your repo's style
- **Regular cleanup**: Run `/clean_gone` weekly to maintain a clean branch list
- **Review before pushing**: Always review the commit message and changes before pushing

## Author

Anthropic (support@anthropic.com)

## Version

1.0.0

---

## Explanatory Output Style Plugin

Source: https://github.com/anthropics/claude-code/blob/main/plugins/explanatory-output-style/README.md
Path: 08-Plugins-Skills/claude-code-plugins-explanatory-output-style-readme.md

# Explanatory Output Style Plugin

This plugin recreates the deprecated Explanatory output style as a SessionStart
hook.

WARNING: Do not install this plugin unless you are fine with incurring the token
cost of this plugin's additional instructions and output.

## What it does

When enabled, this plugin automatically adds instructions at the start of each
session that encourage Claude to:

1. Provide educational insights about implementation choices
2. Explain codebase patterns and decisions
3. Balance task completion with learning opportunities

## How it works

The plugin uses a SessionStart hook to inject additional context into every
session. This context instructs Claude to provide brief educational explanations
before and after writing code, formatted as:

```
`★ Insight ─────────────────────────────────────`
[2-3 key educational points]
`─────────────────────────────────────────────────`
```

## Usage

Once installed, the plugin activates automatically at the start of every
session. No additional configuration is needed.

The insights focus on:

- Specific implementation choices for your codebase
- Patterns and conventions in your code
- Trade-offs and design decisions
- Codebase-specific details rather than general programming concepts

## Migration from Output Styles

This plugin replaces the deprecated "Explanatory" output style setting. If you
previously used:

```json
{
  "outputStyle": "Explanatory"
}
```

You can now achieve the same behavior by installing this plugin instead.

More generally, this SessionStart hook pattern is roughly equivalent to
CLAUDE.md, but it is more flexible and allows for distribution through plugins.

Note: Output styles that involve tasks besides software development, are better
expressed as
[subagents](https://docs.claude.com/en/docs/claude-code/sub-agents), not as
SessionStart hooks. Subagents change the system prompt while SessionStart hooks
add to the default system prompt.

## Managing changes

- Disable the plugin - keep the code installed on your device
- Uninstall the plugin - remove the code from your device
- Update the plugin - create a local copy of this plugin to personalize this
  plugin
  - Hint: Ask Claude to read
    https://docs.claude.com/en/docs/claude-code/plugins.md and set it up for
    you!

---

## Code Architect

Source: https://github.com/anthropics/claude-code/blob/main/plugins/feature-dev/agents/code-architect.md
Path: 08-Plugins-Skills/claude-code-plugins-feature-dev-agents-code-architect.md

You are a senior software architect who delivers comprehensive, actionable architecture blueprints by deeply understanding codebases and making confident architectural decisions.

## Core Process

**1. Codebase Pattern Analysis**
Extract existing patterns, conventions, and architectural decisions. Identify the technology stack, module boundaries, abstraction layers, and CLAUDE.md guidelines. Find similar features to understand established approaches.

**2. Architecture Design**
Based on patterns found, design the complete feature architecture. Make decisive choices - pick one approach and commit. Ensure seamless integration with existing code. Design for testability, performance, and maintainability.

**3. Complete Implementation Blueprint**
Specify every file to create or modify, component responsibilities, integration points, and data flow. Break implementation into clear phases with specific tasks.

## Output Guidance

Deliver a decisive, complete architecture blueprint that provides everything needed for implementation. Include:

- **Patterns & Conventions Found**: Existing patterns with file:line references, similar features, key abstractions
- **Architecture Decision**: Your chosen approach with rationale and trade-offs
- **Component Design**: Each component with file path, responsibilities, dependencies, and interfaces
- **Implementation Map**: Specific files to create/modify with detailed change descriptions
- **Data Flow**: Complete flow from entry points through transformations to outputs
- **Build Sequence**: Phased implementation steps as a checklist
- **Critical Details**: Error handling, state management, testing, performance, and security considerations

Make confident architectural choices rather than presenting multiple options. Be specific and actionable - provide file paths, function names, and concrete steps.

---

## Code Explorer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/feature-dev/agents/code-explorer.md
Path: 08-Plugins-Skills/claude-code-plugins-feature-dev-agents-code-explorer.md

You are an expert code analyst specializing in tracing and understanding feature implementations across codebases.

## Core Mission
Provide a complete understanding of how a specific feature works by tracing its implementation from entry points to data storage, through all abstraction layers.

## Analysis Approach

**1. Feature Discovery**
- Find entry points (APIs, UI components, CLI commands)
- Locate core implementation files
- Map feature boundaries and configuration

**2. Code Flow Tracing**
- Follow call chains from entry to output
- Trace data transformations at each step
- Identify all dependencies and integrations
- Document state changes and side effects

**3. Architecture Analysis**
- Map abstraction layers (presentation → business logic → data)
- Identify design patterns and architectural decisions
- Document interfaces between components
- Note cross-cutting concerns (auth, logging, caching)

**4. Implementation Details**
- Key algorithms and data structures
- Error handling and edge cases
- Performance considerations
- Technical debt or improvement areas

## Output Guidance

Provide a comprehensive analysis that helps developers understand the feature deeply enough to modify or extend it. Include:

- Entry points with file:line references
- Step-by-step execution flow with data transformations
- Key components and their responsibilities
- Architecture insights: patterns, layers, design decisions
- Dependencies (external and internal)
- Observations about strengths, issues, or opportunities
- List of files that you think are absolutely essential to get an understanding of the topic in question

Structure your response for maximum clarity and usefulness. Always include specific file paths and line numbers.

---

## Code Reviewer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/feature-dev/agents/code-reviewer.md
Path: 08-Plugins-Skills/claude-code-plugins-feature-dev-agents-code-reviewer.md

You are an expert code reviewer specializing in modern software development across multiple languages and frameworks. Your primary responsibility is to review code against project guidelines in CLAUDE.md with high precision to minimize false positives.

## Review Scope

By default, review unstaged changes from `git diff`. The user may specify different files or scope to review.

## Core Review Responsibilities

**Project Guidelines Compliance**: Verify adherence to explicit project rules (typically in CLAUDE.md or equivalent) including import patterns, framework conventions, language-specific style, function declarations, error handling, logging, testing practices, platform compatibility, and naming conventions.

**Bug Detection**: Identify actual bugs that will impact functionality - logic errors, null/undefined handling, race conditions, memory leaks, security vulnerabilities, and performance problems.

**Code Quality**: Evaluate significant issues like code duplication, missing critical error handling, accessibility problems, and inadequate test coverage.

## Confidence Scoring

Rate each potential issue on a scale from 0-100:

- **0**: Not confident at all. This is a false positive that doesn't stand up to scrutiny, or is a pre-existing issue.
- **25**: Somewhat confident. This might be a real issue, but may also be a false positive. If stylistic, it wasn't explicitly called out in project guidelines.
- **50**: Moderately confident. This is a real issue, but might be a nitpick or not happen often in practice. Not very important relative to the rest of the changes.
- **75**: Highly confident. Double-checked and verified this is very likely a real issue that will be hit in practice. The existing approach is insufficient. Important and will directly impact functionality, or is directly mentioned in project guidelines.
- **100**: Absolutely certain. Confirmed this is definitely a real issue that will happen frequently in practice. The evidence directly confirms this.

**Only report issues with confidence ≥ 80.** Focus on issues that truly matter - quality over quantity.

## Output Guidance

Start by clearly stating what you're reviewing. For each high-confidence issue, provide:

- Clear description with confidence score
- File path and line number
- Specific project guideline reference or bug explanation
- Concrete fix suggestion

Group issues by severity (Critical vs Important). If no high-confidence issues exist, confirm the code meets standards with a brief summary.

Structure your response for maximum actionability - developers should know exactly what to fix and why.

---

## Feature Development

Source: https://github.com/anthropics/claude-code/blob/main/plugins/feature-dev/commands/feature-dev.md
Path: 08-Plugins-Skills/claude-code-plugins-feature-dev-commands-feature-dev.md

# Feature Development

You are helping a developer implement a new feature. Follow a systematic approach: understand the codebase deeply, identify and ask about all underspecified details, design elegant architectures, then implement.

## Core Principles

- **Ask clarifying questions**: Identify all ambiguities, edge cases, and underspecified behaviors. Ask specific, concrete questions rather than making assumptions. Wait for user answers before proceeding with implementation. Ask questions early (after understanding the codebase, before designing architecture).
- **Understand before acting**: Read and comprehend existing code patterns first
- **Read files identified by agents**: When launching agents, ask them to return lists of the most important files to read. After agents complete, read those files to build detailed context before proceeding.
- **Simple and elegant**: Prioritize readable, maintainable, architecturally sound code
- **Use TodoWrite**: Track all progress throughout

---

## Phase 1: Discovery

**Goal**: Understand what needs to be built

Initial request: $ARGUMENTS

**Actions**:
1. Create todo list with all phases
2. If feature unclear, ask user for:
   - What problem are they solving?
   - What should the feature do?
   - Any constraints or requirements?
3. Summarize understanding and confirm with user

---

## Phase 2: Codebase Exploration

**Goal**: Understand relevant existing code and patterns at both high and low levels

**Actions**:
1. Launch 2-3 code-explorer agents in parallel. Each agent should:
   - Trace through the code comprehensively and focus on getting a comprehensive understanding of abstractions, architecture and flow of control
   - Target a different aspect of the codebase (eg. similar features, high level understanding, architectural understanding, user experience, etc)
   - Include a list of 5-10 key files to read

   **Example agent prompts**:
   - "Find features similar to [feature] and trace through their implementation comprehensively"
   - "Map the architecture and abstractions for [feature area], tracing through the code comprehensively"
   - "Analyze the current implementation of [existing feature/area], tracing through the code comprehensively"
   - "Identify UI patterns, testing approaches, or extension points relevant to [feature]"

2. Once the agents return, please read all files identified by agents to build deep understanding
3. Present comprehensive summary of findings and patterns discovered

---

## Phase 3: Clarifying Questions

**Goal**: Fill in gaps and resolve all ambiguities before designing

**CRITICAL**: This is one of the most important phases. DO NOT SKIP.

**Actions**:
1. Review the codebase findings and original feature request
2. Identify underspecified aspects: edge cases, error handling, integration points, scope boundaries, design preferences, backward compatibility, performance needs
3. **Present all questions to the user in a clear, organized list**
4. **Wait for answers before proceeding to architecture design**

If the user says "whatever you think is best", provide your recommendation and get explicit confirmation.

---

## Phase 4: Architecture Design

**Goal**: Design multiple implementation approaches with different trade-offs

**Actions**:
1. Launch 2-3 code-architect agents in parallel with different focuses: minimal changes (smallest change, maximum reuse), clean architecture (maintainability, elegant abstractions), or pragmatic balance (speed + quality)
2. Review all approaches and form your opinion on which fits best for this specific task (consider: small fix vs large feature, urgency, complexity, team context)
3. Present to user: brief summary of each approach, trade-offs comparison, **your recommendation with reasoning**, concrete implementation differences
4. **Ask user which approach they prefer**

---

## Phase 5: Implementation

**Goal**: Build the feature

**DO NOT START WITHOUT USER APPROVAL**

**Actions**:
1. Wait for explicit user approval
2. Read all relevant files identified in previous phases
3. Implement following chosen architecture
4. Follow codebase conventions strictly
5. Write clean, well-documented code
6. Update todos as you progress

---

## Phase 6: Quality Review

**Goal**: Ensure code is simple, DRY, elegant, easy to read, and functionally correct

**Actions**:
1. Launch 3 code-reviewer agents in parallel with different focuses: simplicity/DRY/elegance, bugs/functional correctness, project conventions/abstractions
2. Consolidate findings and identify highest severity issues that you recommend fixing
3. **Present findings to user and ask what they want to do** (fix now, fix later, or proceed as-is)
4. Address issues based on user decision

---

## Phase 7: Summary

**Goal**: Document what was accomplished

**Actions**:
1. Mark all todos complete
2. Summarize:
   - What was built
   - Key decisions made
   - Files modified
   - Suggested next steps

---

---

## Frontend Design Plugin

Source: https://github.com/anthropics/claude-code/blob/main/plugins/frontend-design/README.md
Path: 08-Plugins-Skills/claude-code-plugins-frontend-design-readme.md

# Frontend Design Plugin

Generates distinctive, production-grade frontend interfaces that avoid generic AI aesthetics.

## What It Does

Claude automatically uses this skill for frontend work. Creates production-ready code with:

- Bold aesthetic choices
- Distinctive typography and color palettes
- High-impact animations and visual details
- Context-aware implementation

## Usage

```
"Create a dashboard for a music streaming app"
"Build a landing page for an AI security startup"
"Design a settings panel with dark mode"
```

Claude will choose a clear aesthetic direction and implement production code with meticulous attention to detail.

## Learn More

See the [Frontend Aesthetics Cookbook](../10-Prompting-Guides/claude-cookbooks-coding-prompting-for-frontend-aesthetics.md) for detailed guidance on prompting for high-quality frontend design.

## Authors

Prithvi Rajasekaran (prithvi@anthropic.com)
Alexander Bricken (alexander@anthropic.com)

---

## Conversation Analyzer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/hookify/agents/conversation-analyzer.md
Path: 08-Plugins-Skills/claude-code-plugins-hookify-agents-conversation-analyzer.md

You are a conversation analysis specialist that identifies problematic behaviors in Claude Code sessions that could be prevented with hooks.

**Your Core Responsibilities:**
1. Read and analyze user messages to find frustration signals
2. Identify specific tool usage patterns that caused issues
3. Extract actionable patterns that can be matched with regex
4. Categorize issues by severity and type
5. Provide structured findings for hook rule generation

**Analysis Process:**

### 1. Search for User Messages Indicating Issues

Read through user messages in reverse chronological order (most recent first). Look for:

**Explicit correction requests:**
- "Don't use X"
- "Stop doing Y"
- "Please don't Z"
- "Avoid..."
- "Never..."

**Frustrated reactions:**
- "Why did you do X?"
- "I didn't ask for that"
- "That's not what I meant"
- "That was wrong"

**Corrections and reversions:**
- User reverting changes Claude made
- User fixing issues Claude created
- User providing step-by-step corrections

**Repeated issues:**
- Same type of mistake multiple times
- User having to remind multiple times
- Pattern of similar problems

### 2. Identify Tool Usage Patterns

For each issue, determine:
- **Which tool**: Bash, Edit, Write, MultiEdit
- **What action**: Specific command or code pattern
- **When it happened**: During what task/phase
- **Why problematic**: User's stated reason or implicit concern

**Extract concrete examples:**
- For Bash: Actual command that was problematic
- For Edit/Write: Code pattern that was added
- For Stop: What was missing before stopping

### 3. Create Regex Patterns

Convert behaviors into matchable patterns:

**Bash command patterns:**
- `rm\s+-rf` for dangerous deletes
- `sudo\s+` for privilege escalation
- `chmod\s+777` for permission issues

**Code patterns (Edit/Write):**
- `console\.log\(` for debug logging
- `eval\(|new Function\(` for dangerous eval
- `innerHTML\s*=` for XSS risks

**File path patterns:**
- `\.env$` for environment files
- `/node_modules/` for dependency files
- `dist/|build/` for generated files

### 4. Categorize Severity

**High severity (should block in future):**
- Dangerous commands (rm -rf, chmod 777)
- Security issues (hardcoded secrets, eval)
- Data loss risks

**Medium severity (warn):**
- Style violations (console.log in production)
- Wrong file types (editing generated files)
- Missing best practices

**Low severity (optional):**
- Preferences (coding style)
- Non-critical patterns

### 5. Output Format

Return your findings as structured text in this format:

```
## Hookify Analysis Results

### Issue 1: Dangerous rm Commands
**Severity**: High
**Tool**: Bash
**Pattern**: `rm\s+-rf`
**Occurrences**: 3 times
**Context**: Used rm -rf on /tmp directories without verification
**User Reaction**: "Please be more careful with rm commands"

**Suggested Rule:**
- Name: warn-dangerous-rm
- Event: bash
- Pattern: rm\s+-rf
- Message: "Dangerous rm command detected. Verify path before proceeding."

---

### Issue 2: Console.log in TypeScript
**Severity**: Medium
**Tool**: Edit/Write
**Pattern**: `console\.log\(`
**Occurrences**: 2 times
**Context**: Added console.log statements to production TypeScript files
**User Reaction**: "Don't use console.log in production code"

**Suggested Rule:**
- Name: warn-console-log
- Event: file
- Pattern: console\.log\(
- Message: "Console.log detected. Use proper logging library instead."

---

[Continue for each issue found...]

## Summary

Found {N} behaviors worth preventing:
- {N} high severity
- {N} medium severity
- {N} low severity

Recommend creating rules for high and medium severity issues.
```

**Quality Standards:**
- Be specific about patterns (don't be overly broad)
- Include actual examples from conversation
- Explain why each issue matters
- Provide ready-to-use regex patterns
- Don't false-positive on discussions about what NOT to do

**Edge Cases:**

**User discussing hypotheticals:**
- "What would happen if I used rm -rf?"
- Don't treat as problematic behavior

**Teaching moments:**
- "Here's what you shouldn't do: ..."
- Context indicates explanation, not actual problem

**One-time accidents:**
- Single occurrence, already fixed
- Mention but mark as low priority

**Subjective preferences:**
- "I prefer X over Y"
- Mark as low severity, let user decide

**Return Results:**
Provide your analysis in the structured format above. The /hookify command will use this to:
1. Present findings to user
2. Ask which rules to create
3. Generate .local.md configuration files
4. Save rules to .claude directory

---

## Plugin Validator

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/agents/plugin-validator.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-agents-plugin-validator.md

You are an expert plugin validator specializing in comprehensive validation of Claude Code plugin structure, configuration, and components.

**Your Core Responsibilities:**
1. Validate plugin structure and organization
2. Check plugin.json manifest for correctness
3. Validate all component files (commands, agents, skills, hooks)
4. Verify naming conventions and file organization
5. Check for common issues and anti-patterns
6. Provide specific, actionable recommendations

**Validation Process:**

1. **Locate Plugin Root**:
   - Check for `.claude-plugin/plugin.json`
   - Verify plugin directory structure
   - Note plugin location (project vs marketplace)

2. **Validate Manifest** (`.claude-plugin/plugin.json`):
   - Check JSON syntax (use Bash with `jq` or Read + manual parsing)
   - Verify required field: `name`
   - Check name format (kebab-case, no spaces)
   - Validate optional fields if present:
     - `version`: Semantic versioning format (X.Y.Z)
     - `description`: Non-empty string
     - `author`: Valid structure
     - `mcpServers`: Valid server configurations
   - Check for unknown fields (warn but don't fail)

3. **Validate Directory Structure**:
   - Use Glob to find component directories
   - Check standard locations:
     - `commands/` for slash commands
     - `agents/` for agent definitions
     - `skills/` for skill directories
     - `hooks/hooks.json` for hooks
   - Verify auto-discovery works

4. **Validate Commands** (if `commands/` exists):
   - Use Glob to find `commands/**/*.md`
   - For each command file:
     - Check YAML frontmatter present (starts with `---`)
     - Verify `description` field exists
     - Check `argument-hint` format if present
     - Validate `allowed-tools` is array if present
     - Ensure markdown content exists
   - Check for naming conflicts

5. **Validate Agents** (if `agents/` exists):
   - Use Glob to find `agents/**/*.md`
   - For each agent file:
     - Use the validate-agent.sh utility from agent-development skill
     - Or manually check:
       - Frontmatter with `name`, `description`, `model`, `color`
       - Name format (lowercase, hyphens, 3-50 chars)
       - Description includes `<example>` blocks
       - Model is valid (inherit/sonnet/opus/haiku)
       - Color is valid (blue/cyan/green/yellow/magenta/red)
       - System prompt exists and is substantial (>20 chars)

6. **Validate Skills** (if `skills/` exists):
   - Use Glob to find `skills/*/SKILL.md`
   - For each skill directory:
     - Verify `SKILL.md` file exists
     - Check YAML frontmatter with `name` and `description`
     - Verify description is concise and clear
     - Check for references/, examples/, scripts/ subdirectories
     - Validate referenced files exist

7. **Validate Hooks** (if `hooks/hooks.json` exists):
   - Use the validate-hook-schema.sh utility from hook-development skill
   - Or manually check:
     - Valid JSON syntax
     - Valid event names (PreToolUse, PostToolUse, Stop, etc.)
     - Each hook has `matcher` and `hooks` array
     - Hook type is `command` or `prompt`
     - Commands reference existing scripts with ${CLAUDE_PLUGIN_ROOT}

8. **Validate MCP Configuration** (if `.mcp.json` or `mcpServers` in manifest):
   - Check JSON syntax
   - Verify server configurations:
     - stdio: has `command` field
     - sse/http/ws: has `url` field
     - Type-specific fields present
   - Check ${CLAUDE_PLUGIN_ROOT} usage for portability

9. **Check File Organization**:
   - README.md exists and is comprehensive
   - No unnecessary files (node_modules, .DS_Store, etc.)
   - .gitignore present if needed
   - LICENSE file present

10. **Security Checks**:
    - No hardcoded credentials in any files
    - MCP servers use HTTPS/WSS not HTTP/WS
    - Hooks don't have obvious security issues
    - No secrets in example files

**Quality Standards:**
- All validation errors include file path and specific issue
- Warnings distinguished from errors
- Provide fix suggestions for each issue
- Include positive findings for well-structured components
- Categorize by severity (critical/major/minor)

**Output Format:**
## Plugin Validation Report

### Plugin: [name]
Location: [path]

### Summary
[Overall assessment - pass/fail with key stats]

### Critical Issues ([count])
- `file/path` - [Issue] - [Fix]

### Warnings ([count])
- `file/path` - [Issue] - [Recommendation]

### Component Summary
- Commands: [count] found, [count] valid
- Agents: [count] found, [count] valid
- Skills: [count] found, [count] valid
- Hooks: [present/not present], [valid/invalid]
- MCP Servers: [count] configured

### Positive Findings
- [What's done well]

### Recommendations
1. [Priority recommendation]
2. [Additional recommendation]

### Overall Assessment
[PASS/FAIL] - [Reasoning]

**Edge Cases:**
- Minimal plugin (just plugin.json): Valid if manifest correct
- Empty directories: Warn but don't fail
- Unknown fields in manifest: Warn but don't fail
- Multiple validation errors: Group by file, prioritize critical
- Plugin not found: Clear error message with guidance
- Corrupted files: Skip and report, continue validation
```

Excellent work! The agent-development skill is now complete and all 6 skills are documented in the README. Would you like me to create more agents (like skill-reviewer) or work on something else?

---

## Skill Reviewer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/agents/skill-reviewer.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-agents-skill-reviewer.md

You are an expert skill architect specializing in reviewing and improving Claude Code skills for maximum effectiveness and reliability.

**Your Core Responsibilities:**
1. Review skill structure and organization
2. Evaluate description quality and triggering effectiveness
3. Assess progressive disclosure implementation
4. Check adherence to skill-creator best practices
5. Provide specific recommendations for improvement

**Skill Review Process:**

1. **Locate and Read Skill**:
   - Find SKILL.md file (user should indicate path)
   - Read frontmatter and body content
   - Check for supporting directories (references/, examples/, scripts/)

2. **Validate Structure**:
   - Frontmatter format (YAML between `---`)
   - Required fields: `name`, `description`
   - Optional fields: `version`, `when_to_use` (note: deprecated, use description only)
   - Body content exists and is substantial

3. **Evaluate Description** (Most Critical):
   - **Trigger Phrases**: Does description include specific phrases users would say?
   - **Third Person**: Uses "This skill should be used when..." not "Load this skill when..."
   - **Specificity**: Concrete scenarios, not vague
   - **Length**: Appropriate (not too short <50 chars, not too long >500 chars for description)
   - **Example Triggers**: Lists specific user queries that should trigger skill

4. **Assess Content Quality**:
   - **Word Count**: SKILL.md body should be 1,000-3,000 words (lean, focused)
   - **Writing Style**: Imperative/infinitive form ("To do X, do Y" not "You should do X")
   - **Organization**: Clear sections, logical flow
   - **Specificity**: Concrete guidance, not vague advice

5. **Check Progressive Disclosure**:
   - **Core SKILL.md**: Essential information only
   - **references/**: Detailed docs moved out of core
   - **examples/**: Working code examples separate
   - **scripts/**: Utility scripts if needed
   - **Pointers**: SKILL.md references these resources clearly

6. **Review Supporting Files** (if present):
   - **references/**: Check quality, relevance, organization
   - **examples/**: Verify examples are complete and correct
   - **scripts/**: Check scripts are executable and documented

7. **Identify Issues**:
   - Categorize by severity (critical/major/minor)
   - Note anti-patterns:
     - Vague trigger descriptions
     - Too much content in SKILL.md (should be in references/)
     - Second person in description
     - Missing key triggers
     - No examples/references when they'd be valuable

8. **Generate Recommendations**:
   - Specific fixes for each issue
   - Before/after examples when helpful
   - Prioritized by impact

**Quality Standards:**
- Description must have strong, specific trigger phrases
- SKILL.md should be lean (under 3,000 words ideally)
- Writing style must be imperative/infinitive form
- Progressive disclosure properly implemented
- All file references work correctly
- Examples are complete and accurate

**Output Format:**
## Skill Review: [skill-name]

### Summary
[Overall assessment and word counts]

### Description Analysis
**Current:** [Show current description]

**Issues:**
- [Issue 1 with description]
- [Issue 2...]

**Recommendations:**
- [Specific fix 1]
- Suggested improved description: "[better version]"

### Content Quality

**SKILL.md Analysis:**
- Word count: [count] ([assessment: too long/good/too short])
- Writing style: [assessment]
- Organization: [assessment]

**Issues:**
- [Content issue 1]
- [Content issue 2]

**Recommendations:**
- [Specific improvement 1]
- Consider moving [section X] to references/[filename].md

### Progressive Disclosure

**Current Structure:**
- SKILL.md: [word count]
- references/: [count] files, [total words]
- examples/: [count] files
- scripts/: [count] files

**Assessment:**
[Is progressive disclosure effective?]

**Recommendations:**
[Suggestions for better organization]

### Specific Issues

#### Critical ([count])
- [File/location]: [Issue] - [Fix]

#### Major ([count])
- [File/location]: [Issue] - [Recommendation]

#### Minor ([count])
- [File/location]: [Issue] - [Suggestion]

### Positive Aspects
- [What's done well 1]
- [What's done well 2]

### Overall Rating
[Pass/Needs Improvement/Needs Major Revision]

### Priority Recommendations
1. [Highest priority fix]
2. [Second priority]
3. [Third priority]

**Edge Cases:**
- Skill with no description issues: Focus on content and organization
- Very long skill (>5,000 words): Strongly recommend splitting into references
- New skill (minimal content): Provide constructive building guidance
- Perfect skill: Acknowledge quality and suggest minor enhancements only
- Missing referenced files: Report errors clearly with paths
```

This agent helps users create high-quality skills by applying the same standards used in plugin-dev's own skills.

---

## Plugin Creation Workflow

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/commands/create-plugin.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-commands-create-plugin.md

# Plugin Creation Workflow

Guide the user through creating a complete, high-quality Claude Code plugin from initial concept to tested implementation. Follow a systematic approach: understand requirements, design components, clarify details, implement following best practices, validate, and test.

## Core Principles

- **Ask clarifying questions**: Identify all ambiguities about plugin purpose, triggering, scope, and components. Ask specific, concrete questions rather than making assumptions. Wait for user answers before proceeding with implementation.
- **Load relevant skills**: Use the Skill tool to load plugin-dev skills when needed (plugin-structure, hook-development, agent-development, etc.)
- **Use specialized agents**: Leverage agent-creator, plugin-validator, and skill-reviewer agents for AI-assisted development
- **Follow best practices**: Apply patterns from plugin-dev's own implementation
- **Progressive disclosure**: Create lean skills with references/examples
- **Use TodoWrite**: Track all progress throughout all phases

**Initial request:** $ARGUMENTS

---

## Phase 1: Discovery

**Goal**: Understand what plugin needs to be built and what problem it solves

**Actions**:
1. Create todo list with all 7 phases
2. If plugin purpose is clear from arguments:
   - Summarize understanding
   - Identify plugin type (integration, workflow, analysis, toolkit, etc.)
3. If plugin purpose is unclear, ask user:
   - What problem does this plugin solve?
   - Who will use it and when?
   - What should it do?
   - Any similar plugins to reference?
4. Summarize understanding and confirm with user before proceeding

**Output**: Clear statement of plugin purpose and target users

---

## Phase 2: Component Planning

**Goal**: Determine what plugin components are needed

**MUST load plugin-structure skill** using Skill tool before this phase.

**Actions**:
1. Load plugin-structure skill to understand component types
2. Analyze plugin requirements and determine needed components:
   - **Skills**: Does it need specialized knowledge? (hooks API, MCP patterns, etc.)
   - **Commands**: User-initiated actions? (deploy, configure, analyze)
   - **Agents**: Autonomous tasks? (validation, generation, analysis)
   - **Hooks**: Event-driven automation? (validation, notifications)
   - **MCP**: External service integration? (databases, APIs)
   - **Settings**: User configuration? (.local.md files)
3. For each component type needed, identify:
   - How many of each type
   - What each one does
   - Rough triggering/usage patterns
4. Present component plan to user as table:
   ```
   | Component Type | Count | Purpose |
   |----------------|-------|---------|
   | Skills         | 2     | Hook patterns, MCP usage |
   | Commands       | 3     | Deploy, configure, validate |
   | Agents         | 1     | Autonomous validation |
   | Hooks          | 0     | Not needed |
   | MCP            | 1     | Database integration |
   ```
5. Get user confirmation or adjustments

**Output**: Confirmed list of components to create

---

## Phase 3: Detailed Design & Clarifying Questions

**Goal**: Specify each component in detail and resolve all ambiguities

**CRITICAL**: This is one of the most important phases. DO NOT SKIP.

**Actions**:
1. For each component in the plan, identify underspecified aspects:
   - **Skills**: What triggers them? What knowledge do they provide? How detailed?
   - **Commands**: What arguments? What tools? Interactive or automated?
   - **Agents**: When to trigger (proactive/reactive)? What tools? Output format?
   - **Hooks**: Which events? Prompt or command based? Validation criteria?
   - **MCP**: What server type? Authentication? Which tools?
   - **Settings**: What fields? Required vs optional? Defaults?

2. **Present all questions to user in organized sections** (one section per component type)

3. **Wait for answers before proceeding to implementation**

4. If user says "whatever you think is best", provide specific recommendations and get explicit confirmation

**Example questions for a skill**:
- What specific user queries should trigger this skill?
- Should it include utility scripts? What functionality?
- How detailed should the core SKILL.md be vs references/?
- Any real-world examples to include?

**Example questions for an agent**:
- Should this agent trigger proactively after certain actions, or only when explicitly requested?
- What tools does it need (Read, Write, Bash, etc.)?
- What should the output format be?
- Any specific quality standards to enforce?

**Output**: Detailed specification for each component

---

## Phase 4: Plugin Structure Creation

**Goal**: Create plugin directory structure and manifest

**Actions**:
1. Determine plugin name (kebab-case, descriptive)
2. Choose plugin location:
   - Ask user: "Where should I create the plugin?"
   - Offer options: current directory, ../new-plugin-name, custom path
3. Create directory structure using bash:
   ```bash
   mkdir -p plugin-name/.claude-plugin
   mkdir -p plugin-name/skills     # if needed
   mkdir -p plugin-name/commands   # if needed
   mkdir -p plugin-name/agents     # if needed
   mkdir -p plugin-name/hooks      # if needed
   ```
4. Create plugin.json manifest using Write tool:
   ```json
   {
     "name": "plugin-name",
     "version": "0.1.0",
     "description": "[brief description]",
     "author": {
       "name": "[author from user or default]",
       "email": "[email or default]"
     }
   }
   ```
5. Create README.md template
6. Create .gitignore if needed (for .claude/*.local.md, etc.)
7. Initialize git repo if creating new directory

**Output**: Plugin directory structure created and ready for components

---

## Phase 5: Component Implementation

**Goal**: Create each component following best practices

**LOAD RELEVANT SKILLS** before implementing each component type:
- Skills: Load skill-development skill
- Commands: Load command-development skill
- Agents: Load agent-development skill
- Hooks: Load hook-development skill
- MCP: Load mcp-integration skill
- Settings: Load plugin-settings skill

**Actions for each component**:

### For Skills:
1. Load skill-development skill using Skill tool
2. For each skill:
   - Ask user for concrete usage examples (or use from Phase 3)
   - Plan resources (scripts/, references/, examples/)
   - Create skill directory structure
   - Write SKILL.md with:
     - Third-person description with specific trigger phrases
     - Lean body (1,500-2,000 words) in imperative form
     - References to supporting files
   - Create reference files for detailed content
   - Create example files for working code
   - Create utility scripts if needed
3. Use skill-reviewer agent to validate each skill

### For Commands:
1. Load command-development skill using Skill tool
2. For each command:
   - Write command markdown with frontmatter
   - Include clear description and argument-hint
   - Specify allowed-tools (minimal necessary)
   - Write instructions FOR Claude (not TO user)
   - Provide usage examples and tips
   - Reference relevant skills if applicable

### For Agents:
1. Load agent-development skill using Skill tool
2. For each agent, use agent-creator agent:
   - Provide description of what agent should do
   - Agent-creator generates: identifier, whenToUse with examples, systemPrompt
   - Create agent markdown file with frontmatter and system prompt
   - Add appropriate model, color, and tools
   - Validate with validate-agent.sh script

### For Hooks:
1. Load hook-development skill using Skill tool
2. For each hook:
   - Create hooks/hooks.json with hook configuration
   - Prefer prompt-based hooks for complex logic
   - Use ${CLAUDE_PLUGIN_ROOT} for portability
   - Create hook scripts if needed (in examples/ not scripts/)
   - Test with validate-hook-schema.sh and test-hook.sh utilities

### For MCP:
1. Load mcp-integration skill using Skill tool
2. Create .mcp.json configuration with:
   - Server type (stdio for local, SSE for hosted)
   - Command and args (with ${CLAUDE_PLUGIN_ROOT})
   - extensionToLanguage mapping if LSP
   - Environment variables as needed
3. Document required env vars in README
4. Provide setup instructions

### For Settings:
1. Load plugin-settings skill using Skill tool
2. Create settings template in README
3. Create example .claude/plugin-name.local.md file (as documentation)
4. Implement settings reading in hooks/commands as needed
5. Add to .gitignore: `.claude/*.local.md`

**Progress tracking**: Update todos as each component is completed

**Output**: All plugin components implemented

---

## Phase 6: Validation & Quality Check

**Goal**: Ensure plugin meets quality standards and works correctly

**Actions**:
1. **Run plugin-validator agent**:
   - Use plugin-validator agent to comprehensively validate plugin
   - Check: manifest, structure, naming, components, security
   - Review validation report

2. **Fix critical issues**:
   - Address any critical errors from validation
   - Fix any warnings that indicate real problems

3. **Review with skill-reviewer** (if plugin has skills):
   - For each skill, use skill-reviewer agent
   - Check description quality, progressive disclosure, writing style
   - Apply recommendations

4. **Test agent triggering** (if plugin has agents):
   - For each agent, verify <example> blocks are clear
   - Check triggering conditions are specific
   - Run validate-agent.sh on agent files

5. **Test hook configuration** (if plugin has hooks):
   - Run validate-hook-schema.sh on hooks/hooks.json
   - Test hook scripts with test-hook.sh
   - Verify ${CLAUDE_PLUGIN_ROOT} usage

6. **Present findings**:
   - Summary of validation results
   - Any remaining issues
   - Overall quality assessment

7. **Ask user**: "Validation complete. Issues found: [count critical], [count warnings]. Would you like me to fix them now, or proceed to testing?"

**Output**: Plugin validated and ready for testing

---

## Phase 7: Testing & Verification

**Goal**: Test that plugin works correctly in Claude Code

**Actions**:
1. **Installation instructions**:
   - Show user how to test locally:
     ```bash
     cc --plugin-dir /path/to/plugin-name
     ```
   - Or copy to `.claude-plugin/` for project testing

2. **Verification checklist** for user to perform:
   - [ ] Skills load when triggered (ask questions with trigger phrases)
   - [ ] Commands appear in `/help` and execute correctly
   - [ ] Agents trigger on appropriate scenarios
   - [ ] Hooks activate on events (if applicable)
   - [ ] MCP servers connect (if applicable)
   - [ ] Settings files work (if applicable)

3. **Testing recommendations**:
   - For skills: Ask questions using trigger phrases from descriptions
   - For commands: Run `/plugin-name:command-name` with various arguments
   - For agents: Create scenarios matching agent examples
   - For hooks: Use `claude --debug` to see hook execution
   - For MCP: Use `/mcp` to verify servers and tools

4. **Ask user**: "I've prepared the plugin for testing. Would you like me to guide you through testing each component, or do you want to test it yourself?"

5. **If user wants guidance**, walk through testing each component with specific test cases

**Output**: Plugin tested and verified working

---

## Phase 8: Documentation & Next Steps

**Goal**: Ensure plugin is well-documented and ready for distribution

**Actions**:
1. **Verify README completeness**:
   - Check README has: overview, features, installation, prerequisites, usage
   - For MCP plugins: Document required environment variables
   - For hook plugins: Explain hook activation
   - For settings: Provide configuration templates

2. **Add marketplace entry** (if publishing):
   - Show user how to add to marketplace.json
   - Help draft marketplace description
   - Suggest category and tags

3. **Create summary**:
   - Mark all todos complete
   - List what was created:
     - Plugin name and purpose
     - Components created (X skills, Y commands, Z agents, etc.)
     - Key files and their purposes
     - Total file count and structure
   - Next steps:
     - Testing recommendations
     - Publishing to marketplace (if desired)
     - Iteration based on usage

4. **Suggest improvements** (optional):
   - Additional components that could enhance plugin
   - Integration opportunities
   - Testing strategies

**Output**: Complete, documented plugin ready for use or publication

---

## Important Notes

### Throughout All Phases

- **Use TodoWrite** to track progress at every phase
- **Load skills with Skill tool** when working on specific component types
- **Use specialized agents** (agent-creator, plugin-validator, skill-reviewer)
- **Ask for user confirmation** at key decision points
- **Follow plugin-dev's own patterns** as reference examples
- **Apply best practices**:
  - Third-person descriptions for skills
  - Imperative form in skill bodies
  - Commands written FOR Claude
  - Strong trigger phrases
  - ${CLAUDE_PLUGIN_ROOT} for portability
  - Progressive disclosure
  - Security-first (HTTPS, no hardcoded credentials)

### Key Decision Points (Wait for User)

1. After Phase 1: Confirm plugin purpose
2. After Phase 2: Approve component plan
3. After Phase 3: Proceed to implementation
4. After Phase 6: Fix issues or proceed
5. After Phase 7: Continue to documentation

### Skills to Load by Phase

- **Phase 2**: plugin-structure
- **Phase 5**: skill-development, command-development, agent-development, hook-development, mcp-integration, plugin-settings (as needed)
- **Phase 6**: (agents will use skills automatically)

### Quality Standards

Every component must meet these standards:
- ✅ Follows plugin-dev's proven patterns
- ✅ Uses correct naming conventions
- ✅ Has strong trigger conditions (skills/agents)
- ✅ Includes working examples
- ✅ Properly documented
- ✅ Validated with utilities
- ✅ Tested in Claude Code

---

## Example Workflow

### User Request
"Create a plugin for managing database migrations"

### Phase 1: Discovery
- Understand: Migration management, database schema versioning
- Confirm: User wants to create, run, rollback migrations

### Phase 2: Component Planning
- Skills: 1 (migration best practices)
- Commands: 3 (create-migration, run-migrations, rollback)
- Agents: 1 (migration-validator)
- MCP: 1 (database connection)

### Phase 3: Clarifying Questions
- Which databases? (PostgreSQL, MySQL, etc.)
- Migration file format? (SQL, code-based?)
- Should agent validate before applying?
- What MCP tools needed? (query, execute, schema)

### Phase 4-8: Implementation, Validation, Testing, Documentation

---

**Begin with Phase 1: Discovery**

---

## Plugin Command Examples

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/examples/plugin-commands.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-command-development-examples-plugin-commands.md

# Plugin Command Examples

Practical examples of commands designed for Claude Code plugins, demonstrating plugin-specific patterns and features.

## Table of Contents

1. [Simple Plugin Command](#1-simple-plugin-command)
2. [Script-Based Analysis](#2-script-based-analysis)
3. [Template-Based Generation](#3-template-based-generation)
4. [Multi-Script Workflow](#4-multi-script-workflow)
5. [Configuration-Driven Deployment](#5-configuration-driven-deployment)
6. [Agent Integration](#6-agent-integration)
7. [Skill Integration](#7-skill-integration)
8. [Multi-Component Workflow](#8-multi-component-workflow)
9. [Validated Input Command](#9-validated-input-command)
10. [Environment-Aware Command](#10-environment-aware-command)

---

## 1. Simple Plugin Command

**Use case:** Basic command that uses plugin script

**File:** `commands/analyze.md`

```markdown
---
description: Analyze code quality using plugin tools
argument-hint: [file-path]
allowed-tools: Bash(node:*), Read
---

Analyze @$1 using plugin's quality checker:

!`node ${CLAUDE_PLUGIN_ROOT}/scripts/quality-check.js $1`

Review the analysis output and provide:
1. Summary of findings
2. Priority issues to address
3. Suggested improvements
4. Code quality score interpretation
```

**Key features:**
- Uses `${CLAUDE_PLUGIN_ROOT}` for portable path
- Combines file reference with script execution
- Simple single-purpose command

---

## 2. Script-Based Analysis

**Use case:** Run comprehensive analysis using multiple plugin scripts

**File:** `commands/full-audit.md`

```markdown
---
description: Complete code audit using plugin suite
argument-hint: [directory]
allowed-tools: Bash(*)
model: sonnet
---

Running complete audit on $1:

**Security scan:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh $1`

**Performance analysis:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-analyze.sh $1`

**Best practices check:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/best-practices.sh $1`

Analyze all results and create comprehensive report including:
- Critical issues requiring immediate attention
- Performance optimization opportunities
- Security vulnerabilities and fixes
- Overall health score and recommendations
```

**Key features:**
- Multiple script executions
- Organized output sections
- Comprehensive workflow
- Clear reporting structure

---

## 3. Template-Based Generation

**Use case:** Generate documentation following plugin template

**File:** `commands/gen-api-docs.md`

```markdown
---
description: Generate API documentation from template
argument-hint: [api-file]
---

Template structure: @${CLAUDE_PLUGIN_ROOT}/templates/api-documentation.md

API implementation: @$1

Generate complete API documentation following the template format above.

Ensure documentation includes:
- Endpoint descriptions with HTTP methods
- Request/response schemas
- Authentication requirements
- Error codes and handling
- Usage examples with curl commands
- Rate limiting information

Format output as markdown suitable for README or docs site.
```

**Key features:**
- Uses plugin template
- Combines template with source file
- Standardized output format
- Clear documentation structure

---

## 4. Multi-Script Workflow

**Use case:** Orchestrate build, test, and deploy workflow

**File:** `commands/release.md`

```markdown
---
description: Execute complete release workflow
argument-hint: [version]
allowed-tools: Bash(*), Read
---

Executing release workflow for version $1:

**Step 1 - Pre-release validation:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/pre-release-check.sh $1`

**Step 2 - Build artifacts:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build-release.sh $1`

**Step 3 - Run test suite:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/run-tests.sh`

**Step 4 - Package release:**
!`bash ${CLAUDE_PLUGIN_ROOT}/scripts/package.sh $1`

Review all step outputs and report:
1. Any failures or warnings
2. Build artifacts location
3. Test results summary
4. Next steps for deployment
5. Rollback plan if needed
```

**Key features:**
- Multi-step workflow
- Sequential script execution
- Clear step numbering
- Comprehensive reporting

---

## 5. Configuration-Driven Deployment

**Use case:** Deploy using environment-specific plugin configuration

**File:** `commands/deploy.md`

```markdown
---
description: Deploy application to environment
argument-hint: [environment]
allowed-tools: Read, Bash(*)
---

Deployment configuration for $1: @${CLAUDE_PLUGIN_ROOT}/config/$1-deploy.json

Current git state: !`git rev-parse --short HEAD`

Build info: !`cat package.json | grep -E '(name|version)'`

Execute deployment to $1 environment using configuration above.

Deployment checklist:
1. Validate configuration settings
2. Build application for $1
3. Run pre-deployment tests
4. Deploy to target environment
5. Run smoke tests
6. Verify deployment success
7. Update deployment log

Report deployment status and any issues encountered.
```

**Key features:**
- Environment-specific configuration
- Dynamic config file loading
- Pre-deployment validation
- Structured checklist

---

## 6. Agent Integration

**Use case:** Command that launches plugin agent for complex task

**File:** `commands/deep-review.md`

```markdown
---
description: Deep code review using plugin agent
argument-hint: [file-or-directory]
---

Initiate comprehensive code review of @$1 using the code-reviewer agent.

The agent will perform:
1. **Static analysis** - Check for code smells and anti-patterns
2. **Security audit** - Identify potential vulnerabilities
3. **Performance review** - Find optimization opportunities
4. **Best practices** - Ensure code follows standards
5. **Documentation check** - Verify adequate documentation

The agent has access to:
- Plugin's linting rules: ${CLAUDE_PLUGIN_ROOT}/config/lint-rules.json
- Security checklist: ${CLAUDE_PLUGIN_ROOT}/checklists/security.md
- Performance guidelines: ${CLAUDE_PLUGIN_ROOT}/docs/performance.md

Note: This uses the Task tool to launch the plugin's code-reviewer agent for thorough analysis.
```

**Key features:**
- Delegates to plugin agent
- Documents agent capabilities
- References plugin resources
- Clear scope definition

---

## 7. Skill Integration

**Use case:** Command that leverages plugin skill for specialized knowledge

**File:** `commands/document-api.md`

```markdown
---
description: Document API following plugin standards
argument-hint: [api-file]
---

API source code: @$1

Generate API documentation following the plugin's API documentation standards.

Use the api-documentation-standards skill to ensure:
- **OpenAPI compliance** - Follow OpenAPI 3.0 specification
- **Consistent formatting** - Use plugin's documentation style
- **Complete coverage** - Document all endpoints and schemas
- **Example quality** - Provide realistic usage examples
- **Error documentation** - Cover all error scenarios

The skill provides:
- Standard documentation templates
- API documentation best practices
- Common patterns for this codebase
- Quality validation criteria

Generate production-ready API documentation.
```

**Key features:**
- Invokes plugin skill by name
- Documents skill purpose
- Clear expectations
- Leverages skill knowledge

---

## 8. Multi-Component Workflow

**Use case:** Complex workflow using agents, skills, and scripts

**File:** `commands/complete-review.md`

```markdown
---
description: Comprehensive review using all plugin components
argument-hint: [file-path]
allowed-tools: Bash(node:*), Read
---

Target file: @$1

Execute comprehensive review workflow:

**Phase 1: Automated Analysis**
Run plugin analyzer: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js $1`

**Phase 2: Deep Review (Agent)**
Launch the code-quality-reviewer agent for detailed analysis.
Agent will examine:
- Code structure and organization
- Error handling patterns
- Testing coverage
- Documentation quality

**Phase 3: Standards Check (Skill)**
Use the coding-standards skill to validate:
- Naming conventions
- Code formatting
- Best practices adherence
- Framework-specific patterns

**Phase 4: Report Generation**
Template: @${CLAUDE_PLUGIN_ROOT}/templates/review-report.md

Compile all findings into comprehensive report following template.

**Phase 5: Recommendations**
Generate prioritized action items:
1. Critical issues (must fix)
2. Important improvements (should fix)
3. Nice-to-have enhancements (could fix)

Include specific file locations and suggested changes for each item.
```

**Key features:**
- Multi-phase workflow
- Combines scripts, agents, skills
- Template-based reporting
- Prioritized outputs

---

## 9. Validated Input Command

**Use case:** Command with input validation and error handling

**File:** `commands/build-env.md`

```markdown
---
description: Build for specific environment with validation
argument-hint: [environment]
allowed-tools: Bash(*)
---

Validate environment argument: !`echo "$1" | grep -E "^(dev|staging|prod)$" && echo "VALID" || echo "INVALID"`

Check build script exists: !`test -x ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh && echo "EXISTS" || echo "MISSING"`

Verify configuration available: !`test -f ${CLAUDE_PLUGIN_ROOT}/config/$1.json && echo "FOUND" || echo "NOT_FOUND"`

If all validations pass:

**Configuration:** @${CLAUDE_PLUGIN_ROOT}/config/$1.json

**Execute build:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh $1 2>&1`

**Validation results:** !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate-build.sh $1 2>&1`

Report build status and any issues.

If validations fail:
- Explain which validation failed
- Provide expected values/locations
- Suggest corrective actions
- Document troubleshooting steps
```

**Key features:**
- Input validation
- Resource existence checks
- Error handling
- Helpful error messages
- Graceful failure handling

---

## 10. Environment-Aware Command

**Use case:** Command that adapts behavior based on environment

**File:** `commands/run-checks.md`

```markdown
---
description: Run environment-appropriate checks
argument-hint: [environment]
allowed-tools: Bash(*), Read
---

Environment: $1

Load environment configuration: @${CLAUDE_PLUGIN_ROOT}/config/$1-checks.json

Determine check level: !`echo "$1" | grep -E "^prod$" && echo "FULL" || echo "BASIC"`

**For production environment:**
- Full test suite: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-full.sh`
- Security scan: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/security-scan.sh`
- Performance audit: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/perf-check.sh`
- Compliance check: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/compliance.sh`

**For non-production environments:**
- Basic tests: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test-basic.sh`
- Quick lint: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/lint.sh`

Analyze results based on environment requirements:

**Production:** All checks must pass with zero critical issues
**Staging:** No critical issues, warnings acceptable
**Development:** Focus on blocking issues only

Report status and recommend proceed/block decision.
```

**Key features:**
- Environment-aware logic
- Conditional execution
- Different validation levels
- Appropriate reporting per environment

---

## Common Patterns Summary

### Pattern: Plugin Script Execution
```markdown
!`node ${CLAUDE_PLUGIN_ROOT}/scripts/script-name.js $1`
```
Use for: Running plugin-provided Node.js scripts

### Pattern: Plugin Configuration Loading
```markdown
@${CLAUDE_PLUGIN_ROOT}/config/config-name.json
```
Use for: Loading plugin configuration files

### Pattern: Plugin Template Usage
```markdown
@${CLAUDE_PLUGIN_ROOT}/templates/template-name.md
```
Use for: Using plugin templates for generation

### Pattern: Agent Invocation
```markdown
Launch the [agent-name] agent for [task description].
```
Use for: Delegating complex tasks to plugin agents

### Pattern: Skill Reference
```markdown
Use the [skill-name] skill to ensure [requirements].
```
Use for: Leveraging plugin skills for specialized knowledge

### Pattern: Input Validation
```markdown
Validate input: !`echo "$1" | grep -E "^pattern$" && echo "OK" || echo "ERROR"`
```
Use for: Validating command arguments

### Pattern: Resource Validation
```markdown
Check exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/path/file && echo "YES" || echo "NO"`
```
Use for: Verifying required plugin files exist

---

## Development Tips

### Testing Plugin Commands

1. **Test with plugin installed:**
   ```bash
   cd /path/to/plugin
   claude /command-name args
   ```

2. **Verify ${CLAUDE_PLUGIN_ROOT} expansion:**
   ```bash
   # Add debug output to command
   !`echo "Plugin root: ${CLAUDE_PLUGIN_ROOT}"`
   ```

3. **Test across different working directories:**
   ```bash
   cd /tmp && claude /command-name
   cd /other/project && claude /command-name
   ```

4. **Validate resource availability:**
   ```bash
   # Check all plugin resources exist
   !`ls -la ${CLAUDE_PLUGIN_ROOT}/scripts/`
   !`ls -la ${CLAUDE_PLUGIN_ROOT}/config/`
   ```

### Common Mistakes to Avoid

1. **Using relative paths instead of ${CLAUDE_PLUGIN_ROOT}:**
   ```markdown
   # Wrong
   !`node ./scripts/analyze.js`

   # Correct
   !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`
   ```

2. **Forgetting to allow required tools:**
   ```markdown
   # Missing allowed-tools
   !`bash script.sh`  # Will fail without Bash permission

   # Correct
   ---
   allowed-tools: Bash(*)
   ---
   !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/script.sh`
   ```

3. **Not validating inputs:**
   ```markdown
   # Risky - no validation
   Deploy to $1 environment

   # Better - with validation
   Validate: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`
   Deploy to $1 environment (if valid)
   ```

4. **Hardcoding plugin paths:**
   ```markdown
   # Wrong - breaks on different installations
   @/home/user/.claude/plugins/my-plugin/config.json

   # Correct - works everywhere
   @${CLAUDE_PLUGIN_ROOT}/config.json
   ```

---

For detailed plugin-specific features, see `references/plugin-features-reference.md`.
For general command development, see main `SKILL.md`.

---

## Command Development Skill

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/README.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-command-development-readme.md

# Command Development Skill

Comprehensive guidance on creating Claude Code slash commands, including file format, frontmatter options, dynamic arguments, and best practices.

## Overview

This skill provides knowledge about:
- Slash command file format and structure
- YAML frontmatter configuration fields
- Dynamic arguments ($ARGUMENTS, $1, $2, etc.)
- File references with @ syntax
- Bash execution with !` syntax
- Command organization and namespacing
- Best practices for command development
- Plugin-specific features (${CLAUDE_PLUGIN_ROOT}, plugin patterns)
- Integration with plugin components (agents, skills, hooks)
- Validation patterns and error handling

## Skill Structure

### SKILL.md (~2,470 words)

Core skill content covering:

**Fundamentals:**
- Command basics and locations
- File format (Markdown with optional frontmatter)
- YAML frontmatter fields overview
- Dynamic arguments ($ARGUMENTS and positional)
- File references (@ syntax)
- Bash execution (!` syntax)
- Command organization patterns
- Best practices and common patterns
- Troubleshooting

**Plugin-Specific:**
- ${CLAUDE_PLUGIN_ROOT} environment variable
- Plugin command discovery and organization
- Plugin command patterns (configuration, template, multi-script)
- Integration with plugin components (agents, skills, hooks)
- Validation patterns (argument, file, resource, error handling)

### References

Detailed documentation:

- **frontmatter-reference.md**: Complete YAML frontmatter field specifications
  - All field descriptions with types and defaults
  - When to use each field
  - Examples and best practices
  - Validation and common errors

- **plugin-features-reference.md**: Plugin-specific command features
  - Plugin command discovery and organization
  - ${CLAUDE_PLUGIN_ROOT} environment variable usage
  - Plugin command patterns (configuration, template, multi-script)
  - Integration with plugin agents, skills, and hooks
  - Validation patterns and error handling

### Examples

Practical command examples:

- **simple-commands.md**: 10 complete command examples
  - Code review commands
  - Testing commands
  - Deployment commands
  - Documentation generators
  - Git integration commands
  - Analysis and research commands

- **plugin-commands.md**: 10 plugin-specific command examples
  - Simple plugin commands with scripts
  - Multi-script workflows
  - Template-based generation
  - Configuration-driven deployment
  - Agent and skill integration
  - Multi-component workflows
  - Validated input commands
  - Environment-aware commands

## When This Skill Triggers

Claude Code activates this skill when users:
- Ask to "create a slash command" or "add a command"
- Need to "write a custom command"
- Want to "define command arguments"
- Ask about "command frontmatter" or YAML configuration
- Need to "organize commands" or use namespacing
- Want to create commands with file references
- Ask about "bash execution in commands"
- Need command development best practices

## Progressive Disclosure

The skill uses progressive disclosure:

1. **SKILL.md** (~2,470 words): Core concepts, common patterns, and plugin features overview
2. **References** (~13,500 words total): Detailed specifications
   - frontmatter-reference.md (~1,200 words)
   - plugin-features-reference.md (~1,800 words)
   - interactive-commands.md (~2,500 words)
   - advanced-workflows.md (~1,700 words)
   - testing-strategies.md (~2,200 words)
   - documentation-patterns.md (~2,000 words)
   - marketplace-considerations.md (~2,200 words)
3. **Examples** (~6,000 words total): Complete working command examples
   - simple-commands.md
   - plugin-commands.md

Claude loads references and examples as needed based on task.

## Command Basics Quick Reference

### File Format

```markdown
---
description: Brief description
argument-hint: [arg1] [arg2]
allowed-tools: Read, Bash(git:*)
---

Command prompt content with:
- Arguments: $1, $2, or $ARGUMENTS
- Files: @path/to/file
- Bash: !`command here`
```

### Locations

- **Project**: `.claude/commands/` (shared with team)
- **Personal**: `~/.claude/commands/` (your commands)
- **Plugin**: `plugin-name/commands/` (plugin-specific)

### Key Features

**Dynamic arguments:**
- `$ARGUMENTS` - All arguments as single string
- `$1`, `$2`, `$3` - Positional arguments

**File references:**
- `@path/to/file` - Include file contents

**Bash execution:**
- `!`command`` - Execute and include output

## Frontmatter Fields Quick Reference

| Field | Purpose | Example |
|-------|---------|---------|
| `description` | Brief description for /help | `"Review code for issues"` |
| `allowed-tools` | Restrict tool access | `Read, Bash(git:*)` |
| `model` | Specify model | `sonnet`, `opus`, `haiku` |
| `argument-hint` | Document arguments | `[pr-number] [priority]` |
| `disable-model-invocation` | Manual-only command | `true` |

## Common Patterns

### Simple Review Command

```markdown
---
description: Review code for issues
---

Review this code for quality and potential bugs.
```

### Command with Arguments

```markdown
---
description: Deploy to environment
argument-hint: [environment] [version]
---

Deploy to $1 environment using version $2
```

### Command with File Reference

```markdown
---
description: Document file
argument-hint: [file-path]
---

Generate documentation for @$1
```

### Command with Bash Execution

```markdown
---
description: Show Git status
allowed-tools: Bash(git:*)
---

Current status: !`git status`
Recent commits: !`git log --oneline -5`
```

## Development Workflow

1. **Design command:**
   - Define purpose and scope
   - Determine required arguments
   - Identify needed tools

2. **Create file:**
   - Choose appropriate location
   - Create `.md` file with command name
   - Write basic prompt

3. **Add frontmatter:**
   - Start minimal (just description)
   - Add fields as needed (allowed-tools, etc.)
   - Document arguments with argument-hint

4. **Test command:**
   - Invoke with `/command-name`
   - Verify arguments work
   - Check bash execution
   - Test file references

5. **Refine:**
   - Improve prompt clarity
   - Handle edge cases
   - Add examples in comments
   - Document requirements

## Best Practices Summary

1. **Single responsibility**: One command, one clear purpose
2. **Clear descriptions**: Make discoverable in `/help`
3. **Document arguments**: Always use argument-hint
4. **Minimal tools**: Use most restrictive allowed-tools
5. **Test thoroughly**: Verify all features work
6. **Add comments**: Explain complex logic
7. **Handle errors**: Consider missing arguments/files

## Status

**Completed enhancements:**
- ✓ Plugin command patterns (${CLAUDE_PLUGIN_ROOT}, discovery, organization)
- ✓ Integration patterns (agents, skills, hooks coordination)
- ✓ Validation patterns (input, file, resource validation, error handling)

**Remaining enhancements (in progress):**
- Advanced workflows (multi-step command sequences)
- Testing strategies (how to test commands effectively)
- Documentation patterns (command documentation best practices)
- Marketplace considerations (publishing and distribution)

## Maintenance

To update this skill:
1. Keep SKILL.md focused on core fundamentals
2. Move detailed specifications to references/
3. Add new examples/ for different use cases
4. Update frontmatter when new fields added
5. Ensure imperative/infinitive form throughout
6. Test examples work with current Claude Code

## Version History

**v0.1.0** (2025-01-15):
- Initial release with basic command fundamentals
- Frontmatter field reference
- 10 simple command examples
- Ready for plugin-specific pattern additions

---

## Command Frontmatter Reference

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/references/frontmatter-reference.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-command-development-references-frontmatter-reference.md

# Command Frontmatter Reference

Complete reference for YAML frontmatter fields in slash commands.

## Frontmatter Overview

YAML frontmatter is optional metadata at the start of command files:

```markdown
---
description: Brief description
allowed-tools: Read, Write
model: sonnet
argument-hint: [arg1] [arg2]
---

Command prompt content here...
```

All fields are optional. Commands work without any frontmatter.

## Field Specifications

### description

**Type:** String
**Required:** No
**Default:** First line of command prompt
**Max Length:** ~60 characters recommended for `/help` display

**Purpose:** Describes what the command does, shown in `/help` output

**Examples:**
```yaml
description: Review code for security issues
```
```yaml
description: Deploy to staging environment
```
```yaml
description: Generate API documentation
```

**Best practices:**
- Keep under 60 characters for clean display
- Start with verb (Review, Deploy, Generate)
- Be specific about what command does
- Avoid redundant "command" or "slash command"

**Good:**
- ✅ "Review PR for code quality and security"
- ✅ "Deploy application to specified environment"
- ✅ "Generate comprehensive API documentation"

**Bad:**
- ❌ "This command reviews PRs" (unnecessary "This command")
- ❌ "Review" (too vague)
- ❌ "A command that reviews pull requests for code quality, security issues, and best practices" (too long)

### allowed-tools

**Type:** String or Array of strings
**Required:** No
**Default:** Inherits from conversation permissions

**Purpose:** Restrict or specify which tools command can use

**Formats:**

**Single tool:**
```yaml
allowed-tools: Read
```

**Multiple tools (comma-separated):**
```yaml
allowed-tools: Read, Write, Edit
```

**Multiple tools (array):**
```yaml
allowed-tools:
  - Read
  - Write
  - Bash(git:*)
```

**Tool Patterns:**

**Specific tools:**
```yaml
allowed-tools: Read, Grep, Edit
```

**Bash with command filter:**
```yaml
allowed-tools: Bash(git:*)           # Only git commands
allowed-tools: Bash(npm:*)           # Only npm commands
allowed-tools: Bash(docker:*)        # Only docker commands
```

**All tools (not recommended):**
```yaml
allowed-tools: "*"
```

**When to use:**

1. **Security:** Restrict command to safe operations
   ```yaml
   allowed-tools: Read, Grep  # Read-only command
   ```

2. **Clarity:** Document required tools
   ```yaml
   allowed-tools: Bash(git:*), Read
   ```

3. **Bash execution:** Enable bash command output
   ```yaml
   allowed-tools: Bash(git status:*), Bash(git diff:*)
   ```

**Best practices:**
- Be as restrictive as possible
- Use command filters for Bash (e.g., `git:*` not `*`)
- Only specify when different from conversation permissions
- Document why specific tools are needed

### model

**Type:** String
**Required:** No
**Default:** Inherits from conversation
**Values:** `sonnet`, `opus`, `haiku`

**Purpose:** Specify which Claude model executes the command

**Examples:**
```yaml
model: haiku    # Fast, efficient for simple tasks
```
```yaml
model: sonnet   # Balanced performance (default)
```
```yaml
model: opus     # Maximum capability for complex tasks
```

**When to use:**

**Use `haiku` for:**
- Simple, formulaic commands
- Fast execution needed
- Low complexity tasks
- Frequent invocations

```yaml
---
description: Format code file
model: haiku
---
```

**Use `sonnet` for:**
- Standard commands (default)
- Balanced speed/quality
- Most common use cases

```yaml
---
description: Review code changes
model: sonnet
---
```

**Use `opus` for:**
- Complex analysis
- Architectural decisions
- Deep code understanding
- Critical tasks

```yaml
---
description: Analyze system architecture
model: opus
---
```

**Best practices:**
- Omit unless specific need
- Use `haiku` for speed when possible
- Reserve `opus` for genuinely complex tasks
- Test with different models to find right balance

### argument-hint

**Type:** String
**Required:** No
**Default:** None

**Purpose:** Document expected arguments for users and autocomplete

**Format:**
```yaml
argument-hint: [arg1] [arg2] [optional-arg]
```

**Examples:**

**Single argument:**
```yaml
argument-hint: [pr-number]
```

**Multiple required arguments:**
```yaml
argument-hint: [environment] [version]
```

**Optional arguments:**
```yaml
argument-hint: [file-path] [options]
```

**Descriptive names:**
```yaml
argument-hint: [source-branch] [target-branch] [commit-message]
```

**Best practices:**
- Use square brackets `[]` for each argument
- Use descriptive names (not `arg1`, `arg2`)
- Indicate optional vs required in description
- Match order to positional arguments in command
- Keep concise but clear

**Examples by pattern:**

**Simple command:**
```yaml
---
description: Fix issue by number
argument-hint: [issue-number]
---

Fix issue #$1...
```

**Multi-argument:**
```yaml
---
description: Deploy to environment
argument-hint: [app-name] [environment] [version]
---

Deploy $1 to $2 using version $3...
```

**With options:**
```yaml
---
description: Run tests with options
argument-hint: [test-pattern] [options]
---

Run tests matching $1 with options: $2
```

### disable-model-invocation

**Type:** Boolean
**Required:** No
**Default:** false

**Purpose:** Prevent SlashCommand tool from programmatically invoking command

**Examples:**
```yaml
disable-model-invocation: true
```

**When to use:**

1. **Manual-only commands:** Commands requiring user judgment
   ```yaml
   ---
   description: Approve deployment to production
   disable-model-invocation: true
   ---
   ```

2. **Destructive operations:** Commands with irreversible effects
   ```yaml
   ---
   description: Delete all test data
   disable-model-invocation: true
   ---
   ```

3. **Interactive workflows:** Commands needing user input
   ```yaml
   ---
   description: Walk through setup wizard
   disable-model-invocation: true
   ---
   ```

**Default behavior (false):**
- Command available to SlashCommand tool
- Claude can invoke programmatically
- Still available for manual invocation

**When true:**
- Command only invokable by user typing `/command`
- Not available to SlashCommand tool
- Safer for sensitive operations

**Best practices:**
- Use sparingly (limits Claude's autonomy)
- Document why in command comments
- Consider if command should exist if always manual

## Complete Examples

### Minimal Command

No frontmatter needed:

```markdown
Review this code for common issues and suggest improvements.
```

### Simple Command

Just description:

```markdown
---
description: Review code for issues
---

Review this code for common issues and suggest improvements.
```

### Standard Command

Description and tools:

```markdown
---
description: Review Git changes
allowed-tools: Bash(git:*), Read
---

Current changes: !`git diff --name-only`

Review each changed file for:
- Code quality
- Potential bugs
- Best practices
```

### Complex Command

All common fields:

```markdown
---
description: Deploy application to environment
argument-hint: [app-name] [environment] [version]
allowed-tools: Bash(kubectl:*), Bash(helm:*), Read
model: sonnet
---

Deploy $1 to $2 environment using version $3

Pre-deployment checks:
- Verify $2 configuration
- Check cluster status: !`kubectl cluster-info`
- Validate version $3 exists

Proceed with deployment following deployment runbook.
```

### Manual-Only Command

Restricted invocation:

```markdown
---
description: Approve production deployment
argument-hint: [deployment-id]
disable-model-invocation: true
allowed-tools: Bash(gh:*)
---

<!--
MANUAL APPROVAL REQUIRED
This command requires human judgment and cannot be automated.
-->

Review deployment $1 for production approval:

Deployment details: !`gh api /deployments/$1`

Verify:
- All tests passed
- Security scan clean
- Stakeholder approval
- Rollback plan ready

Type "APPROVED" to confirm deployment.
```

## Validation

### Common Errors

**Invalid YAML syntax:**
```yaml
---
description: Missing quote
allowed-tools: Read, Write
model: sonnet
---  # ❌ Missing closing quote above
```

**Fix:** Validate YAML syntax

**Incorrect tool specification:**
```yaml
allowed-tools: Bash  # ❌ Missing command filter
```

**Fix:** Use `Bash(git:*)` format

**Invalid model name:**
```yaml
model: gpt4  # ❌ Not a valid Claude model
```

**Fix:** Use `sonnet`, `opus`, or `haiku`

### Validation Checklist

Before committing command:
- [ ] YAML syntax valid (no errors)
- [ ] Description under 60 characters
- [ ] allowed-tools uses proper format
- [ ] model is valid value if specified
- [ ] argument-hint matches positional arguments
- [ ] disable-model-invocation used appropriately

## Best Practices Summary

1. **Start minimal:** Add frontmatter only when needed
2. **Document arguments:** Always use argument-hint with arguments
3. **Restrict tools:** Use most restrictive allowed-tools that works
4. **Choose right model:** Use haiku for speed, opus for complexity
5. **Manual-only sparingly:** Only use disable-model-invocation when necessary
6. **Clear descriptions:** Make commands discoverable in `/help`
7. **Test thoroughly:** Verify frontmatter works as expected

---

## Marketplace Considerations for Commands

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/references/marketplace-considerations.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-command-development-references-marketplace.md

# Marketplace Considerations for Commands

Guidelines for creating commands designed for distribution and marketplace success.

## Overview

Commands distributed through marketplaces need additional consideration beyond personal use commands. They must work across environments, handle diverse use cases, and provide excellent user experience for unknown users.

## Design for Distribution

### Universal Compatibility

**Cross-platform considerations:**

```markdown
---
description: Cross-platform command
allowed-tools: Bash(*)
---

# Platform-Aware Command

Detecting platform...

case "$(uname)" in
  Darwin*)  PLATFORM="macOS" ;;
  Linux*)   PLATFORM="Linux" ;;
  MINGW*|MSYS*|CYGWIN*) PLATFORM="Windows" ;;
  *)        PLATFORM="Unknown" ;;
esac

Platform: $PLATFORM

<!-- Adjust behavior based on platform -->
if [ "$PLATFORM" = "Windows" ]; then
  # Windows-specific handling
  PATH_SEP="\\"
  NULL_DEVICE="NUL"
else
  # Unix-like handling
  PATH_SEP="/"
  NULL_DEVICE="/dev/null"
fi

[Platform-appropriate implementation...]
```

**Avoid platform-specific commands:**

```markdown
<!-- BAD: macOS-specific -->
!`pbcopy < file.txt`

<!-- GOOD: Platform detection -->
if command -v pbcopy > /dev/null; then
  pbcopy < file.txt
elif command -v xclip > /dev/null; then
  xclip -selection clipboard < file.txt
elif command -v clip.exe > /dev/null; then
  cat file.txt | clip.exe
else
  echo "Clipboard not available on this platform"
fi
```

### Minimal Dependencies

**Check for required tools:**

```markdown
---
description: Dependency-aware command
allowed-tools: Bash(*)
---

# Check Dependencies

Required tools:
- git
- jq
- node

Checking availability...

MISSING_DEPS=""

for tool in git jq node; do
  if ! command -v $tool > /dev/null; then
    MISSING_DEPS="$MISSING_DEPS $tool"
  fi
done

if [ -n "$MISSING_DEPS" ]; then
  ❌ ERROR: Missing required dependencies:$MISSING_DEPS

  INSTALLATION:
  - git: https://git-scm.com/downloads
  - jq: https://stedolan.github.io/jq/download/
  - node: https://nodejs.org/

  Install missing tools and try again.

  Exit.
fi

✓ All dependencies available

[Continue with command...]
```

**Document optional dependencies:**

```markdown
<!--
DEPENDENCIES:
  Required:
  - git 2.0+: Version control
  - jq 1.6+: JSON processing

  Optional:
  - gh: GitHub CLI (for PR operations)
  - docker: Container operations (for containerized tests)

  Feature availability depends on installed tools.
-->
```

### Graceful Degradation

**Handle missing features:**

```markdown
---
description: Feature-aware command
---

# Feature Detection

Detecting available features...

FEATURES=""

if command -v gh > /dev/null; then
  FEATURES="$FEATURES github"
fi

if command -v docker > /dev/null; then
  FEATURES="$FEATURES docker"
fi

Available features: $FEATURES

if echo "$FEATURES" | grep -q "github"; then
  # Full functionality with GitHub integration
  echo "✓ GitHub integration available"
else
  # Reduced functionality without GitHub
  echo "⚠ Limited functionality: GitHub CLI not installed"
  echo "  Install 'gh' for full features"
fi

[Adapt behavior based on available features...]
```

## User Experience for Unknown Users

### Clear Onboarding

**First-run experience:**

```markdown
---
description: Command with onboarding
allowed-tools: Read, Write
---

# First Run Check

if [ ! -f ".claude/command-initialized" ]; then
  **Welcome to Command Name!**

  This appears to be your first time using this command.

  WHAT THIS COMMAND DOES:
  [Brief explanation of purpose and benefits]

  QUICK START:
  1. Basic usage: /command [arg]
  2. For help: /command help
  3. Examples: /command examples

  SETUP:
  No additional setup required. You're ready to go!

  ✓ Initialization complete

  [Create initialization marker]

  Ready to proceed with your request...
fi

[Normal command execution...]
```

**Progressive feature discovery:**

```markdown
---
description: Command with tips
---

# Command Execution

[Main functionality...]

---

💡 TIP: Did you know?

You can speed up this command with the --fast flag:
  /command --fast [args]

For more tips: /command tips
```

### Comprehensive Error Handling

**Anticipate user mistakes:**

```markdown
---
description: Forgiving command
---

# User Input Handling

Argument: "$1"

<!-- Check for common typos -->
if [ "$1" = "hlep" ] || [ "$1" = "hepl" ]; then
  Did you mean: help?

  Showing help instead...
  [Display help]

  Exit.
fi

<!-- Suggest similar commands if not found -->
if [ "$1" != "valid-option1" ] && [ "$1" != "valid-option2" ]; then
  ❌ Unknown option: $1

  Did you mean:
  - valid-option1 (most similar)
  - valid-option2

  For all options: /command help

  Exit.
fi

[Command continues...]
```

**Helpful diagnostics:**

```markdown
---
description: Diagnostic command
---

# Operation Failed

The operation could not complete.

**Diagnostic Information:**

Environment:
- Platform: $(uname)
- Shell: $SHELL
- Working directory: $(pwd)
- Command: /command $@

Checking common issues:
- Git repository: $(git rev-parse --git-dir 2>&1)
- Write permissions: $(test -w . && echo "OK" || echo "DENIED")
- Required files: $(test -f config.yml && echo "Found" || echo "Missing")

This information helps debug the issue.

For support, include the above diagnostics.
```

## Distribution Best Practices

### Namespace Awareness

**Avoid name collisions:**

```markdown
---
description: Namespaced command
---

<!--
COMMAND NAME: plugin-name-command

This command is namespaced with the plugin name to avoid
conflicts with commands from other plugins.

Alternative naming approaches:
- Use plugin prefix: /plugin-command
- Use category: /category-command
- Use verb-noun: /verb-noun

Chosen approach: plugin-name prefix
Reasoning: Clearest ownership, least likely to conflict
-->

# Plugin Name Command

[Implementation...]
```

**Document naming rationale:**

```markdown
<!--
NAMING DECISION:

Command name: /deploy-app

Alternatives considered:
- /deploy: Too generic, likely conflicts
- /app-deploy: Less intuitive ordering
- /my-plugin-deploy: Too verbose

Final choice balances:
- Discoverability (clear purpose)
- Brevity (easy to type)
- Uniqueness (unlikely conflicts)
-->
```

### Configurability

**User preferences:**

```markdown
---
description: Configurable command
allowed-tools: Read
---

# Load User Configuration

Default configuration:
- verbose: false
- color: true
- max_results: 10

Checking for user config: .claude/plugin-name.local.md

if [ -f ".claude/plugin-name.local.md" ]; then
  # Parse YAML frontmatter for settings
  VERBOSE=$(grep "^verbose:" .claude/plugin-name.local.md | cut -d: -f2 | tr -d ' ')
  COLOR=$(grep "^color:" .claude/plugin-name.local.md | cut -d: -f2 | tr -d ' ')
  MAX_RESULTS=$(grep "^max_results:" .claude/plugin-name.local.md | cut -d: -f2 | tr -d ' ')

  echo "✓ Using user configuration"
else
  echo "Using default configuration"
  echo "Create .claude/plugin-name.local.md to customize"
fi

[Use configuration in command...]
```

**Sensible defaults:**

```markdown
---
description: Command with smart defaults
---

# Smart Defaults

Configuration:
- Format: ${FORMAT:-json}  # Defaults to json
- Output: ${OUTPUT:-stdout}  # Defaults to stdout
- Verbose: ${VERBOSE:-false}  # Defaults to false

These defaults work for 80% of use cases.

Override with arguments:
  /command --format yaml --output file.txt --verbose

Or set in .claude/plugin-name.local.md:
\`\`\`yaml
---
format: yaml
output: custom.txt
verbose: true
---
\`\`\`
```

### Version Compatibility

**Version checking:**

```markdown
---
description: Version-aware command
---

<!--
COMMAND VERSION: 2.1.0

COMPATIBILITY:
- Requires plugin version: >= 2.0.0
- Breaking changes from v1.x documented in MIGRATION.md

VERSION HISTORY:
- v2.1.0: Added --new-feature flag
- v2.0.0: BREAKING: Changed argument order
- v1.0.0: Initial release
-->

# Version Check

Command version: 2.1.0
Plugin version: [detect from plugin.json]

if [  "$PLUGIN_VERSION" < "2.0.0" ]; then
  ❌ ERROR: Incompatible plugin version

  This command requires plugin version >= 2.0.0
  Current version: $PLUGIN_VERSION

  Update plugin:
    /plugin update plugin-name

  Exit.
fi

✓ Version compatible

[Command continues...]
```

**Deprecation warnings:**

```markdown
---
description: Command with deprecation warnings
---

# Deprecation Check

if [ "$1" = "--old-flag" ]; then
  ⚠️  DEPRECATION WARNING

  The --old-flag option is deprecated as of v2.0.0
  It will be removed in v3.0.0 (est. June 2025)

  Use instead: --new-flag

  Example:
    Old: /command --old-flag value
    New: /command --new-flag value

  See migration guide: /command migrate

  Continuing with deprecated behavior for now...
fi

[Handle both old and new flags during deprecation period...]
```

## Marketplace Presentation

### Command Discovery

**Descriptive naming:**

```markdown
---
description: Review pull request with security and quality checks
---

<!-- GOOD: Descriptive name and description -->
```

```markdown
---
description: Do the thing
---

<!-- BAD: Vague description -->
```

**Searchable keywords:**

```markdown
<!--
KEYWORDS: security, code-review, quality, validation, audit

These keywords help users discover this command when searching
for related functionality in the marketplace.
-->
```

### Showcase Examples

**Compelling demonstrations:**

```markdown
---
description: Advanced code analysis command
---

# Code Analysis Command

This command performs deep code analysis with actionable insights.

## Demo: Quick Security Audit

Try it now:
\`\`\`
/analyze-code src/ --security
\`\`\`

**What you'll get:**
- Security vulnerability detection
- Code quality metrics
- Performance bottleneck identification
- Actionable recommendations

**Sample output:**
\`\`\`
Security Analysis Results
=========================

🔴 Critical (2):
  - SQL injection risk in users.js:45
  - XSS vulnerability in display.js:23

🟡 Warnings (5):
  - Unvalidated input in api.js:67
  ...

Recommendations:
1. Fix critical issues immediately
2. Review warnings before next release
3. Run /analyze-code --fix for auto-fixes
\`\`\`

---

Ready to analyze your code...

[Command implementation...]
```

### User Reviews and Feedback

**Feedback mechanism:**

```markdown
---
description: Command with feedback
---

# Command Complete

[Command results...]

---

**How was your experience?**

This helps improve the command for everyone.

Rate this command:
- 👍 Helpful
- 👎 Not helpful
- 🐛 Found a bug
- 💡 Have a suggestion

Reply with an emoji or:
- /command feedback

Your feedback matters!
```

**Usage analytics preparation:**

```markdown
<!--
ANALYTICS NOTES:

Track for improvement:
- Most common arguments
- Failure rates
- Average execution time
- User satisfaction scores

Privacy-preserving:
- No personally identifiable information
- Aggregate statistics only
- User opt-out respected
-->
```

## Quality Standards

### Professional Polish

**Consistent branding:**

```markdown
---
description: Branded command
---

# ✨ Command Name

Part of the [Plugin Name] suite

[Command functionality...]

---

**Need Help?**
- Documentation: https://docs.example.com
- Support: support@example.com
- Community: https://community.example.com

Powered by Plugin Name v2.1.0
```

**Attention to detail:**

```markdown
<!-- Details that matter -->

✓ Use proper emoji/symbols consistently
✓ Align output columns neatly
✓ Format numbers with thousands separators
✓ Use color/formatting appropriately
✓ Provide progress indicators
✓ Show estimated time remaining
✓ Confirm successful operations
```

### Reliability

**Idempotency:**

```markdown
---
description: Idempotent command
---

# Safe Repeated Execution

Checking if operation already completed...

if [ -f ".claude/operation-completed.flag" ]; then
  ℹ️  Operation already completed

  Completed at: $(cat .claude/operation-completed.flag)

  To re-run:
  1. Remove flag: rm .claude/operation-completed.flag
  2. Run command again

  Otherwise, no action needed.

  Exit.
fi

Performing operation...

[Safe, repeatable operation...]

Marking complete...
echo "$(date)" > .claude/operation-completed.flag
```

**Atomic operations:**

```markdown
---
description: Atomic command
---

# Atomic Operation

This operation is atomic - either fully succeeds or fully fails.

Creating temporary workspace...
TEMP_DIR=$(mktemp -d)

Performing changes in isolated environment...
[Make changes in $TEMP_DIR]

if [ $? -eq 0 ]; then
  ✓ Changes validated

  Applying changes atomically...
  mv $TEMP_DIR/* ./target/

  ✓ Operation complete
else
  ❌ Changes failed validation

  Rolling back...
  rm -rf $TEMP_DIR

  No changes applied. Safe to retry.
fi
```

## Testing for Distribution

### Pre-Release Checklist

```markdown
<!--
PRE-RELEASE CHECKLIST:

Functionality:
- [ ] Works on macOS
- [ ] Works on Linux
- [ ] Works on Windows (WSL)
- [ ] All arguments tested
- [ ] Error cases handled
- [ ] Edge cases covered

User Experience:
- [ ] Clear description
- [ ] Helpful error messages
- [ ] Examples provided
- [ ] First-run experience good
- [ ] Documentation complete

Distribution:
- [ ] No hardcoded paths
- [ ] Dependencies documented
- [ ] Configuration options clear
- [ ] Version number set
- [ ] Changelog updated

Quality:
- [ ] No TODO comments
- [ ] No debug code
- [ ] Performance acceptable
- [ ] Security reviewed
- [ ] Privacy considered

Support:
- [ ] README complete
- [ ] Troubleshooting guide
- [ ] Support contact provided
- [ ] Feedback mechanism
- [ ] License specified
-->
```

### Beta Testing

**Beta release approach:**

```markdown
---
description: Beta command (v0.9.0)
---

# 🧪 Beta Command

**This is a beta release**

Features may change based on feedback.

BETA STATUS:
- Version: 0.9.0
- Stability: Experimental
- Support: Limited
- Feedback: Encouraged

Known limitations:
- Performance not optimized
- Some edge cases not handled
- Documentation incomplete

Help improve this command:
- Report issues: /command report-issue
- Suggest features: /command suggest
- Join beta testers: /command join-beta

---

[Command implementation...]

---

**Thank you for beta testing!**

Your feedback helps make this command better.
```

## Maintenance and Updates

### Update Strategy

**Versioned commands:**

```markdown
<!--
VERSION STRATEGY:

Major (X.0.0): Breaking changes
- Document all breaking changes
- Provide migration guide
- Support old version briefly

Minor (x.Y.0): New features
- Backward compatible
- Announce new features
- Update examples

Patch (x.y.Z): Bug fixes
- No user-facing changes
- Update changelog
- Security fixes prioritized

Release schedule:
- Patches: As needed
- Minors: Monthly
- Majors: Annually or as needed
-->
```

**Update notifications:**

```markdown
---
description: Update-aware command
---

# Check for Updates

Current version: 2.1.0
Latest version: [check if available]

if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
  📢 UPDATE AVAILABLE

  New version: $LATEST_VERSION
  Current: $CURRENT_VERSION

  What's new:
  - Feature improvements
  - Bug fixes
  - Performance enhancements

  Update with:
    /plugin update plugin-name

  Release notes: https://releases.example.com/v$LATEST_VERSION
fi

[Command continues...]
```

## Best Practices Summary

### Distribution Design

1. **Universal**: Works across platforms and environments
2. **Self-contained**: Minimal dependencies, clear requirements
3. **Graceful**: Degrades gracefully when features unavailable
4. **Forgiving**: Anticipates and handles user mistakes
5. **Helpful**: Clear errors, good defaults, excellent docs

### Marketplace Success

1. **Discoverable**: Clear name, good description, searchable keywords
2. **Professional**: Polished presentation, consistent branding
3. **Reliable**: Tested thoroughly, handles edge cases
4. **Maintainable**: Versioned, updated regularly, supported
5. **User-focused**: Great UX, responsive to feedback

### Quality Standards

1. **Complete**: Fully documented, all features working
2. **Tested**: Works in real environments, edge cases handled
3. **Secure**: No vulnerabilities, safe operations
4. **Performant**: Reasonable speed, resource-efficient
5. **Ethical**: Privacy-respecting, user consent

With these considerations, commands become marketplace-ready and delight users across diverse environments and use cases.

---

## Plugin-Specific Command Features Reference

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/command-development/references/plugin-features-reference.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-command-development-references-plugin-features.md

# Plugin-Specific Command Features Reference

This reference covers features and patterns specific to commands bundled in Claude Code plugins.

## Table of Contents

- [Plugin Command Discovery](#plugin-command-discovery)
- [CLAUDE_PLUGIN_ROOT Environment Variable](#claude_plugin_root-environment-variable)
- [Plugin Command Patterns](#plugin-command-patterns)
- [Integration with Plugin Components](#integration-with-plugin-components)
- [Validation Patterns](#validation-patterns)

## Plugin Command Discovery

### Auto-Discovery

Claude Code automatically discovers commands in plugins using the following locations:

```
plugin-name/
├── commands/              # Auto-discovered commands
│   ├── foo.md            # /foo (plugin:plugin-name)
│   └── bar.md            # /bar (plugin:plugin-name)
└── plugin.json           # Plugin manifest
```

**Key points:**
- Commands are discovered at plugin load time
- No manual registration required
- Commands appear in `/help` with "(plugin:plugin-name)" label
- Subdirectories create namespaces

### Namespaced Plugin Commands

Organize commands in subdirectories for logical grouping:

```
plugin-name/
└── commands/
    ├── review/
    │   ├── security.md    # /security (plugin:plugin-name:review)
    │   └── style.md       # /style (plugin:plugin-name:review)
    └── deploy/
        ├── staging.md     # /staging (plugin:plugin-name:deploy)
        └── prod.md        # /prod (plugin:plugin-name:deploy)
```

**Namespace behavior:**
- Subdirectory name becomes namespace
- Shown as "(plugin:plugin-name:namespace)" in `/help`
- Helps organize related commands
- Use when plugin has 5+ commands

### Command Naming Conventions

**Plugin command names should:**
1. Be descriptive and action-oriented
2. Avoid conflicts with common command names
3. Use hyphens for multi-word names
4. Consider prefixing with plugin name for uniqueness

**Examples:**
```
Good:
- /mylyn-sync          (plugin-specific prefix)
- /analyze-performance (descriptive action)
- /docker-compose-up   (clear purpose)

Avoid:
- /test               (conflicts with common name)
- /run                (too generic)
- /do-stuff           (not descriptive)
```

## CLAUDE_PLUGIN_ROOT Environment Variable

### Purpose

`${CLAUDE_PLUGIN_ROOT}` is a special environment variable available in plugin commands that resolves to the absolute path of the plugin directory.

**Why it matters:**
- Enables portable paths within plugin
- Allows referencing plugin files and scripts
- Works across different installations
- Essential for multi-file plugin operations

### Basic Usage

Reference files within your plugin:

```markdown
---
description: Analyze using plugin script
allowed-tools: Bash(node:*), Read
---

Run analysis: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/analyze.js`

Read template: @${CLAUDE_PLUGIN_ROOT}/templates/report.md
```

**Expands to:**
```
Run analysis: !`node /path/to/plugins/plugin-name/scripts/analyze.js`

Read template: @/path/to/plugins/plugin-name/templates/report.md
```

### Common Patterns

#### 1. Executing Plugin Scripts

```markdown
---
description: Run custom linter from plugin
allowed-tools: Bash(node:*)
---

Lint results: !`node ${CLAUDE_PLUGIN_ROOT}/bin/lint.js $1`

Review the linting output and suggest fixes.
```

#### 2. Loading Configuration Files

```markdown
---
description: Deploy using plugin configuration
allowed-tools: Read, Bash(*)
---

Configuration: @${CLAUDE_PLUGIN_ROOT}/config/deploy-config.json

Deploy application using the configuration above for $1 environment.
```

#### 3. Accessing Plugin Resources

```markdown
---
description: Generate report from template
---

Use this template: @${CLAUDE_PLUGIN_ROOT}/templates/api-report.md

Generate a report for @$1 following the template format.
```

#### 4. Multi-Step Plugin Workflows

```markdown
---
description: Complete plugin workflow
allowed-tools: Bash(*), Read
---

Step 1 - Prepare: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/prepare.sh $1`
Step 2 - Config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json
Step 3 - Execute: !`${CLAUDE_PLUGIN_ROOT}/bin/execute $1`

Review results and report status.
```

### Best Practices

1. **Always use for plugin-internal paths:**
   ```markdown
   # Good
   @${CLAUDE_PLUGIN_ROOT}/templates/foo.md

   # Bad
   @./templates/foo.md  # Relative to current directory, not plugin
   ```

2. **Validate file existence:**
   ```markdown
   ---
   description: Use plugin config if exists
   allowed-tools: Bash(test:*), Read
   ---

   !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "exists" || echo "missing"`

   If config exists, load it: @${CLAUDE_PLUGIN_ROOT}/config.json
   Otherwise, use defaults...
   ```

3. **Document plugin file structure:**
   ```markdown
   <!--
   Plugin structure:
   ${CLAUDE_PLUGIN_ROOT}/
   ├── scripts/analyze.js  (analysis script)
   ├── templates/          (report templates)
   └── config/             (configuration files)
   -->
   ```

4. **Combine with arguments:**
   ```markdown
   Run: !`${CLAUDE_PLUGIN_ROOT}/bin/process.sh $1 $2`
   ```

### Troubleshooting

**Variable not expanding:**
- Ensure command is loaded from plugin
- Check bash execution is allowed
- Verify syntax is exact: `${CLAUDE_PLUGIN_ROOT}`

**File not found errors:**
- Verify file exists in plugin directory
- Check file path is correct relative to plugin root
- Ensure file permissions allow reading/execution

**Path with spaces:**
- Bash commands automatically handle spaces
- File references work with spaces in paths
- No special quoting needed

## Plugin Command Patterns

### Pattern 1: Configuration-Based Commands

Commands that load plugin-specific configuration:

```markdown
---
description: Deploy using plugin settings
allowed-tools: Read, Bash(*)
---

Load configuration: @${CLAUDE_PLUGIN_ROOT}/deploy-config.json

Deploy to $1 environment using:
1. Configuration settings above
2. Current git branch: !`git branch --show-current`
3. Application version: !`cat package.json | grep version`

Execute deployment and monitor progress.
```

**When to use:** Commands that need consistent settings across invocations

### Pattern 2: Template-Based Generation

Commands that use plugin templates:

```markdown
---
description: Generate documentation from template
argument-hint: [component-name]
---

Template: @${CLAUDE_PLUGIN_ROOT}/templates/component-docs.md

Generate documentation for $1 component following the template structure.
Include:
- Component purpose and usage
- API reference
- Examples
- Testing guidelines
```

**When to use:** Standardized output generation

### Pattern 3: Multi-Script Workflow

Commands that orchestrate multiple plugin scripts:

```markdown
---
description: Complete build and test workflow
allowed-tools: Bash(*)
---

Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`
Validate: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh`
Test: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/test.sh`

Review all outputs and report:
1. Build status
2. Validation results
3. Test results
4. Recommended next steps
```

**When to use:** Complex plugin workflows with multiple steps

### Pattern 4: Environment-Aware Commands

Commands that adapt to environment:

```markdown
---
description: Deploy based on environment
argument-hint: [dev|staging|prod]
---

Environment config: @${CLAUDE_PLUGIN_ROOT}/config/$1.json

Environment check: !`echo "Deploying to: $1"`

Deploy application using $1 environment configuration.
Verify deployment and run smoke tests.
```

**When to use:** Commands that behave differently per environment

### Pattern 5: Plugin Data Management

Commands that manage plugin-specific data:

```markdown
---
description: Save analysis results to plugin cache
allowed-tools: Bash(*), Read, Write
---

Cache directory: ${CLAUDE_PLUGIN_ROOT}/cache/

Analyze @$1 and save results to cache:
!`mkdir -p ${CLAUDE_PLUGIN_ROOT}/cache && date > ${CLAUDE_PLUGIN_ROOT}/cache/last-run.txt`

Store analysis for future reference and comparison.
```

**When to use:** Commands that need persistent data storage

## Integration with Plugin Components

### Invoking Plugin Agents

Commands can trigger plugin agents using the Task tool:

```markdown
---
description: Deep analysis using plugin agent
argument-hint: [file-path]
---

Initiate deep code analysis of @$1 using the code-analyzer agent.

The agent will:
1. Analyze code structure
2. Identify patterns
3. Suggest improvements
4. Generate detailed report

Note: This uses the Task tool to launch the plugin's code-analyzer agent.
```

**Key points:**
- Agent must be defined in plugin's `agents/` directory
- Claude will automatically use Task tool to launch agent
- Agent has access to same plugin resources

### Invoking Plugin Skills

Commands can reference plugin skills for specialized knowledge:

```markdown
---
description: API documentation with best practices
argument-hint: [api-file]
---

Document the API in @$1 following our API documentation standards.

Use the api-docs-standards skill to ensure documentation includes:
- Endpoint descriptions
- Parameter specifications
- Response formats
- Error codes
- Usage examples

Note: This leverages the plugin's api-docs-standards skill for consistency.
```

**Key points:**
- Skill must be defined in plugin's `skills/` directory
- Mention skill by name to hint Claude should invoke it
- Skills provide specialized domain knowledge

### Coordinating with Plugin Hooks

Commands can be designed to work with plugin hooks:

```markdown
---
description: Commit with pre-commit validation
allowed-tools: Bash(git:*)
---

Stage changes: !\`git add $1\`

Commit changes: !\`git commit -m "$2"\`

Note: This commit will trigger the plugin's pre-commit hook for validation.
Review hook output for any issues.
```

**Key points:**
- Hooks execute automatically on events
- Commands can prepare state for hooks
- Document hook interaction in command

### Multi-Component Plugin Commands

Commands that coordinate multiple plugin components:

```markdown
---
description: Comprehensive code review workflow
argument-hint: [file-path]
---

File to review: @$1

Execute comprehensive review:

1. **Static Analysis** (via plugin scripts)
   !`node ${CLAUDE_PLUGIN_ROOT}/scripts/lint.js $1`

2. **Deep Review** (via plugin agent)
   Launch the code-reviewer agent for detailed analysis.

3. **Best Practices** (via plugin skill)
   Use the code-standards skill to ensure compliance.

4. **Documentation** (via plugin template)
   Template: @${CLAUDE_PLUGIN_ROOT}/templates/review-report.md

Generate final report combining all outputs.
```

**When to use:** Complex workflows leveraging multiple plugin capabilities

## Validation Patterns

### Input Validation

Commands should validate inputs before processing:

```markdown
---
description: Deploy to environment with validation
argument-hint: [environment]
---

Validate environment: !`echo "$1" | grep -E "^(dev|staging|prod)$" || echo "INVALID"`

$IF($1 in [dev, staging, prod],
  Deploy to $1 environment using validated configuration,
  ERROR: Invalid environment '$1'. Must be one of: dev, staging, prod
)
```

**Validation approaches:**
1. Bash validation using grep/test
2. Inline validation in prompt
3. Script-based validation

### File Existence Checks

Verify required files exist:

```markdown
---
description: Process configuration file
argument-hint: [config-file]
---

Check file: !`test -f $1 && echo "EXISTS" || echo "MISSING"`

Process configuration if file exists: @$1

If file doesn't exist, explain:
- Expected location
- Required format
- How to create it
```

### Required Arguments

Validate required arguments provided:

```markdown
---
description: Create deployment with version
argument-hint: [environment] [version]
---

Validate inputs: !`test -n "$1" -a -n "$2" && echo "OK" || echo "MISSING"`

$IF($1 AND $2,
  Deploy version $2 to $1 environment,
  ERROR: Both environment and version required. Usage: /deploy [env] [version]
)
```

### Plugin Resource Validation

Verify plugin resources available:

```markdown
---
description: Run analysis with plugin tools
allowed-tools: Bash(test:*)
---

Validate plugin setup:
- Config exists: !`test -f ${CLAUDE_PLUGIN_ROOT}/config.json && echo "✓" || echo "✗"`
- Scripts exist: !`test -d ${CLAUDE_PLUGIN_ROOT}/scripts && echo "✓" || echo "✗"`
- Tools available: !`test -x ${CLAUDE_PLUGIN_ROOT}/bin/analyze && echo "✓" || echo "✗"`

If all checks pass, proceed with analysis.
Otherwise, report missing components and installation steps.
```

### Output Validation

Validate command execution results:

```markdown
---
description: Build and validate output
allowed-tools: Bash(*)
---

Build: !`bash ${CLAUDE_PLUGIN_ROOT}/scripts/build.sh`

Validate output:
- Exit code: !`echo $?`
- Output exists: !`test -d dist && echo "✓" || echo "✗"`
- File count: !`find dist -type f | wc -l`

Report build status and any validation failures.
```

### Graceful Error Handling

Handle errors gracefully with helpful messages:

```markdown
---
description: Process file with error handling
argument-hint: [file-path]
---

Try processing: !`node ${CLAUDE_PLUGIN_ROOT}/scripts/process.js $1 2>&1 || echo "ERROR: $?"`

If processing succeeded:
- Report results
- Suggest next steps

If processing failed:
- Explain likely causes
- Provide troubleshooting steps
- Suggest alternative approaches
```

## Best Practices Summary

### Plugin Commands Should:

1. **Use ${CLAUDE_PLUGIN_ROOT} for all plugin-internal paths**
   - Scripts, templates, configuration, resources

2. **Validate inputs early**
   - Check required arguments
   - Verify file existence
   - Validate argument formats

3. **Document plugin structure**
   - Explain required files
   - Document script purposes
   - Clarify dependencies

4. **Integrate with plugin components**
   - Reference agents for complex tasks
   - Use skills for specialized knowledge
   - Coordinate with hooks when relevant

5. **Provide helpful error messages**
   - Explain what went wrong
   - Suggest how to fix
   - Offer alternatives

6. **Handle edge cases**
   - Missing files
   - Invalid arguments
   - Failed script execution
   - Missing dependencies

7. **Keep commands focused**
   - One clear purpose per command
   - Delegate complex logic to scripts
   - Use agents for multi-step workflows

8. **Test across installations**
   - Verify paths work everywhere
   - Test with different arguments
   - Validate error cases

---

For general command development, see main SKILL.md.
For command examples, see examples/ directory.

---

## Create Plugin Settings

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-settings/examples/create-settings-command.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-settings-examples-create-settings-command.md

# Create Plugin Settings

This command helps users create a `.claude/my-plugin.local.md` settings file.

## Steps

### Step 1: Ask User for Preferences

Use AskUserQuestion to gather configuration:

```json
{
  "questions": [
    {
      "question": "Enable plugin for this project?",
      "header": "Enable Plugin",
      "multiSelect": false,
      "options": [
        {
          "label": "Yes",
          "description": "Plugin will be active"
        },
        {
          "label": "No",
          "description": "Plugin will be disabled"
        }
      ]
    },
    {
      "question": "Validation mode?",
      "header": "Mode",
      "multiSelect": false,
      "options": [
        {
          "label": "Strict",
          "description": "Maximum validation and security checks"
        },
        {
          "label": "Standard",
          "description": "Balanced validation (recommended)"
        },
        {
          "label": "Lenient",
          "description": "Minimal validation only"
        }
      ]
    }
  ]
}
```

### Step 2: Parse Answers

Extract answers from AskUserQuestion result:

- answers["0"]: enabled (Yes/No)
- answers["1"]: mode (Strict/Standard/Lenient)

### Step 3: Create Settings File

Use Write tool to create `.claude/my-plugin.local.md`:

```markdown
---
enabled: <true if Yes, false if No>
validation_mode: <strict, standard, or lenient>
max_file_size: 1000000
notify_on_errors: true
---

# Plugin Configuration

Your plugin is configured with <mode> validation mode.

To modify settings, edit this file and restart Claude Code.
```

### Step 4: Inform User

Tell the user:
- Settings file created at `.claude/my-plugin.local.md`
- Current configuration summary
- How to edit manually if needed
- Reminder: Restart Claude Code for changes to take effect
- Settings file is gitignored (won't be committed)

## Implementation Notes

Always validate user input before writing:
- Check mode is valid
- Validate numeric fields are numbers
- Ensure paths don't have traversal attempts
- Sanitize any free-text fields

---

## Real-World Plugin Settings Examples

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-settings/references/real-world-examples.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-settings-references-real-world-examples.md

# Real-World Plugin Settings Examples

Detailed analysis of how production plugins use the `.claude/plugin-name.local.md` pattern.

## multi-agent-swarm Plugin

### Settings File Structure

**.claude/multi-agent-swarm.local.md:**

```markdown
---
agent_name: auth-implementation
task_number: 3.5
pr_number: 1234
coordinator_session: team-leader
enabled: true
dependencies: ["Task 3.4"]
additional_instructions: "Use JWT tokens, not sessions"
---

# Task: Implement Authentication

Build JWT-based authentication for the REST API.

## Requirements
- JWT token generation and validation
- Refresh token flow
- Secure password hashing

## Success Criteria
- Auth endpoints implemented
- Tests passing (100% coverage)
- PR created and CI green
- Documentation updated

## Coordination
Depends on Task 3.4 (user model).
Report status to 'team-leader' session.
```

### How It's Used

**File:** `hooks/agent-stop-notification.sh`

**Purpose:** Send notifications to coordinator when agent becomes idle

**Implementation:**

```bash
#!/bin/bash
set -euo pipefail

SWARM_STATE_FILE=".claude/multi-agent-swarm.local.md"

# Quick exit if no swarm active
if [[ ! -f "$SWARM_STATE_FILE" ]]; then
  exit 0
fi

# Parse frontmatter
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$SWARM_STATE_FILE")

# Extract configuration
COORDINATOR_SESSION=$(echo "$FRONTMATTER" | grep '^coordinator_session:' | sed 's/coordinator_session: *//' | sed 's/^"\(.*\)"$/\1/')
AGENT_NAME=$(echo "$FRONTMATTER" | grep '^agent_name:' | sed 's/agent_name: *//' | sed 's/^"\(.*\)"$/\1/')
TASK_NUMBER=$(echo "$FRONTMATTER" | grep '^task_number:' | sed 's/task_number: *//' | sed 's/^"\(.*\)"$/\1/')
PR_NUMBER=$(echo "$FRONTMATTER" | grep '^pr_number:' | sed 's/pr_number: *//' | sed 's/^"\(.*\)"$/\1/')
ENABLED=$(echo "$FRONTMATTER" | grep '^enabled:' | sed 's/enabled: *//')

# Check if enabled
if [[ "$ENABLED" != "true" ]]; then
  exit 0
fi

# Send notification to coordinator
NOTIFICATION="🤖 Agent ${AGENT_NAME} (Task ${TASK_NUMBER}, PR #${PR_NUMBER}) is idle."

if tmux has-session -t "$COORDINATOR_SESSION" 2>/dev/null; then
  tmux send-keys -t "$COORDINATOR_SESSION" "$NOTIFICATION" Enter
  sleep 0.5
  tmux send-keys -t "$COORDINATOR_SESSION" Enter
fi

exit 0
```

**Key patterns:**
1. **Quick exit** (line 7-9): Returns immediately if file doesn't exist
2. **Field extraction** (lines 11-17): Parses each frontmatter field
3. **Enabled check** (lines 19-21): Respects enabled flag
4. **Action based on settings** (lines 23-29): Uses coordinator_session to send notification

### Creation

**File:** `commands/launch-swarm.md`

Settings files are created during swarm launch with:

```bash
cat > "$WORKTREE_PATH/.claude/multi-agent-swarm.local.md" <<EOF
---
agent_name: $AGENT_NAME
task_number: $TASK_ID
pr_number: TBD
coordinator_session: $COORDINATOR_SESSION
enabled: true
dependencies: [$DEPENDENCIES]
additional_instructions: "$EXTRA_INSTRUCTIONS"
---

# Task: $TASK_DESCRIPTION

$TASK_DETAILS
EOF
```

### Updates

PR number updated after PR creation:

```bash
# Update pr_number field
sed "s/^pr_number: .*/pr_number: $PR_NUM/" \
  ".claude/multi-agent-swarm.local.md" > temp.md
mv temp.md ".claude/multi-agent-swarm.local.md"
```

## ralph-wiggum Plugin

### Settings File Structure

**.claude/ralph-loop.local.md:**

```markdown
---
iteration: 1
max_iterations: 10
completion_promise: "All tests passing and build successful"
started_at: "2025-01-15T14:30:00Z"
---

Fix all the linting errors in the project.
Make sure tests pass after each fix.
Document any changes needed in CLAUDE.md.
```

### How It's Used

**File:** `hooks/stop-hook.sh`

**Purpose:** Prevent session exit and loop Claude's output back as input

**Implementation:**

```bash
#!/bin/bash
set -euo pipefail

RALPH_STATE_FILE=".claude/ralph-loop.local.md"

# Quick exit if no active loop
if [[ ! -f "$RALPH_STATE_FILE" ]]; then
  exit 0
fi

# Parse frontmatter
FRONTMATTER=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$RALPH_STATE_FILE")

# Extract configuration
ITERATION=$(echo "$FRONTMATTER" | grep '^iteration:' | sed 's/iteration: *//')
MAX_ITERATIONS=$(echo "$FRONTMATTER" | grep '^max_iterations:' | sed 's/max_iterations: *//')
COMPLETION_PROMISE=$(echo "$FRONTMATTER" | grep '^completion_promise:' | sed 's/completion_promise: *//' | sed 's/^"\(.*\)"$/\1/')

# Check max iterations
if [[ $MAX_ITERATIONS -gt 0 ]] && [[ $ITERATION -ge $MAX_ITERATIONS ]]; then
  echo "🛑 Ralph loop: Max iterations ($MAX_ITERATIONS) reached."
  rm "$RALPH_STATE_FILE"
  exit 0
fi

# Get transcript and check for completion promise
TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path')
LAST_OUTPUT=$(grep '"role":"assistant"' "$TRANSCRIPT_PATH" | tail -1 | jq -r '.message.content | map(select(.type == "text")) | map(.text) | join("\n")')

# Check for completion
if [[ "$COMPLETION_PROMISE" != "null" ]] && [[ -n "$COMPLETION_PROMISE" ]]; then
  PROMISE_TEXT=$(echo "$LAST_OUTPUT" | perl -0777 -pe 's/.*?<promise>(.*?)<\/promise>.*/$1/s; s/^\s+|\s+$//g')

  if [[ "$PROMISE_TEXT" = "$COMPLETION_PROMISE" ]]; then
    echo "✅ Ralph loop: Detected completion"
    rm "$RALPH_STATE_FILE"
    exit 0
  fi
fi

# Continue loop - increment iteration
NEXT_ITERATION=$((ITERATION + 1))

# Extract prompt from markdown body
PROMPT_TEXT=$(awk '/^---$/{i++; next} i>=2' "$RALPH_STATE_FILE")

# Update iteration counter
TEMP_FILE="${RALPH_STATE_FILE}.tmp.$$"
sed "s/^iteration: .*/iteration: $NEXT_ITERATION/" "$RALPH_STATE_FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$RALPH_STATE_FILE"

# Block exit and feed prompt back
jq -n \
  --arg prompt "$PROMPT_TEXT" \
  --arg msg "🔄 Ralph iteration $NEXT_ITERATION" \
  '{
    "decision": "block",
    "reason": $prompt,
    "systemMessage": $msg
  }'

exit 0
```

**Key patterns:**
1. **Quick exit** (line 7-9): Skip if not active
2. **Iteration tracking** (lines 11-20): Count and enforce max iterations
3. **Promise detection** (lines 25-33): Check for completion signal in output
4. **Prompt extraction** (line 38): Read markdown body as next prompt
5. **State update** (lines 40-43): Increment iteration atomically
6. **Loop continuation** (lines 45-53): Block exit and feed prompt back

### Creation

**File:** `scripts/setup-ralph-loop.sh`

```bash
#!/bin/bash
PROMPT="$1"
MAX_ITERATIONS="${2:-0}"
COMPLETION_PROMISE="${3:-}"

# Create state file
cat > ".claude/ralph-loop.local.md" <<EOF
---
iteration: 1
max_iterations: $MAX_ITERATIONS
completion_promise: "$COMPLETION_PROMISE"
started_at: "$(date -Iseconds)"
---

$PROMPT
EOF

echo "Ralph loop initialized: .claude/ralph-loop.local.md"
```

## Pattern Comparison

| Feature | multi-agent-swarm | ralph-wiggum |
|---------|-------------------|--------------|
| **File** | `.claude/multi-agent-swarm.local.md` | `.claude/ralph-loop.local.md` |
| **Purpose** | Agent coordination state | Loop iteration state |
| **Frontmatter** | Agent metadata | Loop configuration |
| **Body** | Task assignment | Prompt to loop |
| **Updates** | PR number, status | Iteration counter |
| **Deletion** | Manual or on completion | On loop exit |
| **Hook** | Stop (notifications) | Stop (loop control) |

## Best Practices from Real Plugins

### 1. Quick Exit Pattern

Both plugins check file existence first:

```bash
if [[ ! -f "$STATE_FILE" ]]; then
  exit 0  # Not active
fi
```

**Why:** Avoids errors when plugin isn't configured and performs fast.

### 2. Enabled Flag

Both use an `enabled` field for explicit control:

```yaml
enabled: true
```

**Why:** Allows temporary deactivation without deleting file.

### 3. Atomic Updates

Both use temp file + atomic move:

```bash
TEMP_FILE="${FILE}.tmp.$$"
sed "s/^field: .*/field: $NEW_VALUE/" "$FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$FILE"
```

**Why:** Prevents corruption if process is interrupted.

### 4. Quote Handling

Both strip surrounding quotes from YAML values:

```bash
sed 's/^"\(.*\)"$/\1/'
```

**Why:** YAML allows both `field: value` and `field: "value"`.

### 5. Error Handling

Both handle missing/corrupt files gracefully:

```bash
if [[ ! -f "$FILE" ]]; then
  exit 0  # No error, just not configured
fi

if [[ -z "$CRITICAL_FIELD" ]]; then
  echo "Settings file corrupt" >&2
  rm "$FILE"  # Clean up
  exit 0
fi
```

**Why:** Fails gracefully instead of crashing.

## Anti-Patterns to Avoid

### ❌ Hardcoded Paths

```bash
# BAD
FILE="/Users/alice/.claude/my-plugin.local.md"

# GOOD
FILE=".claude/my-plugin.local.md"
```

### ❌ Unquoted Variables

```bash
# BAD
echo $VALUE

# GOOD
echo "$VALUE"
```

### ❌ Non-Atomic Updates

```bash
# BAD: Can corrupt file if interrupted
sed -i "s/field: .*/field: $VALUE/" "$FILE"

# GOOD: Atomic
TEMP_FILE="${FILE}.tmp.$$"
sed "s/field: .*/field: $VALUE/" "$FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$FILE"
```

### ❌ No Default Values

```bash
# BAD: Fails if field missing
if [[ $MAX -gt 100 ]]; then
  # MAX might be empty!
fi

# GOOD: Provide default
MAX=${MAX:-10}
```

### ❌ Ignoring Edge Cases

```bash
# BAD: Assumes exactly 2 --- markers
sed -n '/^---$/,/^---$/{ /^---$/d; p; }'

# GOOD: Handles --- in body
awk '/^---$/{i++; next} i>=2'  # For body
```

## Conclusion

The `.claude/plugin-name.local.md` pattern provides:
- Simple, human-readable configuration
- Version-control friendly (gitignored)
- Per-project settings
- Easy parsing with standard bash tools
- Supports both structured config (YAML) and freeform content (markdown)

Use this pattern for any plugin that needs user-configurable behavior or state persistence.

---

## Advanced Plugin Example

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-structure/examples/advanced-plugin.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-structure-examples-advanced-plugin.md

# Advanced Plugin Example

A complex, enterprise-grade plugin with MCP integration and advanced organization.

## Directory Structure

```
enterprise-devops/
├── .claude-plugin/
│   └── plugin.json
├── commands/
│   ├── ci/
│   │   ├── build.md
│   │   ├── test.md
│   │   └── deploy.md
│   ├── monitoring/
│   │   ├── status.md
│   │   └── logs.md
│   └── admin/
│       ├── configure.md
│       └── manage.md
├── agents/
│   ├── orchestration/
│   │   ├── deployment-orchestrator.md
│   │   └── rollback-manager.md
│   └── specialized/
│       ├── kubernetes-expert.md
│       ├── terraform-expert.md
│       └── security-auditor.md
├── skills/
│   ├── kubernetes-ops/
│   │   ├── SKILL.md
│   │   ├── references/
│   │   │   ├── deployment-patterns.md
│   │   │   ├── troubleshooting.md
│   │   │   └── security.md
│   │   ├── examples/
│   │   │   ├── basic-deployment.yaml
│   │   │   ├── stateful-set.yaml
│   │   │   └── ingress-config.yaml
│   │   └── scripts/
│   │       ├── validate-manifest.sh
│   │       └── health-check.sh
│   ├── terraform-iac/
│   │   ├── SKILL.md
│   │   ├── references/
│   │   │   └── best-practices.md
│   │   └── examples/
│   │       └── module-template/
│   └── ci-cd-pipelines/
│       ├── SKILL.md
│       └── references/
│           └── pipeline-patterns.md
├── hooks/
│   ├── hooks.json
│   └── scripts/
│       ├── security/
│       │   ├── scan-secrets.sh
│       │   ├── validate-permissions.sh
│       │   └── audit-changes.sh
│       ├── quality/
│       │   ├── check-config.sh
│       │   └── verify-tests.sh
│       └── workflow/
│           ├── notify-team.sh
│           └── update-status.sh
├── .mcp.json
├── servers/
│   ├── kubernetes-mcp/
│   │   ├── index.js
│   │   ├── package.json
│   │   └── lib/
│   ├── terraform-mcp/
│   │   ├── main.py
│   │   └── requirements.txt
│   └── github-actions-mcp/
│       ├── server.js
│       └── package.json
├── lib/
│   ├── core/
│   │   ├── logger.js
│   │   ├── config.js
│   │   └── auth.js
│   ├── integrations/
│   │   ├── slack.js
│   │   ├── pagerduty.js
│   │   └── datadog.js
│   └── utils/
│       ├── retry.js
│       └── validation.js
└── config/
    ├── environments/
    │   ├── production.json
    │   ├── staging.json
    │   └── development.json
    └── templates/
        ├── deployment.yaml
        └── service.yaml
```

## File Contents

### .claude-plugin/plugin.json

```json
{
  "name": "enterprise-devops",
  "version": "2.3.1",
  "description": "Comprehensive DevOps automation for enterprise CI/CD pipelines, infrastructure management, and monitoring",
  "author": {
    "name": "DevOps Platform Team",
    "email": "devops-platform@company.com",
    "url": "https://company.com/teams/devops"
  },
  "homepage": "https://docs.company.com/plugins/devops",
  "repository": {
    "type": "git",
    "url": "https://github.com/company/devops-plugin.git"
  },
  "license": "Apache-2.0",
  "keywords": [
    "devops",
    "ci-cd",
    "kubernetes",
    "terraform",
    "automation",
    "infrastructure",
    "deployment",
    "monitoring"
  ],
  "commands": [
    "./commands/ci",
    "./commands/monitoring",
    "./commands/admin"
  ],
  "agents": [
    "./agents/orchestration",
    "./agents/specialized"
  ],
  "hooks": "./hooks/hooks.json",
  "mcpServers": "./.mcp.json"
}
```

### .mcp.json

```json
{
  "mcpServers": {
    "kubernetes": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/servers/kubernetes-mcp/index.js"],
      "env": {
        "KUBECONFIG": "${KUBECONFIG}",
        "K8S_NAMESPACE": "${K8S_NAMESPACE:-default}"
      }
    },
    "terraform": {
      "command": "python",
      "args": ["${CLAUDE_PLUGIN_ROOT}/servers/terraform-mcp/main.py"],
      "env": {
        "TF_STATE_BUCKET": "${TF_STATE_BUCKET}",
        "AWS_REGION": "${AWS_REGION}"
      }
    },
    "github-actions": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/servers/github-actions-mcp/server.js"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "GITHUB_ORG": "${GITHUB_ORG}"
      }
    }
  }
}
```

### commands/ci/build.md

```markdown
---
name: build
description: Trigger and monitor CI build pipeline
---

# Build Command

Trigger CI/CD build pipeline and monitor progress in real-time.

## Process

1. **Validation**: Check prerequisites
   - Verify branch status
   - Check for uncommitted changes
   - Validate configuration files

2. **Trigger**: Start build via MCP server
   \`\`\`javascript
   // Uses github-actions MCP server
   const build = await tools.github_actions_trigger_workflow({
     workflow: 'build.yml',
     ref: currentBranch
   })
   \`\`\`

3. **Monitor**: Track build progress
   - Display real-time logs
   - Show test results as they complete
   - Alert on failures

4. **Report**: Summarize results
   - Build status
   - Test coverage
   - Performance metrics
   - Deploy readiness

## Integration

After successful build:
- Offer to deploy to staging
- Suggest performance optimizations
- Generate deployment checklist
```

### agents/orchestration/deployment-orchestrator.md

```markdown
---
description: Orchestrates complex multi-environment deployments with rollback capabilities and health monitoring
capabilities:
  - Plan and execute multi-stage deployments
  - Coordinate service dependencies
  - Monitor deployment health
  - Execute automated rollbacks
  - Manage deployment approvals
---

# Deployment Orchestrator Agent

Specialized agent for orchestrating complex deployments across multiple environments.

## Expertise

- **Deployment strategies**: Blue-green, canary, rolling updates
- **Dependency management**: Service startup ordering, dependency injection
- **Health monitoring**: Service health checks, metric validation
- **Rollback automation**: Automatic rollback on failure detection
- **Approval workflows**: Multi-stage approval processes

## Orchestration Process

1. **Planning Phase**
   - Analyze deployment requirements
   - Identify service dependencies
   - Generate deployment plan
   - Calculate rollback strategy

2. **Validation Phase**
   - Verify environment readiness
   - Check resource availability
   - Validate configurations
   - Run pre-deployment tests

3. **Execution Phase**
   - Deploy services in dependency order
   - Monitor health after each stage
   - Validate metrics and logs
   - Proceed to next stage on success

4. **Verification Phase**
   - Run smoke tests
   - Validate service integration
   - Check performance metrics
   - Confirm deployment success

5. **Rollback Phase** (if needed)
   - Detect failure conditions
   - Execute rollback plan
   - Restore previous state
   - Notify stakeholders

## MCP Integration

Uses multiple MCP servers:
- `kubernetes`: Deploy and manage containers
- `terraform`: Provision infrastructure
- `github-actions`: Trigger deployment pipelines

## Monitoring Integration

Integrates with monitoring tools via lib:
\`\`\`javascript
const { DatadogClient } = require('${CLAUDE_PLUGIN_ROOT}/lib/integrations/datadog')
const metrics = await DatadogClient.getMetrics(service, timeRange)
\`\`\`

## Notification Integration

Sends updates via Slack and PagerDuty:
\`\`\`javascript
const { SlackClient } = require('${CLAUDE_PLUGIN_ROOT}/lib/integrations/slack')
await SlackClient.notify({
  channel: '#deployments',
  message: 'Deployment started',
  metadata: deploymentPlan
})
\`\`\`
```

### skills/kubernetes-ops/SKILL.md

```markdown
---
name: Kubernetes Operations
description: This skill should be used when deploying to Kubernetes, managing K8s resources, troubleshooting cluster issues, configuring ingress/services, scaling deployments, or working with Kubernetes manifests. Provides comprehensive Kubernetes operational knowledge and best practices.
version: 2.0.0
---

# Kubernetes Operations

Comprehensive operational knowledge for managing Kubernetes clusters and workloads.

## Overview

Manage Kubernetes infrastructure effectively through:
- Deployment strategies and patterns
- Resource configuration and optimization
- Troubleshooting and debugging
- Security best practices
- Performance tuning

## Core Concepts

### Resource Management

**Deployments**: Use for stateless applications
- Rolling updates for zero-downtime deployments
- Rollback capabilities for failed deployments
- Replica management for scaling

**StatefulSets**: Use for stateful applications
- Stable network identities
- Persistent storage
- Ordered deployment and scaling

**DaemonSets**: Use for node-level services
- Log collectors
- Monitoring agents
- Network plugins

### Configuration

**ConfigMaps**: Store non-sensitive configuration
- Environment-specific settings
- Application configuration files
- Feature flags

**Secrets**: Store sensitive data
- API keys and tokens
- Database credentials
- TLS certificates

Use external secret management (Vault, AWS Secrets Manager) for production.

### Networking

**Services**: Expose applications internally
- ClusterIP for internal communication
- NodePort for external access (non-production)
- LoadBalancer for external access (production)

**Ingress**: HTTP/HTTPS routing
- Path-based routing
- Host-based routing
- TLS termination
- Load balancing

## Deployment Strategies

### Rolling Update

Default strategy, gradual replacement:
\`\`\`yaml
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
\`\`\`

**When to use**: Standard deployments, minor updates

### Recreate

Stop all pods, then create new ones:
\`\`\`yaml
strategy:
  type: Recreate
\`\`\`

**When to use**: Stateful apps that can't run multiple versions

### Blue-Green

Run two complete environments, switch traffic:
1. Deploy new version (green)
2. Test green environment
3. Switch traffic to green
4. Keep blue for quick rollback

**When to use**: Critical services, need instant rollback

### Canary

Gradually roll out to subset of users:
1. Deploy canary version (10% traffic)
2. Monitor metrics and errors
3. Increase traffic gradually
4. Complete rollout or rollback

**When to use**: High-risk changes, want gradual validation

## Resource Configuration

### Resource Requests and Limits

Always set for production workloads:
\`\`\`yaml
resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"
\`\`\`

**Requests**: Guaranteed resources
**Limits**: Maximum allowed resources

### Health Checks

Essential for reliability:
\`\`\`yaml
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
\`\`\`

**Liveness**: Restart unhealthy pods
**Readiness**: Remove unready pods from service

## Troubleshooting

### Common Issues

1. **Pods not starting**
   - Check: `kubectl describe pod <name>`
   - Look for: Image pull errors, resource constraints
   - Fix: Verify image name, increase resources

2. **Service not reachable**
   - Check: `kubectl get svc`, `kubectl get endpoints`
   - Look for: No endpoints, wrong selector
   - Fix: Verify pod labels match service selector

3. **High memory usage**
   - Check: `kubectl top pods`
   - Look for: Pods near memory limit
   - Fix: Increase limits, optimize application

4. **Frequent restarts**
   - Check: `kubectl get pods`, `kubectl logs <name>`
   - Look for: Liveness probe failures, OOMKilled
   - Fix: Adjust health checks, increase memory

### Debugging Commands

Get pod details:
\`\`\`bash
kubectl describe pod <name>
kubectl logs <name>
kubectl logs <name> --previous  # logs from crashed container
\`\`\`

Execute commands in pod:
\`\`\`bash
kubectl exec -it <name> -- /bin/sh
kubectl exec <name> -- env
\`\`\`

Check resource usage:
\`\`\`bash
kubectl top nodes
kubectl top pods
\`\`\`

## Security Best Practices

### Pod Security

- Run as non-root user
- Use read-only root filesystem
- Drop unnecessary capabilities
- Use security contexts

Example:
\`\`\`yaml
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL
\`\`\`

### Network Policies

Restrict pod communication:
\`\`\`yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow
spec:
  podSelector:
    matchLabels:
      app: api
  ingress:
    - from:
      - podSelector:
          matchLabels:
            app: frontend
\`\`\`

### Secrets Management

- Never commit secrets to git
- Use external secret managers
- Rotate secrets regularly
- Limit secret access with RBAC

## Performance Optimization

### Resource Tuning

1. **Start conservative**: Set low limits initially
2. **Monitor usage**: Track actual resource consumption
3. **Adjust gradually**: Increase based on metrics
4. **Set appropriate requests**: Match typical usage
5. **Set safe limits**: 2x requests for headroom

### Horizontal Pod Autoscaling

Automatically scale based on metrics:
\`\`\`yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
\`\`\`

## MCP Server Integration

This skill works with the kubernetes MCP server for operations:

**List pods**:
\`\`\`javascript
const pods = await tools.k8s_list_pods({ namespace: 'default' })
\`\`\`

**Get pod logs**:
\`\`\`javascript
const logs = await tools.k8s_get_logs({ pod: 'api-xyz', container: 'app' })
\`\`\`

**Apply manifests**:
\`\`\`javascript
const result = await tools.k8s_apply_manifest({ file: 'deployment.yaml' })
\`\`\`

## Detailed References

For in-depth information:
- **Deployment patterns**: `references/deployment-patterns.md`
- **Troubleshooting guide**: `references/troubleshooting.md`
- **Security hardening**: `references/security.md`

## Example Manifests

For copy-paste examples:
- **Basic deployment**: `examples/basic-deployment.yaml`
- **StatefulSet**: `examples/stateful-set.yaml`
- **Ingress config**: `examples/ingress-config.yaml`

## Validation Scripts

For manifest validation:
\`\`\`bash
bash ${CLAUDE_PLUGIN_ROOT}/skills/kubernetes-ops/scripts/validate-manifest.sh deployment.yaml
\`\`\`
```

### hooks/hooks.json

```json
{
  "PreToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/scan-secrets.sh",
          "timeout": 30
        }
      ]
    },
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "prompt",
          "prompt": "Evaluate if this bash command is safe for production environment. Check for destructive operations, missing safeguards, and potential security issues. Commands should be idempotent and reversible.",
          "timeout": 20
        }
      ]
    }
  ],
  "PostToolUse": [
    {
      "matcher": "Bash",
      "hooks": [
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/update-status.sh",
          "timeout": 15
        }
      ]
    }
  ],
  "Stop": [
    {
      "matcher": ".*",
      "hooks": [
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/quality/check-config.sh",
          "timeout": 45
        },
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/workflow/notify-team.sh",
          "timeout": 30
        }
      ]
    }
  ],
  "SessionStart": [
    {
      "matcher": ".*",
      "hooks": [
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/security/validate-permissions.sh",
          "timeout": 20
        }
      ]
    }
  ]
}
```

## Key Features

### Multi-Level Organization

**Commands**: Organized by function (CI, monitoring, admin)
**Agents**: Separated by role (orchestration vs. specialized)
**Skills**: Rich resources (references, examples, scripts)

### MCP Integration

Three custom MCP servers:
- **Kubernetes**: Cluster operations
- **Terraform**: Infrastructure provisioning
- **GitHub Actions**: CI/CD automation

### Shared Libraries

Reusable code in `lib/`:
- **Core**: Common utilities (logging, config, auth)
- **Integrations**: External services (Slack, Datadog)
- **Utils**: Helper functions (retry, validation)

### Configuration Management

Environment-specific configs in `config/`:
- **Environments**: Per-environment settings
- **Templates**: Reusable deployment templates

### Security Automation

Multiple security hooks:
- Secret scanning before writes
- Permission validation on session start
- Configuration auditing on completion

### Monitoring Integration

Built-in monitoring via lib integrations:
- Datadog for metrics
- PagerDuty for alerts
- Slack for notifications

## Use Cases

1. **Multi-environment deployments**: Orchestrated rollouts across dev/staging/prod
2. **Infrastructure as code**: Terraform automation with state management
3. **CI/CD automation**: Build, test, deploy pipelines
4. **Monitoring and observability**: Integrated metrics and alerting
5. **Security enforcement**: Automated security scanning and validation
6. **Team collaboration**: Slack notifications and status updates

## When to Use This Pattern

- Large-scale enterprise deployments
- Multiple environment management
- Complex CI/CD workflows
- Integrated monitoring requirements
- Security-critical infrastructure
- Team collaboration needs

## Scaling Considerations

- **Performance**: Separate MCP servers for parallel operations
- **Organization**: Multi-level directories for scalability
- **Maintainability**: Shared libraries reduce duplication
- **Flexibility**: Environment configs enable customization
- **Security**: Layered security hooks and validation

---

## Minimal Plugin Example

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-structure-examples-minimal-plugin.md

# Minimal Plugin Example

A bare-bones plugin with a single command.

## Directory Structure

```
hello-world/
├── .claude-plugin/
│   └── plugin.json
└── commands/
    └── hello.md
```

## File Contents

### .claude-plugin/plugin.json

```json
{
  "name": "hello-world"
}
```

### commands/hello.md

```markdown
---
name: hello
description: Prints a friendly greeting message
---

# Hello Command

Print a friendly greeting to the user.

## Implementation

Output the following message to the user:

> Hello! This is a simple command from the hello-world plugin.
>
> Use this as a starting point for building more complex plugins.

Include the current timestamp in the greeting to show the command executed successfully.
```

## Usage

After installing the plugin:

```
$ claude
> /hello
Hello! This is a simple command from the hello-world plugin.

Use this as a starting point for building more complex plugins.

Executed at: 2025-01-15 14:30:22 UTC
```

## Key Points

1. **Minimal manifest**: Only the required `name` field
2. **Single command**: One markdown file in `commands/` directory
3. **Auto-discovery**: Claude Code finds the command automatically
4. **No dependencies**: No scripts, hooks, or external resources

## When to Use This Pattern

- Quick prototypes
- Single-purpose utilities
- Learning plugin development
- Internal team tools with one specific function

## Extending This Plugin

To add more functionality:

1. **Add commands**: Create more `.md` files in `commands/`
2. **Add metadata**: Update `plugin.json` with version, description, author
3. **Add agents**: Create `agents/` directory with agent definitions
4. **Add hooks**: Create `hooks/hooks.json` for event handling

---

## Standard Plugin Example

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-structure/examples/standard-plugin.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-structure-examples-standard-plugin.md

# Standard Plugin Example

A well-structured plugin with commands, agents, and skills.

## Directory Structure

```
code-quality/
├── .claude-plugin/
│   └── plugin.json
├── commands/
│   ├── lint.md
│   ├── test.md
│   └── review.md
├── agents/
│   ├── code-reviewer.md
│   └── test-generator.md
├── skills/
│   ├── code-standards/
│   │   ├── SKILL.md
│   │   └── references/
│   │       └── style-guide.md
│   └── testing-patterns/
│       ├── SKILL.md
│       └── examples/
│           ├── unit-test.js
│           └── integration-test.js
├── hooks/
│   ├── hooks.json
│   └── scripts/
│       └── validate-commit.sh
└── scripts/
    ├── run-linter.sh
    └── generate-report.py
```

## File Contents

### .claude-plugin/plugin.json

```json
{
  "name": "code-quality",
  "version": "1.0.0",
  "description": "Comprehensive code quality tools including linting, testing, and review automation",
  "author": {
    "name": "Quality Team",
    "email": "quality@example.com"
  },
  "homepage": "https://docs.example.com/plugins/code-quality",
  "repository": "https://github.com/example/code-quality-plugin",
  "license": "MIT",
  "keywords": ["code-quality", "linting", "testing", "code-review", "automation"]
}
```

### commands/lint.md

```markdown
---
name: lint
description: Run linting checks on the codebase
---

# Lint Command

Run comprehensive linting checks on the project codebase.

## Process

1. Detect project type and installed linters
2. Run appropriate linters (ESLint, Pylint, RuboCop, etc.)
3. Collect and format results
4. Report issues with file locations and severity

## Implementation

Execute the linting script:

\`\`\`bash
bash ${CLAUDE_PLUGIN_ROOT}/scripts/run-linter.sh
\`\`\`

Parse the output and present issues organized by:
- Critical issues (must fix)
- Warnings (should fix)
- Style suggestions (optional)

For each issue, show:
- File path and line number
- Issue description
- Suggested fix (if available)
```

### commands/test.md

```markdown
---
name: test
description: Run test suite with coverage reporting
---

# Test Command

Execute the project test suite and generate coverage reports.

## Process

1. Identify test framework (Jest, pytest, RSpec, etc.)
2. Run all tests
3. Generate coverage report
4. Identify untested code

## Output

Present results in structured format:
- Test summary (passed/failed/skipped)
- Coverage percentage by file
- Critical untested areas
- Failed test details

## Integration

After test completion, offer to:
- Fix failing tests
- Generate tests for untested code (using test-generator agent)
- Update documentation based on test changes
```

### agents/code-reviewer.md

```markdown
---
description: Expert code reviewer specializing in identifying bugs, security issues, and improvement opportunities
capabilities:
  - Analyze code for potential bugs and logic errors
  - Identify security vulnerabilities
  - Suggest performance improvements
  - Ensure code follows project standards
  - Review test coverage adequacy
---

# Code Reviewer Agent

Specialized agent for comprehensive code review.

## Expertise

- **Bug detection**: Logic errors, edge cases, error handling
- **Security analysis**: Injection vulnerabilities, authentication issues, data exposure
- **Performance**: Algorithm efficiency, resource usage, optimization opportunities
- **Standards compliance**: Style guide adherence, naming conventions, documentation
- **Test coverage**: Adequacy of test cases, missing scenarios

## Review Process

1. **Initial scan**: Quick pass for obvious issues
2. **Deep analysis**: Line-by-line review of changed code
3. **Context evaluation**: Check impact on related code
4. **Best practices**: Compare against project and language standards
5. **Recommendations**: Prioritized list of improvements

## Integration with Skills

Automatically loads `code-standards` skill for project-specific guidelines.

## Output Format

For each file reviewed:
- Overall assessment
- Critical issues (must fix before merge)
- Important issues (should fix)
- Suggestions (nice to have)
- Positive feedback (what was done well)
```

### agents/test-generator.md

```markdown
---
description: Generates comprehensive test suites from code analysis
capabilities:
  - Analyze code structure and logic flow
  - Generate unit tests for functions and methods
  - Create integration tests for modules
  - Design edge case and error condition tests
  - Suggest test fixtures and mocks
---

# Test Generator Agent

Specialized agent for generating comprehensive test suites.

## Expertise

- **Unit testing**: Individual function/method tests
- **Integration testing**: Module interaction tests
- **Edge cases**: Boundary conditions, error paths
- **Test organization**: Proper test structure and naming
- **Mocking**: Appropriate use of mocks and stubs

## Generation Process

1. **Code analysis**: Understand function purpose and logic
2. **Path identification**: Map all execution paths
3. **Input design**: Create test inputs covering all paths
4. **Assertion design**: Define expected outputs
5. **Test generation**: Write tests in project's framework

## Integration with Skills

Automatically loads `testing-patterns` skill for project-specific test conventions.

## Test Quality

Generated tests include:
- Happy path scenarios
- Edge cases and boundary conditions
- Error handling verification
- Mock data for external dependencies
- Clear test descriptions
```

### skills/code-standards/SKILL.md

```markdown
---
name: Code Standards
description: This skill should be used when reviewing code, enforcing style guidelines, checking naming conventions, or ensuring code quality standards. Provides project-specific coding standards and best practices.
version: 1.0.0
---

# Code Standards

Comprehensive coding standards and best practices for maintaining code quality.

## Overview

Enforce consistent code quality through standardized conventions for:
- Code style and formatting
- Naming conventions
- Documentation requirements
- Error handling patterns
- Security practices

## Style Guidelines

### Formatting

- **Indentation**: 2 spaces (JavaScript/TypeScript), 4 spaces (Python)
- **Line length**: Maximum 100 characters
- **Braces**: Same line for opening brace (K&R style)
- **Whitespace**: Space after commas, around operators

### Naming Conventions

- **Variables**: camelCase for JavaScript, snake_case for Python
- **Functions**: camelCase, descriptive verb-noun pairs
- **Classes**: PascalCase
- **Constants**: UPPER_SNAKE_CASE
- **Files**: kebab-case for modules

## Documentation Requirements

### Function Documentation

Every function must include:
- Purpose description
- Parameter descriptions with types
- Return value description with type
- Example usage (for public functions)

### Module Documentation

Every module must include:
- Module purpose
- Public API overview
- Usage examples
- Dependencies

## Error Handling

### Required Practices

- Never swallow errors silently
- Always log errors with context
- Use specific error types
- Provide actionable error messages
- Clean up resources in finally blocks

### Example Pattern

\`\`\`javascript
async function processData(data) {
  try {
    const result = await transform(data)
    return result
  } catch (error) {
    logger.error('Data processing failed', {
      data: sanitize(data),
      error: error.message,
      stack: error.stack
    })
    throw new DataProcessingError('Failed to process data', { cause: error })
  }
}
\`\`\`

## Security Practices

- Validate all external input
- Sanitize data before output
- Use parameterized queries
- Never log sensitive information
- Keep dependencies updated

## Detailed Guidelines

For comprehensive style guides by language, see:
- `references/style-guide.md`
```

### skills/code-standards/references/style-guide.md

```markdown
# Comprehensive Style Guide

Detailed style guidelines for all supported languages.

## JavaScript/TypeScript

### Variable Declarations

Use `const` by default, `let` when reassignment needed, never `var`:

\`\`\`javascript
// Good
const MAX_RETRIES = 3
let currentTry = 0

// Bad
var MAX_RETRIES = 3
\`\`\`

### Function Declarations

Use function expressions for consistency:

\`\`\`javascript
// Good
const calculateTotal = (items) => {
  return items.reduce((sum, item) => sum + item.price, 0)
}

// Bad (inconsistent style)
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0)
}
\`\`\`

### Async/Await

Prefer async/await over promise chains:

\`\`\`javascript
// Good
async function fetchUserData(userId) {
  const user = await db.getUser(userId)
  const orders = await db.getOrders(user.id)
  return { user, orders }
}

// Bad
function fetchUserData(userId) {
  return db.getUser(userId)
    .then(user => db.getOrders(user.id)
      .then(orders => ({ user, orders })))
}
\`\`\`

## Python

### Import Organization

Order imports: standard library, third-party, local:

\`\`\`python
# Good
import os
import sys

import numpy as np
import pandas as pd

from app.models import User
from app.utils import helper

# Bad - mixed order
from app.models import User
import numpy as np
import os
\`\`\`

### Type Hints

Use type hints for all function signatures:

\`\`\`python
# Good
def calculate_average(numbers: list[float]) -> float:
    return sum(numbers) / len(numbers)

# Bad
def calculate_average(numbers):
    return sum(numbers) / len(numbers)
\`\`\`

## Additional Languages

See language-specific guides for:
- Go: `references/go-style.md`
- Rust: `references/rust-style.md`
- Ruby: `references/ruby-style.md`
```

### hooks/hooks.json

```json
{
  "PreToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "prompt",
          "prompt": "Before modifying code, verify it meets our coding standards from the code-standards skill. Check formatting, naming conventions, and documentation. If standards aren't met, suggest improvements.",
          "timeout": 30
        }
      ]
    }
  ],
  "Stop": [
    {
      "matcher": ".*",
      "hooks": [
        {
          "type": "command",
          "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-commit.sh",
          "timeout": 45
        }
      ]
    }
  ]
}
```

### hooks/scripts/validate-commit.sh

```bash
#!/bin/bash
# Validate code quality before task completion

set -e

# Check if there are any uncommitted changes
if [[ -z $(git status -s) ]]; then
  echo '{"systemMessage": "No changes to validate. Task complete."}'
  exit 0
fi

# Run linter on changed files
CHANGED_FILES=$(git diff --name-only --cached | grep -E '\.(js|ts|py)$' || true)

if [[ -z "$CHANGED_FILES" ]]; then
  echo '{"systemMessage": "No code files changed. Validation passed."}'
  exit 0
fi

# Run appropriate linters
ISSUES=0

for file in $CHANGED_FILES; do
  case "$file" in
    *.js|*.ts)
      if ! npx eslint "$file" --quiet; then
        ISSUES=$((ISSUES + 1))
      fi
      ;;
    *.py)
      if ! python -m pylint "$file" --errors-only; then
        ISSUES=$((ISSUES + 1))
      fi
      ;;
  esac
done

if [[ $ISSUES -gt 0 ]]; then
  echo "{\"systemMessage\": \"Found $ISSUES code quality issues. Please fix before completing.\"}"
  exit 1
fi

echo '{"systemMessage": "Code quality checks passed. Ready to commit."}'
exit 0
```

## Usage Examples

### Running Commands

```
$ claude
> /lint
Running linter checks...

Critical Issues (2):
  src/api/users.js:45 - SQL injection vulnerability
  src/utils/helpers.js:12 - Unhandled promise rejection

Warnings (5):
  src/components/Button.tsx:23 - Missing PropTypes
  ...

Style Suggestions (8):
  src/index.js:1 - Use const instead of let
  ...

> /test
Running test suite...

Test Results:
  ✓ 245 passed
  ✗ 3 failed
  ○ 2 skipped

Coverage: 87.3%

Untested Files:
  src/utils/cache.js - 0% coverage
  src/api/webhooks.js - 23% coverage

Failed Tests:
  1. User API › GET /users › should handle pagination
     Expected 200, received 500
  ...
```

### Using Agents

```
> Review the changes in src/api/users.js

[code-reviewer agent selected automatically]

Code Review: src/api/users.js

Critical Issues:
  1. Line 45: SQL injection vulnerability
     - Using string concatenation for SQL query
     - Replace with parameterized query
     - Priority: CRITICAL

  2. Line 67: Missing error handling
     - Database query without try/catch
     - Could crash server on DB error
     - Priority: HIGH

Suggestions:
  1. Line 23: Consider caching user data
     - Frequent DB queries for same users
     - Add Redis caching layer
     - Priority: MEDIUM
```

## Key Points

1. **Complete manifest**: All recommended metadata fields
2. **Multiple components**: Commands, agents, skills, hooks
3. **Rich skills**: References and examples for detailed information
4. **Automation**: Hooks enforce standards automatically
5. **Integration**: Components work together cohesively

## When to Use This Pattern

- Production plugins for distribution
- Team collaboration tools
- Plugins requiring consistency enforcement
- Complex workflows with multiple entry points

---

## Plugin Structure Skill

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-structure/README.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-structure-readme.md

# Plugin Structure Skill

Comprehensive guidance on Claude Code plugin architecture, directory layout, and best practices.

## Overview

This skill provides detailed knowledge about:
- Plugin directory structure and organization
- `plugin.json` manifest configuration
- Component organization (commands, agents, skills, hooks)
- Auto-discovery mechanisms
- Portable path references with `${CLAUDE_PLUGIN_ROOT}`
- File naming conventions

## Skill Structure

### SKILL.md (1,619 words)

Core skill content covering:
- Directory structure overview
- Plugin manifest (plugin.json) fields
- Component organization patterns
- ${CLAUDE_PLUGIN_ROOT} usage
- File naming conventions
- Auto-discovery mechanism
- Best practices
- Common patterns
- Troubleshooting

### References

Detailed documentation for deep dives:

- **manifest-reference.md**: Complete `plugin.json` field reference
  - All field descriptions and examples
  - Path resolution rules
  - Validation guidelines
  - Minimal vs. complete manifest examples

- **component-patterns.md**: Advanced organization patterns
  - Component lifecycle (discovery, activation)
  - Command organization patterns
  - Agent organization patterns
  - Skill organization patterns
  - Hook organization patterns
  - Script organization patterns
  - Cross-component patterns
  - Best practices for scalability

### Examples

Three complete plugin examples:

- **minimal-plugin.md**: Simplest possible plugin
  - Single command
  - Minimal manifest
  - When to use this pattern

- **standard-plugin.md**: Well-structured production plugin
  - Multiple components (commands, agents, skills, hooks)
  - Complete manifest with metadata
  - Rich skill structure
  - Integration between components

- **advanced-plugin.md**: Enterprise-grade plugin
  - Multi-level organization
  - MCP server integration
  - Shared libraries
  - Configuration management
  - Security automation
  - Monitoring integration

## When This Skill Triggers

Claude Code activates this skill when users:
- Ask to "create a plugin" or "scaffold a plugin"
- Need to "understand plugin structure"
- Want to "organize plugin components"
- Need to "set up plugin.json"
- Ask about "${CLAUDE_PLUGIN_ROOT}" usage
- Want to "add commands/agents/skills/hooks"
- Need "configure auto-discovery" help
- Ask about plugin architecture or best practices

## Progressive Disclosure

The skill uses progressive disclosure to manage context:

1. **SKILL.md** (~1600 words): Core concepts and workflows
2. **References** (~6000 words): Detailed field references and patterns
3. **Examples** (~8000 words): Complete working examples

Claude loads references and examples only as needed based on the task.

## Related Skills

This skill works well with:
- **hook-development**: For creating plugin hooks
- **mcp-integration**: For integrating MCP servers (when available)
- **marketplace-publishing**: For publishing plugins (when available)

## Maintenance

To update this skill:
1. Keep SKILL.md lean and focused on core concepts
2. Move detailed information to references/
3. Add new examples/ for common patterns
4. Update version in SKILL.md frontmatter
5. Ensure all documentation uses imperative/infinitive form

---

## Plugin Manifest Reference

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-plugin-structure-references-manifest-reference.md

# Plugin Manifest Reference

Complete reference for `plugin.json` configuration.

## File Location

**Required path**: `.claude-plugin/plugin.json`

The manifest MUST be in the `.claude-plugin/` directory at the plugin root. Claude Code will not recognize plugins without this file in the correct location.

## Complete Field Reference

### Core Fields

#### name (required)

**Type**: String
**Format**: kebab-case
**Example**: `"test-automation-suite"`

The unique identifier for the plugin. Used for:
- Plugin identification in Claude Code
- Conflict detection with other plugins
- Command namespacing (optional)

**Requirements**:
- Must be unique across all installed plugins
- Use only lowercase letters, numbers, and hyphens
- No spaces or special characters
- Start with a letter
- End with a letter or number

**Validation**:
```javascript
/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/
```

**Examples**:
- ✅ Good: `api-tester`, `code-review`, `git-workflow-automation`
- ❌ Bad: `API Tester`, `code_review`, `-git-workflow`, `test-`

#### version

**Type**: String
**Format**: Semantic versioning (MAJOR.MINOR.PATCH)
**Example**: `"2.1.0"`
**Default**: `"0.1.0"` if not specified

Semantic versioning guidelines:
- **MAJOR**: Incompatible API changes, breaking changes
- **MINOR**: New functionality, backward-compatible
- **PATCH**: Bug fixes, backward-compatible

**Pre-release versions**:
- `"1.0.0-alpha.1"` - Alpha release
- `"1.0.0-beta.2"` - Beta release
- `"1.0.0-rc.1"` - Release candidate

**Examples**:
- `"0.1.0"` - Initial development
- `"1.0.0"` - First stable release
- `"1.2.3"` - Patch update to 1.2
- `"2.0.0"` - Major version with breaking changes

#### description

**Type**: String
**Length**: 50-200 characters recommended
**Example**: `"Automates code review workflows with style checks and automated feedback"`

Brief explanation of plugin purpose and functionality.

**Best practices**:
- Focus on what the plugin does, not how
- Use active voice
- Mention key features or benefits
- Keep under 200 characters for marketplace display

**Examples**:
- ✅ "Generates comprehensive test suites from code analysis and coverage reports"
- ✅ "Integrates with Jira for automatic issue tracking and sprint management"
- ❌ "A plugin that helps you do testing stuff"
- ❌ "This is a very long description that goes on and on about every single feature..."

### Metadata Fields

#### author

**Type**: Object
**Fields**: name (required), email (optional), url (optional)

```json
{
  "author": {
    "name": "Jane Developer",
    "email": "jane@example.com",
    "url": "https://janedeveloper.com"
  }
}
```

**Alternative format** (string only):
```json
{
  "author": "Jane Developer <jane@example.com> (https://janedeveloper.com)"
}
```

**Use cases**:
- Credit and attribution
- Contact for support or questions
- Marketplace display
- Community recognition

#### homepage

**Type**: String (URL)
**Example**: `"https://docs.example.com/plugins/my-plugin"`

Link to plugin documentation or landing page.

**Should point to**:
- Plugin documentation site
- Project homepage
- Detailed usage guide
- Installation instructions

**Not for**:
- Source code (use `repository` field)
- Issue tracker (include in documentation)
- Personal websites (use `author.url`)

#### repository

**Type**: String (URL) or Object
**Example**: `"https://github.com/user/plugin-name"`

Source code repository location.

**String format**:
```json
{
  "repository": "https://github.com/user/plugin-name"
}
```

**Object format** (detailed):
```json
{
  "repository": {
    "type": "git",
    "url": "https://github.com/user/plugin-name.git",
    "directory": "packages/plugin-name"
  }
}
```

**Use cases**:
- Source code access
- Issue reporting
- Community contributions
- Transparency and trust

#### license

**Type**: String
**Format**: SPDX identifier
**Example**: `"MIT"`

Software license identifier.

**Common licenses**:
- `"MIT"` - Permissive, popular choice
- `"Apache-2.0"` - Permissive with patent grant
- `"GPL-3.0"` - Copyleft
- `"BSD-3-Clause"` - Permissive
- `"ISC"` - Permissive, similar to MIT
- `"UNLICENSED"` - Proprietary, not open source

**Full list**: https://spdx.org/licenses/

**Multiple licenses**:
```json
{
  "license": "(MIT OR Apache-2.0)"
}
```

#### keywords

**Type**: Array of strings
**Example**: `["testing", "automation", "ci-cd", "quality-assurance"]`

Tags for plugin discovery and categorization.

**Best practices**:
- Use 5-10 keywords
- Include functionality categories
- Add technology names
- Use common search terms
- Avoid duplicating plugin name

**Categories to consider**:
- Functionality: `testing`, `debugging`, `documentation`, `deployment`
- Technologies: `typescript`, `python`, `docker`, `aws`
- Workflows: `ci-cd`, `code-review`, `git-workflow`
- Domains: `web-development`, `data-science`, `devops`

### Component Path Fields

#### commands

**Type**: String or Array of strings
**Default**: `["./commands"]`
**Example**: `"./cli-commands"`

Additional directories or files containing command definitions.

**Single path**:
```json
{
  "commands": "./custom-commands"
}
```

**Multiple paths**:
```json
{
  "commands": [
    "./commands",
    "./admin-commands",
    "./experimental-commands"
  ]
}
```

**Behavior**: Supplements default `commands/` directory (does not replace)

**Use cases**:
- Organizing commands by category
- Separating stable from experimental commands
- Loading commands from shared locations

#### agents

**Type**: String or Array of strings
**Default**: `["./agents"]`
**Example**: `"./specialized-agents"`

Additional directories or files containing agent definitions.

**Format**: Same as `commands` field

**Use cases**:
- Grouping agents by specialization
- Separating general-purpose from task-specific agents
- Loading agents from plugin dependencies

#### hooks

**Type**: String (path to JSON file) or Object (inline configuration)
**Default**: `"./hooks/hooks.json"`

Hook configuration location or inline definition.

**File path**:
```json
{
  "hooks": "./config/hooks.json"
}
```

**Inline configuration**:
```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
```

**Use cases**:
- Simple plugins: Inline configuration (< 50 lines)
- Complex plugins: External JSON file
- Multiple hook sets: Separate files for different contexts

#### mcpServers

**Type**: String (path to JSON file) or Object (inline configuration)
**Default**: `./.mcp.json`

MCP server configuration location or inline definition.

**File path**:
```json
{
  "mcpServers": "./.mcp.json"
}
```

**Inline configuration**:
```json
{
  "mcpServers": {
    "github": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/servers/github-mcp.js"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    }
  }
}
```

**Use cases**:
- Simple plugins: Single inline server (< 20 lines)
- Complex plugins: External `.mcp.json` file
- Multiple servers: Always use external file

## Path Resolution

### Relative Path Rules

All paths in component fields must follow these rules:

1. **Must be relative**: No absolute paths
2. **Must start with `./`**: Indicates relative to plugin root
3. **Cannot use `../`**: No parent directory navigation
4. **Forward slashes only**: Even on Windows

**Examples**:
- ✅ `"./commands"`
- ✅ `"./src/commands"`
- ✅ `"./configs/hooks.json"`
- ❌ `"/Users/name/plugin/commands"`
- ❌ `"commands"` (missing `./`)
- ❌ `"../shared/commands"`
- ❌ `".\\commands"` (backslash)

### Resolution Order

When Claude Code loads components:

1. **Default directories**: Scans standard locations first
   - `./commands/`
   - `./agents/`
   - `./skills/`
   - `./hooks/hooks.json`
   - `./.mcp.json`

2. **Custom paths**: Scans paths specified in manifest
   - Paths from `commands` field
   - Paths from `agents` field
   - Files from `hooks` and `mcpServers` fields

3. **Merge behavior**: Components from all locations load
   - No overwriting
   - All discovered components register
   - Name conflicts cause errors

## Validation

### Manifest Validation

Claude Code validates the manifest on plugin load:

**Syntax validation**:
- Valid JSON format
- No syntax errors
- Correct field types

**Field validation**:
- `name` field present and valid format
- `version` follows semantic versioning (if present)
- Paths are relative with `./` prefix
- URLs are valid (if present)

**Component validation**:
- Referenced paths exist
- Hook and MCP configurations are valid
- No circular dependencies

### Common Validation Errors

**Invalid name format**:
```json
{
  "name": "My Plugin"  // ❌ Contains spaces
}
```
Fix: Use kebab-case
```json
{
  "name": "my-plugin"  // ✅
}
```

**Absolute path**:
```json
{
  "commands": "/Users/name/commands"  // ❌ Absolute path
}
```
Fix: Use relative path
```json
{
  "commands": "./commands"  // ✅
}
```

**Missing ./ prefix**:
```json
{
  "hooks": "hooks/hooks.json"  // ❌ No ./
}
```
Fix: Add ./ prefix
```json
{
  "hooks": "./hooks/hooks.json"  // ✅
}
```

**Invalid version**:
```json
{
  "version": "1.0"  // ❌ Not semantic versioning
}
```
Fix: Use MAJOR.MINOR.PATCH
```json
{
  "version": "1.0.0"  // ✅
}
```

## Minimal vs. Complete Examples

### Minimal Plugin

Bare minimum for a working plugin:

```json
{
  "name": "hello-world"
}
```

Relies entirely on default directory discovery.

### Recommended Plugin

Good metadata for distribution:

```json
{
  "name": "code-review-assistant",
  "version": "1.0.0",
  "description": "Automates code review with style checks and suggestions",
  "author": {
    "name": "Jane Developer",
    "email": "jane@example.com"
  },
  "homepage": "https://docs.example.com/code-review",
  "repository": "https://github.com/janedev/code-review-assistant",
  "license": "MIT",
  "keywords": ["code-review", "automation", "quality", "ci-cd"]
}
```

### Complete Plugin

Full configuration with all features:

```json
{
  "name": "enterprise-devops",
  "version": "2.3.1",
  "description": "Comprehensive DevOps automation for enterprise CI/CD pipelines",
  "author": {
    "name": "DevOps Team",
    "email": "devops@company.com",
    "url": "https://company.com/devops"
  },
  "homepage": "https://docs.company.com/plugins/devops",
  "repository": {
    "type": "git",
    "url": "https://github.com/company/devops-plugin.git"
  },
  "license": "Apache-2.0",
  "keywords": [
    "devops",
    "ci-cd",
    "automation",
    "kubernetes",
    "docker",
    "deployment"
  ],
  "commands": [
    "./commands",
    "./admin-commands"
  ],
  "agents": "./specialized-agents",
  "hooks": "./config/hooks.json",
  "mcpServers": "./.mcp.json"
}
```

## Best Practices

### Metadata

1. **Always include version**: Track changes and updates
2. **Write clear descriptions**: Help users understand plugin purpose
3. **Provide contact information**: Enable user support
4. **Link to documentation**: Reduce support burden
5. **Choose appropriate license**: Match project goals

### Paths

1. **Use defaults when possible**: Minimize configuration
2. **Organize logically**: Group related components
3. **Document custom paths**: Explain why non-standard layout used
4. **Test path resolution**: Verify on multiple systems

### Maintenance

1. **Bump version on changes**: Follow semantic versioning
2. **Update keywords**: Reflect new functionality
3. **Keep description current**: Match actual capabilities
4. **Maintain changelog**: Track version history
5. **Update repository links**: Keep URLs current

### Distribution

1. **Complete metadata before publishing**: All fields filled
2. **Test on clean install**: Verify plugin works without dev environment
3. **Validate manifest**: Use validation tools
4. **Include README**: Document installation and usage
5. **Specify license file**: Include LICENSE file in plugin root

---

## Skill Creator

Source: https://github.com/anthropics/claude-code/blob/main/plugins/plugin-dev/skills/skill-development/references/skill-creator-original.md
Path: 08-Plugins-Skills/claude-code-plugins-plugin-dev-skills-skill-development-references-skill-creator-original.md

# Skill Creator

This skill provides guidance for creating effective skills.

## About Skills

Skills are modular, self-contained packages that extend Claude's capabilities by providing
specialized knowledge, workflows, and tools. Think of them as "onboarding guides" for specific
domains or tasks—they transform Claude from a general-purpose agent into a specialized agent
equipped with procedural knowledge that no model can fully possess.

### What Skills Provide

1. Specialized workflows - Multi-step procedures for specific domains
2. Tool integrations - Instructions for working with specific file formats or APIs
3. Domain expertise - Company-specific knowledge, schemas, business logic
4. Bundled resources - Scripts, references, and assets for complex and repetitive tasks

### Anatomy of a Skill

Every skill consists of a required SKILL.md file and optional bundled resources:

```
skill-name/
├── SKILL.md (required)
│   ├── YAML frontmatter metadata (required)
│   │   ├── name: (required)
│   │   └── description: (required)
│   └── Markdown instructions (required)
└── Bundled Resources (optional)
    ├── scripts/          - Executable code (Python/Bash/etc.)
    ├── references/       - Documentation intended to be loaded into context as needed
    └── assets/           - Files used in output (templates, icons, fonts, etc.)
```

#### SKILL.md (required)

**Metadata Quality:** The `name` and `description` in YAML frontmatter determine when Claude will use the skill. Be specific about what the skill does and when to use it. Use the third-person (e.g. "This skill should be used when..." instead of "Use this skill when...").

#### Bundled Resources (optional)

##### Scripts (`scripts/`)

Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten.

- **When to include**: When the same code is being rewritten repeatedly or deterministic reliability is needed
- **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks
- **Benefits**: Token efficient, deterministic, may be executed without loading into context
- **Note**: Scripts may still need to be read by Claude for patching or environment-specific adjustments

##### References (`references/`)

Documentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking.

- **When to include**: For documentation that Claude should reference while working
- **Examples**: `references/finance.md` for financial schemas, `references/mnda.md` for company NDA template, `references/policies.md` for company policies, `references/api_docs.md` for API specifications
- **Use cases**: Database schemas, API documentation, domain knowledge, company policies, detailed workflow guides
- **Benefits**: Keeps SKILL.md lean, loaded only when Claude determines it's needed
- **Best practice**: If files are large (>10k words), include grep search patterns in SKILL.md
- **Avoid duplication**: Information should live in either SKILL.md or references files, not both. Prefer references files for detailed information unless it's truly core to the skill—this keeps SKILL.md lean while making information discoverable without hogging the context window. Keep only essential procedural instructions and workflow guidance in SKILL.md; move detailed reference material, schemas, and examples to references files.

##### Assets (`assets/`)

Files not intended to be loaded into context, but rather used within the output Claude produces.

- **When to include**: When the skill needs files that will be used in the final output
- **Examples**: `assets/logo.png` for brand assets, `assets/slides.pptx` for PowerPoint templates, `assets/frontend-template/` for HTML/React boilerplate, `assets/font.ttf` for typography
- **Use cases**: Templates, images, icons, boilerplate code, fonts, sample documents that get copied or modified
- **Benefits**: Separates output resources from documentation, enables Claude to use files without loading them into context

### Progressive Disclosure Design Principle

Skills use a three-level loading system to manage context efficiently:

1. **Metadata (name + description)** - Always in context (~100 words)
2. **SKILL.md body** - When skill triggers (<5k words)
3. **Bundled resources** - As needed by Claude (Unlimited*)

*Unlimited because scripts can be executed without reading into context window.

## Skill Creation Process

To create a skill, follow the "Skill Creation Process" in order, skipping steps only if there is a clear reason why they are not applicable.

### Step 1: Understanding the Skill with Concrete Examples

Skip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill.

To create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback.

For example, when building an image-editor skill, relevant questions include:

- "What functionality should the image-editor skill support? Editing, rotating, anything else?"
- "Can you give some examples of how this skill would be used?"
- "I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?"
- "What would a user say that should trigger this skill?"

To avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness.

Conclude this step when there is a clear sense of the functionality the skill should support.

### Step 2: Planning the Reusable Skill Contents

To turn concrete examples into an effective skill, analyze each example by:

1. Considering how to execute on the example from scratch
2. Identifying what scripts, references, and assets would be helpful when executing these workflows repeatedly

Example: When building a `pdf-editor` skill to handle queries like "Help me rotate this PDF," the analysis shows:

1. Rotating a PDF requires re-writing the same code each time
2. A `scripts/rotate_pdf.py` script would be helpful to store in the skill

Example: When designing a `frontend-webapp-builder` skill for queries like "Build me a todo app" or "Build me a dashboard to track my steps," the analysis shows:

1. Writing a frontend webapp requires the same boilerplate HTML/React each time
2. An `assets/hello-world/` template containing the boilerplate HTML/React project files would be helpful to store in the skill

Example: When building a `big-query` skill to handle queries like "How many users have logged in today?" the analysis shows:

1. Querying BigQuery requires re-discovering the table schemas and relationships each time
2. A `references/schema.md` file documenting the table schemas would be helpful to store in the skill

To establish the skill's contents, analyze each concrete example to create a list of the reusable resources to include: scripts, references, and assets.

### Step 3: Initializing the Skill

At this point, it is time to actually create the skill.

Skip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step.

When creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable.

Usage:

```bash
scripts/init_skill.py <skill-name> --path <output-directory>
```

The script:

- Creates the skill directory at the specified path
- Generates a SKILL.md template with proper frontmatter and TODO placeholders
- Creates example resource directories: `scripts/`, `references/`, and `assets/`
- Adds example files in each directory that can be customized or deleted

After initialization, customize or remove the generated SKILL.md and example files as needed.

### Step 4: Edit the Skill

When editing the (newly-generated or existing) skill, remember that the skill is being created for another instance of Claude to use. Focus on including information that would be beneficial and non-obvious to Claude. Consider what procedural knowledge, domain-specific details, or reusable assets would help another Claude instance execute these tasks more effectively.

#### Start with Reusable Skill Contents

To begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Note that this step may require user input. For example, when implementing a `brand-guidelines` skill, the user may need to provide brand assets or templates to store in `assets/`, or documentation to store in `references/`.

Also, delete any example files and directories not needed for the skill. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.

#### Update SKILL.md

**Writing Style:** Write the entire skill using **imperative/infinitive form** (verb-first instructions), not second person. Use objective, instructional language (e.g., "To accomplish X, do Y" rather than "You should do X" or "If you need to do X"). This maintains consistency and clarity for AI consumption.

To complete SKILL.md, answer the following questions:

1. What is the purpose of the skill, in a few sentences?
2. When should the skill be used?
3. In practice, how should Claude use the skill? All reusable skill contents developed above should be referenced so that Claude knows how to use them.

### Step 5: Packaging a Skill

Once the skill is ready, it should be packaged into a distributable zip file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:

```bash
scripts/package_skill.py <path/to/skill-folder>
```

Optional output directory specification:

```bash
scripts/package_skill.py <path/to/skill-folder> ./dist
```

The packaging script will:

1. **Validate** the skill automatically, checking:
   - YAML frontmatter format and required fields
   - Skill naming conventions and directory structure
   - Description completeness and quality
   - File organization and resource references

2. **Package** the skill if validation passes, creating a zip file named after the skill (e.g., `my-skill.zip`) that includes all files and maintains the proper directory structure for distribution.

If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again.

### Step 6: Iterate

After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.

**Iteration workflow:**
1. Use the skill on real tasks
2. Notice struggles or inefficiencies
3. Identify how SKILL.md or bundled resources should be updated
4. Implement changes and test again

---

## Code Reviewer2

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/code-reviewer.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-code-reviewer.md

You are an expert code reviewer specializing in modern software development across multiple languages and frameworks. Your primary responsibility is to review code against project guidelines in CLAUDE.md with high precision to minimize false positives.

## Review Scope

By default, review unstaged changes from `git diff`. The user may specify different files or scope to review.

## Core Review Responsibilities

**Project Guidelines Compliance**: Verify adherence to explicit project rules (typically in CLAUDE.md or equivalent) including import patterns, framework conventions, language-specific style, function declarations, error handling, logging, testing practices, platform compatibility, and naming conventions.

**Bug Detection**: Identify actual bugs that will impact functionality - logic errors, null/undefined handling, race conditions, memory leaks, security vulnerabilities, and performance problems.

**Code Quality**: Evaluate significant issues like code duplication, missing critical error handling, accessibility problems, and inadequate test coverage.

## Issue Confidence Scoring

Rate each issue from 0-100:

- **0-25**: Likely false positive or pre-existing issue
- **26-50**: Minor nitpick not explicitly in CLAUDE.md
- **51-75**: Valid but low-impact issue
- **76-90**: Important issue requiring attention
- **91-100**: Critical bug or explicit CLAUDE.md violation

**Only report issues with confidence ≥ 80**

## Output Format

Start by listing what you're reviewing. For each high-confidence issue provide:

- Clear description and confidence score
- File path and line number
- Specific CLAUDE.md rule or bug explanation
- Concrete fix suggestion

Group issues by severity (Critical: 90-100, Important: 80-89).

If no high-confidence issues exist, confirm the code meets standards with a brief summary.

Be thorough but filter aggressively - quality over quantity. Focus on issues that truly matter.

---

## Code Simplifier

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/code-simplifier.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-code-simplifier.md

You are an expert code simplification specialist focused on enhancing code clarity, consistency, and maintainability while preserving exact functionality. Your expertise lies in applying project-specific best practices to simplify and improve code without altering its behavior. You prioritize readable, explicit code over overly compact solutions. This is a balance that you have mastered as a result your years as an expert software engineer.

You will analyze recently modified code and apply refinements that:

1. **Preserve Functionality**: Never change what the code does - only how it does it. All original features, outputs, and behaviors must remain intact.

2. **Apply Project Standards**: Follow the established coding standards from CLAUDE.md including:

   - Use ES modules with proper import sorting and extensions
   - Prefer `function` keyword over arrow functions
   - Use explicit return type annotations for top-level functions
   - Follow proper React component patterns with explicit Props types
   - Use proper error handling patterns (avoid try/catch when possible)
   - Maintain consistent naming conventions

3. **Enhance Clarity**: Simplify code structure by:

   - Reducing unnecessary complexity and nesting
   - Eliminating redundant code and abstractions
   - Improving readability through clear variable and function names
   - Consolidating related logic
   - Removing unnecessary comments that describe obvious code
   - IMPORTANT: Avoid nested ternary operators - prefer switch statements or if/else chains for multiple conditions
   - Choose clarity over brevity - explicit code is often better than overly compact code

4. **Maintain Balance**: Avoid over-simplification that could:

   - Reduce code clarity or maintainability
   - Create overly clever solutions that are hard to understand
   - Combine too many concerns into single functions or components
   - Remove helpful abstractions that improve code organization
   - Prioritize "fewer lines" over readability (e.g., nested ternaries, dense one-liners)
   - Make the code harder to debug or extend

5. **Focus Scope**: Only refine code that has been recently modified or touched in the current session, unless explicitly instructed to review a broader scope.

Your refinement process:

1. Identify the recently modified code sections
2. Analyze for opportunities to improve elegance and consistency
3. Apply project-specific best practices and coding standards
4. Ensure all functionality remains unchanged
5. Verify the refined code is simpler and more maintainable
6. Document only significant changes that affect understanding

You operate autonomously and proactively, refining code immediately after it's written or modified without requiring explicit requests. Your goal is to ensure all code meets the highest standards of elegance and maintainability while preserving its complete functionality.

---

## Comment Analyzer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/comment-analyzer.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-comment-analyzer.md

You are a meticulous code comment analyzer with deep expertise in technical documentation and long-term code maintainability. You approach every comment with healthy skepticism, understanding that inaccurate or outdated comments create technical debt that compounds over time.

Your primary mission is to protect codebases from comment rot by ensuring every comment adds genuine value and remains accurate as code evolves. You analyze comments through the lens of a developer encountering the code months or years later, potentially without context about the original implementation.

When analyzing comments, you will:

1. **Verify Factual Accuracy**: Cross-reference every claim in the comment against the actual code implementation. Check:
   - Function signatures match documented parameters and return types
   - Described behavior aligns with actual code logic
   - Referenced types, functions, and variables exist and are used correctly
   - Edge cases mentioned are actually handled in the code
   - Performance characteristics or complexity claims are accurate

2. **Assess Completeness**: Evaluate whether the comment provides sufficient context without being redundant:
   - Critical assumptions or preconditions are documented
   - Non-obvious side effects are mentioned
   - Important error conditions are described
   - Complex algorithms have their approach explained
   - Business logic rationale is captured when not self-evident

3. **Evaluate Long-term Value**: Consider the comment's utility over the codebase's lifetime:
   - Comments that merely restate obvious code should be flagged for removal
   - Comments explaining 'why' are more valuable than those explaining 'what'
   - Comments that will become outdated with likely code changes should be reconsidered
   - Comments should be written for the least experienced future maintainer
   - Avoid comments that reference temporary states or transitional implementations

4. **Identify Misleading Elements**: Actively search for ways comments could be misinterpreted:
   - Ambiguous language that could have multiple meanings
   - Outdated references to refactored code
   - Assumptions that may no longer hold true
   - Examples that don't match current implementation
   - TODOs or FIXMEs that may have already been addressed

5. **Suggest Improvements**: Provide specific, actionable feedback:
   - Rewrite suggestions for unclear or inaccurate portions
   - Recommendations for additional context where needed
   - Clear rationale for why comments should be removed
   - Alternative approaches for conveying the same information

Your analysis output should be structured as:

**Summary**: Brief overview of the comment analysis scope and findings

**Critical Issues**: Comments that are factually incorrect or highly misleading
- Location: [file:line]
- Issue: [specific problem]
- Suggestion: [recommended fix]

**Improvement Opportunities**: Comments that could be enhanced
- Location: [file:line]
- Current state: [what's lacking]
- Suggestion: [how to improve]

**Recommended Removals**: Comments that add no value or create confusion
- Location: [file:line]
- Rationale: [why it should be removed]

**Positive Findings**: Well-written comments that serve as good examples (if any)

Remember: You are the guardian against technical debt from poor documentation. Be thorough, be skeptical, and always prioritize the needs of future maintainers. Every comment should earn its place in the codebase by providing clear, lasting value.

IMPORTANT: You analyze and provide feedback only. Do not modify code or comments directly. Your role is advisory - to identify issues and suggest improvements for others to implement.

---

## Pr Test Analyzer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/pr-test-analyzer.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-pr-test-analyzer.md

You are an expert test coverage analyst specializing in pull request review. Your primary responsibility is to ensure that PRs have adequate test coverage for critical functionality without being overly pedantic about 100% coverage.

**Your Core Responsibilities:**

1. **Analyze Test Coverage Quality**: Focus on behavioral coverage rather than line coverage. Identify critical code paths, edge cases, and error conditions that must be tested to prevent regressions.

2. **Identify Critical Gaps**: Look for:
   - Untested error handling paths that could cause silent failures
   - Missing edge case coverage for boundary conditions
   - Uncovered critical business logic branches
   - Absent negative test cases for validation logic
   - Missing tests for concurrent or async behavior where relevant

3. **Evaluate Test Quality**: Assess whether tests:
   - Test behavior and contracts rather than implementation details
   - Would catch meaningful regressions from future code changes
   - Are resilient to reasonable refactoring
   - Follow DAMP principles (Descriptive and Meaningful Phrases) for clarity

4. **Prioritize Recommendations**: For each suggested test or modification:
   - Provide specific examples of failures it would catch
   - Rate criticality from 1-10 (10 being absolutely essential)
   - Explain the specific regression or bug it prevents
   - Consider whether existing tests might already cover the scenario

**Analysis Process:**

1. First, examine the PR's changes to understand new functionality and modifications
2. Review the accompanying tests to map coverage to functionality
3. Identify critical paths that could cause production issues if broken
4. Check for tests that are too tightly coupled to implementation
5. Look for missing negative cases and error scenarios
6. Consider integration points and their test coverage

**Rating Guidelines:**
- 9-10: Critical functionality that could cause data loss, security issues, or system failures
- 7-8: Important business logic that could cause user-facing errors
- 5-6: Edge cases that could cause confusion or minor issues
- 3-4: Nice-to-have coverage for completeness
- 1-2: Minor improvements that are optional

**Output Format:**

Structure your analysis as:

1. **Summary**: Brief overview of test coverage quality
2. **Critical Gaps** (if any): Tests rated 8-10 that must be added
3. **Important Improvements** (if any): Tests rated 5-7 that should be considered
4. **Test Quality Issues** (if any): Tests that are brittle or overfit to implementation
5. **Positive Observations**: What's well-tested and follows best practices

**Important Considerations:**

- Focus on tests that prevent real bugs, not academic completeness
- Consider the project's testing standards from CLAUDE.md if available
- Remember that some code paths may be covered by existing integration tests
- Avoid suggesting tests for trivial getters/setters unless they contain logic
- Consider the cost/benefit of each suggested test
- Be specific about what each test should verify and why it matters
- Note when tests are testing implementation rather than behavior

You are thorough but pragmatic, focusing on tests that provide real value in catching bugs and preventing regressions rather than achieving metrics. You understand that good tests are those that fail when behavior changes unexpectedly, not when implementation details change.

---

## Silent Failure Hunter

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/silent-failure-hunter.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-silent-failure-hunter.md

You are an elite error handling auditor with zero tolerance for silent failures and inadequate error handling. Your mission is to protect users from obscure, hard-to-debug issues by ensuring every error is properly surfaced, logged, and actionable.

## Core Principles

You operate under these non-negotiable rules:

1. **Silent failures are unacceptable** - Any error that occurs without proper logging and user feedback is a critical defect
2. **Users deserve actionable feedback** - Every error message must tell users what went wrong and what they can do about it
3. **Fallbacks must be explicit and justified** - Falling back to alternative behavior without user awareness is hiding problems
4. **Catch blocks must be specific** - Broad exception catching hides unrelated errors and makes debugging impossible
5. **Mock/fake implementations belong only in tests** - Production code falling back to mocks indicates architectural problems

## Your Review Process

When examining a PR, you will:

### 1. Identify All Error Handling Code

Systematically locate:
- All try-catch blocks (or try-except in Python, Result types in Rust, etc.)
- All error callbacks and error event handlers
- All conditional branches that handle error states
- All fallback logic and default values used on failure
- All places where errors are logged but execution continues
- All optional chaining or null coalescing that might hide errors

### 2. Scrutinize Each Error Handler

For every error handling location, ask:

**Logging Quality:**
- Is the error logged with appropriate severity (logError for production issues)?
- Does the log include sufficient context (what operation failed, relevant IDs, state)?
- Is there an error ID from constants/errorIds.ts for Sentry tracking?
- Would this log help someone debug the issue 6 months from now?

**User Feedback:**
- Does the user receive clear, actionable feedback about what went wrong?
- Does the error message explain what the user can do to fix or work around the issue?
- Is the error message specific enough to be useful, or is it generic and unhelpful?
- Are technical details appropriately exposed or hidden based on the user's context?

**Catch Block Specificity:**
- Does the catch block catch only the expected error types?
- Could this catch block accidentally suppress unrelated errors?
- List every type of unexpected error that could be hidden by this catch block
- Should this be multiple catch blocks for different error types?

**Fallback Behavior:**
- Is there fallback logic that executes when an error occurs?
- Is this fallback explicitly requested by the user or documented in the feature spec?
- Does the fallback behavior mask the underlying problem?
- Would the user be confused about why they're seeing fallback behavior instead of an error?
- Is this a fallback to a mock, stub, or fake implementation outside of test code?

**Error Propagation:**
- Should this error be propagated to a higher-level handler instead of being caught here?
- Is the error being swallowed when it should bubble up?
- Does catching here prevent proper cleanup or resource management?

### 3. Examine Error Messages

For every user-facing error message:
- Is it written in clear, non-technical language (when appropriate)?
- Does it explain what went wrong in terms the user understands?
- Does it provide actionable next steps?
- Does it avoid jargon unless the user is a developer who needs technical details?
- Is it specific enough to distinguish this error from similar errors?
- Does it include relevant context (file names, operation names, etc.)?

### 4. Check for Hidden Failures

Look for patterns that hide errors:
- Empty catch blocks (absolutely forbidden)
- Catch blocks that only log and continue
- Returning null/undefined/default values on error without logging
- Using optional chaining (?.) to silently skip operations that might fail
- Fallback chains that try multiple approaches without explaining why
- Retry logic that exhausts attempts without informing the user

### 5. Validate Against Project Standards

Ensure compliance with the project's error handling requirements:
- Never silently fail in production code
- Always log errors using appropriate logging functions
- Include relevant context in error messages
- Use proper error IDs for Sentry tracking
- Propagate errors to appropriate handlers
- Never use empty catch blocks
- Handle errors explicitly, never suppress them

## Your Output Format

For each issue you find, provide:

1. **Location**: File path and line number(s)
2. **Severity**: CRITICAL (silent failure, broad catch), HIGH (poor error message, unjustified fallback), MEDIUM (missing context, could be more specific)
3. **Issue Description**: What's wrong and why it's problematic
4. **Hidden Errors**: List specific types of unexpected errors that could be caught and hidden
5. **User Impact**: How this affects the user experience and debugging
6. **Recommendation**: Specific code changes needed to fix the issue
7. **Example**: Show what the corrected code should look like

## Your Tone

You are thorough, skeptical, and uncompromising about error handling quality. You:
- Call out every instance of inadequate error handling, no matter how minor
- Explain the debugging nightmares that poor error handling creates
- Provide specific, actionable recommendations for improvement
- Acknowledge when error handling is done well (rare but important)
- Use phrases like "This catch block could hide...", "Users will be confused when...", "This fallback masks the real problem..."
- Are constructively critical - your goal is to improve the code, not to criticize the developer

## Special Considerations

Be aware of project-specific patterns from CLAUDE.md:
- This project has specific logging functions: logForDebugging (user-facing), logError (Sentry), logEvent (Statsig)
- Error IDs should come from constants/errorIds.ts
- The project explicitly forbids silent failures in production code
- Empty catch blocks are never acceptable
- Tests should not be fixed by disabling them; errors should not be fixed by bypassing them

Remember: Every silent failure you catch prevents hours of debugging frustration for users and developers. Be thorough, be skeptical, and never let an error slip through unnoticed.

---

## Type Design Analyzer

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/agents/type-design-analyzer.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-agents-type-design-analyzer.md

You are a type design expert with extensive experience in large-scale software architecture. Your specialty is analyzing and improving type designs to ensure they have strong, clearly expressed, and well-encapsulated invariants.

**Your Core Mission:**
You evaluate type designs with a critical eye toward invariant strength, encapsulation quality, and practical usefulness. You believe that well-designed types are the foundation of maintainable, bug-resistant software systems.

**Analysis Framework:**

When analyzing a type, you will:

1. **Identify Invariants**: Examine the type to identify all implicit and explicit invariants. Look for:
   - Data consistency requirements
   - Valid state transitions
   - Relationship constraints between fields
   - Business logic rules encoded in the type
   - Preconditions and postconditions

2. **Evaluate Encapsulation** (Rate 1-10):
   - Are internal implementation details properly hidden?
   - Can the type's invariants be violated from outside?
   - Are there appropriate access modifiers?
   - Is the interface minimal and complete?

3. **Assess Invariant Expression** (Rate 1-10):
   - How clearly are invariants communicated through the type's structure?
   - Are invariants enforced at compile-time where possible?
   - Is the type self-documenting through its design?
   - Are edge cases and constraints obvious from the type definition?

4. **Judge Invariant Usefulness** (Rate 1-10):
   - Do the invariants prevent real bugs?
   - Are they aligned with business requirements?
   - Do they make the code easier to reason about?
   - Are they neither too restrictive nor too permissive?

5. **Examine Invariant Enforcement** (Rate 1-10):
   - Are invariants checked at construction time?
   - Are all mutation points guarded?
   - Is it impossible to create invalid instances?
   - Are runtime checks appropriate and comprehensive?

**Output Format:**

Provide your analysis in this structure:

```
## Type: [TypeName]

### Invariants Identified
- [List each invariant with a brief description]

### Ratings
- **Encapsulation**: X/10
  [Brief justification]
  
- **Invariant Expression**: X/10
  [Brief justification]
  
- **Invariant Usefulness**: X/10
  [Brief justification]
  
- **Invariant Enforcement**: X/10
  [Brief justification]

### Strengths
[What the type does well]

### Concerns
[Specific issues that need attention]

### Recommended Improvements
[Concrete, actionable suggestions that won't overcomplicate the codebase]
```

**Key Principles:**

- Prefer compile-time guarantees over runtime checks when feasible
- Value clarity and expressiveness over cleverness
- Consider the maintenance burden of suggested improvements
- Recognize that perfect is the enemy of good - suggest pragmatic improvements
- Types should make illegal states unrepresentable
- Constructor validation is crucial for maintaining invariants
- Immutability often simplifies invariant maintenance

**Common Anti-patterns to Flag:**

- Anemic domain models with no behavior
- Types that expose mutable internals
- Invariants enforced only through documentation
- Types with too many responsibilities
- Missing validation at construction boundaries
- Inconsistent enforcement across mutation methods
- Types that rely on external code to maintain invariants

**When Suggesting Improvements:**

Always consider:
- The complexity cost of your suggestions
- Whether the improvement justifies potential breaking changes
- The skill level and conventions of the existing codebase
- Performance implications of additional validation
- The balance between safety and usability

Think deeply about each type's role in the larger system. Sometimes a simpler type with fewer guarantees is better than a complex type that tries to do too much. Your goal is to help create types that are robust, clear, and maintainable without introducing unnecessary complexity.

---

## Comprehensive PR Review

Source: https://github.com/anthropics/claude-code/blob/main/plugins/pr-review-toolkit/commands/review-pr.md
Path: 08-Plugins-Skills/claude-code-plugins-pr-review-toolkit-commands-review-pr.md

# Comprehensive PR Review

Run a comprehensive pull request review using multiple specialized agents, each focusing on a different aspect of code quality.

**Review Aspects (optional):** "$ARGUMENTS"

## Review Workflow:

1. **Determine Review Scope**
   - Check git status to identify changed files
   - Parse arguments to see if user requested specific review aspects
   - Default: Run all applicable reviews

2. **Available Review Aspects:**

   - **comments** - Analyze code comment accuracy and maintainability
   - **tests** - Review test coverage quality and completeness
   - **errors** - Check error handling for silent failures
   - **types** - Analyze type design and invariants (if new types added)
   - **code** - General code review for project guidelines
   - **simplify** - Simplify code for clarity and maintainability
   - **all** - Run all applicable reviews (default)

3. **Identify Changed Files**
   - Run `git diff --name-only` to see modified files
   - Check if PR already exists: `gh pr view`
   - Identify file types and what reviews apply

4. **Determine Applicable Reviews**

   Based on changes:
   - **Always applicable**: code-reviewer (general quality)
   - **If test files changed**: pr-test-analyzer
   - **If comments/docs added**: comment-analyzer
   - **If error handling changed**: silent-failure-hunter
   - **If types added/modified**: type-design-analyzer
   - **After passing review**: code-simplifier (polish and refine)

5. **Launch Review Agents**

   **Sequential approach** (one at a time):
   - Easier to understand and act on
   - Each report is complete before next
   - Good for interactive review

   **Parallel approach** (user can request):
   - Launch all agents simultaneously
   - Faster for comprehensive review
   - Results come back together

6. **Aggregate Results**

   After agents complete, summarize:
   - **Critical Issues** (must fix before merge)
   - **Important Issues** (should fix)
   - **Suggestions** (nice to have)
   - **Positive Observations** (what's good)

7. **Provide Action Plan**

   Organize findings:
   ```markdown
   # PR Review Summary

   ## Critical Issues (X found)
   - [agent-name]: Issue description [file:line]

   ## Important Issues (X found)
   - [agent-name]: Issue description [file:line]

   ## Suggestions (X found)
   - [agent-name]: Suggestion [file:line]

   ## Strengths
   - What's well-done in this PR

   ## Recommended Action
   1. Fix critical issues first
   2. Address important issues
   3. Consider suggestions
   4. Re-run review after fixes
   ```

## Usage Examples:

**Full review (default):**
```
/pr-review-toolkit:review-pr
```

**Specific aspects:**
```
/pr-review-toolkit:review-pr tests errors
# Reviews only test coverage and error handling

/pr-review-toolkit:review-pr comments
# Reviews only code comments

/pr-review-toolkit:review-pr simplify
# Simplifies code after passing review
```

**Parallel review:**
```
/pr-review-toolkit:review-pr all parallel
# Launches all agents in parallel
```

## Agent Descriptions:

**comment-analyzer**:
- Verifies comment accuracy vs code
- Identifies comment rot
- Checks documentation completeness

**pr-test-analyzer**:
- Reviews behavioral test coverage
- Identifies critical gaps
- Evaluates test quality

**silent-failure-hunter**:
- Finds silent failures
- Reviews catch blocks
- Checks error logging

**type-design-analyzer**:
- Analyzes type encapsulation
- Reviews invariant expression
- Rates type design quality

**code-reviewer**:
- Checks CLAUDE.md compliance
- Detects bugs and issues
- Reviews general code quality

**code-simplifier**:
- Simplifies complex code
- Improves clarity and readability
- Applies project standards
- Preserves functionality

## Tips:

- **Run early**: Before creating PR, not after
- **Focus on changes**: Agents analyze git diff by default
- **Address critical first**: Fix high-priority issues before lower priority
- **Re-run after fixes**: Verify issues are resolved
- **Use specific reviews**: Target specific aspects when you know the concern

## Workflow Integration:

**Before committing:**
```
1. Write code
2. Run: /pr-review-toolkit:review-pr code errors
3. Fix any critical issues
4. Commit
```

**Before creating PR:**
```
1. Stage all changes
2. Run: /pr-review-toolkit:review-pr all
3. Address all critical and important issues
4. Run specific reviews again to verify
5. Create PR
```

**After PR feedback:**
```
1. Make requested changes
2. Run targeted reviews based on feedback
3. Verify issues are resolved
4. Push updates
```

## Notes:

- Agents run autonomously and return detailed reports
- Each agent focuses on its specialty for deep analysis
- Results are actionable with specific file:line references
- Agents use appropriate models for their complexity
- All agents available in `/agents` list

---

## Ralph Wiggum Plugin Help

Source: https://github.com/anthropics/claude-code/blob/main/plugins/ralph-wiggum/commands/help.md
Path: 08-Plugins-Skills/claude-code-plugins-ralph-wiggum-commands-help.md

# Ralph Wiggum Plugin Help

Please explain the following to the user:

## What is the Ralph Wiggum Technique?

The Ralph Wiggum technique is an iterative development methodology based on continuous AI loops, pioneered by Geoffrey Huntley.

**Core concept:**
```bash
while :; do
  cat PROMPT.md | claude-code --continue
done
```

The same prompt is fed to Claude repeatedly. The "self-referential" aspect comes from Claude seeing its own previous work in the files and git history, not from feeding output back as input.

**Each iteration:**
1. Claude receives the SAME prompt
2. Works on the task, modifying files
3. Tries to exit
4. Stop hook intercepts and feeds the same prompt again
5. Claude sees its previous work in the files
6. Iteratively improves until completion

The technique is described as "deterministically bad in an undeterministic world" - failures are predictable, enabling systematic improvement through prompt tuning.

## Available Commands

### /ralph-loop <PROMPT> [OPTIONS]

Start a Ralph loop in your current session.

**Usage:**
```
/ralph-loop "Refactor the cache layer" --max-iterations 20
/ralph-loop "Add tests" --completion-promise "TESTS COMPLETE"
```

**Options:**
- `--max-iterations <n>` - Max iterations before auto-stop
- `--completion-promise <text>` - Promise phrase to signal completion

**How it works:**
1. Creates `.claude/.ralph-loop.local.md` state file
2. You work on the task
3. When you try to exit, stop hook intercepts
4. Same prompt fed back
5. You see your previous work
6. Continues until promise detected or max iterations

---

### /cancel-ralph

Cancel an active Ralph loop (removes the loop state file).

**Usage:**
```
/cancel-ralph
```

**How it works:**
- Checks for active loop state file
- Removes `.claude/.ralph-loop.local.md`
- Reports cancellation with iteration count

---

## Key Concepts

### Completion Promises

To signal completion, Claude must output a `<promise>` tag:

```
<promise>TASK COMPLETE</promise>
```

The stop hook looks for this specific tag. Without it (or `--max-iterations`), Ralph runs infinitely.

### Self-Reference Mechanism

The "loop" doesn't mean Claude talks to itself. It means:
- Same prompt repeated
- Claude's work persists in files
- Each iteration sees previous attempts
- Builds incrementally toward goal

## Example

### Interactive Bug Fix

```
/ralph-loop "Fix the token refresh logic in auth.ts. Output <promise>FIXED</promise> when all tests pass." --completion-promise "FIXED" --max-iterations 10
```

You'll see Ralph:
- Attempt fixes
- Run tests
- See failures
- Iterate on solution
- In your current session

## When to Use Ralph

**Good for:**
- Well-defined tasks with clear success criteria
- Tasks requiring iteration and refinement
- Iterative development with self-correction
- Greenfield projects

**Not good for:**
- Tasks requiring human judgment or design decisions
- One-shot operations
- Tasks with unclear success criteria
- Debugging production issues (use targeted debugging instead)

## Learn More

- Original technique: https://ghuntley.com/ralph/
- Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator

---

## Ralph Loop Command

Source: https://github.com/anthropics/claude-code/blob/main/plugins/ralph-wiggum/commands/ralph-loop.md
Path: 08-Plugins-Skills/claude-code-plugins-ralph-wiggum-commands-ralph-loop.md

# Ralph Loop Command

Execute the setup script to initialize the Ralph loop:

```!
"${CLAUDE_PLUGIN_ROOT}/scripts/setup-ralph-loop.sh" $ARGUMENTS
```

Please work on the task. When you try to exit, the Ralph loop will feed the SAME PROMPT back to you for the next iteration. You'll see your previous work in files and git history, allowing you to iterate and improve.

CRITICAL RULE: If a completion promise is set, you may ONLY output it when the statement is completely and unequivocally TRUE. Do not output false promises to escape the loop, even if you think you're stuck or should exit for other reasons. The loop is designed to continue until genuine completion.

---

## Ralph Wiggum Plugin

Source: https://github.com/anthropics/claude-code/blob/main/plugins/ralph-wiggum/README.md
Path: 08-Plugins-Skills/claude-code-plugins-ralph-wiggum-readme.md

# Ralph Wiggum Plugin

Implementation of the Ralph Wiggum technique for iterative, self-referential AI development loops in Claude Code.

## What is Ralph?

Ralph is a development methodology based on continuous AI agent loops. As Geoffrey Huntley describes it: **"Ralph is a Bash loop"** - a simple `while true` that repeatedly feeds an AI agent a prompt file, allowing it to iteratively improve its work until completion.

The technique is named after Ralph Wiggum from The Simpsons, embodying the philosophy of persistent iteration despite setbacks.

### Core Concept

This plugin implements Ralph using a **Stop hook** that intercepts Claude's exit attempts:

```bash
# You run ONCE:
/ralph-loop "Your task description" --completion-promise "DONE"

# Then Claude Code automatically:
# 1. Works on the task
# 2. Tries to exit
# 3. Stop hook blocks exit
# 4. Stop hook feeds the SAME prompt back
# 5. Repeat until completion
```

The loop happens **inside your current session** - you don't need external bash loops. The Stop hook in `hooks/stop-hook.sh` creates the self-referential feedback loop by blocking normal session exit.

This creates a **self-referential feedback loop** where:
- The prompt never changes between iterations
- Claude's previous work persists in files
- Each iteration sees modified files and git history
- Claude autonomously improves by reading its own past work in files

## Quick Start

```bash
/ralph-loop "Build a REST API for todos. Requirements: CRUD operations, input validation, tests. Output <promise>COMPLETE</promise> when done." --completion-promise "COMPLETE" --max-iterations 50
```

Claude will:
- Implement the API iteratively
- Run tests and see failures
- Fix bugs based on test output
- Iterate until all requirements met
- Output the completion promise when done

## Commands

### /ralph-loop

Start a Ralph loop in your current session.

**Usage:**
```bash
/ralph-loop "<prompt>" --max-iterations <n> --completion-promise "<text>"
```

**Options:**
- `--max-iterations <n>` - Stop after N iterations (default: unlimited)
- `--completion-promise <text>` - Phrase that signals completion

### /cancel-ralph

Cancel the active Ralph loop.

**Usage:**
```bash
/cancel-ralph
```

## Prompt Writing Best Practices

### 1. Clear Completion Criteria

❌ Bad: "Build a todo API and make it good."

✅ Good:
```markdown
Build a REST API for todos.

When complete:
- All CRUD endpoints working
- Input validation in place
- Tests passing (coverage > 80%)
- README with API docs
- Output: <promise>COMPLETE</promise>
```

### 2. Incremental Goals

❌ Bad: "Create a complete e-commerce platform."

✅ Good:
```markdown
Phase 1: User authentication (JWT, tests)
Phase 2: Product catalog (list/search, tests)
Phase 3: Shopping cart (add/remove, tests)

Output <promise>COMPLETE</promise> when all phases done.
```

### 3. Self-Correction

❌ Bad: "Write code for feature X."

✅ Good:
```markdown
Implement feature X following TDD:
1. Write failing tests
2. Implement feature
3. Run tests
4. If any fail, debug and fix
5. Refactor if needed
6. Repeat until all green
7. Output: <promise>COMPLETE</promise>
```

### 4. Escape Hatches

Always use `--max-iterations` as a safety net to prevent infinite loops on impossible tasks:

```bash
# Recommended: Always set a reasonable iteration limit
/ralph-loop "Try to implement feature X" --max-iterations 20

# In your prompt, include what to do if stuck:
# "After 15 iterations, if not complete:
#  - Document what's blocking progress
#  - List what was attempted
#  - Suggest alternative approaches"
```

**Note**: The `--completion-promise` uses exact string matching, so you cannot use it for multiple completion conditions (like "SUCCESS" vs "BLOCKED"). Always rely on `--max-iterations` as your primary safety mechanism.

## Philosophy

Ralph embodies several key principles:

### 1. Iteration > Perfection
Don't aim for perfect on first try. Let the loop refine the work.

### 2. Failures Are Data
"Deterministically bad" means failures are predictable and informative. Use them to tune prompts.

### 3. Operator Skill Matters
Success depends on writing good prompts, not just having a good model.

### 4. Persistence Wins
Keep trying until success. The loop handles retry logic automatically.

## When to Use Ralph

**Good for:**
- Well-defined tasks with clear success criteria
- Tasks requiring iteration and refinement (e.g., getting tests to pass)
- Greenfield projects where you can walk away
- Tasks with automatic verification (tests, linters)

**Not good for:**
- Tasks requiring human judgment or design decisions
- One-shot operations
- Tasks with unclear success criteria
- Production debugging (use targeted debugging instead)

## Real-World Results

- Successfully generated 6 repositories overnight in Y Combinator hackathon testing
- One $50k contract completed for $297 in API costs
- Created entire programming language ("cursed") over 3 months using this approach

## Learn More

- Original technique: https://ghuntley.com/ralph/
- Ralph Orchestrator: https://github.com/mikeyobrien/ralph-orchestrator

## For Help

Run `/help` in Claude Code for detailed command reference and examples.

---

## Plugins | Claude Marketplace | Claude by Anthropic

Source: https://www.claude.com/plugins
Path: 08-Plugins-Skills/claude-com-plugins.md

# Add new capabilities to Claude

Browse plugins that bundle tools, skills, and integrations for one-click installation.

[Submit a plugin](https://claude.com/docs/plugins/submit)

Filter

Works with

Claude

Claude Code

340 plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

### [CLAUDE.md Management](https://www.claude.com/marketplace/plugins/claude-md-management)

Anthropic verified

Tools to maintain CLAUDE.md - audit quality, capture learnings, and keep project memory current.

### [Feature Dev](https://www.claude.com/marketplace/plugins/feature-dev)

Anthropic verified

Feature development workflow with agents for exploration, design, and review

### [Security Guidance](https://www.claude.com/marketplace/plugins/security-guidance)

Anthropic verified

Security hook warns about command injection, XSS, and unsafe code patterns when editing files

### [Vercel](https://www.claude.com/marketplace/plugins/vercel)

Vercel integration for Claude Code. Manage deployments, builds, logs, domains, and frontend infrastructure directly.

### [TypeScript LSP](https://www.claude.com/marketplace/plugins/typescript-lsp)

Anthropic verified

TypeScript/JavaScript language server for enhanced code intelligence

### [Ralph Loop](https://www.claude.com/marketplace/plugins/ralph-loop)

Anthropic verified

Interactive AI loops for iterative development using the Ralph Wiggum technique: Claude works on tasks repeatedly, seeing prior work until completion.

### [Claude Code Setup](https://www.claude.com/marketplace/plugins/claude-code-setup)

Anthropic verified

Analyze codebases and recommend tailored Claude Code automations such as hooks, skills, MCP servers, and subagents.

### [Commit Commands](https://www.claude.com/marketplace/plugins/commit-commands)

Anthropic verified

Commands for git commit workflows including commit, push, and PR creation

### [Figma](https://www.claude.com/marketplace/plugins/figma)

Figma integration: access design files, extract components, read tokens, translate to code. Bridge design-development gap.

### [Supabase](https://www.claude.com/marketplace/plugins/supabase)

Supabase MCP: Database ops, auth, storage, real-time. Manage projects, run SQL, interact with your backend.

### [PR Review Toolkit](https://www.claude.com/marketplace/plugins/pr-review-toolkit)

Anthropic verified

PR review agents for comments, tests, errors, types, quality, and simplification

### [Pyright LSP](https://www.claude.com/marketplace/plugins/pyright-lsp)

Anthropic verified

Python language server (Pyright) for type checking and code intelligence

### [Chrome DevTools](https://www.claude.com/marketplace/plugins/chrome-devtools-mcp)

Control and inspect a live Chrome browser from your coding agent. Record performance traces, analyze network requests...

### [telegram](https://www.claude.com/marketplace/plugins/telegram)

Telegram messaging bridge with built-in access control. Manage pairing, allowlists, and policy via /telegram:access.

### [Atlassian](https://www.claude.com/marketplace/plugins/atlassian)

Connect to Jira & Confluence. Search/create issues, access docs, manage sprints, integrate development workflows.

### [Slack](https://www.claude.com/marketplace/plugins/slack)

Anthropic verified

Official Slack MCP server for interactive and collaborative workflows. Surface insights, draft messages, and engage teams directly within Slack from Claude Cowork.

### [Serena](https://www.claude.com/marketplace/plugins/serena)

Semantic code analysis MCP server for intelligent code understanding, refactoring, and navigation via language server protocol.

View more

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Skills Cookbook - Claude Code Guide

Source: https://github.com/anthropics/claude-cookbooks/blob/main/skills/CLAUDE.md
Path: 08-Plugins-Skills/claude-cookbooks-skills-claude.md

# Skills Cookbook - Claude Code Guide

## Project Overview

This is a comprehensive Jupyter notebook cookbook demonstrating Claude's Skills feature for document generation (Excel, PowerPoint, PDF). It's designed for developers learning to integrate Skills into their applications.

## Quick Start Commands

### Environment Setup
```bash
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies (MUST use local whl for Skills support)
pip install -r requirements.txt

# Configure API key
cp .env.example .env
# Edit .env and add your ANTHROPIC_API_KEY
```

### Running Notebooks
```bash
# Launch Jupyter
jupyter notebook

# Or use VSCode with Jupyter extension
# Make sure to select the venv kernel in VSCode: Cmd+Shift+P → "Python: Select Interpreter"
```

### Testing & Verification
```bash
# Verify environment and SDK version
python -c "import anthropic; print(f'SDK Version: {anthropic.__version__}')"

# Check outputs directory for generated files
ls -lh outputs/
```

## Architecture Overview

### Directory Structure
```
skills/
├── notebooks/              # 3 progressive Jupyter notebooks
│   ├── 01_skills_introduction.ipynb
│   ├── 02_skills_financial_applications.ipynb  # WIP
│   └── 03_skills_custom_development.ipynb      # WIP
├── sample_data/           # Financial datasets for examples
├── custom_skills/         # Custom skill development area
├── outputs/               # Generated files (xlsx, pptx, pdf)
├── file_utils.py          # Files API helper functions
└── docs/                  # Implementation tracking
```

### Key Technical Details

**Beta API Requirements:**
- All Skills functionality uses `client.beta.*` namespace
- Required beta headers: `code-execution-2025-08-25`, `files-api-2025-04-14`, `skills-2025-10-02`
- Must use `client.beta.messages.create()` with `container` parameter
- Code execution tool (`code_execution_20250825`) is REQUIRED
- Use pre-built Agent skills by referencing their `skill_id` or create and upload your own via the Skills API

**Files API Integration:**
- Skills generate files and return `file_id` attributes
- Must use `client.beta.files.download()` to download files
- Must use `client.beta.files.retrieve_metadata()` to get file info
- Helper functions in `file_utils.py` handle extraction and download

**Built-in Skills:**
- `xlsx` - Excel workbooks with formulas and charts
- `pptx` - PowerPoint presentations
- `pdf` - PDF documents
- `docx` - Word documents

## Development Gotchas

### 1. SDK Version
**Important**: Ensure you have the Anthropic SDK version 0.71.0 or later with Skills support
```bash
pip install anthropic>=0.71.0
# Restart Jupyter kernel after installation if upgrading!
```

### 2. Beta Namespace Required
**Problem**: `container` parameter not recognized, files API fails
**Solution**: Use `client.beta.messages.create()` and `client.beta.files.*`
```python
# ❌ Wrong
response = client.messages.create(container={...})
content = client.files.content(file_id)

# ✅ Correct
response = client.beta.messages.create(container={...})
content = client.beta.files.content(file_id)
```

### 3. Beta Headers Placement
**Problem**: Setting Skills beta in default_headers requires code_execution on ALL requests
**Solution**: Use `betas` parameter per-request instead
```python
# ❌ Wrong (affects all requests)
client = Anthropic(default_headers={"anthropic-beta": "skills-2025-10-02"})

# ✅ Correct (per-request)
response = client.beta.messages.create(
    betas=["code-execution-2025-08-25", "files-api-2025-04-14", "skills-2025-10-02"],
    ...
)
```

### 4. File ID Extraction
**Problem**: Response structure differs from standard Messages API
**Solution**: File IDs in `bash_code_execution_tool_result.content.content[0].file_id`
```python
# Use file_utils.extract_file_ids() - handles beta response structure
from file_utils import extract_file_ids, download_all_files
file_ids = extract_file_ids(response)
```

### 5. Files API Response Objects
**Problem**: `'BinaryAPIResponse' object has no attribute 'content'`, `'FileMetadata' object has no attribute 'size'`
**Solution**: Use `.read()` for file content and `.size_bytes` for file size
```python
# ❌ Wrong
file_content = client.beta.files.download(file_id)
with open(path, 'wb') as f:
    f.write(file_content.content)  # No .content attribute!

# ✅ Correct
file_content = client.beta.files.download(file_id)
with open(path, 'wb') as f:
    f.write(file_content.read())  # Use .read()

# FileMetadata fields: id, filename, size_bytes (not size), mime_type, created_at, type, downloadable
metadata = client.beta.files.retrieve_metadata(file_id)
print(f"Size: {metadata.size_bytes} bytes")  # Use size_bytes, not size
```

### 6. Jupyter Kernel Selection
**Problem**: Wrong Python interpreter = wrong dependencies
**Solution**: Always select venv kernel in VSCode/Jupyter
- VSCode: Cmd+Shift+P → "Python: Select Interpreter" → select venv
- Jupyter: Kernel → Change Kernel → select venv

### 7. Module Reload Required
**Problem**: Changes to `file_utils.py` not reflected in running notebooks
**Solution**: Restart kernel or reload module
```python
import importlib
importlib.reload(file_utils)
```

### 8. Document Generation Times
**Problem**: File creation takes longer than typical API calls, users may think cell is frozen
**Actual Observed Times:**
- Excel: ~2 minutes
- PowerPoint: ~1-2 minutes (simple 2-3 slide presentations)
- PDF: ~1-2 minutes

**Solution**: Add clear timing expectations before file creation cells
```markdown
**⏱️ Note**: Excel generation typically takes 1-2 minutes.
Be patient - the cell will show [*] while running!
```
**Important**: Keep examples simple and focused. Generation times are consistent at 1-2 minutes for well-scoped examples.

## Common Tasks

### Adding a New Notebook Section
1. Follow existing structure in `01_skills_introduction.ipynb`
2. Include setup cell with imports and beta headers
3. Show API call, response handling, file download
4. Add error handling examples
5. Update `docs/skills_cookbook_plan.md` checklist

### Creating Sample Data
1. Add realistic financial data to `sample_data/`
2. Use CSV for tabular, JSON for structured
3. Include headers and proper formatting
4. Reference in notebook with pandas
5. Keep file sizes reasonable (<100KB)

### Testing File Download
1. Run notebook cell to generate file
2. Check response for file_id
3. Use `download_all_files()` helper
4. Verify file in `outputs/` directory
5. Open file in native app to validate

**Note**: Files are overwritten by default. You'll see `[overwritten]` in the download summary when a file already existed. Set `overwrite=False` to prevent this.

### Debugging API Errors
1. Check SDK version: `anthropic.__version__` should be `0.69.0`
2. Verify beta headers are passed per-request
3. Ensure code_execution tool is included
4. Check response structure with `print(response)`
5. Look for error details in `response.stop_reason`

## Testing Checklist

Before committing notebook changes:
- [ ] Restart kernel and run all cells
- [ ] Verify all file downloads work
- [ ] Check outputs/ for generated files
- [ ] Validate files open correctly in native apps
- [ ] Update skills_cookbook_plan.md checklist
- [ ] Test in fresh virtual environment

## Resources

- **API Reference**: https://docs.claude.com/en/api/messages
- **Files API**: https://docs.claude.com/en/api/files-content
- **Skills Documentation**: https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview

## Project-Specific Notes

- **Focus Domain**: Finance & Analytics with practical business applications
- **Target Audience**: Intermediate developers and business analysts
- **Notebook 1**: Complete and tested (file downloads working)
- **Notebook 2**: Financial Applications - next priority
- **Notebook 3**: Custom Skills Development - after Notebook 2

## Environment Variables

Required in `.env`:
```bash
ANTHROPIC_API_KEY=your-api-key-here
```

Optional (for advanced examples):
```bash
ANTHROPIC_BASE_URL=https://api.anthropic.com  # If using proxy
```

---

## Financial Modeling Suite

Source: https://github.com/anthropics/claude-cookbooks/blob/main/skills/custom_skills/creating-financial-models/SKILL.md
Path: 08-Plugins-Skills/claude-cookbooks-skills-custom-skills-creating-financial-models-skill.md

# Financial Modeling Suite

A comprehensive financial modeling toolkit for investment analysis, valuation, and risk assessment using industry-standard methodologies.

## Core Capabilities

### 1. Discounted Cash Flow (DCF) Analysis
- Build complete DCF models with multiple growth scenarios
- Calculate terminal values using perpetuity growth and exit multiple methods
- Determine weighted average cost of capital (WACC)
- Generate enterprise and equity valuations

### 2. Sensitivity Analysis
- Test key assumptions impact on valuation
- Create data tables for multiple variables
- Generate tornado charts for sensitivity ranking
- Identify critical value drivers

### 3. Monte Carlo Simulation
- Run thousands of scenarios with probability distributions
- Model uncertainty in key inputs
- Generate confidence intervals for valuations
- Calculate probability of achieving targets

### 4. Scenario Planning
- Build best/base/worst case scenarios
- Model different economic environments
- Test strategic alternatives
- Compare outcome probabilities

## Input Requirements

### For DCF Analysis
- Historical financial statements (3-5 years)
- Revenue growth assumptions
- Operating margin projections
- Capital expenditure forecasts
- Working capital requirements
- Terminal growth rate or exit multiple
- Discount rate components (risk-free rate, beta, market premium)

### For Sensitivity Analysis
- Base case model
- Variable ranges to test
- Key metrics to track

### For Monte Carlo Simulation
- Probability distributions for uncertain variables
- Correlation assumptions between variables
- Number of iterations (typically 1,000-10,000)

### For Scenario Planning
- Scenario definitions and assumptions
- Probability weights for scenarios
- Key performance indicators to track

## Output Formats

### DCF Model Output
- Complete financial projections
- Free cash flow calculations
- Terminal value computation
- Enterprise and equity value summary
- Valuation multiples implied
- Excel workbook with full model

### Sensitivity Analysis Output
- Sensitivity tables showing value ranges
- Tornado chart of key drivers
- Break-even analysis
- Charts showing relationships

### Monte Carlo Output
- Probability distribution of valuations
- Confidence intervals (e.g., 90%, 95%)
- Statistical summary (mean, median, std dev)
- Risk metrics (VaR, probability of loss)

### Scenario Planning Output
- Scenario comparison table
- Probability-weighted expected values
- Decision tree visualization
- Risk-return profiles

## Model Types Supported

1. **Corporate Valuation**
   - Mature companies with stable cash flows
   - Growth companies with J-curve projections
   - Turnaround situations

2. **Project Finance**
   - Infrastructure projects
   - Real estate developments
   - Energy projects

3. **M&A Analysis**
   - Acquisition valuations
   - Synergy modeling
   - Accretion/dilution analysis

4. **LBO Models**
   - Leveraged buyout analysis
   - Returns analysis (IRR, MOIC)
   - Debt capacity assessment

## Best Practices Applied

### Modeling Standards
- Consistent formatting and structure
- Clear assumption documentation
- Separation of inputs, calculations, outputs
- Error checking and validation
- Version control and change tracking

### Valuation Principles
- Use multiple valuation methods for triangulation
- Apply appropriate risk adjustments
- Consider market comparables
- Validate against trading multiples
- Document key assumptions clearly

### Risk Management
- Identify and quantify key risks
- Use probability-weighted scenarios
- Stress test extreme cases
- Consider correlation effects
- Provide confidence intervals

## Example Usage

"Build a DCF model for this technology company using the attached financials"

"Run a Monte Carlo simulation on this acquisition model with 5,000 iterations"

"Create sensitivity analysis showing impact of growth rate and WACC on valuation"

"Develop three scenarios for this expansion project with probability weights"

## Scripts Included

- `dcf_model.py`: Complete DCF valuation engine
- `sensitivity_analysis.py`: Sensitivity testing framework

## Limitations and Disclaimers

- Models are only as good as their assumptions
- Past performance doesn't guarantee future results
- Market conditions can change rapidly
- Regulatory and tax changes may impact results
- Professional judgment required for interpretation
- Not a substitute for professional financial advice

## Quality Checks

The model automatically performs:
1. Balance sheet balancing checks
2. Cash flow reconciliation
3. Circular reference resolution
4. Sensitivity bound checking
5. Statistical validation of Monte Carlo results

## Updates and Maintenance

- Models use latest financial theory and practices
- Regular updates for market parameter defaults
- Incorporation of regulatory changes
- Continuous improvement based on usage patterns

---

## Claude Skills for Financial Applications

Source: https://github.com/anthropics/claude-cookbooks/blob/main/skills/notebooks/02_skills_financial_applications.ipynb
Path: 08-Plugins-Skills/claude-cookbooks-skills-notebooks-02-skills-financial-applications.md

# Claude Skills for Financial Applications

Build real-world financial dashboards, portfolio analytics, and
automated reporting workflows using Claude\'s Excel, PowerPoint, and PDF
skills.

> **💡 Real-world Impact:** These are the same Skills that power
> **[Claude Creates
> Files](https://github.com/anthropics/claude-cookbooks/blob/main/skills/19-Reference/claude-can-now-create-and-edit-files-claude.md)**, enabling Claude
> to create professional financial documents directly in the interface.

**What you\'ll learn:**

- Create comprehensive financial models in Excel with formulas and
  charts
- Generate executive presentations from financial data
- Build portfolio analysis tools with risk metrics
- Automate multi-format reporting pipelines
:::

::: {.cell .markdown}
## Table of Contents

1.  [Setup & Data Loading](#setup)
2.  [Use Case 1: Financial Dashboard Creation](#financial-dashboard)
    - [Excel Financial Model](#excel-model)
    - [Executive PowerPoint](#executive-ppt)
    - [PDF Financial Report](#pdf-report)
3.  [Use Case 2: Portfolio Analysis Workflow](#portfolio-analysis)
    - [Portfolio Analytics Excel](#portfolio-excel)
    - [Investment Committee Deck](#investment-deck)
4.  [Use Case 3: Automated Reporting Pipeline](#reporting-pipeline)
:::

::: {.cell .markdown}
## Prerequisites

This notebook assumes you\'ve completed **Notebook 1: Introduction to
Skills**.

If you haven\'t:

1.  Complete the setup in Notebook 1 first
2.  Verify your environment with the test cells
3.  Ensure you can create and download files

**Required:**

- Anthropic API key configured
- SDK version 0.69.0 installed from whl
- Virtual environment activated
:::

::: {.cell .markdown}
## 1. Setup & Data Loading {#setup} {#1-setup--data-loading-setup}

Let\'s start by importing our dependencies and loading the financial
data we\'ll work with throughout this notebook.
:::

::: {.cell .code}
``` python
# Standard imports
import json
import os
import sys
from pathlib import Path

import pandas as pd

# Add parent directory for imports
sys.path.insert(0, str(Path.cwd().parent))

# Anthropic SDK
from anthropic import Anthropic
from dotenv import load_dotenv

# Our utilities
from file_utils import (
    download_all_files,
    print_download_summary,
)

# Load environment
load_dotenv(Path.cwd().parent / ".env")

# Configuration
API_KEY = os.getenv("ANTHROPIC_API_KEY")
MODEL = "claude-sonnet-4-5"

if not API_KEY:
    raise ValueError("ANTHROPIC_API_KEY not found. Please configure your .env file.")

# Initialize client
client = Anthropic(api_key=API_KEY)

# Setup directories
OUTPUT_DIR = Path.cwd().parent / "outputs" / "financial"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

DATA_DIR = Path.cwd().parent / "sample_data"

print("✓ Environment configured")
print(f"✓ Output directory: {OUTPUT_DIR}")
print(f"✓ Data directory: {DATA_DIR}")
```
:::

::: {.cell .markdown}
### Load Financial Data

We have four datasets representing different aspects of a company\'s
financial position:
:::

::: {.cell .code}
``` python
# Load financial statements
financial_statements = pd.read_csv(DATA_DIR / "financial_statements.csv")
print("📊 Financial Statements Overview:")
print(f"   Shape: {financial_statements.shape}")
print(f"   Categories: {len(financial_statements['Category'].unique())} financial metrics")
print(f"   Quarters: {list(financial_statements.columns[1:5])}")
print()

# Show sample data
print("Sample data (first 5 rows):")
financial_statements.head()
```
:::

::: {.cell .code}
``` python
# Load portfolio holdings
with open(DATA_DIR / "portfolio_holdings.json") as f:
    portfolio_data = json.load(f)

print("💼 Portfolio Overview:")
print(f"   Portfolio: {portfolio_data['portfolio_name']}")
print(f"   Total Value: ${portfolio_data['total_value']:,.2f}")
print(f"   Holdings: {len(portfolio_data['holdings'])} stocks")
print(f"   Cash Position: ${portfolio_data['cash_position']['amount']:,.2f}")
print(f"   Total Return: {portfolio_data['performance_metrics']['total_return_percent']:.1f}%")
print()

# Convert holdings to DataFrame for easier manipulation
portfolio_df = pd.DataFrame(portfolio_data["holdings"])
print("Top 5 holdings by value:")
portfolio_df.nlargest(5, "market_value")[["ticker", "name", "market_value", "unrealized_gain"]]
```
:::

::: {.cell .code}
``` python
# Load quarterly metrics
with open(DATA_DIR / "quarterly_metrics.json") as f:
    quarterly_metrics = json.load(f)

print("📈 Quarterly Metrics Overview:")
print(f"   Quarters available: {len(quarterly_metrics['quarters'])}")
print(f"   Metrics per quarter: {len(quarterly_metrics['quarters'][0])} KPIs")
print()

# Show latest quarter metrics
latest_quarter = quarterly_metrics["quarters"][-1]
print(f"Latest Quarter ({latest_quarter['quarter']}):")
for key, value in latest_quarter.items():
    if key != "quarter" and isinstance(value, int | float):
        if "revenue" in key.lower() or "cost" in key.lower():
            print(f"   {key.replace('_', ' ').title()}: ${value:,.0f}")
        elif "percent" in key.lower() or "margin" in key.lower() or "rate" in key.lower():
            print(f"   {key.replace('_', ' ').title()}: {value:.1f}%")
        else:
            print(f"   {key.replace('_', ' ').title()}: {value:,.0f}")
```
:::

::: {.cell .markdown}
### Helper Functions

Let\'s define some helper functions for this notebook:
:::

::: {.cell .code}
``` python
def create_skills_message(client, prompt, skills, prefix="", show_token_usage=True):
    """
    Helper function to create messages with Skills.

    Args:
        client: Anthropic client
        prompt: User prompt
        skills: List of skill dicts [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]
        prefix: Prefix for downloaded files
        show_token_usage: Whether to print token usage

    Returns:
        Tuple of (response, download_results)
    """
    response = client.beta.messages.create(
        model=MODEL,
        max_tokens=4096,
        container={"skills": skills},
        tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
        messages=[{"role": "user", "content": prompt}],
        betas=[
            "code-execution-2025-08-25",
            "files-api-2025-04-14",
            "skills-2025-10-02",
        ],
    )

    if show_token_usage:
        print(
            f"\n📊 Token Usage: {response.usage.input_tokens} in, {response.usage.output_tokens} out"
        )

    # Download files
    results = download_all_files(client, response, output_dir=str(OUTPUT_DIR), prefix=prefix)

    return response, results


def format_financial_value(value, is_currency=True, decimals=0):
    """Format financial values for display."""
    if is_currency:
        return f"${value:,.{decimals}f}"
    else:
        return f"{value:,.{decimals}f}"


print("✓ Helper functions defined")
```
:::

::: {.cell .markdown}
## 2. Use Case 1: Financial Dashboard Creation {#financial-dashboard} {#2-use-case-1-financial-dashboard-creation-financial-dashboard}

Now that we have our data loaded and helper functions defined, let\'s
dive into our first practical use case: creating comprehensive financial
dashboards. We\'ll start by generating multi-sheet Excel workbooks that
automatically include formulas, formatting, and charts.

### 2.1 Excel Financial Model {#excel-model} {#21-excel-financial-model-excel-model}

We\'ll create a financial dashboard that includes:

- Profit & Loss statements with year-over-year comparisons
- Balance sheet analysis
- Cash flow tracking
- KPI dashboards with visualizations

This demonstrates how Claude\'s Skills can handle complex Excel
generation tasks that would typically require hours of manual work.
:::

::: {.cell .code}
``` python
# Create Financial Dashboard Excel
print("Creating financial dashboard Excel file...")
print("This creates a 2-sheet dashboard optimized for the Skills API.")
print("\n⏱️ Generation time: 1-2 minutes\n")

# Prepare the financial data
fs_data = financial_statements.to_dict("records")
quarters_2024 = ["Q1_2024", "Q2_2024", "Q3_2024", "Q4_2024"]

# Extract key financial metrics
revenue_by_quarter = {
    "Q1 2024": financial_statements[financial_statements["Category"] == "Revenue"][
        "Q1_2024"
    ].values[0],
    "Q2 2024": financial_statements[financial_statements["Category"] == "Revenue"][
        "Q2_2024"
    ].values[0],
    "Q3 2024": financial_statements[financial_statements["Category"] == "Revenue"][
        "Q3_2024"
    ].values[0],
    "Q4 2024": financial_statements[financial_statements["Category"] == "Revenue"][
        "Q4_2024"
    ].values[0],
}

financial_dashboard_prompt = f"""
Create a financial dashboard Excel workbook with 2 sheets:

Sheet 1 - "P&L Summary":
Create a Profit & Loss summary table for 2024 quarters with these rows:
- Revenue: {", ".join([f"Q{i + 1}: ${v / 1000000:.1f}M" for i, v in enumerate(revenue_by_quarter.values())])}
- Gross Profit: Use values from the data
- Operating Income: Use values from the data
- Net Income: Use values from the data
- Add a Total column with SUM formulas
- Add a row showing profit margins (Net Income / Revenue)
- Apply currency formatting and bold headers
- Add a simple bar chart showing quarterly revenue

Sheet 2 - "Key Metrics":
Create a metrics dashboard with:
- Total Revenue 2024: SUM of all quarters
- Average Quarterly Revenue: AVERAGE formula
- Q4 vs Q1 Growth: Percentage increase
- Best Quarter: MAX formula to identify
- Operating Margin Q4: Calculate from data
- Year-over-year growth vs 2023

Apply professional formatting with borders, bold headers, and currency formats.
"""

# Create the Excel financial dashboard
excel_response, excel_results = create_skills_message(
    client,
    financial_dashboard_prompt,
    [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}],
    prefix="financial_dashboard_",
)

print("\n" + "=" * 60)
print_download_summary(excel_results)

if len(excel_results) > 0 and excel_results[0]["success"]:
    print("\n✅ Financial dashboard Excel created successfully!")
```
:::

::: {.cell .markdown}
### 💡 Best Practices for Excel Generation {#bulb-best-practices-for-excel-generation}

Based on our testing, here are the optimal approaches for creating Excel
files with Skills:

**Recommended Approach:**

- **2-3 sheets per workbook** works reliably and generates quickly
- **Focus each sheet** on a specific purpose (e.g., P&L, metrics,
  charts)
- **Add complexity incrementally** - start simple, then enhance

**For Complex Dashboards:**

1.  **Create multiple focused files** instead of one complex file
    - Example: `financial_pnl.xlsx`, `balance_sheet.xlsx`,
      `kpi_dashboard.xlsx`
2.  **Use the pipeline pattern** to create and enhance files
    sequentially
3.  **Combine files programmatically** using pandas or openpyxl if
    needed

**Performance Tips:**

- Simple 2-sheet dashboards: \~1-2 minutes
- PowerPoint and PDF generation: Very reliable for complex content
- Token usage: Structured data (JSON/CSV) is more efficient than prose
:::

::: {.cell .markdown}
### 2.2 Executive PowerPoint {#executive-ppt} {#22-executive-powerpoint-executive-ppt}

With our financial data now organized in Excel, let\'s create an
executive presentation that summarizes the key insights. This
demonstrates how Skills can generate professional PowerPoint
presentations with charts, formatted text, and multiple slides - perfect
for board meetings or investor updates.

The presentation will include:

- Q4 2024 performance highlights
- Financial metrics with year-over-year comparisons
- Profitability trends with visualizations
- Key takeaways and outlook
:::

::: {.cell .code}
``` python
print("Creating executive presentation from financial metrics...")
print("\n⏱️ Generation time: 1-2 minutes\n")

# Calculate some key metrics for the presentation
q4_2024_revenue = 14500000
q4_2023_revenue = 12300000
yoy_growth = (q4_2024_revenue - q4_2023_revenue) / q4_2023_revenue * 100

q4_2024_net_income = 1878750
q4_2023_net_income = 1209000
net_income_growth = (q4_2024_net_income - q4_2023_net_income) / q4_2023_net_income * 100

executive_ppt_prompt = f"""
Create a 4-slide executive presentation for Q4 2024 financial results:

Slide 1 - Title:
- Title: "Q4 2024 Financial Results"
- Subtitle: "Executive Summary - Acme Corporation"
- Date: January 2025

Slide 2 - Financial Highlights:
- Title: "Q4 2024 Performance Highlights"
- Create a two-column layout:
  Left side - Key Metrics:
  • Revenue: $14.5M (+{yoy_growth:.1f}% YoY)
  • Net Income: $1.88M (+{net_income_growth:.1f}% YoY)
  • Operating Margin: 17.9% (up 2.9pp)
  • Operating Cash Flow: $2.85M

  Right side - Column chart showing quarterly revenue:
  Q1 2024: $12.5M
  Q2 2024: $13.2M
  Q3 2024: $13.8M
  Q4 2024: $14.5M

Slide 3 - Profitability Trends:
- Title: "Margin Expansion & Profitability"
- Add a line chart showing net margin % by quarter:
  Q1 2024: 11.4%
  Q2 2024: 11.8%
  Q3 2024: 12.4%
  Q4 2024: 13.0%
- Add bullet points below:
  • Consistent margin expansion throughout 2024
  • Operating leverage driving profitability
  • Cost optimization initiatives delivering results

Slide 4 - Key Takeaways:
- Title: "Key Takeaways & Outlook"
- Bullet points:
  ✓ Record Q4 revenue of $14.5M
  ✓ 17.9% YoY revenue growth
  ✓ 55% increase in net income YoY
  ✓ Strong cash generation: $2.85M operating cash flow
  ✓ Well-positioned for continued growth in 2025

Use professional corporate design:
- Dark blue (#003366) for headers
- Clean, modern layout
- Data-driven visualizations
"""

# Create the executive presentation
ppt_response, ppt_results = create_skills_message(
    client,
    executive_ppt_prompt,
    [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}],
    prefix="executive_summary_",
)

print("\n" + "=" * 60)
print_download_summary(ppt_results)

if len(ppt_results) > 0 and ppt_results[0]["success"]:
    print("\n✅ Executive presentation created successfully!")
```
:::

::: {.cell .markdown}
## 3. Use Case 2: Portfolio Analysis Workflow {#portfolio-analysis} {#3-use-case-2-portfolio-analysis-workflow-portfolio-analysis}

Now let\'s shift our focus from company financials to investment
portfolio analysis. In this section, we\'ll demonstrate how to create
comprehensive portfolio analytics and investment committee presentations
using the portfolio data we loaded earlier.

This workflow showcases:

- Detailed portfolio performance analysis in Excel
- Risk metrics and sector allocation visualization
- Professional investment committee presentations
- Data-driven rebalancing recommendations

We\'ll start by creating an Excel workbook with portfolio analytics,
then generate an investment committee presentation that summarizes our
findings.
:::

::: {.cell .markdown}
### First, let\'s create a comprehensive portfolio analysis Excel workbook

Before we create the investment committee presentation, we need to
analyze our portfolio data in detail. This Excel workbook will serve as
the foundation for our investment recommendations.
:::

::: {.cell .code}
``` python
print("Creating portfolio analysis Excel workbook...")
print("This creates a focused 2-sheet portfolio analysis optimized for the Skills API.")
print("\n⏱️ Generation time: 1-2 minutes\n")

# Prepare portfolio data for the prompt
top_holdings = portfolio_df.nlargest(5, "market_value")
sector_allocation = portfolio_data["sector_allocation"]

portfolio_excel_prompt = f"""
Create a portfolio analysis Excel workbook with 2 sheets:

Sheet 1 - "Portfolio Overview":
Create a comprehensive holdings and performance table:

Section 1 - Holdings (top of sheet):
{portfolio_df[["ticker", "name", "shares", "current_price", "market_value", "unrealized_gain", "allocation_percent"]].head(10).to_string()}

Section 2 - Portfolio Summary:
- Total portfolio value: ${portfolio_data["total_value"]:,.2f}
- Total unrealized gain: ${portfolio_df["unrealized_gain"].sum():,.2f}
- Total Return: {portfolio_data["performance_metrics"]["total_return_percent"]:.1f}%
- YTD Return: {portfolio_data["performance_metrics"]["year_to_date_return"]:.1f}%
- Sharpe Ratio: {portfolio_data["performance_metrics"]["sharpe_ratio"]:.2f}
- Portfolio Beta: {portfolio_data["performance_metrics"]["beta"]:.2f}

Apply conditional formatting: green for gains, red for losses.
Add a bar chart showing top 5 holdings by value.

Sheet 2 - "Sector Analysis & Risk":
Create sector allocation and risk metrics:

Section 1 - Sector Allocation:
{json.dumps(sector_allocation, indent=2)}
Include a pie chart of sector allocation.

Section 2 - Key Risk Metrics:
- Portfolio Beta: {portfolio_data["performance_metrics"]["beta"]:.2f}
- Standard Deviation: {portfolio_data["performance_metrics"]["standard_deviation"]:.1f}%
- Value at Risk (95%): $62,500
- Maximum Drawdown: -12.3%
- Sharpe Ratio: {portfolio_data["performance_metrics"]["sharpe_ratio"]:.2f}

Section 3 - Rebalancing Recommendations:
- Reduce Technology from 20% to 18%
- Increase Healthcare from 8.7% to 10%
- Maintain current diversification

Apply professional formatting with clear sections and headers.
"""

# Create portfolio analysis Excel
portfolio_response, portfolio_results = create_skills_message(
    client,
    portfolio_excel_prompt,
    [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}],
    prefix="portfolio_analysis_",
)

print("\n" + "=" * 60)
print_download_summary(portfolio_results)

if len(portfolio_results) > 0 and portfolio_results[0]["success"]:
    print("\n✅ Portfolio analysis Excel created successfully!")
```
:::

::: {.cell .markdown}
### 3.2 Investment Committee Presentation {#investment-deck} {#32-investment-committee-presentation-investment-deck}

With our detailed portfolio analysis complete, let\'s now create a
professional presentation for the investment committee. This
presentation will distill the key insights from our Excel analysis into
a concise, visual format suitable for decision-makers.

The presentation will cover:

- Portfolio performance summary with key metrics
- Asset allocation and diversification analysis
- Risk metrics and risk-adjusted returns
- Strategic recommendations for rebalancing
:::

::: {.cell .code}
``` python
print("Creating investment committee presentation...")
print("\n⏱️ Generation time: 1-2 minutes\n")

investment_deck_prompt = f"""
Create a 5-slide investment committee presentation:

Slide 1 - Title:
- Title: "Portfolio Review - Q4 2024"
- Subtitle: "{portfolio_data["portfolio_name"]}"
- Date: January 2025
- Portfolio Value: ${portfolio_data["total_value"]:,.0f}

Slide 2 - Portfolio Overview:
- Title: "Portfolio Performance Summary"
- Two-column layout:

  Left - Key Metrics:
  • Total Value: ${portfolio_data["total_value"]:,.0f}
  • YTD Return: +{portfolio_data["performance_metrics"]["year_to_date_return"]:.1f}%
  • Total Return: ${portfolio_data["performance_metrics"]["total_return"]:,.0f}
  • Sharpe Ratio: {portfolio_data["performance_metrics"]["sharpe_ratio"]:.2f}

  Right - Bar chart of top 5 holdings by value:
  {", ".join([f"{h['ticker']}: ${h['market_value']:,.0f}" for h in top_holdings.to_dict("records")])}

Slide 3 - Sector Allocation:
- Title: "Asset Allocation & Diversification"
- Pie chart showing:
  Technology: {sector_allocation["Technology"]:.1f}%
  Financials: {sector_allocation["Financials"]:.1f}%
  Healthcare: {sector_allocation["Healthcare"]:.1f}%
  Consumer: {sector_allocation["Consumer Discretionary"] + sector_allocation["Consumer Staples"]:.1f}%
  Fixed Income: {sector_allocation["Bonds"]:.1f}%
  Cash: {sector_allocation["Cash"]:.1f}%

Slide 4 - Risk Analysis:
- Title: "Risk Metrics & Analysis"
- Content:
  Risk Indicators:
  • Portfolio Beta: {portfolio_data["performance_metrics"]["beta"]:.2f} (lower market risk)
  • Standard Deviation: {portfolio_data["performance_metrics"]["standard_deviation"]:.1f}%
  • Maximum Drawdown: -12.3%
  • Value at Risk (95%): $62,500

  Risk-Adjusted Performance:
  • Sharpe Ratio: {portfolio_data["performance_metrics"]["sharpe_ratio"]:.2f} (excellent)
  • Alpha Generation: +2.3% vs benchmark

Slide 5 - Recommendations:
- Title: "Strategic Recommendations"
- Bullet points:
  ✓ Maintain current allocation - well diversified
  ✓ Consider profit-taking in Technology (20% → 18%)
  ✓ Increase Healthcare allocation (8.7% → 10%)
  ✓ Monitor bond duration given rate environment
  ✓ Rebalance quarterly to maintain targets

Use professional investment presentation design.
"""

# Create investment committee deck
investment_response, investment_results = create_skills_message(
    client,
    investment_deck_prompt,
    [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}],
    prefix="investment_committee_",
)

print("\n" + "=" * 60)
print_download_summary(investment_results)
print("\n✅ Investment committee presentation created successfully!")
```
:::

::: {.cell .markdown}
## 4. Use Case 3: Automated Reporting Pipeline {#reporting-pipeline} {#4-use-case-3-automated-reporting-pipeline-reporting-pipeline}

So far, we\'ve created individual documents for specific purposes. Now
let\'s demonstrate the power of chaining multiple Skills together in an
automated workflow. This pipeline pattern is essential for production
systems where you need to generate multiple related documents from the
same data source.

In this example, we\'ll create a complete reporting suite that:

1.  **Analyzes data** in Excel with calculations and charts
2.  **Summarizes insights** in a PowerPoint presentation
3.  **Documents the process** in a formal PDF report

This showcases how Skills can work together to create a comprehensive
reporting solution that would traditionally require multiple tools and
manual coordination.

**Key benefits of the pipeline approach:**

- Consistent data across all documents
- Reduced total generation time
- Token usage optimization
- Scalable to multiple report types

**⏱️ Total expected time:** 2-3 minutes for the complete pipeline
:::

::: {.cell .code}
``` python
print("🔄 Starting Automated Reporting Pipeline")
print("=" * 60)
print("This will create a complete reporting suite:")
print("1. Excel analysis → 2. PowerPoint summary → 3. PDF documentation")
print("\n⏱️ Total pipeline time: 2-3 minutes\n")

# Track token usage across the pipeline
pipeline_tokens = {"input": 0, "output": 0}

# Step 1: Create Excel Analysis
print("Step 1/3: Creating Excel analysis with quarterly metrics...")

excel_pipeline_prompt = f"""
Create a quarterly business metrics Excel file:

Sheet 1 - "Quarterly KPIs":
Create a table with these quarterly metrics for 2024:
{
    json.dumps(
        [
            {
                k: v
                for k, v in q.items()
                if k in ["quarter", "revenue", "gross_margin", "customer_count", "churn_rate"]
            }
            for q in quarterly_metrics["quarters"]
        ],
        indent=2,
    )
}

Add:
- Quarter-over-quarter growth calculations
- Average and total rows
- Conditional formatting for trends
- Line chart showing revenue trend
- Column chart showing customer count

Sheet 2 - "YoY Comparison":
Compare Q4 2024 vs Q4 2023 for all metrics.
Calculate percentage changes and highlight improvements.

Professional formatting with headers and borders.
"""

excel_response, excel_results = create_skills_message(
    client,
    excel_pipeline_prompt,
    [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}],
    prefix="pipeline_1_metrics_",
    show_token_usage=False,
)

pipeline_tokens["input"] += excel_response.usage.input_tokens
pipeline_tokens["output"] += excel_response.usage.output_tokens
print(
    f"✓ Excel created - Tokens: {excel_response.usage.input_tokens} in, {excel_response.usage.output_tokens} out"
)

# Step 2: Create PowerPoint Summary
print("\nStep 2/3: Creating PowerPoint summary from metrics...")

ppt_pipeline_prompt = """
Create a 3-slide quarterly metrics summary presentation:

Slide 1:
- Title: "Q4 2024 Metrics Summary"
- Subtitle: "Automated Reporting Pipeline Demo"

Slide 2:
- Title: "Key Performance Indicators"
- Show Q4 2024 metrics:
  • Revenue: $3.2M (+15% QoQ)
  • Customers: 850 (+8.9% QoQ)
  • Gross Margin: 72%
  • Churn Rate: 2.8% (improved from 3.5%)
- Add a simple bar chart comparing Q3 vs Q4 revenue

Slide 3:
- Title: "Quarterly Trend Analysis"
- Line chart showing revenue growth Q1-Q4
- Key insight bullets:
  • Consistent QoQ growth
  • Customer acquisition accelerating
  • Churn reduction successful

Clean, data-focused design.
"""

ppt_response, ppt_results = create_skills_message(
    client,
    ppt_pipeline_prompt,
    [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}],
    prefix="pipeline_2_summary_",
    show_token_usage=False,
)

pipeline_tokens["input"] += ppt_response.usage.input_tokens
pipeline_tokens["output"] += ppt_response.usage.output_tokens
print(
    f"✓ PowerPoint created - Tokens: {ppt_response.usage.input_tokens} in, {ppt_response.usage.output_tokens} out"
)

# Step 3: Create PDF Documentation
print("\nStep 3/3: Creating PDF documentation...")

pdf_pipeline_prompt = """
Create a PDF document summarizing the quarterly reporting pipeline:

AUTOMATED REPORTING PIPELINE
Q4 2024 Results Documentation

EXECUTIVE SUMMARY
This document summarizes the Q4 2024 business metrics generated through
our automated reporting pipeline.

KEY METRICS
- Revenue: $3.2M (15% QoQ growth)
- Customer Base: 850 active customers
- Gross Margin: 72%
- Churn Rate: 2.8% (improved from 3.5%)

PIPELINE COMPONENTS
1. Data Processing: Quarterly metrics analyzed in Excel
2. Visualization: Key insights presented in PowerPoint
3. Documentation: Formal report generated in PDF

AUTOMATION BENEFITS
• Reduced reporting time by 90%
• Consistent format and quality
• Eliminated manual errors
• Scalable to multiple reports

NEXT STEPS
- Expand pipeline to include predictive analytics
- Add automated email distribution
- Implement real-time data feeds

Generated: January 2025
Pipeline Version: 1.0

Format as a professional technical document.
"""

pdf_response, pdf_results = create_skills_message(
    client,
    pdf_pipeline_prompt,
    [{"type": "anthropic", "skill_id": "pdf", "version": "latest"}],
    prefix="pipeline_3_documentation_",
    show_token_usage=False,
)

pipeline_tokens["input"] += pdf_response.usage.input_tokens
pipeline_tokens["output"] += pdf_response.usage.output_tokens
print(
    f"✓ PDF created - Tokens: {pdf_response.usage.input_tokens} in, {pdf_response.usage.output_tokens} out"
)

# Pipeline Summary
print("\n" + "=" * 60)
print("🎯 PIPELINE COMPLETE!")
print("=" * 60)

print("\n📊 Pipeline Token Usage Summary:")
print(f"   Total Input Tokens: {pipeline_tokens['input']:,}")
print(f"   Total Output Tokens: {pipeline_tokens['output']:,}")
print(f"   Total Tokens: {pipeline_tokens['input'] + pipeline_tokens['output']:,}")
print(f"   Average per document: {(pipeline_tokens['input'] + pipeline_tokens['output']) // 3:,}")

print("\n📁 Generated Files:")
all_results = excel_results + ppt_results + pdf_results
for i, result in enumerate(all_results, 1):
    if result["success"]:
        print(f"   {i}. {os.path.basename(result['output_path'])} ({result['size'] / 1024:.1f} KB)")

print("\n✅ Automated reporting pipeline executed successfully!")
print("   All three documents created and linked in workflow.")
```
:::

::: {.cell .markdown}
## Summary & Next Steps {#summary--next-steps}

### What We\'ve Accomplished

In this notebook, you\'ve learned how to:

✅ **Financial Dashboard Creation**

- Built multi-sheet Excel models with formulas and charts
- Generated executive PowerPoint presentations
- Created professional PDF reports

✅ **Portfolio Analysis**

- Developed portfolio analytics workbooks
- Created investment committee presentations
- Implemented risk metrics and rebalancing tools

✅ **Automated Pipelines**

- Chained multiple document formats
- Optimized token usage
- Built production-ready patterns

### Key Takeaways

1.  **Skills dramatically simplify financial document creation** - What
    would take hours manually takes minutes
2.  **Token efficiency is excellent** - Skills use \~90% fewer tokens
    than manual instructions
3.  **Quality is professional-grade** - Documents are immediately usable
    in business contexts
4.  **Automation is straightforward** - Pipeline patterns enable complex
    workflows

### Continue Your Learning

📚 **Next: [Notebook 3 - Custom Skills
Development](https://github.com/anthropics/claude-cookbooks/blob/main/skills/notebooks/03_skills_custom_development.ipynb)**

- Build your own specialized financial skills
- Create company-specific templates
- Implement advanced automation

### Try These Experiments

1.  **Modify the financial dashboard** to include your own metrics
2.  **Create a custom portfolio** with different asset classes
3.  **Build a pipeline** for your specific reporting needs
4.  **Experiment with complexity** to understand generation times
5.  **Track token usage** across different document types

### Resources

- [Claude API Documentation](https://docs.anthropic.com/en/api/messages)
- [Skills
  Documentation](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
- [Best
  Practices](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/best-practices)
- [Files API Reference](https://docs.claude.com/en/api/files-content)
:::

---

## Building Custom Skills for Claude

Source: https://github.com/anthropics/claude-cookbooks/blob/main/skills/notebooks/03_skills_custom_development.ipynb
Path: 08-Plugins-Skills/claude-cookbooks-skills-notebooks-03-skills-custom-development.md

# Building Custom Skills for Claude

Learn how to create, deploy, and manage custom skills to extend
Claude\'s capabilities with your organization\'s specialized knowledge
and workflows.
:::

::: {.cell .markdown}
## Table of Contents

1.  [Introduction & Setup](#introduction)
2.  [Understanding Custom Skills Architecture](#architecture)
3.  [Example 1: Financial Ratio Calculator](#financial-ratio)
4.  [Example 2: Company Brand Guidelines](#brand-guidelines)
5.  [Example 3: Financial Modeling Suite](#financial-modeling)
6.  [Skill Management & Versioning](#management)
7.  [Best Practices & Production Tips](#best-practices)
8.  [Troubleshooting](#troubleshooting)
:::

::: {.cell .markdown}
## 1. Introduction & Setup {#introduction} {#1-introduction--setup-introduction}

### What are Custom Skills?

**Custom skills** are specialized expertise packages you create to teach
Claude your organization\'s unique workflows, domain knowledge, and best
practices. Unlike Anthropic\'s pre-built skills (Excel, PowerPoint,
PDF), custom skills allow you to:

- **Codify organizational knowledge** - Capture your team\'s specific
  methodologies
- **Ensure consistency** - Apply the same standards across all
  interactions
- **Automate complex workflows** - Chain together multi-step processes
- **Maintain intellectual property** - Keep proprietary methods secure

### Key Benefits

  -----------------------------------------------------------------------
  Benefit                       Description
  ----------------------------- -----------------------------------------
  **Expertise at Scale**        Deploy specialized knowledge to every
                                Claude interaction

  **Version Control**           Track changes and roll back if needed

  **Composability**             Combine multiple skills for complex tasks

  **Privacy**                   Your skills remain private to your
                                organization
  -----------------------------------------------------------------------

### Prerequisites

Before starting, ensure you have:

- Completed [Notebook 1: Introduction to
  Skills](https://github.com/anthropics/claude-cookbooks/blob/main/skills/notebooks/01_skills_introduction.ipynb)
- An Anthropic API key with Skills beta access
- Python environment with the local SDK installed
:::

::: {.cell .markdown}
### Environment Setup

Let\'s set up our environment and import necessary libraries:
:::

::: {.cell .code}
``` python
import os
import sys
from pathlib import Path
from typing import Any

# Add parent directory for imports
sys.path.insert(0, str(Path.cwd().parent))

from anthropic import Anthropic
from anthropic.lib import files_from_dir
from dotenv import load_dotenv

# Import our utilities
from file_utils import (
    download_all_files,
    extract_file_ids,
    print_download_summary,
)

# We'll create skill_utils later in this notebook
# from skill_utils import (
#     create_skill,
#     list_skills,
#     delete_skill,
#     test_skill
# )

# Load environment variables
load_dotenv(Path.cwd().parent / ".env")

API_KEY = os.getenv("ANTHROPIC_API_KEY")
MODEL = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-5")

if not API_KEY:
    raise ValueError(
        "ANTHROPIC_API_KEY not found. Copy ../.env.example to ../.env and add your API key."
    )

# Initialize client with Skills beta
client = Anthropic(api_key=API_KEY, default_headers={"anthropic-beta": "skills-2025-10-02"})

# Setup directories
SKILLS_DIR = Path.cwd().parent / "custom_skills"
OUTPUT_DIR = Path.cwd().parent / "outputs"
OUTPUT_DIR.mkdir(exist_ok=True)

print("✓ API key loaded")
print(f"✓ Using model: {MODEL}")
print(f"✓ Custom skills directory: {SKILLS_DIR}")
print(f"✓ Output directory: {OUTPUT_DIR}")
print("\n📝 Skills beta header configured for skill management")
```
:::

::: {.cell .markdown}
## 2. Understanding Custom Skills Architecture {#architecture} {#2-understanding-custom-skills-architecture-architecture}

### Skill Structure

Every custom skill follows this directory structure:

    skill_name/
    ├── SKILL.md           # REQUIRED: Instructions with YAML frontmatter
    ├── *.md               # Optional: Any additional .md files (documentation, guides)
    ├── scripts/           # Optional: Executable code
    │   ├── process.py
    │   └── utils.js
    └── resources/         # Optional: Templates, data files
        └── template.xlsx

**Important:**

- **SKILL.md is the ONLY required file** - everything else is optional
- **Multiple .md files allowed** - You can have any number of markdown
  files in the top-level folder
- **All .md files are loaded** - Not just SKILL.md and REFERENCE.md, but
  any .md file you include
- **Organize as needed** - Use multiple .md files to structure complex
  documentation

📖 Read our engineering blog post on [Equipping agents for the real
world with
Skills](https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills)

### Skills Are Not Just Markdown

![Skills Can Include Scripts and Files](https://github.com/anthropics/claude-cookbooks/blob/main/skills/assets/not-just-markdown.png)

Skills can bundle various file types:

- **Markdown files**: Instructions and documentation (SKILL.md,
  REFERENCE.md, etc.)
- **Scripts**: Python, JavaScript, or other executable code for complex
  operations
- **Templates**: Pre-built files that can be customized (Excel
  templates, document templates)
- **Resources**: Supporting data files, configuration, or assets

### SKILL.md Requirements {#skillmd-requirements}

The `SKILL.md` file must include:

1.  **YAML Frontmatter** (name: 64 chars, description: 1024 chars)
    - `name`: Lowercase alphanumeric with hyphens (required)
    - `description`: Brief description of what the skill does (required)
2.  **Instructions** (markdown format)
    - Clear guidance for Claude
    - Examples of usage
    - Any constraints or rules
    - Recommended: Keep under 5,000 tokens

### Additional Documentation Files

You can include multiple markdown files for better organization:

    skill_name/
    ├── SKILL.md           # Main instructions (required)
    ├── REFERENCE.md       # API reference (optional)
    ├── EXAMPLES.md        # Usage examples (optional)
    ├── TROUBLESHOOTING.md # Common issues (optional)
    └── CHANGELOG.md       # Version history (optional)

All `.md` files in the root directory will be available to Claude when
the skill is loaded.

### Bundled Files Example

![Bundled Files in Skills](https://github.com/anthropics/claude-cookbooks/blob/main/skills/assets/skills-bundled-files.png)

This example shows how Skills can bundle multiple files:

- **SKILL.md**: Contains the main instructions with colors, typography,
  and sections
- **slide-decks.md**: Additional documentation for specific use cases
- **Scripts and resources**: Can be referenced and used during skill
  execution

### Progressive Disclosure

Skills load in three stages to optimize token usage:

  ----------------------------------------------------------------------------
  Stage            Content         Token Cost           When Loaded
  ---------------- --------------- -------------------- ----------------------
  **1. Metadata**  Name &          name: 64 chars,      Always visible
                   description     description: 1024    
                                   chars                

  **2.             All .md files   \<5,000 tokens       When relevant
  Instructions**                   recommended          

  **3. Resources** Scripts & files As needed            During execution
  ----------------------------------------------------------------------------

### API Workflow

``` python
# 1. Create skill
skill = client.beta.skills.create(
    display_title="My Skill",
    files=files_from_dir("path/to/skill")
)

# 2. Use in messages
response = client.beta.messages.create(
    container={
        "skills": [{
            "type": "custom",
            "skill_id": skill.id,
            "version": "latest"
        }]
    },
    # ... rest of message parameters
)
```

### Best Practices

For detailed guidance on skill creation and best practices, see:

- [Claude Skills Best
  Practices](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/best-practices)
- [Skills
  Documentation](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
:::

::: {.cell .markdown}
### Create Skill Utility Functions

Let\'s create helper functions for skill management:
:::

::: {.cell .code}
``` python
def create_skill(client: Anthropic, skill_path: str, display_title: str) -> dict[str, Any]:
    """
    Create a new custom skill from a directory.

    Args:
        client: Anthropic client instance
        skill_path: Path to skill directory
        display_title: Human-readable skill name

    Returns:
        Dictionary with skill_id, version, and metadata
    """
    try:
        # Create skill using files_from_dir
        skill = client.beta.skills.create(
            display_title=display_title, files=files_from_dir(skill_path)
        )

        return {
            "success": True,
            "skill_id": skill.id,
            "display_title": skill.display_title,
            "latest_version": skill.latest_version,
            "created_at": skill.created_at,
            "source": skill.source,
        }
    except Exception as e:
        return {"success": False, "error": str(e)}


def list_custom_skills(client: Anthropic) -> list[dict[str, Any]]:
    """
    List all custom skills in the workspace.

    Returns:
        List of skill dictionaries
    """
    try:
        skills_response = client.beta.skills.list(source="custom")

        skills = []
        for skill in skills_response.data:
            skills.append(
                {
                    "skill_id": skill.id,
                    "display_title": skill.display_title,
                    "latest_version": skill.latest_version,
                    "created_at": skill.created_at,
                    "updated_at": skill.updated_at,
                }
            )

        return skills
    except Exception as e:
        print(f"Error listing skills: {e}")
        return []


def delete_skill(client: Anthropic, skill_id: str) -> bool:
    """
    Delete a custom skill and all its versions.

    Args:
        client: Anthropic client
        skill_id: ID of skill to delete

    Returns:
        True if successful, False otherwise
    """
    try:
        # First delete all versions
        versions = client.beta.skills.versions.list(skill_id=skill_id)

        for version in versions.data:
            client.beta.skills.versions.delete(skill_id=skill_id, version=version.version)

        # Then delete the skill itself
        client.beta.skills.delete(skill_id)
        return True

    except Exception as e:
        print(f"Error deleting skill: {e}")
        return False


def test_skill(
    client: Anthropic,
    skill_id: str,
    test_prompt: str,
    model: str = "claude-sonnet-4-5",
) -> Any:
    """
    Test a custom skill with a prompt.

    Args:
        client: Anthropic client
        skill_id: ID of skill to test
        test_prompt: Prompt to test the skill
        model: Model to use for testing

    Returns:
        Response from Claude
    """
    response = client.beta.messages.create(
        model=model,
        max_tokens=4096,
        container={"skills": [{"type": "custom", "skill_id": skill_id, "version": "latest"}]},
        tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
        messages=[{"role": "user", "content": test_prompt}],
        betas=[
            "code-execution-2025-08-25",
            "files-api-2025-04-14",
            "skills-2025-10-02",
        ],
    )

    return response


print("✓ Skill utility functions defined")
print("  - create_skill()")
print("  - list_custom_skills()")
print("  - delete_skill()")
print("  - test_skill()")
```
:::

::: {.cell .markdown}
### Check Existing Custom Skills

Let\'s see if any custom skills already exist in your workspace:
:::

::: {.cell .markdown}
### ⚠️ Important: Clean Up Existing Skills Before Starting {#warning-important-clean-up-existing-skills-before-starting}

If you\'re re-running this notebook, you may have skills from a previous
session. Skills cannot have duplicate display titles, so you have three
options:

1.  **Delete existing skills** (recommended for testing) - Clean slate
    approach
2.  **Use different display titles** - Add timestamps or version numbers
    to names
3.  **Update existing skills with new versions** - See [Skill Management
    & Versioning](#management) section

Let\'s check for and optionally clean up existing skills:
:::

::: {.cell .code}
``` python
# Check for existing skills that might conflict
existing_skills = list_custom_skills(client)
skill_titles_to_create = [
    "Financial Ratio Analyzer",
    "Corporate Brand Guidelines",
    "Financial Modeling Suite",
]
conflicting_skills = []

if existing_skills:
    print(f"Found {len(existing_skills)} existing custom skill(s):")
    for skill in existing_skills:
        print(f"  - {skill['display_title']} (ID: {skill['skill_id']})")
        if skill["display_title"] in skill_titles_to_create:
            conflicting_skills.append(skill)

    if conflicting_skills:
        print(
            f"\n⚠️ Found {len(conflicting_skills)} skill(s) that will conflict with this notebook:"
        )
        for skill in conflicting_skills:
            print(f"  - {skill['display_title']} (ID: {skill['skill_id']})")

        print("\n" + "=" * 70)
        print("To clean up these skills and start fresh, uncomment and run:")
        print("=" * 70)
        print("\n# UNCOMMENT THE LINES BELOW TO DELETE CONFLICTING SKILLS:")
        print("# for skill in conflicting_skills:")
        print("#     if delete_skill(client, skill['skill_id']):")
        print("#         print(f\"✅ Deleted: {skill['display_title']}\")")
        print("#     else:")
        print("#         print(f\"❌ Failed to delete: {skill['display_title']}\")")

        # for skill in conflicting_skills:
        #     if delete_skill(client, skill['skill_id']):
        #         print(f"✅ Deleted: {skill['display_title']}")
        #     else:
        #         print(f"❌ Failed to delete: {skill['display_title']}")
    else:
        print("\n✅ No conflicting skills found. Ready to proceed!")
else:
    print("✅ No existing custom skills found. Ready to create new ones!")
```
:::

::: {.cell .markdown}
## 3. Example 1: Financial Ratio Calculator {#financial-ratio} {#3-example-1-financial-ratio-calculator-financial-ratio}

Let\'s create our first custom skill - a financial ratio calculator that
can analyze company financial health.

### Skill Overview

The **Financial Ratio Calculator** skill will:

- Calculate key financial ratios (ROE, P/E, Current Ratio, etc.)
- Interpret ratios with industry context
- Generate formatted reports
- Work with various data formats (CSV, JSON, text)
:::

::: {.cell .markdown}
### Upload the Financial Analyzer Skill

Now let\'s upload our financial analyzer skill to Claude:
:::

::: {.cell .code}
``` python
# Upload the Financial Analyzer skill
financial_skill_path = SKILLS_DIR / "analyzing-financial-statements"

if financial_skill_path.exists():
    print("Uploading Financial Analyzer skill...")
    result = create_skill(client, str(financial_skill_path), "Financial Ratio Analyzer")

    if result["success"]:
        financial_skill_id = result["skill_id"]
        print("✅ Skill uploaded successfully!")
        print(f"   Skill ID: {financial_skill_id}")
        print(f"   Version: {result['latest_version']}")
        print(f"   Created: {result['created_at']}")
    else:
        print(f"❌ Upload failed: {result['error']}")
        if "cannot reuse an existing display_title" in str(result["error"]):
            print("\n💡 Solution: A skill with this name already exists.")
            print("   Run the 'Clean Up Existing Skills' cell above to delete it first,")
            print("   or change the display_title to something unique.")
else:
    print(f"⚠️ Skill directory not found: {financial_skill_path}")
    print(
        "Please ensure the custom_skills directory contains the analyzing-financial-statements folder."
    )
```
:::

::: {.cell .markdown}
### Test the Financial Analyzer Skill

Let\'s test the skill with sample financial data:
:::

::: {.cell .code}
``` python
# Test the Financial Analyzer skill
if "financial_skill_id" in locals():
    test_prompt = """
    Calculate financial ratios for this company:

    Income Statement:
    - Revenue: $1,000M
    - EBITDA: $200M
    - Net Income: $120M

    Balance Sheet:
    - Total Assets: $2,000M
    - Current Assets: $500M
    - Current Liabilities: $300M
    - Total Debt: $400M
    - Shareholders Equity: $1,200M

    Market Data:
    - Share Price: $50
    - Shares Outstanding: 100M

    Please calculate key ratios and provide analysis.
    """

    print("Testing Financial Analyzer skill...")
    response = test_skill(client, financial_skill_id, test_prompt)

    # Print response
    for content in response.content:
        if content.type == "text":
            print(content.text)
else:
    print("⚠️ Please upload the Financial Analyzer skill first (run the previous cell)")
```
:::

::: {.cell .markdown}
## 4. Example 2: Company Brand Guidelines {#brand-guidelines} {#4-example-2-company-brand-guidelines-brand-guidelines}

Now let\'s create a skill that ensures all documents follow corporate
brand standards.

### Skill Overview {#skill-overview}

The **Brand Guidelines** skill will:

- Apply consistent colors, fonts, and layouts
- Ensure logo placement and usage
- Maintain professional tone and messaging
- Work across all document types (Excel, PowerPoint, PDF)
:::

::: {.cell .code}
``` python
# Upload the Brand Guidelines skill
brand_skill_path = SKILLS_DIR / "applying-brand-guidelines"

if brand_skill_path.exists():
    print("Uploading Brand Guidelines skill...")
    result = create_skill(client, str(brand_skill_path), "Corporate Brand Guidelines")

    if result["success"]:
        brand_skill_id = result["skill_id"]
        print("✅ Skill uploaded successfully!")
        print(f"   Skill ID: {brand_skill_id}")
        print(f"   Version: {result['latest_version']}")
    else:
        print(f"❌ Upload failed: {result['error']}")
        if "cannot reuse an existing display_title" in str(result["error"]):
            print("\n💡 Solution: A skill with this name already exists.")
            print("   Run the 'Clean Up Existing Skills' cell above to delete it first,")
            print("   or change the display_title to something unique.")
else:
    print(f"⚠️ Skill directory not found: {brand_skill_path}")
```
:::

::: {.cell .markdown}
### Test Brand Guidelines with Document Creation

Let\'s test the brand skill by creating a branded PowerPoint
presentation:
:::

::: {.cell .code}
``` python
# Test Brand Guidelines skill with PowerPoint creation
if "brand_skill_id" in locals():
    # Combine brand skill with Anthropic's pptx skill
    response = client.beta.messages.create(
        model=MODEL,
        max_tokens=4096,
        container={
            "skills": [
                {"type": "custom", "skill_id": brand_skill_id, "version": "latest"},
                {"type": "anthropic", "skill_id": "pptx", "version": "latest"},
            ]
        },
        tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
        messages=[
            {
                "role": "user",
                "content": """Create a 3-slide PowerPoint presentation following Acme Corporation brand guidelines:

            Slide 1: Title slide for "Q4 2025 Results"
            Slide 2: Revenue Overview with a chart showing Q1-Q4 growth
            Slide 3: Key Achievements (3 bullet points)

            Apply all brand colors, fonts, and formatting standards.
            """,
            }
        ],
        betas=[
            "code-execution-2025-08-25",
            "files-api-2025-04-14",
            "skills-2025-10-02",
        ],
    )

    print("Response from Claude:")
    for content in response.content:
        if content.type == "text":
            print(content.text[:500] + "..." if len(content.text) > 500 else content.text)

    # Download generated file
    file_ids = extract_file_ids(response)
    if file_ids:
        results = download_all_files(
            client, response, output_dir=str(OUTPUT_DIR), prefix="branded_"
        )
        print_download_summary(results)
else:
    print("⚠️ Please upload the Brand Guidelines skill first")
```
:::

::: {.cell .markdown}
## 5. Example 3: Financial Modeling Suite {#financial-modeling} {#5-example-3-financial-modeling-suite-financial-modeling}

Let\'s create our most advanced skill - a comprehensive financial
modeling suite for valuation and risk analysis.

### Skill Overview {#skill-overview}

The **Financial Modeling Suite** skill provides:

- **DCF Valuation**: Complete discounted cash flow models
- **Sensitivity Analysis**: Test impact of variables on valuation
- **Monte Carlo Simulation**: Risk modeling with probability
  distributions
- **Scenario Planning**: Best/base/worst case analysis

This demonstrates a multi-file skill with complex calculations and
professional-grade financial modeling.
:::

::: {.cell .markdown}
### Upload the Financial Modeling Suite

First, upload the financial modeling skill:
:::

::: {.cell .code}
``` python
# Upload the Financial Modeling Suite skill
modeling_skill_path = SKILLS_DIR / "creating-financial-models"

if modeling_skill_path.exists():
    print("Uploading Financial Modeling Suite skill...")
    result = create_skill(client, str(modeling_skill_path), "Financial Modeling Suite")

    if result["success"]:
        modeling_skill_id = result["skill_id"]
        print("✅ Skill uploaded successfully!")
        print(f"   Skill ID: {modeling_skill_id}")
        print(f"   Version: {result['latest_version']}")
        print("\nThis skill includes:")
        print("   - DCF valuation model (dcf_model.py)")
        print("   - Sensitivity analysis framework (sensitivity_analysis.py)")
        print("   - Monte Carlo simulation capabilities")
        print("   - Scenario planning tools")
    else:
        print(f"❌ Upload failed: {result['error']}")
else:
    print(f"⚠️ Skill directory not found: {modeling_skill_path}")
    print(
        "Please ensure the custom_skills directory contains the creating-financial-models folder."
    )
```
:::

::: {.cell .markdown}
### Test the Financial Modeling Suite

Let\'s test the advanced modeling capabilities with a DCF valuation
request:
:::

::: {.cell .code}
``` python
# Test the Financial Modeling Suite with a DCF valuation
if "modeling_skill_id" in locals():
    dcf_test_prompt = """
    Perform a DCF valuation for TechCorp with the following data:

    Historical Financials (Last 3 Years):
    - Revenue: $500M, $600M, $750M
    - EBITDA Margin: 25%, 27%, 30%
    - CapEx: $50M, $55M, $60M
    - Working Capital: 15% of revenue

    Projections:
    - Revenue growth: 20% for years 1-3, then declining to 5% by year 5
    - EBITDA margin expanding to 35% by year 5
    - Terminal growth rate: 3%

    Market Assumptions:
    - WACC: 10%
    - Tax rate: 25%
    - Current net debt: $200M
    - Shares outstanding: 100M

    Please create a complete DCF model with sensitivity analysis on WACC and terminal growth.
    Generate an Excel file with the full model including:
    1. Revenue projections
    2. Free cash flow calculations
    3. Terminal value
    4. Enterprise value to equity value bridge
    5. Sensitivity table
    """

    print("Testing Financial Modeling Suite with DCF valuation...")
    print("=" * 70)
    print("\n⏱️ Note: Complex financial model generation may take 1-2 minutes.\n")

    response = client.beta.messages.create(
        model=MODEL,
        max_tokens=4096,
        container={
            "skills": [
                {"type": "custom", "skill_id": modeling_skill_id, "version": "latest"},
                {"type": "anthropic", "skill_id": "xlsx", "version": "latest"},
            ]
        },
        tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
        messages=[{"role": "user", "content": dcf_test_prompt}],
        betas=[
            "code-execution-2025-08-25",
            "files-api-2025-04-14",
            "skills-2025-10-02",
        ],
    )

    # Print Claude's response
    for content in response.content:
        if content.type == "text":
            # Print first 800 characters to keep output manageable
            text = content.text
            if len(text) > 800:
                print(text[:800] + "\n\n[... Output truncated for brevity ...]")
            else:
                print(text)

    # Download the DCF model if generated
    file_ids = extract_file_ids(response)
    if file_ids:
        print("\n" + "=" * 70)
        print("Downloading generated DCF model...")
        results = download_all_files(
            client, response, output_dir=str(OUTPUT_DIR), prefix="dcf_model_"
        )
        print_download_summary(results)
        print("\n💡 Open the Excel file to explore the complete DCF valuation model!")
else:
    print("⚠️ Please upload the Financial Modeling Suite skill first (run the previous cell)")
```
:::

::: {.cell .markdown}
## 6. Skill Management & Versioning {#management} {#6-skill-management--versioning-management}

Managing skills over time requires understanding versioning, updates,
and lifecycle management.

### Listing Your Skills

Get an overview of all custom skills in your workspace:
:::

::: {.cell .code}
``` python
# List all your custom skills
my_skills = list_custom_skills(client)

if my_skills:
    print(f"You have {len(my_skills)} custom skill(s):\n")
    print("=" * 70)
    for i, skill in enumerate(my_skills, 1):
        print(f"\n{i}. {skill['display_title']}")
        print(f"   Skill ID: {skill['skill_id']}")
        print(f"   Current Version: {skill['latest_version']}")
        print(f"   Created: {skill['created_at']}")
        if skill.get("updated_at"):
            print(f"   Last Updated: {skill['updated_at']}")
    print("\n" + "=" * 70)
else:
    print("No custom skills found in your workspace.")
```
:::

::: {.cell .markdown}
### Creating New Versions

Skills support versioning to maintain history and enable rollback.
Let\'s make an enhancement to our Financial Analyzer skill and create a
new version.

#### Step 1: Enhance the Financial Analyzer

We\'ll add **healthcare industry** benchmarks to make our skill more
versatile. This is a real-world scenario where you\'d expand a skill\'s
capabilities based on user needs.
:::

::: {.cell .code}
``` python
# Add healthcare industry benchmarks to the Financial Analyzer
# This demonstrates a realistic skill enhancement scenario

if "financial_skill_id" in locals():
    # Read the current interpret_ratios.py file
    interpret_file_path = SKILLS_DIR / "analyzing-financial-statements" / "interpret_ratios.py"

    with open(interpret_file_path) as f:
        content = f.read()

    # Add healthcare benchmarks after the 'manufacturing' section
    healthcare_benchmarks = """        },
        'healthcare': {
            'current_ratio': {'excellent': 2.3, 'good': 1.8, 'acceptable': 1.4, 'poor': 1.0},
            'debt_to_equity': {'excellent': 0.3, 'good': 0.6, 'acceptable': 1.0, 'poor': 1.8},
            'roe': {'excellent': 0.22, 'good': 0.16, 'acceptable': 0.11, 'poor': 0.07},
            'gross_margin': {'excellent': 0.65, 'good': 0.45, 'acceptable': 0.30, 'poor': 0.20},
            'pe_ratio': {'undervalued': 18, 'fair': 28, 'growth': 40, 'expensive': 55}
        """

    # Find the position after manufacturing section and before the closing brace
    insert_pos = content.find("        }\n    }")  # Find the end of the BENCHMARKS dict

    if insert_pos != -1:
        # Insert the healthcare benchmarks
        new_content = content[:insert_pos] + healthcare_benchmarks + content[insert_pos:]

        # Save the enhanced file
        with open(interpret_file_path, "w") as f:
            f.write(new_content)

        print("✅ Enhanced Financial Analyzer with healthcare industry benchmarks")
        print("\nChanges made:")
        print("  - Added healthcare industry to BENCHMARKS")
        print("  - Includes specific thresholds for:")
        print("    • Current ratio (liquidity)")
        print("    • Debt-to-equity (leverage)")
        print("    • ROE (profitability)")
        print("    • Gross margin")
        print("    • P/E ratio (valuation)")
        print("\n📝 Now we can create a new version of the skill with this enhancement!")
    else:
        print("⚠️ Could not find the correct position to insert healthcare benchmarks")
        print("The file structure may have changed.")
else:
    print("⚠️ Please upload the Financial Analyzer skill first (run cells in Section 3)")
```
:::

::: {.cell .markdown}
#### Step 2: Create a New Version

Now that we\'ve enhanced our skill, let\'s create a new version to track
this change:
:::

::: {.cell .code}
``` python
# Create a new version of the enhanced Financial Analyzer skill
def create_skill_version(client: Anthropic, skill_id: str, skill_path: str):
    """Create a new version of an existing skill."""
    try:
        version = client.beta.skills.versions.create(
            skill_id=skill_id, files=files_from_dir(skill_path)
        )
        return {
            "success": True,
            "version": version.version,
            "created_at": version.created_at,
        }
    except Exception as e:
        return {"success": False, "error": str(e)}


# Create the new version with our healthcare enhancement
if "financial_skill_id" in locals():
    print("Creating new version of Financial Analyzer with healthcare benchmarks...")

    result = create_skill_version(
        client, financial_skill_id, str(SKILLS_DIR / "analyzing-financial-statements")
    )

    if result["success"]:
        print("✅ New version created successfully!")
        print(f"   Version: {result['version']}")
        print(f"   Created: {result['created_at']}")
        print("\n📊 Version History:")
        print("   v1: Original skill with tech, retail, financial, manufacturing")
        print(f"   v{result['version']}: Enhanced with healthcare industry benchmarks")
    else:
        print(f"❌ Version creation failed: {result['error']}")
else:
    print("⚠️ Please run the previous cells to upload the skill and make enhancements first")
```
:::

::: {.cell .markdown}
#### Step 3: Test the New Version

Let\'s verify our enhancement works by analyzing a healthcare company:
:::

::: {.cell .code}
``` python
# Test the enhanced skill with healthcare industry data
if "financial_skill_id" in locals():
    healthcare_test_prompt = """
    Analyze this healthcare company using the healthcare industry benchmarks:

    Company: MedTech Solutions (Healthcare Industry)

    Income Statement:
    - Revenue: $800M
    - EBITDA: $320M
    - Net Income: $160M

    Balance Sheet:
    - Total Assets: $1,200M
    - Current Assets: $400M
    - Current Liabilities: $200M
    - Total Debt: $300M
    - Shareholders Equity: $700M

    Market Data:
    - Share Price: $75
    - Shares Outstanding: 50M

    Please calculate key ratios and provide healthcare-specific analysis.
    """

    print("Testing enhanced Financial Analyzer with healthcare company...")
    print("=" * 70)

    response = test_skill(client, financial_skill_id, healthcare_test_prompt, MODEL)

    # Print Claude's analysis
    for content in response.content:
        if content.type == "text":
            # Print first 1000 characters to keep output manageable
            text = content.text
            if len(text) > 1000:
                print(text[:1000] + "\n\n[... Output truncated for brevity ...]")
            else:
                print(text)

    print(
        "\n✅ The skill now recognizes 'healthcare' as an industry and applies specific benchmarks!"
    )
else:
    print("⚠️ Please run the previous cells to create the enhanced version first")
```
:::

::: {.cell .markdown}
### Cleanup: Managing Your Skills

When you\'re done testing or need to clean up your workspace, you can
selectively remove skills. Let\'s review what we\'ve created and provide
options for cleanup:
:::

::: {.cell .code}
``` python
# Comprehensive skill cleanup with detailed reporting
def review_and_cleanup_skills(client, dry_run=True):
    """
    Review all skills and optionally clean up the ones created in this notebook.

    Args:
        client: Anthropic client
        dry_run: If True, only show what would be deleted without actually deleting
    """
    # Get all current skills
    all_skills = list_custom_skills(client)

    # Skills we created in this notebook
    notebook_skill_names = [
        "Financial Ratio Analyzer",
        "Corporate Brand Guidelines",
        "Financial Modeling Suite",
    ]

    # Track skills created by this notebook
    notebook_skills = []
    other_skills = []

    for skill in all_skills:
        if skill["display_title"] in notebook_skill_names:
            notebook_skills.append(skill)
        else:
            other_skills.append(skill)

    print("=" * 70)
    print("SKILL INVENTORY REPORT")
    print("=" * 70)

    print(f"\nTotal custom skills in workspace: {len(all_skills)}")

    if notebook_skills:
        print(f"\n📚 Skills created by this notebook ({len(notebook_skills)}):")
        for skill in notebook_skills:
            print(f"   • {skill['display_title']}")
            print(f"     ID: {skill['skill_id']}")
            print(f"     Version: {skill['latest_version']}")
            print(f"     Created: {skill['created_at']}")
    else:
        print("\n✅ No skills from this notebook found")

    if other_skills:
        print(f"\n🔧 Other skills in workspace ({len(other_skills)}):")
        for skill in other_skills:
            print(f"   • {skill['display_title']} (v{skill['latest_version']})")

    # Cleanup options
    if notebook_skills:
        print("\n" + "=" * 70)
        print("CLEANUP OPTIONS")
        print("=" * 70)

        if dry_run:
            print("\n🔍 DRY RUN MODE - No skills will be deleted")
            print("\nTo delete the notebook skills, uncomment and run:")
            print("-" * 40)
            print("# review_and_cleanup_skills(client, dry_run=False)")
            print("-" * 40)

            print("\nThis would delete:")
            for skill in notebook_skills:
                print(f"   • {skill['display_title']}")
        else:
            print("\n⚠️ DELETION MODE - Skills will be permanently removed")
            print("\nDeleting notebook skills...")

            success_count = 0
            for skill in notebook_skills:
                if delete_skill(client, skill["skill_id"]):
                    print(f"   ✅ Deleted: {skill['display_title']}")
                    success_count += 1
                else:
                    print(f"   ❌ Failed to delete: {skill['display_title']}")

            print(f"\n📊 Cleanup complete: {success_count}/{len(notebook_skills)} skills deleted")

    return {
        "total_skills": len(all_skills),
        "notebook_skills": len(notebook_skills),
        "other_skills": len(other_skills),
        "notebook_skill_ids": [s["skill_id"] for s in notebook_skills],
    }


# Run the review (in dry-run mode by default)
print("Reviewing your custom skills workspace...")
cleanup_summary = review_and_cleanup_skills(client, dry_run=True)

# Store skill IDs for potential cleanup
if cleanup_summary["notebook_skill_ids"]:
    skills_to_cleanup = cleanup_summary["notebook_skill_ids"]
    print(f"\n💡 Tip: {len(skills_to_cleanup)} skill(s) can be cleaned up when you're done testing")

# UNCOMMENT THE LINE BELOW TO ACTUALLY DELETE THE NOTEBOOK SKILLS:
# review_and_cleanup_skills(client, dry_run=False)
```
:::

::: {.cell .markdown}
## 7. Best Practices & Production Tips {#best-practices} {#7-best-practices--production-tips-best-practices}

### Skill Design Principles

1.  **Single Responsibility**: Each skill should focus on one area of
    expertise
2.  **Clear Documentation**: SKILL.md should be comprehensive yet
    concise
3.  **Error Handling**: Scripts should handle edge cases gracefully
4.  **Version Control**: Use Git to track skill changes
5.  **Testing**: Always test skills before production deployment

### Directory Structure Best Practices

    custom_skills/
    ├── financial_analyzer/       # Single purpose, clear naming
    │   ├── SKILL.md             # Under 5,000 tokens
    │   ├── scripts/             # Modular Python/JS files
    │   └── tests/               # Unit tests for scripts
    ├── brand_guidelines/         # Organizational standards
    │   ├── SKILL.md
    │   ├── REFERENCE.md         # Additional documentation
    │   └── assets/              # Logos, templates

### Performance Optimization

  -----------------------------------------------------------------------
  Strategy             Impact           Implementation
  -------------------- ---------------- ---------------------------------
  **Minimal            Faster skill     name: 64 chars, description: 1024
  Frontmatter**        discovery        chars

  **Lazy Loading**     Reduced token    Reference files only when needed
                       usage            

  **Skill              Avoid            Combine skills vs. mega-skill
  Composition**        duplication      

  **Caching**          Faster responses Reuse skill containers
  -----------------------------------------------------------------------

### Security Considerations

- **API Keys**: Never hardcode credentials in skills
- **Data Privacy**: Don\'t include sensitive data in skill files
- **Access Control**: Skills are workspace-specific
- **Validation**: Sanitize inputs in scripts
- **Audit Trail**: Log skill usage for compliance
:::

::: {.cell .markdown}
## Next Steps

🎉 **Congratulations!** You\'ve learned how to create, deploy, and
manage custom skills for Claude.

### What You\'ve Learned

- ✅ Custom skill architecture and requirements
- ✅ Creating skills with SKILL.md and Python scripts
- ✅ Uploading skills via the API
- ✅ Combining custom and Anthropic skills
- ✅ Best practices for production deployment
- ✅ Troubleshooting common issues

### Continue Your Journey

1.  **Experiment**: Modify the example skills for your use cases
2.  **Build**: Create skills for your organization\'s workflows
3.  **Optimize**: Monitor token usage and performance
4.  **Share**: Document your skills for team collaboration

### Resources

- [Claude API Documentation](https://docs.anthropic.com/en/api/messages)
- [Skills
  Documentation](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
- [Best
  Practices](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/best-practices)
- [Files API
  Documentation](https://docs.claude.com/en/api/files-content)
- Example Skills Repository (coming soon)

### Skill Ideas to Try

- 📊 **Data Pipeline**: ETL workflows with validation
- 📝 **Document Templates**: Contracts, proposals, reports
- 🔍 **Code Review**: Style guides and best practices
- 📈 **Analytics Dashboard**: KPI tracking and visualization
- 🤖 **Automation Suite**: Repetitive task workflows

Happy skill building! 🚀
:::

---

## How to add skills support to your agent - Agent Skills

Source: https://agentskills.io/client-implementation/adding-skills-support
Path: 08-Plugins-Skills/client-implementation-adding-skills-support.md

## On this page

- [The core principle: progressive disclosure](#the-core-principle-progressive-disclosure)
- [Step 1: Discover skills](#step-1-discover-skills)
  - [Where to scan](#where-to-scan)
  - [What to scan for](#what-to-scan-for)
  - [Handling name collisions](#handling-name-collisions)
  - [Trust considerations](#trust-considerations)
  - [Cloud-hosted and sandboxed agents](#cloud-hosted-and-sandboxed-agents)
- [Step 2: Parse SKILL.md files](#step-2-parse-skill-md-files)
  - [Frontmatter extraction](#frontmatter-extraction)
  - [Handling malformed YAML](#handling-malformed-yaml)
  - [Lenient validation](#lenient-validation)
  - [What to store](#what-to-store)
- [Step 3: Disclose available skills to the model](#step-3-disclose-available-skills-to-the-model)
  - [Building the skill catalog](#building-the-skill-catalog)
  - [Where to place the catalog](#where-to-place-the-catalog)
  - [Behavioral instructions](#behavioral-instructions)
  - [Filtering](#filtering)
  - [When no skills are available](#when-no-skills-are-available)
- [Step 4: Activate skills](#step-4-activate-skills)
  - [Model-driven activation](#model-driven-activation)
  - [User-explicit activation](#user-explicit-activation)
  - [What the model receives](#what-the-model-receives)
  - [Structured wrapping](#structured-wrapping)
  - [Listing bundled resources](#listing-bundled-resources)
  - [Permission allowlisting](#permission-allowlisting)
- [Step 5: Manage skill context over time](#step-5-manage-skill-context-over-time)
  - [Protect skill content from context compaction](#protect-skill-content-from-context-compaction)
  - [Deduplicate activations](#deduplicate-activations)
  - [Subagent delegation (optional)](#subagent-delegation-optional)

For client implementors

# How to add skills support to your agent

Copy pageCopy page

A guide for adding Agent Skills support to an AI agent or development tool.

Copy pageCopy page

This guide walks through how to add Agent Skills support to an AI agent or development tool. It covers the full lifecycle: discovering skills, telling the model about them, loading their content into context, and keeping that content effective over time. The core integration is the same regardless of your agent’s architecture. The implementation details vary based on two factors:

- **Where do skills live?** A locally-running agent can scan the user’s filesystem for skill directories. A cloud-hosted or sandboxed agent will need an alternative discovery mechanism — an API, a remote registry, or bundled assets.
- **How does the model access skill content?** If the model has file-reading capabilities, it can read `SKILL.md` files directly. Otherwise, you’ll provide a dedicated tool or inject skill content into the prompt programmatically.

The guide notes where these differences matter. You don’t need to support every scenario — follow the path that fits your agent. **Prerequisites**: Familiarity with the [Agent Skills specification](specification.md), which defines the `SKILL.md` file format, frontmatter fields, and directory conventions.


[​](#the-core-principle-progressive-disclosure)

The core principle: progressive disclosure

Every skills-compatible agent follows the same three-tier loading strategy:

| Tier             | What’s loaded               | When                                 | Token cost                  |
|------------------|-----------------------------|--------------------------------------|-----------------------------|
| 1\. Catalog      | Name + description          | Session start                        | ~50-100 tokens per skill    |
| 2\. Instructions | Full `SKILL.md` body        | When the skill is activated          | \<5000 tokens (recommended) |
| 3\. Resources    | Scripts, references, assets | When the instructions reference them | Varies                      |

The model sees the catalog from the start, so it knows what skills are available. When it decides a skill is relevant, it loads the full instructions. If those instructions reference supporting files, the model loads them individually as needed. This keeps the base context small while giving the model access to specialized knowledge on demand. An agent with 20 installed skills doesn’t pay the token cost of 20 full instruction sets upfront — only the ones actually used in a given conversation.


[​](#step-1-discover-skills)

Step 1: Discover skills

At session startup, find all available skills and load their metadata.


[​](#where-to-scan)

Where to scan

Which directories you scan depends on your agent’s environment. Most locally-running agents scan at least two scopes:

- **Project-level** (relative to the working directory): Skills specific to a project or repository.
- **User-level** (relative to the home directory): Skills available across all projects for a given user.

Other scopes are possible too — for example, organization-wide skills deployed by an admin, or skills bundled with the agent itself. The right set of scopes depends on your agent’s deployment model. Within each scope, consider scanning both a **client-specific directory** and the **`.agents/skills/` convention**:

| Scope   | Path                               | Purpose                       |
|---------|------------------------------------|-------------------------------|
| Project | `<project>/.<your-client>/skills/` | Your client’s native location |
| Project | `<project>/.agents/skills/`        | Cross-client interoperability |
| User    | `~/.<your-client>/skills/`         | Your client’s native location |
| User    | `~/.agents/skills/`                | Cross-client interoperability |

The `.agents/skills/` paths have emerged as a widely-adopted convention for cross-client skill sharing. While the Agent Skills specification does not mandate where skill directories live (it only defines what goes inside them), scanning `.agents/skills/` means skills installed by other compliant clients are automatically visible to yours, and vice versa.

Some implementations also scan `.claude/skills/` (both project-level and user-level) for pragmatic compatibility, since many existing skills are installed there. Other additional locations include ancestor directories up to the git root (useful for monorepos), [XDG](https://specifications.freedesktop.org/basedir-spec/latest/) config directories, and user-configured paths.


[​](#what-to-scan-for)

What to scan for

Within each skills directory, look for **subdirectories containing a file named exactly `SKILL.md`**:

```python
~/.agents/skills/
├── pdf-processing/
│   ├── SKILL.md          ← discovered
│   └── scripts/
│       └── extract.py
├── data-analysis/
│   └── SKILL.md          ← discovered
└── README.md             ← ignored (not a skill directory)
```

Practical scanning rules:

- Skip directories that won’t contain skills, such as `.git/` and `node_modules/`
- Optionally respect `.gitignore` to avoid scanning build artifacts
- Set reasonable bounds (e.g., max depth of 4-6 levels, max 2000 directories) to prevent runaway scanning in large directory trees


[​](#handling-name-collisions)

Handling name collisions

When two skills share the same `name`, apply a deterministic precedence rule. The universal convention across existing implementations: **project-level skills override user-level skills.** Within the same scope (e.g., two skills named `code-review` found under both `<project>/.agents/skills/` and `<project>/.<your-client>/skills/`), either first-found or last-found is acceptable — pick one and be consistent. Log a warning when a collision occurs so the user knows a skill was shadowed.


[​](#trust-considerations)

Trust considerations

Project-level skills come from the repository being worked on, which may be untrusted (e.g., a freshly cloned open-source project). Consider gating project-level skill loading on a trust check — only load them if the user has marked the project folder as trusted. This prevents untrusted repositories from silently injecting instructions into the agent’s context.


[​](#cloud-hosted-and-sandboxed-agents)

Cloud-hosted and sandboxed agents

If your agent runs in a container or on a remote server, it won’t have access to the user’s local filesystem. Discovery needs to work differently depending on the skill scope:

- **Project-level skills** are often the easiest case. If the agent operates on a cloned repository (even inside a sandbox), project-level skills travel with the code and can be scanned from the repo’s directory tree.
- **User-level and organization-level skills** don’t exist in the sandbox. You’ll need to provision them from an external source — for example, cloning a configuration repository, accepting skill URLs or packages through your agent’s settings, or letting users upload skill directories through a web UI.
- **Built-in skills** can be packaged as static assets within the agent’s deployment artifact, making them available in every session without external fetching.

Once skills are available to the agent, the rest of the lifecycle — parsing, disclosure, activation — works the same.


[​](#step-2-parse-skill-md-files)

Step 2: Parse `SKILL.md` files

For each discovered `SKILL.md`, extract the metadata and body content.


[​](#frontmatter-extraction)

Frontmatter extraction

A `SKILL.md` file has two parts: YAML frontmatter between `---` delimiters, and a markdown body after the closing delimiter. To parse:

1.  Find the opening `---` at the start of the file and the closing `---` after it.
2.  Parse the YAML block between them. Extract `name` and `description` (required), plus any optional fields.
3.  Everything after the closing `---`, trimmed, is the skill’s body content.

See the [specification](specification.md) for the full set of frontmatter fields and their constraints.


[​](#handling-malformed-yaml)

Handling malformed YAML

Skill files authored for other clients may contain technically invalid YAML that their parsers happen to accept. The most common issue is unquoted values containing colons:

```python
# Technically invalid YAML — the colon breaks parsing
description: Use this skill when: the user asks about PDFs
```

Consider a fallback that wraps such values in quotes or converts them to YAML block scalars before retrying. This improves cross-client compatibility at minimal cost.


[​](#lenient-validation)

Lenient validation

Warn on issues but still load the skill when possible:

- Name doesn’t match the parent directory name → warn, load anyway
- Name exceeds 64 characters → warn, load anyway
- Description is missing or empty → skip the skill (a description is essential for disclosure), log the error
- YAML is completely unparseable → skip the skill, log the error

Record diagnostics so they can be surfaced to the user (in a debug command, log file, or UI), but don’t block skill loading on cosmetic issues.

The [specification](specification.md) defines strict constraints on the `name` field (matching the parent directory, character set, max length). The lenient approach above deliberately relaxes these to improve compatibility with skills authored for other clients.


[​](#what-to-store)

What to store

At minimum, each skill record needs three fields:

| Field         | Description                          |
|---------------|--------------------------------------|
| `name`        | From frontmatter                     |
| `description` | From frontmatter                     |
| `location`    | Absolute path to the `SKILL.md` file |

Store these in an in-memory map keyed by `name` for fast lookup during activation. You can also store the **body** (the markdown content after the frontmatter) at discovery time, or read it from `location` at activation time. Storing it makes activation faster; reading it at activation time uses less memory in aggregate and picks up changes to skill files between activations. The skill’s **base directory** (the parent directory of `location`) is needed later to resolve relative paths and enumerate bundled resources — derive it from `location` when needed.


[​](#step-3-disclose-available-skills-to-the-model)

Step 3: Disclose available skills to the model

Tell the model what skills exist without loading their full content. This is [tier 1 of progressive disclosure](#the-core-principle-progressive-disclosure).


[​](#building-the-skill-catalog)

Building the skill catalog

For each discovered skill, include `name`, `description`, and optionally `location` (the path to the `SKILL.md` file) in whatever structured format suits your stack — XML, JSON, or a bulleted list all work:

```python
<available_skills>
  <skill>
    <name>pdf-processing</name>
    <description>Extract PDF text, fill forms, merge files. Use when handling PDFs.</description>
    <location>/home/user/.agents/skills/pdf-processing/SKILL.md</location>
  </skill>
  <skill>
    <name>data-analysis</name>
    <description>Analyze datasets, generate charts, and create summary reports.</description>
    <location>/home/user/project/.agents/skills/data-analysis/SKILL.md</location>
  </skill>
</available_skills>
```

The `location` field serves two purposes: it enables file-read activation (see [Step 4](#step-4-activate-skills)), and it gives the model a base path for resolving relative references in the skill body (like `scripts/evaluate.py`). If your dedicated activation tool provides the skill directory path in its result (see [Structured wrapping](#structured-wrapping) in Step 4), you can omit `location` from the catalog. Otherwise, include it. Each skill adds roughly 50-100 tokens to the catalog. Even with dozens of skills installed, the catalog remains compact.


[​](#where-to-place-the-catalog)

Where to place the catalog

Two approaches are common: **System prompt section**: Add the catalog as a labeled section in the system prompt, preceded by brief instructions on how to use skills. This is the simplest approach and works with any model that has access to a file-reading tool. **Tool description**: Embed the catalog in the description of a dedicated skill-activation tool (see [Step 4](#step-4-activate-skills)). This keeps the system prompt clean and naturally couples discovery with activation. Both work. System prompt placement is simpler and more broadly compatible; tool description embedding is cleaner when you have a dedicated activation tool.


[​](#behavioral-instructions)

Behavioral instructions

Include a short instruction block alongside the catalog telling the model how and when to use skills. The wording depends on which activation mechanism you support (see [Step 4](#step-4-activate-skills)): **If the model activates skills by reading files:**

```python
The following skills provide specialized instructions for specific tasks.
When a task matches a skill's description, use your file-read tool to load
the SKILL.md at the listed location before proceeding.
When a skill references relative paths, resolve them against the skill's
directory (the parent of SKILL.md) and use absolute paths in tool calls.
```

**If the model activates skills via a dedicated tool:**

```python
The following skills provide specialized instructions for specific tasks.
When a task matches a skill's description, call the activate_skill tool
with the skill's name to load its full instructions.
```

Keep these instructions concise. The goal is to tell the model that skills exist and how to load them — the skill content itself provides the detailed instructions once loaded.


[​](#filtering)

Filtering

Some skills should be excluded from the catalog. Common reasons:

- The user has disabled the skill in settings
- A permission system denies access to the skill
- The skill has opted out of model-driven activation (e.g., via a `disable-model-invocation` flag)

**Hide filtered skills entirely** from the catalog rather than listing them and blocking at activation time. This prevents the model from wasting turns attempting to load skills it can’t use.


[​](#when-no-skills-are-available)

When no skills are available

If no skills are discovered, omit the catalog and behavioral instructions entirely. Don’t show an empty `<available_skills/>` block or register a skill tool with no valid options — this would confuse the model.


[​](#step-4-activate-skills)

Step 4: Activate skills

When the model or user selects a skill, deliver the full instructions into the conversation context. This is [tier 2 of progressive disclosure](#the-core-principle-progressive-disclosure).


[​](#model-driven-activation)

Model-driven activation

Most implementations rely on the model’s own judgment as the activation mechanism, rather than implementing harness-side trigger matching or keyword detection. The model reads the catalog (from [Step 3](#step-3-disclose-available-skills-to-the-model)), decides a skill is relevant to the current task, and loads it. Two implementation patterns: **File-read activation**: The model calls its standard file-read tool with the `SKILL.md` path from the catalog. No special infrastructure needed — the agent’s existing file-reading capability is sufficient. The model receives the file content as a tool result. This is the simplest approach when the model has file access. **Dedicated tool activation**: Register a tool (e.g., `activate_skill`) that takes a skill name and returns the content. This is required when the model can’t read files directly, and optional (but useful) even when it can. Advantages over raw file reads:

- Control what content is returned — e.g., strip YAML frontmatter or preserve it (see [What the model receives](#what-the-model-receives) below)
- Wrap content in structured tags for identification during context management
- List bundled resources (e.g., `references/*`) alongside the instructions
- Enforce permissions or prompt for user consent
- Track activation for analytics

If you use a dedicated activation tool, constrain the `name` parameter to the set of valid skill names (e.g., as an enum in the tool schema). This prevents the model from hallucinating nonexistent skill names. If no skills are available, don’t register the tool at all.


[​](#user-explicit-activation)

User-explicit activation

Users should also be able to activate skills directly, without waiting for the model to decide. The most common pattern is a **slash command or mention syntax** (`/skill-name` or `$skill-name`) that the harness intercepts. The specific syntax is up to you — the key idea is that the harness handles the lookup and injection, so the model receives skill content without needing to take an activation action itself. An autocomplete widget (listing available skills as the user types) can also make this discoverable.


[​](#what-the-model-receives)

What the model receives

When a skill is activated, the model receives the skill’s instructions. Two options for what exactly that content looks like: **Full file**: The model sees the entire `SKILL.md` including YAML frontmatter. This is the natural outcome with file-read activation, where the model reads the raw file. It’s also a valid choice for dedicated tools. The frontmatter may contain fields useful at activation time — for example, [`compatibility`](specification.md#compatibility-field) notes environment requirements that could inform how the model executes the skill’s instructions. **Body only (frontmatter stripped)**: The harness parses and removes the YAML frontmatter, returning only the markdown instructions. Among existing implementations with dedicated activation tools, most take this approach — stripping the frontmatter after extracting `name` and `description` during discovery. Both approaches work in practice.


[​](#structured-wrapping)

Structured wrapping

If you use a dedicated activation tool, consider wrapping skill content in identifying tags. For example:

```python
<skill_content name="pdf-processing">
# PDF Processing

## When to use this skill
Use this skill when the user needs to work with PDF files...

[rest of SKILL.md body]

Skill directory: /home/user/.agents/skills/pdf-processing
Relative paths in this skill are relative to the skill directory.

<skill_resources>
  <file>scripts/extract.py</file>
  <file>scripts/merge.py</file>
  <file>references/pdf-spec-summary.md</file>
</skill_resources>
</skill_content>
```

This has practical benefits:

- The model can clearly distinguish skill instructions from other conversation content
- The harness can identify skill content during context compaction ([Step 5](#step-5-manage-skill-context-over-time))
- Bundled resources are surfaced to the model without being eagerly loaded


[​](#listing-bundled-resources)

Listing bundled resources

When a dedicated activation tool returns skill content, it can also enumerate supporting files (scripts, references, assets) in the skill directory — but it should **not eagerly read them**. The model loads specific files on demand using its file-read tools when the skill’s instructions reference them. For large skill directories, consider capping the listing and noting that it may be incomplete.


[​](#permission-allowlisting)

Permission allowlisting

If your agent has a permission system that gates file access, **allowlist skill directories** so the model can read bundled resources without triggering user confirmation prompts. Without this, every reference to a bundled script or reference file results in a permission dialog, breaking the flow for skills that include resources beyond the `SKILL.md` itself.


[​](#step-5-manage-skill-context-over-time)

Step 5: Manage skill context over time

Once skill instructions are in the conversation context, keep them effective for the duration of the session.


[​](#protect-skill-content-from-context-compaction)

Protect skill content from context compaction

If your agent truncates or summarizes older messages when the context window fills up, **exempt skill content from pruning**. Skill instructions are durable behavioral guidance — losing them mid-conversation silently degrades the agent’s performance without any visible error. The model continues operating but without the specialized instructions the skill provided. Common approaches:

- Flag skill tool outputs as protected so the pruning algorithm skips them
- Use the [structured tags](#structured-wrapping) from Step 4 to identify skill content and preserve it during compaction


[​](#deduplicate-activations)

Deduplicate activations

Consider tracking which skills have been activated in the current session. If the model (or user) attempts to load a skill that’s already in context, you can skip the re-injection to avoid the same instructions appearing multiple times in the conversation.


[​](#subagent-delegation-optional)

Subagent delegation (optional)

This is an advanced pattern only supported by some clients. Instead of injecting skill instructions into the main conversation, the skill is run in a **separate subagent session**. The subagent receives the skill instructions, performs the task, and returns a summary of its work to the main conversation. This pattern is useful when a skill’s workflow is complex enough to benefit from a dedicated, focused session.

[Using scripts](skill-creation-using-scripts.md)

---

## Client Showcase - Agent Skills

Source: https://agentskills.io/clients
Path: 08-Plugins-Skills/clients.md

# Client Showcase

Copy pageCopy page

Agent products that support the Agent Skills format.

Copy pageCopy page


Specification

---

## Install and manage plugins - Claude Code Docs

Source: https://code.claude.com/docs/en/discover-plugins
Path: 08-Plugins-Skills/discover-plugins.md

## On this page

- [Install a plugin](#install-a-plugin)
  - [Choose an install scope](#choose-an-install-scope)
  - [JetBrains, non-interactive runs, and the Agent SDK](#other-places-you-run-claude-code)
  - [Plugins from your claude.ai account](#plugins-from-your-claude-ai-account)
  - [Install from your shell](#install-from-your-shell)
- [Add a marketplace](#add-a-marketplace)
  - [Add a marketplace and install in one command](#add-a-marketplace-and-install-in-one-command)
  - [Add a private marketplace](#add-a-private-marketplace)
  - [Add a marketplace from claude.ai](#add-from-claude-ai)
- [Manage installed plugins](#manage-installed-plugins)
  - [Manage plugins synced from claude.ai](#manage-plugins-synced-from-claude-ai)
  - [Uninstall a plugin the project enables](#uninstall-a-plugin-the-project-enables)
  - [See what an installed plugin adds to your sessions](#see-what-an-installed-plugin-adds-to-your-sessions)
  - [Find plugins you no longer use](#find-plugins-you-no-longer-use)
  - [Plugins with dependencies](#plugins-with-dependencies)
  - [Manage plugins from your shell](#manage-plugins-from-your-shell)
- [Keep plugins updated](#keep-plugins-updated)
  - [Turn auto-update on or off for a marketplace](#turn-auto-update-on-or-off-for-a-marketplace)
  - [Update one plugin now](#update-one-plugin-now)
  - [Auto-update from a private marketplace](#auto-update-from-a-private-marketplace)
- [Manage marketplaces](#manage-marketplaces)
- [Next steps](#next-steps)

Use plugins

# Install and manage plugins

Copy pageCopy page

Install Claude Code plugins from a marketplace on any surface you use, choose an install scope, and update or remove them later.

Copy pageCopy page

Installing a plugin adds its skills, agents, hooks, and MCP servers to Claude Code on your machine. This page is for anyone using plugins on their own machine or account, whether in the terminal, the desktop app, an IDE, or a cloud session: it covers installing, choosing a scope, adding marketplaces, and keeping plugins updated.

These cases are covered on other pages:

- **You use claude.ai chat or Cowork, not Claude Code**: see [Plugins on claude.ai and in Cowork](https://claude.com/docs/plugins/overview)
- **Claude Code printed an error**: find it in [Troubleshoot plugins](plugins-troubleshooting.md)

Start with [Install a plugin](#install-a-plugin). If someone sent you an install command whose `@` name isn’t `claude-plugins-official`, [add that marketplace](#add-a-marketplace) first.


[​](#install-a-plugin)

Install a plugin

As an example, this section installs [`commit-commands`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/commit-commands) from [Anthropic’s official marketplace](plugins-anthropic-marketplaces.md), which adds commands for committing, pushing, and opening pull requests. The same steps install any other plugin: substitute its name and its marketplace’s name wherever `commit-commands` and `claude-plugins-official` appear. If that plugin comes from a different marketplace, [add the marketplace](#add-a-marketplace) first. Pick the tab for where you run Claude Code.

- Terminal

- Desktop app

- VS Code

- Cloud session

Start Claude Code with `claude` in your project, then:

1

Open the plugin's details with the install command

Run `/plugin install` with the plugin’s name and marketplace. In a session, this command doesn’t install right away: it opens the `/plugin` panel on that plugin’s details so you can review it and choose a scope first.

```python
/plugin install commit-commands@claude-plugins-official
```

To browse instead, run `/plugin` with no plugin name: the panel opens on the **Discover** tab, which lists plugins from every marketplace you’ve added, and you can type to search, then press **Enter** on a plugin to open its details.

2

Review what the plugin adds

The details pane shows the plugin’s description. It can also show:

- **Will install**: the commands, agents, skills, hooks, and MCP and LSP servers the plugin adds.
- **Last updated**: shown for a plugin in Anthropic’s official marketplace.
- **Context cost**: for a plugin in Anthropic’s official marketplace, two token estimates. **Every turn** is what the plugin adds to each message you send, and **When invoked** is what its skills and agents add once Claude loads them. The estimates appear when you open the plugin by naming its marketplace, as the step 1 command does, or from the **Marketplaces** tab. The details pane you reach from the **Discover** list doesn’t show them.

Plugins from a local or custom marketplace can show `Components will be discovered at installation` instead.A plugin can run hooks and MCP servers, so read the pane before you install. See [Plugin security and trust](plugins-security.md).

3

Choose a scope

Select one of the three install options:

- **Install for you (user scope)**: you get the plugin in every project on this machine
- **Install for all collaborators on this repository (project scope)**: it’s enabled for everyone who works in this repository
- **Install for you, in this repo only (local scope)**: you get it in this repository only

[Choose an install scope](#choose-an-install-scope) says which settings file each one writes to and which applies when the same plugin is set at more than one.After you select a scope, Claude Code installs the plugin along with any dependencies it declares, then prints an install summary.

4

Read the install summary

The last sentence of the summary tells you whether the plugin is usable in this session yet:

- **Active now**: `Plugin is now active.` No reload is needed.
- **Reload needed**: `Run /reload-plugins to activate.` The panel closes and Claude Code runs that reload for you. If the reload would [invalidate the prompt cache](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin), it warns and leaves the plugin pending instead. Run `/reload-plugins --force` to activate it anyway, which costs one uncached request.
- **Load failed**: `The plugin couldn't be loaded`. Open the **Errors** tab in `/plugin` for the reason, then see [After install: plugin not working](plugins-troubleshooting.md#plugin-installed-but-not-working).

5

Confirm the plugin works

Type `/` and look for the plugin’s skills under its name, in the form `/<plugin>:<skill>`. For `commit-commands`, `/commit-commands:commit` appears. Two other places list the plugin too:

- Open the **Installed** tab in `/plugin`, which lists the plugin with its scope.
- In your shell, run `claude plugin list`, which prints the same list with `Version`, `Scope`, and `Status` lines.

If `/commit-commands:commit` doesn’t appear, see [After install: plugin not working](plugins-troubleshooting.md#plugin-installed-but-not-working).

Installing from any other marketplace requires one extra step first: [add the marketplace](#add-a-marketplace). Claude Code adds Anthropic’s official marketplace for you the first time you start an interactive terminal session, which is why the example skips that step. If you found a plugin on [claude.com/marketplace](https://claude.com/marketplace), its **Claude Code** button copies the install command in its [shell form](#install-from-your-shell), `claude plugin install <name>@claude-plugins-official`.

In a local or SSH session in the desktop app’s **Code** tab:

1

Open the plugin browser

Click the **+** button next to the prompt box and select **Plugins**, then **Add plugin**. The plugin browser opens with the plugins from your marketplaces.

2

Select the plugin

Find `commit-commands` and select it.

3

Choose a scope

Choose a [scope](#choose-an-install-scope): your user account, this project, or local-only.

To enable, disable, or uninstall later, use **+ \> Plugins \> Manage plugins**. The plugin browser isn’t available in the desktop app’s cloud sessions. See [Install plugins in the desktop app](../16-Mobile-Desktop/desktop.md#install-plugins).

In the Claude Code panel in VS Code:

1

Open Manage plugins

Type `/plugins` in the prompt box to open **Manage plugins**.

2

Install the plugin

On the **Plugins** tab, search for `commit-commands` and click **Install**. If the tab lists no plugins, add `anthropics/claude-plugins-official` on the **Marketplaces** tab first.

3

Choose a scope

Choose a [scope](#choose-an-install-scope): **Install for you**, **Install for this project**, or **Install locally**.

Your changes apply to open sessions without a restart. See [Manage plugins in VS Code](../03-IDE-Integrations/vs-code.md#manage-plugins).

A [cloud session](../02-Claude-Code-CLI/cloud-environments.md), including [the browser at claude.ai/code](../02-Claude-Code-CLI/claude-code-on-the-web.md), has no plugin browser and doesn’t load the plugins you installed on your own machine or the ones your repository’s `.claude/settings.json` turns on. For plugins your organization distributes through managed settings, see [Manage plugins for your organization](plugins-org.md).See [which parts of your setup are also available in a cloud session](../02-Claude-Code-CLI/cloud-environments.md#what-carries-over-from-your-setup) for the rest of your setup.


[​](#choose-an-install-scope)

Choose an install scope

A plugin’s install scope decides who gets the plugin and which settings file records it as enabled:

- **User scope**: the plugin is enabled for you in every project on this machine. The entry goes in `enabledPlugins` in `~/.claude/settings.json`.
- **Project scope**: the plugin is enabled for everyone who works in this repository. The entry goes in `.claude/settings.json`, which you commit. Committing that entry turns the plugin on for your collaborators but doesn’t download it to their machines, so each collaborator also runs `claude plugin install <name>@<marketplace> --scope project` once; see [Enabled in project settings but not installed](plugins-loading.md#enabled-in-project-settings-but-not-installed).
- **Local scope**: the plugin is enabled for you in this repository only. The entry goes in `.claude/settings.local.json`.

Some plugins are set by their author to start turned off, through the [`defaultEnabled`](plugins-reference.md#defaultenabled) field. Such a plugin is installed but stays off until you turn it on with `claude plugin enable <name>` in your shell, or from the **Installed** tab of `/plugin` in a session. When the same plugin is set at several scopes, the local setting overrides the project setting, and the project setting overrides the user setting. See [Find where a plugin is enabled](plugins-loading.md#find-where-a-plugin-is-enabled) for the full rule. The terminal, the desktop app’s local sessions, and the VS Code extension on one computer read the same settings files, so a plugin you install at user scope in any of them is available in the other two.


[​](#other-places-you-run-claude-code)

JetBrains, non-interactive runs, and the Agent SDK

Some places you run Claude Code have no plugin browser of their own:

- **JetBrains IDEs**: the JetBrains plugin runs Claude Code in the IDE’s terminal, so use the **Terminal** tab’s steps there.
- **`claude -p` and other non-interactive runs**: `/plugin` doesn’t run, and Claude replies `/plugin isn't available in this environment.` Plugins you already installed do load. Install and manage them from your shell with [`claude plugin` commands](#install-from-your-shell).
- **Agent SDK**: load plugins through the SDK’s plugin option. See [Load plugins in the Agent SDK](../05-Agent-SDK/agent-sdk-plugins.md).

If Claude Code reports that a plugin enabled in the repository’s `.claude/settings.json` isn’t installed, see [Enabled in project settings but not installed](plugins-loading.md#enabled-in-project-settings-but-not-installed).

If you’re a plugin author testing a copy of your plugin on disk, start Claude Code from your shell with `--plugin-dir` to load it for one session instead of installing it. See [Flags that load a plugin for one session](plugins-cli-reference.md#flags-that-load-a-plugin-for-one-session).


[​](#plugins-from-your-claude-ai-account)

Plugins from your claude.ai account

Your claude.ai account is a separate source of plugins, alongside the marketplaces you install from:

- **What arrives**: every plugin you turn on for your claude.ai account, and every plugin your organization turns on for its members. In a terminal session they sync in the background each time you start Claude Code while signed in with that account; in Cowork sessions they download when the session starts.
- **Where you see them**: in `/plugin` and `claude plugin list` under the ID `<name>@synced`. You can turn one off at your own scope unless your organization requires it.
- **What doesn’t go the other way**: plugins you install with `/plugin` or `claude plugin install` stay on this machine and aren’t added to your claude.ai account.

For sync timing, sign-in requirements, and turning sync off, see [Plugins synced from claude.ai](plugins-loading.md#synced-plugins).


[​](#install-from-your-shell)

Install from your shell

Run `claude plugin install` in your shell to install a plugin without starting a Claude Code session, for example from a setup script.

- **Scope**: user scope by default. Pass `--scope project` or `--scope local` to change it.
- **When the plugins load**: plugins it installs load the next time you start Claude Code, or when you run `/reload-plugins` in a session that’s already open.
- **The marketplace must be added first**: on a machine where no one has opened an interactive Claude Code session yet, the official marketplace isn’t registered, so a script that installs from it runs `claude plugin marketplace add anthropics/claude-plugins-official` before the install.

```python
claude plugin install formatter@your-org --scope project
```

The command prints `Successfully installed plugin: formatter@your-org (scope: project)` when it finishes. Some plugins install by running a command that their marketplace names, called a [`command` source](plugins-marketplace-reference.md#command-plugin-source). Claude Code shows you that command and asks you to accept it before it runs. A script has no one to answer that prompt, so pass `--yes` there to accept it. For every `claude plugin install` flag, see [plugin install](plugins-cli-reference.md#plugin-install).


[​](#add-a-marketplace)

Add a marketplace

You only need this section when the plugin you want isn’t in Anthropic’s official marketplace, for example one a coworker published or one from Anthropic’s community marketplace. A marketplace is a catalog of plugins, and Claude Code has to know about a marketplace before you can install from it. You add a marketplace once. After that, its plugins appear on the **Discover** tab and install with `/plugin install <plugin>@<marketplace>` in a session or `claude plugin install <plugin>@<marketplace>` in your shell, where `<marketplace>` is the name the marketplace registered under. To do both in one step, see [Add a marketplace and install in one command](#add-a-marketplace-and-install-in-one-command). In a Claude Code session, run `/plugin marketplace add` followed by the marketplace’s source: a GitHub repository, a git repository on any host, a local directory or file, or a hosted `marketplace.json`.

| Source                     | What you type                                                                                                                                                                                                                       | Example                                                                                                                        |
|:---------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|
| GitHub repository          | `owner/repo`. Add `#ref` to pin a branch or tag.                                                                                                                                                                                    | `/plugin marketplace add anthropics/claude-code`, or `/plugin marketplace add your-org/plugins#v1.2.0` to pin the `v1.2.0` tag |
| Git repository on any host | The full clone URL. Add `#ref` to pin a branch or tag.                                                                                                                                                                              | `/plugin marketplace add https://gitlab.example.com/your-group/your-marketplace.git#v1.0.0`                                    |
| Local directory or file    | A relative or absolute path to a directory that holds `.claude-plugin/marketplace.json`, or to the JSON file itself. Start a relative path with `./` or `../`, because Claude Code reads a bare `name/name` as a GitHub repository. | `/plugin marketplace add ./my-marketplace`                                                                                     |
| Hosted `marketplace.json`  | Its `https://` URL                                                                                                                                                                                                                  | `/plugin marketplace add https://example.com/marketplace.json`                                                                 |

From your shell, `claude plugin marketplace add` takes the same sources.

`/plugin market` also works as a shorter form of `/plugin marketplace`.

Include the `https://` prefix on every URL, or use the `git@host:path` form for SSH. If you type a bare `gitlab.example.com/your-group/your-marketplace.git`, Claude Code reads it as GitHub `owner/repo` shorthand and rejects it. When the command succeeds, it prints `Successfully added marketplace: <name>`, and the marketplace’s plugins appear on the **Discover** tab the next time you open `/plugin`, with no reload needed. If it fails, match the error message in [Troubleshoot plugins](plugins-troubleshooting.md#add-a-marketplace).


[​](#add-a-marketplace-and-install-in-one-command)

Add a marketplace and install in one command

To install a plugin from a marketplace you haven’t added yet, run `/plugin install` in a Claude Code session and name the marketplace source with `--marketplace`. Requires Claude Code v2.1.275 or later.

```python
/plugin install deploy-helper --marketplace your-org/plugins
```

The source takes [the same forms as `/plugin marketplace add`](#add-a-marketplace), such as GitHub `owner/repo`, a git URL, or a local path, except that it can’t contain spaces. Give the plugin name by itself, without an `@marketplace` suffix. If you haven’t added that marketplace yet, Claude Code shows the source it resolved and asks you to confirm before adding it. Once the marketplace is added, the plugin’s details open and you choose an [installation scope](#install-a-plugin). If the source matches a marketplace you’ve already added, Claude Code skips the confirmation and opens the plugin’s details in that marketplace.


[​](#add-a-private-marketplace)

Add a private marketplace

A private marketplace is one in a repository you need credentials to clone, on GitHub or any other git host. You add it with the same `/plugin marketplace add` or `claude plugin marketplace add` command as a public one. Claude Code clones it with the git credentials already on your machine and never prompts, so each way of connecting has a requirement:

- **HTTPS**: your git credential helpers apply, so access you set up with `gh auth login`, the macOS Keychain, or `git-credential-store` works. Interactive prompts are suppressed, so a host you have never authenticated to fails instead of asking for a password.
- **SSH**: the host must already be in your `known_hosts` file and the key must work without a passphrase prompt, because the host-fingerprint and passphrase prompts are suppressed too.
- **GitHub `owner/repo` shorthand**: Claude Code checks whether your SSH key authenticates to `github.com`, then clones over SSH if it does and over HTTPS if it doesn’t. Set [`CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`](../02-Claude-Code-CLI/env-vars.md#variables) to skip that check and always clone over HTTPS.

The same credentials apply when you run `/plugin install`, `/plugin marketplace update`, and `claude plugin update`. On a GitHub Enterprise Server host, see [Plugin marketplaces on GHES](../02-Claude-Code-CLI/github-enterprise-server.md#plugin-marketplaces-on-ghes) for the credentials each operation needs. If your organization registers the marketplace for you through managed settings, you don’t add it yourself. See [Pre-install and require plugins](plugins-org.md#pre-install-and-require-plugins).


[​](#add-from-claude-ai)

Add a marketplace from claude.ai

In terminal sessions where [plugins sync from your claude.ai account](plugins-loading.md#synced-plugins), claude.ai can also list plugin marketplaces for you, such as your organization’s plugin library and your own claude.ai uploads. You add one of these by its name rather than by a source. Adding a marketplace from claude.ai requires Claude Code v2.1.273 or later. Add a claude.ai marketplace from the `/plugin` panel or from your shell:

- **Inside a session**: run `/plugin` and go to the **Marketplaces** tab, which lists the marketplaces from claude.ai. Select one there to add it.
- **From your shell**: run `claude plugin marketplace list`, which prints them in a `From claude.ai:` section. Then run `claude plugin marketplace add` with the `--claudeai` flag and the name shown in the list.

For example, this command adds a marketplace named `claudeai-organization-library`:

```python
claude plugin marketplace add --claudeai claudeai-organization-library
```

Claude Code registers the marketplace under a local name that starts with `claudeai-`, derived from the name that claude.ai lists it under. For example, a marketplace listed as “Organization library” becomes `claudeai-organization-library`. Install its plugins by that name, for example with `claude plugin install <plugin>@claudeai-organization-library`. If you sign out, or sign in to a different claude.ai organization, the marketplace stays configured but shows no plugins, and the plugins you already installed from it keep loading. The `From claude.ai:` section can also list git-based marketplaces shared through claude.ai, and it prints a source for each of those. Add them by that source as in [Add a marketplace](#add-a-marketplace), not with `--claudeai`.


[​](#manage-installed-plugins)

Manage installed plugins

The **Installed** tab in `/plugin` lists your plugins with actions to enable, disable, update, or uninstall each one. In a Claude Code session, run `/plugin` and press **Tab** to reach it, or run `/plugin enable`, `/plugin disable`, or `/plugin uninstall` to open the panel and make that change there. Disabled plugins are grouped under a collapsed header at the bottom of the list. Use these keys on the list:

- Type to filter by name or description.
- Press **Space** to enable or disable the selected plugin, and **f** to favorite it.
- Press **Enter** to open a plugin’s details. The menu there offers **Disable plugin** or **Enable plugin**, **Update now**, and **Uninstall**. Plugins that take settings also offer **Configure options**.

The tab can also show plugins at **Managed** scope. Your organization installed those through [managed settings](../02-Claude-Code-CLI/settings.md#settings-files), and you can’t enable, disable, or uninstall them here. For a synced plugin that your organization requires on claude.ai, see [Manage plugins synced from claude.ai](#manage-plugins-synced-from-claude-ai). When you close the `/plugin` panel with pending changes you made in it, Claude Code runs `/reload-plugins` for you to apply them. If the reload would [invalidate the prompt cache](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin), it warns and leaves the changes pending instead. Run `/reload-plugins --force` to apply them anyway.


[​](#manage-plugins-synced-from-claude-ai)

Manage plugins synced from claude.ai

The **Installed** tab in `/plugin` also lists the [plugins synced from your claude.ai account](plugins-loading.md#synced-plugins), with `synced` as their source. Synced plugins appear in terminal sessions on Claude Code v2.1.273 or later.

- **Enable or disable**: use the **Installed** tab, unless your organization marked the plugin as required.
- **Remove**: turn the plugin off on claude.ai.

When Claude Code syncs an added, updated, or removed plugin into an interactive session, you see `Plugins changed. Run /reload-plugins to activate.` Run `/reload-plugins` to load the change in that session, or leave it for the next time you start Claude Code.


[​](#uninstall-a-plugin-the-project-enables)

Uninstall a plugin the project enables

When you choose **Uninstall** for a plugin that this repository’s `.claude/settings.json` enables, whether from the **Installed** tab or with `/plugin uninstall`, Claude Code asks whether to disable it for you or uninstall it for everyone:

- **Disable for me**: press **y**. Claude Code writes `false` for the plugin in your `.claude/settings.local.json` and leaves it installed for the project.
- **Uninstall for everyone**: press **u**. Claude Code removes the plugin from the shared `.claude/settings.json`.


[​](#see-what-an-installed-plugin-adds-to-your-sessions)

See what an installed plugin adds to your sessions

In your shell, run `claude plugin details <name>` for an installed plugin. The `Always-on` line is the number of tokens the plugin adds to every session where it’s enabled, and the per-component rows show which skill or agent contributes most. For the full output and what each figure means, see [Measure what a plugin costs](plugins-measure.md#measure-what-a-plugin-costs).


[​](#find-plugins-you-no-longer-use)

Find plugins you no longer use

On the **Installed** tab in `/plugin`, plugins you installed yourself and haven’t used recently appear under a **Not used recently** header, and each plugin’s details show a **Last used** line. Use that header and that line to find plugins that still add startup and context cost, then disable or uninstall them.


[​](#plugins-with-dependencies)

Plugins with dependencies

A plugin can declare other plugins that it depends on. When you install, disable, or uninstall such a plugin from a marketplace, Claude Code acts on those dependencies too:

- **Install**: Claude Code also installs and enables the plugin’s declared dependencies at the same scope. The success message lists them.
- **Enable**: Claude Code also enables the plugin’s dependencies that are installed but disabled. If a declared dependency isn’t installed, the enable fails and the message tells you to install it first.
- **Disable**: when another enabled plugin still needs the one you named, Claude Code refuses and prints a chained command that disables both in the right order.
- **Uninstall**: auto-installed dependencies stay until you run `claude plugin prune` in your shell; see [plugin prune](plugins-cli-reference.md#plugin-prune).

If you loaded the plugin with `--plugin-dir` instead, see [Test a plugin and its dependency locally](plugins-dependencies.md#test-a-plugin-and-its-dependency-locally).


[​](#manage-plugins-from-your-shell)

Manage plugins from your shell

You can also manage plugins without starting a Claude Code session. In your shell, run `claude plugin install`, `enable`, `disable`, or `uninstall` as ordinary terminal commands; they change the same settings the `/plugin` panel does. Each takes `--scope` to target one scope, and uses a default scope when you omit it:

- `enable` and `disable` act on the most specific scope whose settings already list the plugin.
- `install` and `uninstall` act on user scope.

For example, these commands disable and re-enable a plugin, then uninstall it at project scope:

```python
claude plugin disable formatter@your-org
claude plugin enable formatter@your-org
claude plugin uninstall formatter@your-org --scope project
```


[​](#keep-plugins-updated)

Keep plugins updated

Plugins update automatically when the marketplace they came from has auto-update turned on. After a session starts, Claude Code refreshes those marketplaces and updates the on-disk copies of the plugins you installed from them. The running session keeps the versions it already loaded. After an update, you see `Plugin updated: <name> · Run /reload-plugins to apply`, and the next session loads the new versions automatically. These are the auto-update defaults for each kind of marketplace:

- **On by default**: `claude-plugins-official` and the other [official marketplace names](plugins-security.md#official-marketplace-names) except `knowledge-work-plugins` and `first-party-plugins`, plus [marketplaces added from claude.ai](#add-from-claude-ai).
- **Off by default**: every other marketplace, including the community marketplace, third-party marketplaces, and local development marketplaces.

For when auto-update runs, which plugins it skips, and the environment variables that turn it off, see [When auto-update runs](plugins-loading.md#when-auto-update-runs).


[​](#turn-auto-update-on-or-off-for-a-marketplace)

Turn auto-update on or off for a marketplace

In a Claude Code session, run `/plugin` and go to the **Marketplaces** tab. Select the marketplace, then select **Enable auto-update** or **Disable auto-update**.


[​](#update-one-plugin-now)

Update one plugin now

In a session, open the plugin on the **Installed** tab in `/plugin` and select **Update now**, or in your shell run `claude plugin update <plugin>@<marketplace>`.


[​](#auto-update-from-a-private-marketplace)

Auto-update from a private marketplace

For a private marketplace, see [What background auto-update does with credentials](plugins-host-marketplace.md#what-background-auto-update-does-with-credentials) for how background auto-updates authenticate over SSH and HTTPS, and [Troubleshoot plugins](plugins-troubleshooting.md#add-a-marketplace) for the messages you see when they fail.


[​](#manage-marketplaces)

Manage marketplaces

The **Marketplaces** tab in `/plugin` lists every marketplace you registered, along with its source. Select one to browse its plugins, update its listing, turn auto-update on or off, or remove it. You can also list, update, and remove marketplaces with commands, from your shell or inside a session:

| Action                         | In your shell                             | Inside a session                    |
|:-------------------------------|:------------------------------------------|:------------------------------------|
| List marketplaces              | `claude plugin marketplace list`          | `/plugin marketplace list`          |
| Update a marketplace’s listing | `claude plugin marketplace update <name>` | `/plugin marketplace update <name>` |
| Remove a marketplace           | `claude plugin marketplace remove <name>` | `/plugin marketplace remove <name>` |

When you remove a marketplace, Claude Code uninstalls every plugin you installed from it and removes their `enabledPlugins` entries from your settings files. The **Marketplaces** tab names those plugins before it asks you to confirm.


[​](#next-steps)

Next steps

- [Anthropic’s marketplaces](plugins-anthropic-marketplaces.md): how the official, community, and demo marketplaces differ and where to browse each one
- [Plugin loading reference](plugins-loading.md): why a plugin loaded, didn’t load, or didn’t change after an update
- [Plugin security and trust](plugins-security.md): what to review before you install a plugin from a marketplace you don’t know
- [Troubleshoot plugins](plugins-troubleshooting.md): install and marketplace error messages with their fixes
- [Create a plugin](plugins-create.md): build your own

---

## Constrain plugin dependency versions - Claude Code Docs

Source: https://code.claude.com/docs/en/plugin-dependencies
Path: 08-Plugins-Skills/plugin-dependencies.md

## On this page

- [Why constrain dependency versions](#why-constrain-dependency-versions)
- [Declare a dependency with a version constraint](#declare-a-dependency-with-a-version-constraint)
- [Bundle plugins for a team](#bundle-plugins-for-a-team)
- [Depend on a plugin from another marketplace](#depend-on-a-plugin-from-another-marketplace)
- [Test a plugin and its dependency locally](#test-a-plugin-and-its-dependency-locally)
- [Tag plugin releases for version resolution](#tag-plugin-releases-for-version-resolution)
- [How constraints interact](#how-constraints-interact)
- [Enable or disable a plugin with dependencies](#enable-or-disable-a-plugin-with-dependencies)
- [Remove orphaned auto-installed dependencies](#remove-orphaned-auto-installed-dependencies)
- [Resolve dependency errors](#resolve-dependency-errors)
- [See also](#see-also)

Plugin distribution

# Constrain plugin dependency versions

Copy pageCopy page

Declare version constraints on plugin dependencies, and bundle a curated plugin set behind one install.

Copy pageCopy page

A plugin can depend on other plugins by listing them in `plugin.json` or in its marketplace entry. By default, a dependency tracks the latest available version, so an upstream release can change the dependency under your plugin without warning. Version constraints let you hold a dependency at a tested version range until you choose to move. When you install a plugin that declares dependencies, Claude Code resolves and installs them automatically, apart from a dependency whose marketplace entry has a [`command` source](plugin-marketplaces.md#how-users-accept-the-command) or a [`headersHelper`](plugin-marketplaces.md#how-users-accept-a-headershelper-command), which you install yourself first. Later, `/reload-plugins`, auto-update of the dependent plugin’s marketplace, re-running `claude plugin install` on the dependent plugin, and `claude plugin marketplace add` each install any declared dependency that isn’t installed yet, under the same rules; if one stays unresolved, see [Resolve dependency errors](#resolve-dependency-errors). This guide is for plugin authors who declare dependencies in `plugin.json` and for marketplace maintainers who tag releases. Dependencies here are other plugins; for the npm and Bun packages a plugin itself uses, see [Node.js package dependencies](plugins-reference.md#node-js-package-dependencies). To install plugins that have dependencies, see [Discover and install plugins](discover-plugins.md). For the full manifest schema, see the [Plugins reference](plugins-reference.md).


[​](#why-constrain-dependency-versions)

Why constrain dependency versions

Consider an internal marketplace where two teams publish plugins. The platform team maintains `secrets-vault`, an MCP server that wraps a secrets backend. The deploy team maintains `deploy-kit`, which calls `secrets-vault` to fetch credentials during deploys. `deploy-kit` is tested against `secrets-vault` v2.1.0. Without a version constraint, the next time the platform team tags a release that renames an MCP tool, auto-update moves every engineer’s `secrets-vault` to the new version and `deploy-kit` breaks. With a version constraint, `deploy-kit` declares that it needs `secrets-vault` in the `~2.1.0` range. Engineers with `deploy-kit` installed stay on the highest matching `2.1.x` patch. The deploy team upgrades on their own schedule by publishing a new `deploy-kit` version with a wider constraint.


[​](#declare-a-dependency-with-a-version-constraint)

Declare a dependency with a version constraint

List dependencies in the `dependencies` array of your plugin’s `.claude-plugin/plugin.json`. The following manifest declares one unversioned dependency and one constrained dependency:

.claude-plugin/plugin.json

```python
{
  "name": "deploy-kit",
  "version": "3.1.0",
  "dependencies": [
    "audit-logger",
    { "name": "secrets-vault", "version": "~2.1.0" }
  ]
}
```

An entry can be a bare string with only the plugin name, like `"audit-logger"` in the `deploy-kit` manifest, which depends on whatever version that plugin’s marketplace provides. For more control, use an object with these fields:

| Field         | Type   | Description                                                                                                                                                                                                                                                             |
|:--------------|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`        | string | Plugin name. Resolves within the same marketplace as the declaring plugin. Required.                                                                                                                                                                                    |
| `version`     | string | A [semver range](https://github.com/npm/node-semver#ranges) such as `~2.1.0`, `^2.0`, `>=1.4`, or `=2.1.0`. The dependency is fetched at the highest tagged version that satisfies this range.                                                                          |
| `marketplace` | string | A different marketplace to resolve `name` in. Cross-marketplace dependencies are blocked unless the target marketplace is listed in [`allowCrossMarketplaceDependenciesOn`](#depend-on-a-plugin-from-another-marketplace) in the root marketplace’s `marketplace.json`. |

Pre-release versions such as `2.0.0-beta.1` are excluded unless your range opts in with a pre-release suffix like `^2.0.0-0`.


[​](#bundle-plugins-for-a-team)

Bundle plugins for a team

Besides the required `name`, a plugin manifest can consist of only a `dependencies` array. Installing it pulls in every dependency, which makes it a way to package a curated plugin set behind one install. For example, a platform team can publish role-specific bundles in an internal marketplace so engineers run one `claude plugin install` instead of installing each tool separately:

.claude-plugin/plugin.json

```python
{
  "name": "backend-standard",
  "version": "1.0.0",
  "description": "Standard plugin set for backend engineers",
  "dependencies": [
    "secrets-vault",
    "deploy-kit",
    { "name": "db-migrate", "version": "^3.0" },
    "oncall-runbook"
  ]
}
```

Installing `backend-standard` resolves and installs all four dependencies. To add a tool to the standard set later, publish a new `backend-standard` version with the extra dependency. Unless the marketplace [auto-updates](discover-plugins.md#configure-auto-updates), engineers pick up the new version in one of two ways:

- Enable auto-update for the marketplace in `/plugin`. The next auto-update moves the bundle to the new version and installs any dependencies it adds.
- Run `claude plugin update backend-standard`, then `/reload-plugins` to install the newly added dependencies.

To roll bundles out across an organization, add the bundle plugin to `enabledPlugins` in [managed settings](../02-Claude-Code-CLI/settings-reference.md#enabledplugins).


[​](#depend-on-a-plugin-from-another-marketplace)

Depend on a plugin from another marketplace

By default, Claude Code refuses to auto-install a dependency that lives in a different marketplace than the plugin declaring it. This prevents one marketplace from silently pulling in plugins from a source you have not reviewed. To allow it, the maintainer of the root marketplace adds the target marketplace name to `allowCrossMarketplaceDependenciesOn` in `marketplace.json`. The root marketplace is the one that hosts the plugin the user is installing; only its allowlist is consulted, so trust does not chain through intermediate marketplaces. The following `marketplace.json` allows `deploy-kit` to depend on a plugin from `acme-shared`:

.claude-plugin/marketplace.json

```python
{
  "name": "acme-tools",
  "owner": { "name": "Acme" },
  "allowCrossMarketplaceDependenciesOn": ["acme-shared"],
  "plugins": [
    {
      "name": "deploy-kit",
      "source": "./deploy-kit",
      "dependencies": [
        { "name": "audit-logger", "marketplace": "acme-shared" }
      ]
    }
  ]
}
```

If the field is missing or does not include the target marketplace, install fails with a `cross-marketplace` error naming the field to set. Users can still install the dependency manually first, which satisfies the constraint without changing the allowlist.


[​](#test-a-plugin-and-its-dependency-locally)

Test a plugin and its dependency locally

If you’re developing a plugin and the plugin it depends on at the same time, load both with `--plugin-dir`:

```python
claude --plugin-dir ./my-dependency --plugin-dir ./my-plugin
```

The local copy of the dependency satisfies your plugin’s dependency entry, even when the entry names a marketplace, so you don’t need to install the dependency from its marketplace. Claude Code doesn’t check a [version constraint](#declare-a-dependency-with-a-version-constraint) against a local copy, so the local `plugin.json` doesn’t need a `version`. Before v2.1.242, a dependency entry that named a marketplace never matched the local copy, and Claude Code disabled your plugin at load. When both plugins sit in one parent folder, you can pass that folder to `--plugin-dir` once. If the folder isn’t itself a plugin, Claude Code loads each child folder that has a `.claude-plugin/plugin.json`. Requires Claude Code v2.1.265 or later. If you haven’t installed the dependency from its marketplace, your plugin stops loading when the local copy goes away:

- **You disabled the local copy**: Claude Code disables your plugin at the next plugin load. For a dependency entry that names a marketplace, Claude Code reports `Dependency "<name>@inline" is disabled — enable it or remove the dependency`; for a bare-name entry, it reports the dependency by its bare name. `<name>@inline` is how Claude Code identifies every `--plugin-dir` and `--plugin-url` plugin.
- **You started a session without the dependency’s `--plugin-dir` flag**: Claude Code reports the dependency as not installed. Pass the flag again, or install the dependency from its marketplace.


[​](#tag-plugin-releases-for-version-resolution)

Tag plugin releases for version resolution

Claude Code resolves version constraints against git tags on the repository that hosts the dependency: the plugin’s own repository for `github`, `url`, and `git-subdir` [plugin sources](plugin-marketplaces.md#plugin-sources), or the marketplace repository for a plugin the marketplace references by a relative path. For Claude Code to find a dependency’s available versions, the upstream plugin’s releases must be tagged using a specific naming convention. Tag each release as `{plugin-name}--v{version}`, where `{version}` matches the `version` field in that commit’s `plugin.json`. From the plugin directory, run:

```python
claude plugin tag --push
```

The `claude plugin tag` command derives the tag name from the plugin’s manifest and the enclosing marketplace entry. Before creating the tag, it validates the plugin contents, checks that `plugin.json` and the marketplace entry agree on the version, requires a clean working tree under the plugin directory, and refuses if the tag already exists.

- `--push` pushes the tag to the `origin` remote, so the repository needs a configured `origin` remote. Pass `--remote` to push to a different one.
- If the push fails, the tag is still created locally and the command exits with an error.
- With `--push`, a successful run ends with `Created tag secrets-vault--v2.1.0` and `Pushed to origin`, where the last line names the remote it pushed to. Without `--push`, the command prints the `git push` command to run instead.
- `--dry-run` prints what would be tagged without creating it.

Running `git tag secrets-vault--v2.1.0` directly is equivalent if you keep `plugin.json` and the marketplace entry in sync yourself. The plugin name prefix lets one marketplace repository host multiple plugins with independent version lines. The `--v` separator is parsed as a prefix match on the full plugin name, so plugin names that contain hyphens are handled correctly. When you install a plugin that declares `{ "name": "secrets-vault", "version": "~2.1.0" }`, Claude Code lists the tags on the repository that hosts `secrets-vault`, filters to those starting with `secrets-vault--v`, and fetches the highest version satisfying `~2.1.0`. If no tag on the plugin’s own repository satisfies the range, the install fails with `Dependency "secrets-vault@acme-tools" has no git tag satisfying ~2.1.0`, which names the dependency together with its marketplace. For a relative-path plugin with no matching tag, Claude Code installs the marketplace’s current copy instead and checks the constraint when the plugin loads. For a plugin the marketplace references by a relative path, a marketplace added as a local folder path resolves tags the same way when the folder is a git repository. This requires Claude Code v2.1.196 or later. In two cases Claude Code installs the dependency from the folder’s current contents instead:

- Earlier versions don’t read tags from a local-folder marketplace, so a constrained dependency loads only if that copy satisfies the range.
- A local folder that isn’t a git repository has no tags, regardless of version.

The resolved tag’s semver is recorded separately from `plugin.json`’s `version`, so constraint checks use the tag that was actually fetched even if `plugin.json` at that commit has a stale value. The cache directory name for a tag-resolved install includes a 12-character commit-SHA suffix, so if a maintainer force-moves a tag to a different commit, the next install gets a fresh cache directory instead of reusing stale content.

For dependencies with an `npm`, `archive`, or `command` [plugin source](plugin-marketplaces.md#plugin-sources), the constraint does not control which version is fetched, since tag-based resolution applies only to git-backed sources. The constraint is still checked at load time, and the dependent plugin is disabled with `dependency-version-unsatisfied` if the installed version does not satisfy it. For a `command` source, Claude Code checks the version in the dependency’s `plugin.json` and ignores the content-hash suffix; a dependency whose `plugin.json` sets no version satisfies no constraint, so set one before you constrain it.Claude Code never installs a dependency with a `command` source itself, so users [install it first](plugin-marketplaces.md#how-users-accept-the-command). Claude Code never runs the `headersHelper` on a dependency’s marketplace entry either, so users [install that plugin first](plugin-marketplaces.md#how-users-accept-a-headershelper-command).


[​](#how-constraints-interact)

How constraints interact

When several installed plugins constrain the same dependency, Claude Code intersects their ranges and resolves the dependency to the highest version that satisfies all of them. The table below shows how common combinations resolve.

| Plugin A requires | Plugin B requires | Result                                                                                          |
|:------------------|:------------------|:------------------------------------------------------------------------------------------------|
| `^2.0`            | `>=2.1`           | One install at the highest `2.x` tag at or above `2.1.0`. Both plugins load.                    |
| `~2.1`            | `~3.0`            | Install of plugin B fails with `range-conflict`. Plugin A and the dependency stay as they were. |
| `=2.1.0`          | none              | The dependency stays at `2.1.0`. Auto-update skips newer versions while plugin A is installed.  |

Auto-update fetches a constrained dependency at the highest git tag that satisfies every installed plugin’s range, rather than at the marketplace’s latest version, so the dependency continues to receive updates within its allowed range. If no tag satisfies all ranges, auto-update skips that dependency and lists the skip in the `/plugin` Errors tab, naming the constraining plugin. When you uninstall the last plugin that constrains a dependency, the dependency is no longer held and resumes tracking its marketplace entry on the next update.


[​](#enable-or-disable-a-plugin-with-dependencies)

Enable or disable a plugin with dependencies

This section covers plugins installed from a marketplace. For a copy you loaded with `--plugin-dir`, see [Test a plugin and its dependency locally](#test-a-plugin-and-its-dependency-locally). Enabling a plugin also enables the plugins it depends on, and disabling a plugin is blocked if another enabled plugin still needs it. When you enable a plugin, Claude Code also enables its dependencies at the same scope. If a dependency has its own dependencies, Claude Code enables those too. The success message lists what else was enabled along with the plugin you named. If a dependency can’t be enabled, the command refuses and tells you what’s blocking and how to fix it:

| Condition                                                                              | Result                                                                                                                 |
|:---------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------|
| A dependency is not installed                                                          | Enable fails and prints the `claude plugin install` command for each missing dependency.                               |
| A dependency is blocked by your organization’s plugin policy                           | Enable fails and names the blocked dependency.                                                                         |
| A dependency is set to `false` at a scope with higher precedence than the target scope | Enable fails. Enable the dependency at that scope, or pass `--scope` to write there.                                   |
| All dependencies are installed and allowed                                             | Enable succeeds and writes `true` for the plugin and each dependency that was not already enabled at the target scope. |

This holds even when a dependency sets [`defaultEnabled: false`](plugins-reference.md#default-enablement) in its manifest, because Claude Code writes an explicit `true` for it. The same applies at install: a dependency pulled in to satisfy an active plugin installs with `true` regardless of its own default. When you disable a plugin, Claude Code refuses if another enabled plugin still depends on it. The error names the plugins that depend on it and gives you a chained command that disables them in the right order, ending with the one you asked for. For example, if `deploy-kit` depends on `secrets-vault`, disabling `secrets-vault` alone fails with output similar to the following:

```python
secrets-vault is still required by deploy-kit. Disable that plugin first, or
disable everything together: claude plugin disable deploy-kit@acme-tools && claude plugin disable secrets-vault@acme-tools
```

Copy the chained command from the error to disable the full set in one step.


[​](#remove-orphaned-auto-installed-dependencies)

Remove orphaned auto-installed dependencies

Auto-installed dependencies stay on disk after the plugins that installed them are uninstalled, in case you reinstall a dependent plugin or want to keep using the dependency directly. To clean them up, run `claude plugin prune` to list the auto-installed dependencies that no longer have any installed plugin requiring them and remove them after a confirmation prompt.

```python
claude plugin prune
```

If nothing qualifies for removal, the command prints `Nothing to prune` with the reason and exits. This is the expected output on a fresh install, not an error. By default, prune operates at user scope and asks for confirmation before removing anything:

- `--scope project` or `--scope local` targets a different scope.
- `--dry-run` lists what would be removed without changing anything.
- `-y` skips the confirmation prompt. When stdin or stdout isn’t a terminal, prune lists the orphans and exits without removing them unless you pass `-y`.

To prune as part of an uninstall, pass `--prune` to `claude plugin uninstall`. After removing the named plugin, Claude Code scans for and removes any auto-installed dependencies that are now orphaned. Plugins you installed yourself are never pruned, only those installed automatically through another plugin’s `dependencies` array. The same confirmation behavior applies. When stdin or stdout isn’t a terminal, the uninstall still completes, but the prune step lists the orphans and removes nothing unless you pass `-y`. For example, to uninstall `deploy-kit` and clean up the dependencies it leaves behind:

```python
claude plugin uninstall deploy-kit --prune
```


[​](#resolve-dependency-errors)

Resolve dependency errors

Dependency problems appear in `claude plugin list` and in the `/plugin` interface, as descriptive error messages rather than the literal codes in this table. Claude Code disables the affected plugin until you resolve the error. The table below lists the most common errors and how to resolve them.

| Error                            | Meaning                                                                                                                                                                                                                           | How to resolve                                                                                                                                                                                                                                                          |
|:---------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `dependency-unsatisfied`         | A declared dependency is not installed, or it is installed but disabled.                                                                                                                                                          | Run the `claude plugin install` command shown in the error message. If the dependency’s marketplace is not yet configured, add it with `claude plugin marketplace add` and Claude Code resolves the dependency automatically. If the dependency is disabled, enable it. |
| `range-conflict`                 | The version requirements for a dependency cannot be combined. The error message names the cause: no version satisfies all of the ranges, a range is not valid semver syntax, or the combined ranges are too complex to intersect. | Uninstall or update one of the conflicting plugins, fix any invalid `version` string, simplify long `||` chains, or ask the upstream author to widen its constraint.                                                                                                    |
| `dependency-version-unsatisfied` | The installed dependency’s version is outside this plugin’s declared range.                                                                                                                                                       | Run `claude plugin install <dependency>@<marketplace>` to re-resolve the dependency against all current constraints.                                                                                                                                                    |
| `no-matching-tag`                | The dependency’s repository has no `{name}--v*` tag satisfying the range.                                                                                                                                                         | Check that the upstream has tagged releases using the convention above, or relax your range.                                                                                                                                                                            |

To check for these errors programmatically, run `claude plugin list --json`. Plugins with problems include an `errors` field listing them. Plugins that loaded cleanly omit the field.


[​](#see-also)

See also

- [Create plugins](plugins.md): build plugins with skills, agents, and hooks
- [Create and distribute a plugin marketplace](plugin-marketplaces.md): host plugins for your team
- [Plugins reference](plugins-reference.md#plugin-manifest-schema): the full `plugin.json` schema
- [Version management](plugins-reference.md#version-management): how a plugin’s own version is resolved and used as the cache key

---

## Test plugins with evals - Claude Code Docs

Source: https://code.claude.com/docs/en/plugin-evals
Path: 08-Plugins-Skills/plugin-evals.md

## On this page

- [Requirements](#requirements)
- [How an eval run works](#how-an-eval-run-works)
  - [What happens in a run](#what-happens-in-a-run)
  - [How a case is scored](#how-a-case-is-scored)
  - [The no-plugin baseline](#the-no-plugin-baseline)
- [Create your first eval suite](#create-your-first-eval-suite)
- [Write and refine cases](#write-and-refine-cases)
  - [Write a case manually](#write-a-case-manually)
  - [Set run limits and tools in prompt.md](#set-run-limits-and-tools-in-prompt-md)
  - [Choose and weight graders](#grade-the-result)
  - [Choose graders that give a stable signal](#choose-graders-that-give-a-stable-signal)
  - [Score against the no-plugin baseline](#compare-against-a-no-plugin-baseline)
  - [Use a different eval directory](#use-a-different-eval-directory)
- [Set up fixtures and mocks](#set-up-fixtures-and-mocks)
  - [Seed the workspace or conversation](#add-setup-or-history-with-case-yaml)
  - [Mock MCP servers](#mock-mcp-servers)
  - [Replay agent mock answers](#replay-agent-mock-answers)
- [Run evals](#run-evals)
  - [Choose what to evaluate](#choose-what-to-evaluate)
  - [Grant tools](#grant-tools)
  - [Command options](#command-options)
  - [Run evals in CI](#run-evals-in-ci)
- [Read the results](#read-the-results)
  - [HTML report](#html-report)
  - [JSON result](#json-result)
- [What a run can access](#security)
  - [Trust the plugin directory](#trust-the-plugin-directory)
  - [How runs are isolated](#how-runs-are-isolated)
- [Eval suite reference](#eval-suite-reference)
  - [prompt.md frontmatter](#prompt-md-fields)
  - [case.yaml fields](#case-yaml-fields)
  - [Grader frontmatter](#grader-frontmatter)
  - [What a grader can look at](#what-a-grader-can-look-at)
  - [Grader types](#grader-types)
  - [Mock files](#mock-files)
- [Troubleshooting](#troubleshooting)
  - [”plugin eval is currently in early access”](#%E2%80%9Dplugin-eval-is-currently-in-early-access%E2%80%9D)
  - [”plugin eval is currently unavailable”](#%E2%80%9Dplugin-eval-is-currently-unavailable%E2%80%9D)
  - [”is not a trusted plugin directory, and this run cannot stop to ask you about it”](#%E2%80%9Dis-not-a-trusted-plugin-directory-and-this-run-cannot-stop-to-ask-you-about-it%E2%80%9D)
  - [“is too old for claude plugin eval”](#git-is-too-old-for-claude-plugin-eval)
  - [”No eval cases found”](#%E2%80%9Dno-eval-cases-found%E2%80%9D)
  - [The baseline arm shows no plugin, or delta is zero](#the-baseline-arm-shows-no-plugin-or-delta-is-zero)
  - [”Agent type ’…’ not found” for one of your plugin’s agents](#%E2%80%9Dagent-type-%E2%80%99%E2%80%A6%E2%80%99-not-found%E2%80%9D-for-one-of-your-plugin%E2%80%99s-agents)
  - [Everything scores zero although the right files were produced](#everything-scores-zero-although-the-right-files-were-produced)
  - [A regex over the trace doesn’t match text I can see](#a-regex-over-the-trace-doesn%E2%80%99t-match-text-i-can-see)
  - [Tools are denied, MCP tools are missing, or Bash won’t run](#tools-are-denied-mcp-tools-are-missing-or-bash-won%E2%80%99t-run)
  - [The run exits 1 but the results look fine](#the-run-exits-1-but-the-results-look-fine)
  - [--json output path must end in .json](#json-output-path-must-end-in-json)
  - [A grader shows passed: false under a run that scored 1.0](#a-grader-shows-passed-false-under-a-run-that-scored-1-0)
  - [Runs fail with a usage-limit or rate-limit error partway through](#runs-fail-with-a-usage-limit-or-rate-limit-error-partway-through)
  - [Runs time out or hit the turn cap](#runs-time-out-or-hit-the-turn-cap)
- [See also](#see-also)

Create plugins

# Test plugins with evals

Copy pageCopy page

Write eval cases for your Claude Code plugin, run them with claude plugin eval, grade the results, compare against a no-plugin baseline, and gate CI on the score.

Copy pageCopy page

The `claude plugin eval` shell command runs your [plugin](plugins.md) against a suite of test cases and scores the results. Each case is a realistic prompt plus one or more graders. A grader is a pass/fail check on what Claude produced, such as a regex over the reply, whether a particular tool was called, or a rubric that a second model judges the reply against. You don’t have to write the suite manually. `claude plugin eval init` asks you about your plugin, proposes the cases and graders, tries them, and writes the files. You can also ask Claude to do the same from a session you already have open. Use evals to:

- Measure how reliably your plugin leads Claude to produce the right outcome
- Catch regressions when you change the plugin or a new model is released
- See what the plugin contributes compared with no plugin

This page is for plugin and skill authors who have a working plugin and want to test its behavior, and for teams that gate plugin changes in CI. For iterating on one skill inside a Claude Code conversation, the [skill-creator plugin](skills.md#run-evals-with-skill-creator) runs a similar comparison with its own `evals/evals.json` format, and neither tool reads the other’s case files. To create a plugin, see [Create a plugin](plugins-create.md); to check a plugin’s files for syntax and schema errors rather than its behavior, use [`claude plugin validate`](plugins-cli-reference.md#plugin-validate).

Every eval run and every judge grader is a real model call on your account, counted against your plan’s usage or your API bill, so check the [requirements](#requirements) first. Then [create your first eval suite](#create-your-first-eval-suite), or go to [Run evals in CI](#run-evals-in-ci) if you already have one.


[​](#requirements)

Requirements

To run plugin evals you need:

- Claude Code v2.1.269 or later. Run `claude --version` to check and `claude update` to upgrade.
- Git 2.31 or later, if git is installed. Run `git --version` to check. With an older git, `claude plugin eval` [stops before running any case](#git-is-too-old-for-claude-plugin-eval). Without git, it runs normally.
- A plugin directory with a `plugin.json` or `.claude-plugin/plugin.json` manifest, or a [skills-directory plugin](plugins-loading.md#plugins-shared-through-a-repository).
- The same authentication and model provider your normal Claude Code sessions use. Eval runs, judge-scored graders, and `claude plugin eval init` call the model with your credentials, so they count against your plan’s usage limits or your API bill. When the command reports a cost, the figure is a [list-price estimate](../17-Billing-Plans/costs.md) of those calls.


[​](#how-an-eval-run-works)

How an eval run works

An eval suite lives in a directory called `evals/` inside your plugin, laid out as [Write and refine cases](#write-and-refine-cases) shows. Each case is its own subdirectory with a [prompt](#set-run-limits-and-tools-in-prompt-md) and one or more [graders](#grade-the-result). The prompt is something a person using your plugin might type, such as a request one of its skills should handle.


[​](#what-happens-in-a-run)

What happens in a run

For each run of a case, Claude Code starts a fresh, [isolated](#how-runs-are-isolated) [non-interactive session](../02-Claude-Code-CLI/headless.md) with only your plugin loaded, sends the prompt, and lets Claude work until it finishes or hits the case’s turn or time limit. Each grader then checks the final reply, the transcript, or a file Claude created, and passes or fails.


[​](#how-a-case-is-scored)

How a case is scored

One run of a non-deterministic agent tells you little, so each case runs three times by default. A run’s score is the fraction of its graders that passed, weighted if you set weights, and the case’s score is the mean across its runs. A case passes when its score meets the [`--threshold`](#command-options), `1.0` by default. In model calls, a suite makes roughly cases × runs agent runs with the plugin and the same number again for the [no-plugin baseline](#the-no-plugin-baseline), plus three short judge calls per `llm` or `baseline` grader per run.


[​](#the-no-plugin-baseline)

The no-plugin baseline

A high score on its own doesn’t tell you the plugin helped, because Claude might do as well without it. To separate the two, a case’s runs are repeated with no plugin loaded, and you get two scores, `WITH` and `W/OUT`. Their difference, `Δ`, is what the plugin contributed. If a case scores 1.0 both with and without the plugin, the plugin isn’t what made it pass. The two sets of runs are called the with-arm and the without-arm; [Score against the no-plugin baseline](#compare-against-a-no-plugin-baseline) covers which cases run the with-arm only and how graders are scored across the two arms.


[​](#create-your-first-eval-suite)

Create your first eval suite

This walkthrough writes one case for your own plugin, runs it, and reads the result. Before you start, make sure you have:

- Claude Code v2.1.269 or later and the other [requirements](#requirements)
- A terminal open at your plugin’s root directory, the one containing `plugin.json` or `.claude-plugin/plugin.json`
- One skill in the plugin you want to test, and a request a user would type that should trigger it

1

Create the cases

From the plugin root, run:

```python
claude plugin eval init
```

If Claude Code doesn’t already trust this directory it first asks `Trust this plugin directory?`; answer `y`.An interactive Claude Code session then opens. Claude reads your plugin and asks you what a good result looks like, proposes prompts that should and shouldn’t trigger the plugin, designs graders for each, runs them once as a trial to check they behave, and writes one case directory per prompt under `evals/`, each named after its prompt.When Claude tells you the suite is ready, exit that session with `/exit` or Ctrl+D to return to your shell.If you already have a Claude Code session open at the plugin root, you can instead ask Claude there to run `claude plugin eval init`. Claude runs the command and then asks you the same questions in that conversation.If you’d rather write a case yourself to see exactly what the files contain, follow [Write a case manually](#write-a-case-manually) and come back here to run it.

2

Run the suite

Back at your shell in the plugin root, run every case under `evals/`:

```python
claude plugin eval .
```

You already trusted this directory during step 1, so the run starts immediately. If you wrote the case manually instead, the run first asks `Trust this plugin directory? [y/N]`; answer `y`. [What a run can access](#security) explains what you’re agreeing to.Each case runs three times with your plugin and three times without it, so one case is six runs. A progress line prints as each run finishes, with that run’s score and each grader’s verdict.

3

Read the summary

When the suite finishes you see a summary table, followed by where the report went:

```python
CASE        WITH  W/OUT Δ      RUNS COST    NOTES
first-case  1.00  0.33  +0.67  6    $0.41

1 case(s) · mean Δ +0.67 · 74s · $0.41
Report: /Users/you/my-plugin/evals/results/2026-09-10T17-02-11-482Z/report.html
Published: https://claude.ai/... · keep local next time with --no-publish
```

`WITH` is the case’s score with your plugin loaded, `W/OUT` is the score without it, and a positive `Δ` means the plugin raised the score. `COST` is a list-price estimate of the model calls, and `NOTES` shows the highest-weight failing grader’s explanation, or the run’s error, from the with-arm.

4

Open the report and iterate

Open the `Published:` URL, or the `Report:` path when no `Published:` line appears, to see each grader’s verdict and explanation for every run, and for `llm` graders the judge’s votes and the excerpt it judged. The `Published:` line appears only when your account can [publish reports](#html-report).The most common first finding is a `Δ` near zero with the case’s `tool_used: Skill` grader failing, which means Claude isn’t choosing your skill on natural phrasing. Adjust the skill’s [`description`](skills.md#frontmatter-reference), run `claude plugin eval .` again, and compare.To iterate on one case cheaply, run a single arm once. A single run is noisy, so confirm any change at the default three runs before you trust it. With one arm the table shows `SCORE` and `PASS%` columns instead of `WITH`, `W/OUT`, and `Δ`:

```python
claude plugin eval . --case <case-name> --runs 1 --ablation none
```

Replace `<case-name>` with one of the directory names under `evals/`.


[​](#write-and-refine-cases)

Write and refine cases

The cases `claude plugin eval init` writes are plain files you can open, change, and add to. A case is a directory under the plugin’s eval directory that contains a `prompt.md`, a `case.yaml`, or both. Give each case at least one grader, as a `graders/<name>.md` file or a `graders:` entry in `case.yaml`, because a case without one fails to load. To group cases, nest them under a directory that isn’t itself a case; anything inside a case directory, such as `graders/` and fixture files, belongs to that case. This is the layout `claude plugin eval init` writes and the one to use for new suites. The [eval suite reference](#eval-suite-reference) has the complete tree, including mocks and results:

```python
my-plugin/
├── .claude-plugin/plugin.json
├── skills/...
└── evals/
    ├── first-case/
    │   ├── prompt.md          # frontmatter: case fields; body: the prompt
    │   ├── graders/
    │   │   ├── criteria.md    # frontmatter: type + options; body: rubric or pattern
    │   │   └── skill-fired.md
    │   └── case.yaml          # optional: only for context.* fields
    ├── ignores-unrelated-request/
    │   └── ...
    └── results/               # written by each run; add to .gitignore
```


[​](#write-a-case-manually)

Write a case manually

Having Claude write the cases with `claude plugin eval init` is the recommended path. To write one yourself instead, start from a blank template. The following command writes a case named `first-case` with a placeholder `prompt.md` and one placeholder grader, and runs nothing:

```python
claude plugin eval init --bare first-case
```

```python
evals/first-case/
├── prompt.md            # the prompt sent to Claude, plus run limits
└── graders/
    └── criteria.md      # one grader: how to score the result
```

In `prompt.md` you write the message Claude receives in each run, and set the run’s limits and the tools the case may use in its frontmatter. Open `evals/first-case/prompt.md` and replace the placeholder body with a request one of your skills should handle, phrased the way a user would type it rather than naming the skill. This example is for a skill that drafts commit messages; use your own request:

```python
---
max_turns: 10
allowed_tools: [Read, Glob, Grep, Skill]
---

Write me a commit message for this change: I renamed getUser to fetchUser and updated the three call sites.
```

Each run starts in an empty working directory, so put whatever the task needs in the prompt itself, or [set up the workspace](#add-setup-or-history-with-case-yaml) first. The [full list of frontmatter fields](#prompt-md-fields) covers the model, timeout, tags, and environment variables. Each file under `graders/` is one check applied after the run. Open `evals/first-case/graders/criteria.md` and replace the placeholder with a rubric for the judge model, written as concrete PASS and FAIL conditions:

```python
---
type: llm
---

PASS if <what a correct response contains>.
FAIL if <what a wrong or missing response looks like>.
```

Then add a second grader that checks whether your skill is what produced the answer. Create `evals/first-case/graders/skill-fired.md`, replacing `your-skill-name` with the skill’s directory name under `skills/`, which is the name Claude invokes it by:

```python
---
type: tool_used
tool: Skill
input_match: '"skill"\s*:\s*"(?:[\w-]+:)?your-skill-name"'
---
```

This passes when Claude invoked that skill at least once during the run, including by its namespaced `plugin-name:skill-name` form. [Grader types](#grader-types) lists the other checks available, such as matching a regex or confirming a file was created. With both files saved, run the case the way the [quickstart](#create-your-first-eval-suite) does, with `claude plugin eval .` from the plugin root.


[​](#set-run-limits-and-tools-in-prompt-md)

Set run limits and tools in prompt.md

Set a case’s `max_turns`, `timeout_seconds`, `model`, `tags`, and the `allowed_tools` it may use in `prompt.md` frontmatter; the [prompt.md frontmatter](#prompt-md-fields) reference lists every field and its default. Claude receives the body exactly as you wrote it. `@path` mentions in it aren’t expanded into file attachments, so if Claude needs to read a file, grant a tool for it in `allowed_tools`.


[​](#grade-the-result)

Choose and weight graders

A grader’s frontmatter sets its `type`, and optionally a `weight` that makes it count for more of the run’s score and an [`arm`](#compare-against-a-no-plugin-baseline) that controls how it’s scored against the baseline. Of the six types, `regex`, `tool_used`, `tool_order`, and `file_exists` are computed from the transcript and files and cost nothing, while `llm` and `baseline` call a judge model and add to the run’s cost. There are no custom-code graders. [Grader types](#grader-types) lists each type’s options and pass condition, and [what a grader can look at](#what-a-grader-can-look-at) lists the values `target` and `focus` accept. The judge for `llm` and `baseline` graders is a small fast model by default. Pass `--judge-model sonnet` or a full model ID to use a stronger one for nuanced rubrics.


[​](#choose-graders-that-give-a-stable-signal)

Choose graders that give a stable signal

An `llm` grader asks a model for a verdict, so its answer can differ between runs, and it differs more the longer the text it has to read. These habits keep a suite’s scores steady enough to trust:

- For long output such as a generated file, grade it with a `regex` grader over the file’s contents, which checks the whole file the same way every time. Keep `llm` graders for short outputs, with rubrics written as concrete PASS and FAIL conditions.
- Give each case one grader on the result, such as the final message or a produced file, and one on the steps Claude took to produce it, such as `tool_used` or `tool_order`. Together they tell you both whether the answer was right and whether your plugin produced it.
- If a case’s `tool_used: Skill` grader passes but `Δ` is negative, suspect the judge before the plugin. A small judge model can mark a correct answer wrong because it’s formatted differently from what the rubric describes. Re-run with `--judge-model sonnet`, and tighten the rubric so formatting doesn’t decide the verdict.
- To check that a build or test passed inside the run, have the prompt ask Claude to run it and write the outcome to a file, grade that file, and assert the command ran with a `tool_used` grader whose `input_match` names the command.


[​](#compare-against-a-no-plugin-baseline)

Score against the no-plugin baseline

When a plugin is under test, a case normally runs in two arms. The with-arm is its runs with the plugin loaded, and the without-arm is the same number of runs with no plugin at all. The summary and report show both scores and `Δ`, the with-arm score minus the without-arm score. In these situations a case runs the with-arm only, so it gets no `W/OUT` score or `Δ`:

- **You pass `--ablation none`**: every case runs one arm, which halves the cost when you don’t need the comparison, such as while iterating on graders.
- **The case resumes a transcript and the target is a path**: with a [target](#choose-what-to-evaluate) such as `.` rather than an installed plugin’s name, a [`context.history_file`](#add-setup-or-history-with-case-yaml) case runs one arm by default, on the assumption that the recorded conversation already reflects the plugin. The run prints a `single-arm (no Δ)` notice on stderr naming these cases. To compare the resumed turn with and without the plugin, pass `--ablation with-without`.
- **No plugin was found for the case**: when the target is a path, a case whose plugin Claude Code couldn’t locate also runs one arm by default. See [the baseline arm shows no plugin](#the-baseline-arm-shows-no-plugin-or-delta-is-zero) to fix it.

In a two-arm run, some graders are reported with `scored: false`. A check like “the skill was invoked” can never pass without the plugin, so counting it would push the without-arm toward zero and inflate `Δ`. To keep the two arms comparable, Claude Code excludes such graders from the score in both arms and reports them in the with-arm as pass/fail indicators only. That includes:

- Every `tool_used` grader whose `tool` is `Skill`
- Every `regex` grader with `target: mock_calls` and every `llm` grader with `focus: mock_calls`, when each [mocked server](#mock-mcp-servers) in the case is one your plugin declares
- Any grader you mark `arm: with-only`

Three settings change that exclusion:

- **Every grader excluded**: if every grader in a case is in the excluded set, they’re scored normally instead, since there would be nothing left to score.
- **`arm: both`**: set `arm: both` on a grader to score it in both arms regardless, which is what you want for a “must not invoke the skill” check with `min: 0` and `max: 0`.
- **`--ablation none`**: under `--ablation none` nothing is excluded, so the same suite can produce a different absolute score in the two modes.


[​](#use-a-different-eval-directory)

Use a different eval directory

If `evals/` is already taken by another tool, keep the suite in a different directory. You can record that directory in the plugin’s `plugin.json` so every run and every collaborator uses it, or pass it on the command line for a single run:

- **In `plugin.json`**: add `"experimental": { "evals": "quality/evals" }`.
- **On the command line**: pass `--eval-dir quality/evals` to both `claude plugin eval` and `claude plugin eval init`.

If you set both, the flag’s directory is used. Give a relative path of plain directory names such as `qa` or `quality/evals`. An absolute path or one containing `..` isn’t accepted: as a flag value it’s an error, while an unusable manifest value prints a `Warning:` line and the run uses `evals/` instead. Cases, results, and `init` output all move to that directory.


[​](#set-up-fixtures-and-mocks)

Set up fixtures and mocks

A case can need more than a prompt: files or a git repository in the workspace, an earlier conversation to continue, or answers from the MCP servers your plugin connects to. Each of those is set up beside the case so runs stay repeatable.


[​](#add-setup-or-history-with-case-yaml)

Seed the workspace or conversation

Each run starts in an empty workspace. When a case needs more than the prompt, add a `case.yaml` beside `prompt.md` with a `context` block:

- **Fixture files or a git repository**: write a Bash script in the case directory and name it in `context.scaffold_script`. The script runs as you, outside the agent’s sandbox, and only when you pass `--scaffold`, so pass that flag only for suites you or your organization wrote.
- **An earlier conversation to continue**: save the transcript as a `.jsonl` file and name it in `context.history_file`, and the case’s prompt becomes the next user turn. When the target is a path, such a case runs [without a baseline arm](#compare-against-a-no-plugin-baseline) by default.
- **Fixture directories Claude can read during the run**: list them in `context.add_dirs`.

A `case.yaml` also needs `schema_version: "1.1"` and `name`; the [case.yaml fields](#case-yaml-fields) reference has the full list. This `case.yaml` seeds a workspace from a script and lets Claude read fixtures from a `resources/` directory:

```python
schema_version: "1.1"
name: changelog-from-diff
tags: [smoke]
context:
  scaffold_script: fixture.sh
  add_dirs: [resources]
```

A scaffold script starts in the empty workspace with a small fixed environment: your shell’s `PATH`, `HOME` set to the run’s temporary home directory, `TMPDIR`, and a few constants such as `TERM=dumb`. Nothing else from your shell reaches it, and neither do the case’s `EVAL_*` variables. If the script exits non-zero or runs longer than 120 seconds, that run scores 0 with a `scaffold failed` error. Use the script for files and git state only, since project configuration it writes [isn’t loaded](#how-runs-are-isolated).


[​](#mock-mcp-servers)

Mock MCP servers

You can evaluate a plugin whose skills call MCP tools without the real service behind them. Put one Markdown file per tool under `evals/mocks/<server>/<tool>.md` for the whole suite, or under a case’s own `mocks/` directory for one case, where `<server>` is the server’s name in your plugin’s [MCP configuration](plugins-components.md#mcp-servers). A run never starts your plugin’s real MCP servers unless you ask. Claude Code registers a substitute server under each server’s own name. Tools with a mock file answer from it and are allowed without an `--allow-tools` grant, and a tool with no mock file isn’t available to Claude. A server with no mocks at all appears in the case’s `mocked:` progress line as `plugin_<plugin>_<server>[not started: no mock]`. The file’s body is what the tool returns to Claude. This mock substitutes for a `create_issue` tool on a server named `tracker`, checks the input Claude sends, and echoes the title back. Save it as `evals/mocks/tracker/create_issue.md`:

```python
---
expect:
  title: string
  priority: [low, medium, high]
---

Created issue #4821: {{input.title}}
```

A mock file’s body and frontmatter accept these options:

- **Substitutions**: insert fields from the call’s input with `{{input.<field>}}`, and the contents of a fixture file beside the mock with `{{file:fixtures/{input.<field>}.json}}`.
- **`expect:`**: the `expect:` block guards the input. If a call violates it, the run aborts with score 0 and records why, so a case can assert what your plugin asked the server to do.
- **`error: true`**: set `error: true` to return the body as a tool error instead.
- **`type: agent`**: set `type: agent` to have a small model answer as the server from instructions in the body.

The [mock file reference](#mock-files) lists every key and the `_server.md` and `_tools.json` files. To grade the calls themselves, point a grader at `target: mock_calls`. To run against the plugin’s real MCP servers instead, pass one of these flags. Either way those processes run as you, outside the run’s sandbox, and their tools need an [`--allow-tools` grant](#grant-tools):

- **`--allow-real-servers`**: start the real process for each server you haven’t mocked, and keep answering mocked tools from their files
- **`--mocks off`**: ignore `mocks/` entirely and start every server the plugin declares


[​](#replay-agent-mock-answers)

Replay agent mock answers

A `type: agent` mock answers with a call to the [`--judge-model`](#command-options), so its output varies between runs and changes if you change the judge. When a run completes without an error or abort, Claude Code saves each answer an agent mock gave under the results directory in `mock-recordings/`. Open `ADOPT.txt` there to see each recording and the `.replay/<server>/` directory to copy it into, beside the mock that produced it. After you copy a recording there, later runs answer the identical call from it with no model call. Commit `mocks/.replay/` with the rest of `mocks/` so CI runs are repeatable.


[​](#run-evals)

Run evals

Once a suite exists, `claude plugin eval` runs it. You choose which plugin and cases run with the target argument, grant any tools the cases need beyond the read-only set with `--allow-tools`, and control run count, models, cost, and output with the other options.


[​](#choose-what-to-evaluate)

Choose what to evaluate

Most of the time you run `claude plugin eval .` from the plugin root, which runs every case in the suite with the plugin you’re standing in loaded. To run a single case file, or to evaluate a plugin you installed rather than one you’re developing, pass a different target:

| Target                                                    | What runs                                                                                                                                                                                         |
|:----------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| A plugin’s root directory, such as `.`                    | Every case under its eval directory, with that plugin loaded                                                                                                                                      |
| A single `prompt.md` or `case.yaml` file                  | That case, with its enclosing plugin loaded                                                                                                                                                       |
| An installed plugin by name, `name` or `name@marketplace` | The cases in the installed copy’s eval directory, with the installed copy loaded. Results are written under `./evals/results/` in your current directory, or `./<dir>/results/` with `--eval-dir` |
| `name@skills-dir`                                         | The same, for a [skills-directory plugin](plugins-loading.md#plugins-shared-through-a-repository)                                                                                           |
| Omitted                                                   | The current directory as a path                                                                                                                                                                   |

Add `--case <glob>` to filter by case name and `--tag <tag>` to keep cases with any of the given tags. Put the target before `--tag`, `--allow-tools`, and `--json`. The first two take a list and `--json` takes an optional path, so each of them reads a target that follows as its own value.


[​](#grant-tools)

Grant tools

Runs never stop to ask for permission. Built-in tools that need a grant you didn’t give, such as `Bash`, `Write`, `Edit`, `WebFetch`, and `WebSearch`, are removed from the session, so Claude can’t call them at all. A run allows only the read-only tools the case lists in `allowed_tools`, from `Read`, `Glob`, `Grep`, `NotebookRead`, `Skill`, `AskUserQuestion`, `Agent`, `TodoWrite`, and the task tools `TaskCreate`, `TaskGet`, `TaskList`, `TaskUpdate`, and `TaskStop`, plus whatever you grant with `--allow-tools`. That grant applies to every case in the run. To let cases use `Bash`, `Write`, `Edit`, `WebFetch`, or `WebSearch`, grant them yourself:

```python
claude plugin eval . --allow-tools Write Edit "Bash(npm test *)"
```

When a case asked for a tool you didn’t grant, the progress output lists it as `not granted`. Tools on a [mocked](#mock-mcp-servers) MCP server need no grant. Tools on a real plugin MCP server need both the server started, with `--allow-real-servers` or `--mocks off`, and a grant by name, such as `--allow-tools "mcp__plugin_my-plugin_github__*"`; a plugin’s MCP tools are named `mcp__plugin_<plugin>_<server>__<tool>`. When you grant `Bash` in any form, every command runs under Claude Code’s [OS-level sandbox](../02-Claude-Code-CLI/sandboxing.md). Writes are confined to the run’s workspace, your home directory and Claude Code configuration are unreadable, and network access is limited to domains you grant with `--allow-tools "WebFetch(domain:example.com)"`. If you grant Bash or PowerShell on a machine with no sandbox backend, Claude Code refuses each run rather than running it unconfined, and the case shows a run error and usually scores 0. Native Windows has no backend, so run shell-granting suites under WSL2; on Linux, install `bubblewrap` and `socat` first. See the [sandboxing prerequisites](../02-Claude-Code-CLI/sandboxing.md).


[​](#command-options)

Command options

This table covers the options for run count, models, scoring, cost, tool grants, mocks, and output. Run `claude plugin eval --help` for the complete list, which also includes `--case`, `--tag`, `--eval-dir`, `--no-scaffold`, `--report`, and `--verbose`.

| Option                     | Default                                                                                             | Effect                                                                                                                                                                                                                                                                                        |
|:---------------------------|:----------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--runs <n>`               | Each case’s `runs`, else 3                                                                          | Runs per case per arm                                                                                                                                                                                                                                                                         |
| `-j`, `--concurrency <n>`  | `1`                                                                                                 | Run up to this many agent runs at once, from 1 to 8. They share your account’s rate limit, so this shortens wall-clock time rather than raising throughput past that limit. Results keep case order                                                                                           |
| `--model <model>`          | Each case’s `model`, else `ANTHROPIC_MODEL` if set, else Claude Code’s default                      | Model for the agent under test. Pin it in CI so a model rollout isn’t mistaken for a plugin regression                                                                                                                                                                                        |
| `--judge-model <model>`    | A small fast model                                                                                  | Model for `llm` and `baseline` graders                                                                                                                                                                                                                                                        |
| `--ablation <mode>`        | Decided per case; see [Score against the no-plugin baseline](#compare-against-a-no-plugin-baseline) | Whether to also run each case without the plugin to measure what it adds. `none` runs one arm; `with-without` adds the no-plugin baseline                                                                                                                                                     |
| `--threshold <0..1>`       | `1.0`                                                                                               | A case passes when its with-arm score is at least this. Any case below it makes the command exit 1                                                                                                                                                                                            |
| `--max-cost-usd <usd>`     | No ceiling                                                                                          | A ceiling on the run’s list-price cost estimate, not on plan usage. Checked before each run starts. Once spent, nothing further starts; runs that already started finish, so spend can pass the ceiling by those runs. If any run is left unstarted, the command exits 2 with partial results |
| `--allow-tools <tools...>` | None                                                                                                | Grant tools beyond the read-only set. See [Grant tools](#grant-tools)                                                                                                                                                                                                                         |
| `--scaffold`               | Off                                                                                                 | Run each case’s [`scaffold_script`](#add-setup-or-history-with-case-yaml)                                                                                                                                                                                                                     |
| `--trust-plugin`           | Off                                                                                                 | Skip the first-run trust prompt for a plugin whose code and suite you’d run yourself. Pass it in CI so the job is never refused by or left waiting at the prompt. See [What a run can access](#security)                                                                                      |
| `--mocks <mode>`           | `record`                                                                                            | `record` answers MCP tool calls from [mocks](#mock-mcp-servers), doesn’t start the plugin’s real servers, and saves agent-mock answers for replay. `off` ignores mocks and starts the plugin’s real MCP servers                                                                               |
| `--allow-real-servers`     | Off                                                                                                 | With `--mocks record`, also start the plugin’s real MCP servers for servers that have no mock                                                                                                                                                                                                 |
| `--json [path]`            | Off                                                                                                 | Print the [result document](#json-result) to stdout, or write it to a path ending in `.json`. The run is quiet: no progress lines or summary table                                                                                                                                            |
| `--output-dir <dir>`       | `<eval dir>/results/<timestamp>/`                                                                   | Where `aggregate-result.json` and `report.html` go                                                                                                                                                                                                                                            |
| `--no-publish`             |                                                                                                     | Keep the HTML report local. See [HTML report](#html-report)                                                                                                                                                                                                                                   |
| `--publish-report`         |                                                                                                     | Publish the report even where it would stay local by default, such as a run a Claude Code session started                                                                                                                                                                                     |
| `--keep-temp`              | Off                                                                                                 | Keep every run’s sandbox directory and print its path, for debugging what Claude produced                                                                                                                                                                                                     |


[​](#run-evals-in-ci)

Run evals in CI

In your CI job, run the suite with `--json` to write the result for archiving, and fail the build on the exit code. Pass `--trust-plugin` so the job never waits at the [first-run trust prompt](#security), pin both models so scores are comparable over time, keep the report local, and set a cost ceiling as an upper limit:

```python
claude plugin eval . \
  --trust-plugin \
  --json results.json \
  --threshold 0.8 \
  --model claude-sonnet-5 \
  --judge-model claude-haiku-4-5 \
  --no-publish \
  --max-cost-usd 20
```

The job’s exit code tells you what happened:

| Exit code | Meaning                                                                                                                                                                                                        |
|:----------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 0         | Every case scored at or above `--threshold` and every case file loaded                                                                                                                                         |
| 1         | A case scored below the threshold, a case file failed to load, no cases were found, a run couldn’t be started, the plugin directory isn’t trusted and `--trust-plugin` wasn’t passed, or an option was invalid |
| 2         | Partial run: the `--max-cost-usd` ceiling was hit, or your credential was rejected before or at the first run. `results.json` is still written with `partial: true` and the reason                             |
| 130       | Interrupted. Partial results are written                                                                                                                                                                       |
| 143       | Terminated, such as by a CI timeout                                                                                                                                                                            |

The with-minus-without delta is reported but never changes the exit code, and neither do problems writing or publishing the HTML report. To see why a case scored low, run it locally without `--json` so the per-run progress and grader lines print. A CI runner also needs these in place:

- **Install and credentials**: a CI runner needs a Claude Code install and [credentials in the environment](../13-Enterprise-Admin/iam.md) such as `ANTHROPIC_API_KEY`.
- **Trust**: without `--trust-plugin`, a job whose checkout directory Claude Code doesn’t already trust needs the [first-run trust prompt](#trust-the-plugin-directory), and a run that can’t ask is refused with exit 1.
- **`init` in CI**: `claude plugin eval init` needs a terminal to ask you its questions; in CI, run `claude plugin eval init --bare <name>` to get the blank template.

To keep costs predictable, give quick every-change suites only graders that don’t call a judge, use `--ablation none` where you don’t need `Δ`, and leave `partial: true` documents and runs with `skippedPaidGraders` out of any trend you chart.


[​](#read-the-results)

Read the results

Every run with at least one case writes a `results/<timestamp>/` directory inside the eval directory, containing `aggregate-result.json` and `report.html`. For a path target that’s under the plugin; for a plugin you named, it’s under your current directory, as the [target table](#choose-what-to-evaluate) shows. The summary table, the JSON, and the report all render the same result data.


[​](#html-report)

HTML report

`report.html` is a single self-contained file that makes no external requests, so you can attach it to a CI job or open it from disk. This example is the top of a report for a three-case suite run with `--threshold 0.8`; the cost shown is a list-price estimate and varies with the model and the number of cases:

Read it from the top down:

- **The verdict line and tiles** answer whether the plugin helped across the whole suite. Suite score is the mean of the per-case with-plugin scores, Ablation Δ is how far that is above or below the baseline score, and Cases counts how many met the threshold. Perfect runs is the share of with-plugin runs where every grader passed.
- **Each case card** shows the case’s own `Δ` and with-plugin score, with a tick on the bar at the threshold. A case whose `Δ` is negative gets a red left edge, so regressions stand out when you scroll.
- **Inside a case**, the with-plugin runs come first and the baseline runs after. Each run lists its graders with a pass or fail chip. A failed grader is already expanded with its explanation, and an `llm` grader also shows the judge’s votes and the evidence it was shown, which is where you find out why a run scored low. Graders that don’t count toward the score, such as `tool_used: Skill`, carry a `plugin-fired indicator` badge.
- **Prompt and Graders**, below the runs, show the case’s prompt and each grader’s rubric or pattern, so someone reading the report without the suite can see what was asked and what counted as good.

If you’re signed in with a claude.ai subscription and [artifacts](../02-Claude-Code-CLI/artifacts.md) are available for your account, Claude Code also publishes the report as a private artifact and prints `Published: <url>`. Pass `--no-publish` to keep it local. If no `Published:` line appears, such as with API-key authentication, the local file is the report. A run that a Claude Code session started, such as when you ask Claude to run the suite for you, also stays local, and its `Report:` line says `kept local`. Add `--publish-report` to that command to publish it.


[​](#json-result)

JSON result

`aggregate-result.json`, and `--json` output, is a versioned document with `schemaVersion: 1` for CI scripts to parse. Field names are camelCase and new fields are added without renaming existing ones, so write your script to ignore fields it doesn’t recognize. These are the fields a gating script usually reads. The document also carries the suite configuration, every grader definition, and per-run grader results with explanations and evidence:

| Field                                             | Meaning                                                                                                                                                                                  |
|:--------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `partial`, `partialReason`                        | `true` with `cost_ceiling`, `interrupted`, or `auth_failed` when the suite didn’t finish. Leave partial results out of trend charts                                                      |
| `aggregates.overallScore`                         | Mean case score across the suite                                                                                                                                                         |
| `aggregates.casesPassed`, `aggregates.casesTotal` | Cases at or above `--threshold`, and the total                                                                                                                                           |
| `aggregates.meanDelta`                            | Mean `Δ` across cases, under the two-arm mode                                                                                                                                            |
| `cases[].name`                                    | Case name                                                                                                                                                                                |
| `cases[].aggregates.score`                        | Mean with-arm run score for the case                                                                                                                                                     |
| `cases[].aggregates.delta`                        | With-arm score minus without-arm score. Omitted when the case ran one arm or the arms aren’t comparable                                                                                  |
| `cases[].arms.with[].error`                       | `null`, or why a run ended abnormally, such as `timed out after 300s`. A run that started but ended badly is still graded on what it produced, so a non-null error doesn’t imply score 0 |
| `cases[].arms.with[].aborted`                     | Present when a [mock](#mock-mcp-servers)’s `expect:` or `abort_when` stopped the run, with `server`, `tool`, and `reason`. The run scores 0 and `error` stays `null`                     |
| `cases[].arms.with[].skippedPaidGraders`          | `true` when the cost ceiling skipped this run’s judge graders, so its score isn’t comparable                                                                                             |
| `costUsd`, `durationSeconds`, `claudeVersion`     | Estimated cost at list price including judge calls, wall-clock seconds, and the Claude Code version that ran the suite                                                                   |


[​](#security)

What a run can access

`claude plugin eval` loads the target plugin’s skills, hooks, and agents and runs its eval suite on your machine, as you. Pointing it at a plugin is the same trust decision as `claude --plugin-dir`, so only evaluate plugins you trust. The isolation described in this section limits what the agent under test can reach; it isn’t a boundary against the plugin’s own code, and a suite that passes says nothing about whether the plugin is safe.


[​](#trust-the-plugin-directory)

Trust the plugin directory

The first time you run `claude plugin eval` against a directory, Claude Code asks `Trust this plugin directory?` before it loads anything from it, unless you already accepted the trust prompt there in an interactive `claude` session. Inside a git repository, answering yes trusts the whole repository, for interactive sessions too. When stdin or stdout isn’t a terminal, or under `--json`, the run can’t ask and is refused with exit 1; pass `--trust-plugin` to assert the trust yourself, only for a plugin you’d run on your own machine. A target you name rather than give as a path, meaning an installed plugin or a skills-directory plugin, skips the prompt. Some parts of the plugin and suite run only when you pass their flag for that run:

- A case’s [`scaffold_script`](#add-setup-or-history-with-case-yaml) with `--scaffold`
- [Tools beyond the read-only set](#grant-tools) with `--allow-tools`
- The plugin’s [real MCP servers](#mock-mcp-servers) with `--allow-real-servers` or `--mocks off`

A case’s `allowed_tools` and a skill’s own `allowed-tools` frontmatter can’t widen any of them. When the plugin includes hooks you didn’t write, or you start its real MCP servers, treat its scores as advisory unless you ran it in an isolated environment such as a container or CI runner, since hooks and servers run outside the agent’s sandbox and could modify the files the graders read.


[​](#how-runs-are-isolated)

How runs are isolated

Each run gets a temporary home directory, working directory, and Claude Code configuration, and the agent under test runs there as a `claude -p` child process with only your plugin loaded. Keep these consequences in mind when you write cases:

- **Nothing personal or project-level loads.** Your user settings, hooks, `CLAUDE.md` files, MCP servers, other installed plugins, memory, and skills are absent. Project-scoped configuration isn’t read anywhere either: no `.claude/` directory, `CLAUDE.md`, or `.mcp.json` loads from above the workspace or inside it, even one a `scaffold_script` wrote, and `add_dirs` directories grant read access only. Most of your shell environment is withheld too; only an [allowlist](#prompt-md-fields) and `EVAL_*` variables reach the run. Ship any skills, agents, hooks, or MCP servers a case depends on in the plugin under test, since a [`scaffold_script`](#add-setup-or-history-with-case-yaml) can supply only files and git state.
- **Managed policy can still restrict a run.** Restrictions in [managed settings](../13-Enterprise-Admin/managed-settings.md) an administrator deployed to the machine apply inside a run, so results on a managed machine can differ from an unmanaged one by that policy.
- **The Artifact tool is off.** A skill that publishes an [artifact](../02-Claude-Code-CLI/artifacts.md) can be graded only on what it produces before that step.
- **The case definitions are hidden from the agent.** A run can’t read the eval directory, so Claude can’t see the case’s prompt, its graders, or sibling cases.
- **No network sandbox outside shell commands.** Shell commands you grant run under the sandbox’s network rules. A `WebFetch(domain:…)` grant reaches that domain directly, and the plugin’s own hooks and any real MCP servers you start can reach any host.


[​](#eval-suite-reference)

Eval suite reference

Everything an eval suite can contain lives under the plugin’s eval directory, `evals/` unless you [configured another](#use-a-different-eval-directory). A directory counts as a case when it holds a `prompt.md` or a `case.yaml`, and a case without at least one grader fails to load with an `invalid case.yaml` error that names `graders`. This tree shows every file `claude plugin eval` reads or writes in the eval directory:

```python
evals/
├── <case>/                        # one directory per case; nest under a non-case directory to group
│   ├── prompt.md                  # frontmatter: case and run fields; body: the prompt
│   ├── case.yaml                  # optional: context.* fields, or the whole case in one file
│   ├── graders/
│   │   └── <name>.md              # one grader per file; frontmatter: type and options; body: rubric
│   ├── mocks/                     # optional: mocks for this case only, same layout as below
│   └── <fixtures, scripts, transcripts referenced by case.yaml>
├── mocks/                         # optional: suite-wide MCP mocks
│   ├── <server>/
│   │   ├── <tool>.md              # one mocked tool; body: the tool result
│   │   ├── _server.md             # optional: one agent that answers several tools
│   │   ├── _tools.json            # optional: saved tools/list response for real descriptions and schemas
│   │   └── fixtures/              # files inserted with {{file:fixtures/...}}
│   └── .replay/<server>/          # adopted agent-mock recordings, answered without a model call
└── results/<timestamp>/           # written by each run; add results/ to .gitignore
    ├── aggregate-result.json
    ├── report.html
    └── mock-recordings/           # agent-mock answers from clean runs, with ADOPT.txt
```


[​](#prompt-md-fields)

prompt.md frontmatter

`prompt.md` frontmatter accepts these fields. An unknown key is an error:

| Field                  | Default                      | Purpose                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:-----------------------|:-----------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `schema_version`       | `"1.1"`, set for you         | Case format version. Cases written as `prompt.md` get it automatically, so you rarely set it                                                                                                                                                                                                                                                                                                                                                                                  |
| `name`                 | The directory name           | Case name. `--case` globs match it and the report keys on it                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `description`          |                              | For humans. Not used at run time                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `tags`                 | `[]`                         | Labels for `--tag` filtering. A case runs if any of its tags matches                                                                                                                                                                                                                                                                                                                                                                                                          |
| `plugins`              | The nearest enclosing plugin | Plugin directories under test, relative to the case directory. Set `plugins: ["../.."]` when auto-detection doesn’t find your plugin; see [the plugin didn’t load](#the-baseline-arm-shows-no-plugin-or-delta-is-zero)                                                                                                                                                                                                                                                        |
| `runs`                 | `3`                          | Runs per arm, 1 to 50. `--runs` overrides it                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `expected_outcome`     |                              | For humans. Not used at run time                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `model`                | The child session’s default  | Model for the agent under test. `--model` overrides it                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `max_turns`            | `10`                         | Turn cap, up to 200. Hitting it is recorded as a run error and usually lowers the score, so set it generously                                                                                                                                                                                                                                                                                                                                                                 |
| `timeout_seconds`      | `300`                        | Wall-clock cap per run, up to 3600                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `allowed_tools`        | `[]`                         | Tools the case wants, such as `[Read, Glob, Grep, Skill]`. Read-only tools are granted when listed here; for anything else, see [Grant tools](#grant-tools)                                                                                                                                                                                                                                                                                                                   |
| `append_system_prompt` |                              | Text appended to the child session’s system prompt                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `env`                  | `{}`                         | Extra environment variables for the child session. Keys must match `EVAL_[A-Z0-9_]*`; any other key fails the run. The run inherits only an allowlist from your shell: basics such as `PATH` and locale, proxy and certificate settings, the variables that select and authenticate your model provider, most `ANTHROPIC_*` and `CLAUDE_CODE_*` configuration, and `EVAL_*`. To pass the plugin anything else, such as a toolchain setting, export it as an `EVAL_*` variable |


[​](#case-yaml-fields)

case.yaml fields

`case.yaml` is an alternative or companion to `prompt.md`: it describes a case in YAML and adds the fields that point at other files. It requires `schema_version: "1.1"` and `name`. The `prompt.md` fields `description`, `tags`, `plugins`, `runs`, and `expected_outcome` go at the top level; `model`, `max_turns`, `timeout_seconds`, `allowed_tools`, `append_system_prompt`, and `env` go under `execution:`. When both files exist, `prompt.md` frontmatter overrides the matching `case.yaml` fields, the `prompt.md` body is the prompt, and `graders/*.md` are added after any graders listed in `case.yaml`. These fields exist only in `case.yaml`:

| Field                     | Purpose                                                                                                                                                                                                                                                                                                       |
|:--------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `context.scaffold_script` | A Bash script in the case directory that runs in the empty workspace before Claude starts, to create fixture files or a git repository. It runs only when you pass [`--scaffold`](#add-setup-or-history-with-case-yaml), with a minimal environment and a 120-second limit, and a non-zero exit fails the run |
| `context.history_file`    | A `.jsonl` transcript in the case directory to resume. The case’s prompt becomes the next user turn                                                                                                                                                                                                           |
| `context.add_dirs`        | Directories inside the case directory that Claude may read during the run, granted read-only                                                                                                                                                                                                                  |
| `execution.prompt`        | The prompt, when you keep the whole case in `case.yaml` and omit `prompt.md`                                                                                                                                                                                                                                  |
| `graders`                 | A list of graders, each with a `name` plus the same keys a `graders/*.md` file takes in frontmatter. For `llm` graders, put the rubric in `criteria`                                                                                                                                                          |


[​](#grader-frontmatter)

Grader frontmatter

Every grader file under `graders/` takes these keys in frontmatter, plus the options for its type. The grader’s name is the filename without `.md`:

| Key      | Default  | Purpose                                                                                                                                                                                      |
|:---------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`   | required | One of the [grader types](#grader-types)                                                                                                                                                     |
| `weight` | `1`      | Relative weight in the run’s score. Any positive number                                                                                                                                      |
| `arm`    | unset    | `with-only` excludes the grader from scoring in a [two-arm run](#compare-against-a-no-plugin-baseline); `both` forces a grader Claude Code would otherwise exclude to be scored in both arms |


[​](#what-a-grader-can-look-at)

What a grader can look at

`regex` graders take a `target` and `llm` graders take a `focus`. Both accept the same values:

| Value                            | What the grader sees                                                                                                                                                                                                                                                                                           |
|:---------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `last_message`                   | Claude’s final response text. This is the default                                                                                                                                                                                                                                                              |
| `trace`                          | The session as JSON, one message per line. A `regex` grader sees every message; an `llm` judge sees the first 12 and the last 12. Quotes and newlines inside it are JSON-escaped, so a regex matches `\"` rather than `"`                                                                                      |
| `files`                          | The list of paths Claude created during the run, one per line. Not their contents, and not files that a scaffold created or that Claude only modified                                                                                                                                                          |
| `{ source: file, path: <path> }` | The contents of one file in the workspace after the run. Use this to grade what the plugin produced. A PNG, JPEG, GIF, or WebP file is shown to an `llm` judge as an image. An `llm` judge refuses other binary files such as `.pptx` or PDF; render them to an image or write them out as text and grade that |
| `mock_calls`                     | Each call Claude made to a [mocked MCP tool](#mock-mcp-servers), with its input and the mock’s answer                                                                                                                                                                                                          |


[​](#grader-types)

Grader types

Each grader type below lists its options and when it passes:

| Type          | Options                               | Passes when                                                                                                                                                                                                                  |
|:--------------|:--------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `regex`       | `pattern`, `flags`, `match`, `target` | The JavaScript regex `pattern` is found in the target. Set `match: not_contains` to require absence or `match: "count:N"` to require exactly N matches. Put case-insensitivity in `flags: i`; inline `(?i)` isn’t supported  |
| `tool_used`   | `tool`, `input_match`, `min`, `max`   | The number of calls to `tool` whose JSON-encoded input matches the optional `input_match` regex is between `min`, default 1, and `max`, default unlimited. To assert a tool was never called, set both `min: 0` and `max: 0` |
| `tool_order`  | `before`, `after`                     | Both tools were called and the first matching `before` call precedes the first matching `after` call. Each is a tool name or `{ tool, input_match }`                                                                         |
| `file_exists` | `path`, `exists`                      | A file Claude created matches the `path` glob, or none does with `exists: false`. Only files created during the run count                                                                                                    |
| `llm`         | `criteria`, `focus`                   | A judge model votes PASS on the rubric in at least two of three votes. In the `.md` layout the file body is the criteria                                                                                                     |
| `baseline`    | `baseline_file`, `criteria`           | A judge finds the run satisfies the criteria at least as well as the reference transcript at `baseline_file`, a `.jsonl` in the case directory                                                                               |


[​](#mock-files)

Mock files

A `<tool>.md` file under `mocks/<server>/` answers one tool. Its body is the tool result, with `{{input.<field>}}` and `{{file:fixtures/<name>}}` substitutions. Its frontmatter accepts these keys:

| Key          | Default | Purpose                                                                                                                                                                                                                                                                             |
|:-------------|:--------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`       | `fixed` | `fixed` returns the body as written. `agent` treats the body as instructions for a small model that acts as the server for the run and sees earlier calls as history                                                                                                                |
| `expect`     | unset   | A map from dotted input paths to a type name such as `string`, `number`, `boolean`, `array`, or `object`, a `/regex/`, a literal, or a list of allowed literals. A call that violates it aborts the run with score 0 and is reported as `aborted` with the server, tool, and reason |
| `error`      | `false` | `fixed` only. Return the body as a tool error                                                                                                                                                                                                                                       |
| `abort_when` | unset   | `agent` only. Prose listing the only conditions under which the agent may abort the run                                                                                                                                                                                             |

Two optional files sit beside the tool files in a server’s directory:

- **`_server.md`**: a single `type: agent` mock that answers several tools, listed in its `tools:` frontmatter key. A `<tool>.md` for the same tool takes precedence. Put an `expect:` guard on the individual `<tool>.md`, not here
- **`_tools.json`**: a saved `tools/list` response from the real server, so mocked tools carry their real descriptions and input schemas instead of a permissive placeholder

A case’s own `mocks/` directory uses the same layout and overrides the suite’s mocks file by file.


[​](#troubleshooting)

Troubleshooting

These are the problems authors encounter most often, keyed on what you see.


[​](#”plugin-eval-is-currently-in-early-access”)

”plugin eval is currently in early access”

Your build predates general availability of the command. Run `claude update`, then run the command again in a fresh session.


[​](#”plugin-eval-is-currently-unavailable”)

”plugin eval is currently unavailable”

Anthropic has switched the command off server-side. Nothing on your machine turns it back on; run `claude update` and try again in a fresh session later.


[​](#”is-not-a-trusted-plugin-directory-and-this-run-cannot-stop-to-ask-you-about-it”)

”is not a trusted plugin directory, and this run cannot stop to ask you about it”

This is the first run against a directory Claude Code doesn’t trust yet, and it can’t ask you because stdin or stdout isn’t a terminal or you passed `--json`. Run `claude plugin eval <dir>` once in a terminal and answer the prompt, or pass `--trust-plugin` if you trust the plugin’s code and suite. See [What a run can access](#security).


[​](#git-is-too-old-for-claude-plugin-eval)

“is too old for claude plugin eval”

The `git` on your `PATH` is older than 2.31, so `claude plugin eval` stopped before running any case and exited 1 with a message naming your version:

```python
git 2.30 is too old for claude plugin eval: it ignores the environment configuration (GIT_CONFIG_COUNT, added in git 2.31) that switches off the repository's git hooks and helper programs for the run. Install git 2.31 or newer.
```

For each run, Claude Code switches off git hooks, credential helpers, and other programs a repository’s git configuration can start. It does so through environment configuration that git reads only from version 2.31. An older git ignores that configuration, so the suite stops rather than scoring runs where those programs could execute. Install git 2.31 or later and run the suite again. Before v2.1.283, `claude plugin eval` didn’t check the git version, and on an older git the suite ran with those programs left on.


[​](#”no-eval-cases-found”)

”No eval cases found”

No `<case>/prompt.md` or `<case>/case.yaml` exists beneath the eval directory in effect, or your `--case` and `--tag` filters matched no case. Run from the plugin root, or run `claude plugin eval init` to create a suite.


[​](#the-baseline-arm-shows-no-plugin-or-delta-is-zero)

The baseline arm shows no plugin, or delta is zero

If the summary has no `W/OUT` column, or a case fails with “ablation requested but no plugin resolved”, the usual cause is that no plugin was found for the case. If every case resumes a transcript through `context.history_file`, the missing column is expected instead, because those cases run [one arm by default](#compare-against-a-no-plugin-baseline). Otherwise, add `plugins: ["../.."]` to the case, giving the path from the case directory to the plugin directory. If the plugin did load and `Δ` is still near zero with your `tool_used: Skill` grader failing, that’s usually a real finding, meaning the skill’s `description` doesn’t trigger on the prompt’s phrasing. Adjust the description and re-run the same suite.


[​](#”agent-type-’…’-not-found”-for-one-of-your-plugin’s-agents)

”Agent type ’…’ not found” for one of your plugin’s agents

By default each case runs both with your plugin and without it, and the runs without it are the [no-plugin baseline](#the-no-plugin-baseline). When Claude dispatches one of your plugin’s agents in a baseline run, the Agent tool call fails with `Agent type '<plugin>:<agent-name>' not found. Available agents: ...`. The list names only agents that exist without the plugin, such as the [built-in subagents](../09-Agents-Patterns/sub-agents.md#built-in-subagents). The error is expected, since `Δ` compares your plugin’s runs against the baseline. In the JSON result, the baseline runs are under `cases[].arms.without`. In runs with your plugin loaded, a case that lists `Agent` in `allowed_tools` can dispatch one of your plugin’s agents by its namespaced name, such as `my-plugin:code-reviewer` for the `code-reviewer` agent in a plugin named `my-plugin`. To skip the baseline runs, pass `--ablation none`.


[​](#everything-scores-zero-although-the-right-files-were-produced)

Everything scores zero although the right files were produced

Your graders target `files`, the list of created paths, when you meant the file’s contents. Use `{ source: file, path: <path> }` as the `target` or `focus`. Separately, `file_exists` counts only files created during the run, so a file the scaffold created or that Claude only edited is invisible to it; grade its contents, or use `tool_used` on `Edit`.


[​](#a-regex-over-the-trace-doesn’t-match-text-i-can-see)

A regex over the trace doesn’t match text I can see

- **Wrong target**: the default `target` is `last_message`, not the trace.
- **JSON escaping**: when you do target `trace`, it’s JSON per line, so quotes appear as `\"`.
- **Regex syntax**: regexes use JavaScript syntax, so put `i` in `flags` rather than writing `(?i)`.


[​](#tools-are-denied-mcp-tools-are-missing-or-bash-won’t-run)

Tools are denied, MCP tools are missing, or Bash won’t run

Anything beyond the read-only set needs your grant, such as `--allow-tools Bash Write`. Your personal MCP servers never load in a run. The plugin’s own servers don’t start unless you [opt in](#mock-mcp-servers), and their tools then also need an `--allow-tools "mcp__plugin_<plugin>_<server>__*"` grant; a mocked tool needs neither.


[​](#the-run-exits-1-but-the-results-look-fine)

The run exits 1 but the results look fine

The default `--threshold` is 1.0, so the command exits 1 when any case scores below perfect. Set a threshold that matches the score you require. Exit 1 also covers a case file that failed to load, which is reported on stderr above the table.


[​](#json-output-path-must-end-in-json)

`--json output path must end in .json`

You put the target after `--json`, so it was read as the output path. Put the target first, as in `claude plugin eval . --json`, or give `--json` an explicit `.json` path.


[​](#a-grader-shows-passed-false-under-a-run-that-scored-1-0)

A grader shows passed: false under a run that scored 1.0

That grader is excluded from the score by design in a two-arm run, and its `scored` field is `false`. See [Score against the no-plugin baseline](#compare-against-a-no-plugin-baseline).


[​](#runs-fail-with-a-usage-limit-or-rate-limit-error-partway-through)

Runs fail with a usage-limit or rate-limit error partway through

If your account reaches its plan’s usage limit or an API rate limit while a suite is running, each later run ends with that error, is graded on what it produced, and usually scores 0. The suite still finishes and isn’t marked `partial`, so the result can look like a regression. Check the `NOTES` column or `cases[].arms.with[].error` in the JSON for the limit message before trusting the scores, then re-run after the limit resets, with `--runs 1` or a `--case` filter if you need to stay under it.


[​](#runs-time-out-or-hit-the-turn-cap)

Runs time out or hit the turn cap

The defaults are 10 turns and 300 seconds. Raise `max_turns` and `timeout_seconds` in the case for tasks that need more, and use `--max-cost-usd` as the cost ceiling rather than tight per-run limits.


[​](#see-also)

See also

- [Create a plugin](plugins-create.md): build the plugin you’re testing, and load it with `--plugin-dir` during development
- [Plugin commands reference](plugins-cli-reference.md#plugin-eval): the `plugin eval` and `plugin eval init` command entries. The manifest’s [`experimental.evals`](plugins-reference.md#fields) key is on the manifest reference
- [Skills](skills.md): how a skill’s description decides when Claude invokes it, which is what a case that checks whether the skill triggers is measuring
- [Sandboxing](../02-Claude-Code-CLI/sandboxing.md): the OS-level sandbox that applies when you grant Bash to a run
- [Publish a plugin](plugins-publish.md): publish the plugin once its suite passes
- [Measure plugin cost and usage](plugins-measure.md): what the plugin adds to each session’s context and whether people still use it

---

## Recommend your plugin from your CLI - Claude Code Docs

Source: https://code.claude.com/docs/en/plugin-hints
Path: 08-Plugins-Skills/plugin-hints.md

## On this page

- [How it works](#how-it-works)
- [Emit the hint](#emit-the-hint)
- [Choose where to emit](#choose-where-to-emit)
- [What the user sees](#what-the-user-sees)
- [Hint format](#hint-format)
- [Requirements](#requirements)
- [Get your plugin into the official marketplace](#get-your-plugin-into-the-official-marketplace)
- [See also](#see-also)

Plugin distribution

# Recommend your plugin from your CLI

Copy pageCopy page

Emit a one-line marker from your CLI so Claude Code prompts users to install your official plugin.

Copy pageCopy page

If you maintain a CLI or SDK and have a plugin in the official Anthropic marketplace, your tool can prompt Claude Code users to install that plugin. Your CLI writes a one-line marker to stderr when it detects it is running inside Claude Code. Claude Code reads the marker, strips it from the output, and shows the user a one-time install prompt. The protocol requires no extra commands and does not change what your CLI prints for users outside Claude Code. This page is for CLI and SDK maintainers. If you are looking to install plugins, see [Discover and install plugins](discover-plugins.md).


[​](#how-it-works)

How it works

Claude Code sets the [`CLAUDECODE`](../02-Claude-Code-CLI/env-vars.md) environment variable to `1` for every command it runs through the Bash and PowerShell tools, and for [hook](../07-Hooks/hooks.md) commands. From v2.1.172 it also sets [`CLAUDE_CODE_CHILD_SESSION`](../02-Claude-Code-CLI/env-vars.md) to `1` in those same subprocesses. When your CLI sees one of these variables, it writes a self-closing `<claude-code-hint />` tag to stderr. In hook commands the hint tag is stripped and ignored. Only Bash and PowerShell tool output triggers the install prompt. When Claude Code receives the command output, it:

1.  Scans for hint lines and removes them before the output reaches the model
2.  Checks that the hint targets a plugin in an official Anthropic marketplace
3.  Checks that the plugin is not already installed and has not been prompted before
4.  Shows the user an install prompt that names the command that emitted the hint

Claude Code never installs a plugin automatically. The user always confirms.


[​](#emit-the-hint)

Emit the hint

Hint prompts only fire for plugins listed in the official Anthropic marketplace. See [Get your plugin into the official marketplace](#get-your-plugin-into-the-official-marketplace) before you ship the integration. Gate emission on an environment variable so the marker is unlikely to appear when a human runs your CLI directly, then write the tag to stderr on its own line. Choose which variable to check:

- `CLAUDECODE`: set on every Claude Code version, so it reaches the most sessions. It is also set in tmux sessions and stdio MCP server subprocesses that Claude Code starts. IDE extensions also set it in their integrated terminals, where a human may be running your CLI directly.
- `CLAUDE_CODE_CHILD_SESSION`: set only in subprocesses Claude Code itself spawns, such as tool calls, hook commands, and [status line](../02-Claude-Code-CLI/statusline.md) commands, so the tag does not normally reach a human terminal. A long-lived process that was started inside a session, such as a tmux server, captures the variable, so shells later launched from that process still show the raw tag.

The following examples gate on `CLAUDECODE` for maximum reach and emit a hint for a plugin named `example-cli` in the official marketplace:

Node.js

Python

Go

Shell

```python
if (process.env.CLAUDECODE) {
  process.stderr.write(
    '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',
  )
}
```

```python
import os, sys

if os.environ.get("CLAUDECODE"):
    print(
        '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />',
        file=sys.stderr,
    )
```

```python
if os.Getenv("CLAUDECODE") != "" {
    fmt.Fprintln(os.Stderr,
        `<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />`)
}
```

```python
if [ -n "$CLAUDECODE" ]; then
  printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fi
```

Replace `example-cli` with your plugin’s name in the official marketplace.


[​](#choose-where-to-emit)

Choose where to emit

You control which code paths emit the hint. Claude Code deduplicates by plugin, so emitting on every invocation has no downside. Touchpoints that work well include:

| Placement                 | Why it works                                               |
|:--------------------------|:-----------------------------------------------------------|
| `--help` output           | Claude often runs help when exploring an unfamiliar CLI    |
| Unknown-subcommand errors | Reaches the moment Claude is confused about your interface |
| Login or auth success     | The user is already in a setup mindset                     |
| First-run welcome message | A natural onboarding moment                                |


[​](#what-the-user-sees)

What the user sees

When the hint passes all checks, Claude Code shows a prompt like the following:

```python
─────────────────────────────────────────────────────────────
  Plugin recommendation

    The example-cli command suggests installing a plugin.

    Plugin: example-cli
    Marketplace: claude-plugins-official
    Official integration for example-cli deployments

    Would you like to install it?
    ❯ 1. Yes, install example-cli
      2. No
      3. No, and don't show plugin installation hints again

─────────────────────────────────────────────────────────────
```

The prompt names the command that produced the hint so users can spot a mismatch between the tool and the plugin it recommends. If the user doesn’t respond within 30 seconds, Claude Code dismisses the prompt as **No**. Prompt frequency is bounded, and some sessions never prompt:

- **Once per plugin**: after the prompt is shown, Claude Code records the plugin and never prompts for it again, regardless of the user’s answer.
- **Once per session**: across all CLIs on the machine, at most one hint prompt appears per Claude Code session.
- **Main interactive session only**: Claude Code shows the prompt only in the terminal session the user is typing into. Claude Code never prompts for a command that a [subagent](../09-Agents-Patterns/sub-agents.md) runs, and never prompts when the user runs Claude Code in [non-interactive mode](../02-Claude-Code-CLI/headless.md) with the `-p` flag or through the [Agent SDK](../05-Agent-SDK/agent-sdk-overview.md). Claude Code still strips the hint line from the command output in all of these cases.
- **Telemetry opt-outs**: sessions where analytics are disabled never show hint prompts. This includes sessions with `DISABLE_TELEMETRY` or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set, and sessions on third-party providers such as Amazon Bedrock or Google Cloud’s Agent Platform where the [automatic telemetry opt-out](../13-Enterprise-Admin/data-usage.md#default-behaviors-by-api-provider) applies.

Selecting **Yes** installs the plugin to user scope. Selecting **No, and don’t show plugin installation hints again** disables all future hint prompts for the user.


[​](#hint-format)

Hint format

The hint is a self-closing tag with three required attributes.

```python
<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />
```

| Attribute | Required | Description                                       |
|:----------|:---------|:--------------------------------------------------|
| `v`       | Yes      | Protocol version. `1` is the only supported value |
| `type`    | Yes      | Hint kind. `plugin` is the only supported value   |
| `value`   | Yes      | Plugin identifier in `name@marketplace` form      |

Attribute values may be quoted with double quotes or left unquoted. Unquoted values cannot contain whitespace. Escape sequences are not supported.


[​](#requirements)

Requirements

Claude Code enforces two conditions before acting on a hint. Hints that fail either check are dropped:

- **Own line**: the tag must occupy its own line. A tag embedded mid-line, for example inside a log statement, is ignored. Leading and trailing whitespace on the line is allowed.
- **Official marketplace**: the `value` must reference a plugin in an Anthropic-controlled marketplace such as `claude-plugins-official`. Hints that point to other marketplaces are silently dropped.

The hint line is always removed from the output before it reaches the model, even when the version or type is unrecognized, so the marker is never counted toward token usage. The remaining guidance is recommended but not enforced. Claude Code cannot observe whether your CLI follows it:

- **Write to stderr**: stderr keeps the tag out of shell pipelines such as `example-cli deploy | jq`. Claude Code scans both streams, so stdout also works.
- **Gate on an environment variable**: only emit when `CLAUDECODE` or `CLAUDE_CODE_CHILD_SESSION` is set. See [Emit the hint](#emit-the-hint) for how the two variables differ.


[​](#get-your-plugin-into-the-official-marketplace)

Get your plugin into the official marketplace

The hint protocol only takes effect for plugins listed in the official Anthropic marketplace, `claude-plugins-official`. Anthropic curates that marketplace at its discretion, and the in-app submission forms add plugins to the [community marketplace](plugins.md#submit-your-plugin-to-the-community-marketplace) instead, which the hint protocol does not check. If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing.


[​](#see-also)

See also

- [Create plugins](plugins.md): build the plugin your CLI recommends
- [Create and distribute a plugin marketplace](plugin-marketplaces.md): host plugins outside the official marketplace
- [Environment variables](../02-Claude-Code-CLI/env-vars.md): full reference for `CLAUDECODE` and related variables

---

## Create a marketplace - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/create-marketplace
Path: 08-Plugins-Skills/plugin-marketplaces.md

## On this page

- [Create a marketplace](#create-a-marketplace)
- [Add plugin entries](#add-plugin-entries)
- [Rules for plugin entries](#rules-for-plugin-entries)
  - [Write relative paths from the marketplace root](#write-relative-paths-from-the-marketplace-root)
  - [Keep the entry name and the manifest name the same](#keep-the-entry-name-and-the-manifest-name-the-same)
- [Choose a plugin source](#choose-a-plugin-source)
- [Validate and test](#validate-and-test)
  - [Problems that validation reports](#problems-that-validation-reports)
  - [Problems that surface when you add or install](#problems-that-surface-when-you-add-or-install)
  - [Test an edit to a plugin](#test-an-edit-to-a-plugin)
  - [Remove the marketplace to start over](#remove-the-marketplace-to-start-over)
- [Host your marketplace](#host-your-marketplace)
- [Next steps](#next-steps)

Run a marketplace

# Create a marketplace

Copy pageCopy page

Build a plugin marketplace from a marketplace.json file and test it locally before you host it.

Copy pageCopy page

A plugin marketplace is a directory or repository with a `.claude-plugin/marketplace.json` file that lists your plugins and where to fetch each one. You push the directory to a git host, and anyone with access registers it in Claude Code with one command and installs your plugins from it. Create your own marketplace when you want a group you choose, such as your team or your organization, to install your plugins and keep receiving your updates from a catalog you control. The repository can be private, it can list as many plugins as you like, and an administrator can [require it on every machine](plugins-org.md).

These cases are covered on other pages:

- **Sharing one plugin with a few people**: send them the plugin’s directory or a `.zip` of it. See [Share a plugin without a marketplace](plugins-publish.md#share-a-plugin-without-a-marketplace).
- **Offering a plugin to everyone**: submit it to Anthropic’s directory. See [Submit to Anthropic’s directory](plugins-publish.md#submit-to-anthropics-directory).
- **Using a plugin yourself**: load it with `--plugin-dir` or save it in your skills directory. See [Develop without a marketplace](plugins-create.md#develop-without-a-marketplace).

Start with [Create a marketplace](#create-a-marketplace) to build one on your own machine and install a plugin from it, then [add more plugin entries](#add-plugin-entries).


[​](#create-a-marketplace)

Create a marketplace

The following steps create a marketplace on your machine, add a plugin to it, register it in Claude Code, and install the plugin from it. That is the whole loop, and it’s the same loop your users go through once you host the marketplace somewhere they can reach. Run every command in your shell, from the directory where you want `my-marketplace/` created. You need a plugin to list. The example uses `my-first-plugin` from [Create your first plugin](plugins-create.md#create-your-first-plugin), a plugin with one skill that you run as `/my-first-plugin:hello`; build it first if you don’t have a plugin yet. To use a plugin of your own instead, substitute its directory and its `name` wherever the steps say `my-first-plugin`. For what a plugin directory can contain, see the [plugin directory explorer](plugins-components.md#explore-the-plugin-directory).

1

Set up the marketplace directory

A marketplace is a directory with a `.claude-plugin/marketplace.json` file, plus the plugins it lists. Create the marketplace directory and its `.claude-plugin/` folder, then copy your plugin in under `plugins/`:

```python
mkdir -p my-marketplace/.claude-plugin my-marketplace/plugins
cp -r my-first-plugin my-marketplace/plugins/
```

Check that the plugin is valid where it now sits, so that any later error is about the marketplace and not the plugin:

```python
claude plugin validate ./my-marketplace/plugins/my-first-plugin
```

The last line of the output reads `✔ Validation passed`.

2

Create the marketplace file

Save `marketplace.json` at `my-marketplace/.claude-plugin/marketplace.json`. The file requires a `name`, an `owner`, and a `plugins` array.Each object in `plugins` is a plugin entry and needs a `name` and a `source`. Write the entry’s `source` as a path from the marketplace root. The root is `my-marketplace/`, the directory that contains `.claude-plugin/`.

my-marketplace/.claude-plugin/marketplace.json

```python
{
  "name": "my-marketplace",
  "description": "Plugins for my team",
  "owner": {
    "name": "Your Name"
  },
  "plugins": [
    {
      "name": "my-first-plugin",
      "source": "./plugins/my-first-plugin",
      "description": "A greeting plugin to learn the basics"
    }
  ]
}
```

3

Validate the marketplace

Run `claude plugin validate` on the marketplace directory to check the JSON syntax, the required fields, and each plugin entry in its `.claude-plugin/marketplace.json`.

```python
claude plugin validate ./my-marketplace
```

For the file as written in step 2, the last line of the output reads `✔ Validation passed`.

4

Add the marketplace and install the plugin

Register the directory as a marketplace.

```python
claude plugin marketplace add ./my-marketplace
```

The command prints `✔ Successfully added marketplace: my-marketplace (declared in user settings)`, which means the marketplace is recorded in your user settings file.Install the plugin. The install id is the entry’s `name`, an `@`, and the marketplace `name`.

```python
claude plugin install my-first-plugin@my-marketplace
```

The command prints `✔ Successfully installed plugin: my-first-plugin@my-marketplace (scope: user)`.Inside a session, `/plugin marketplace add ./my-marketplace` registers the marketplace the same way. `/plugin install my-first-plugin@my-marketplace` opens the plugin’s details in the `/plugin` panel, where you install it. For that flow, see [Install and manage plugins](discover-plugins.md).

5

Confirm the plugin loaded

List installed plugins.

```python
claude plugin list
```

The output lists `my-first-plugin@my-marketplace` with `Status: ✔ enabled`.To see what the plugin loaded, show its details.

```python
claude plugin details my-first-plugin
```

The `Component inventory` section reads `Skills (1) hello`.To run the skill, start a session and enter `/my-first-plugin:hello`. Claude greets you. The command has the plugin’s name as a prefix, as every plugin skill’s name does.


[​](#add-plugin-entries)

Add plugin entries

Every plugin you distribute is one object in the `plugins` array of `marketplace.json`. To add a second plugin, add a second object. These fields cover most entries:

- `name`: the identifier people type before `@` when they install. [Plugin entries](plugins-marketplace-reference.md#plugin-entries) gives the characters a name can use.
- `source`: where Claude Code fetches the plugin from. Write a relative path string for a plugin inside the marketplace directory, as in [the walkthrough](#create-a-marketplace), or a source object for a plugin outside it. See [Choose a plugin source](#choose-a-plugin-source).
- `description`: the line people see next to the plugin when they browse your marketplace in `/plugin`.

For the full field list, see [Plugin entries](plugins-marketplace-reference.md#plugin-entries). An entry can also set any [`plugin.json`](plugins-reference.md) field. For when an entry’s `plugin.json` fields apply to a plugin that has its own `plugin.json`, see [Entry and plugin.json](plugins-marketplace-reference.md#entry-and-plugin-json).


[​](#rules-for-plugin-entries)

Rules for plugin entries

Most failed installs from a new marketplace come from a relative path written from the wrong directory, or from an entry name that differs from the `name` in the plugin’s `plugin.json`.


[​](#write-relative-paths-from-the-marketplace-root)

Write relative paths from the marketplace root

The marketplace root is the directory that contains `.claude-plugin/`. In [the walkthrough](#create-a-marketplace), that’s `my-marketplace/`, so the entry’s `source` is `"./plugins/my-first-plugin"`. The path doesn’t start inside `.claude-plugin/`, so don’t use `..` to leave it. A path with `..` and a path to a missing directory fail at different commands:

- **A path with `..`**: `claude plugin validate` reports the entry as invalid. The message begins `Path contains "..": ./../plugins/my-first-plugin`.
- **A path to a directory that doesn’t exist**: `claude plugin validate` passes. `claude plugin install` fails with `Source path does not exist: <path>`, and `<path>` is the absolute location Claude Code checked.


[​](#keep-the-entry-name-and-the-manifest-name-the-same)

Keep the entry name and the manifest name the same

A marketplace plugin has an entry `name` in `marketplace.json` and a `name` in its own `plugin.json`, called the manifest name. Each name appears in different places:

- **Entry name**: the install id, `<entry-name>@<marketplace>`. It’s what people type to install, what `claude plugin list` shows, and the key Claude Code writes under [`enabledPlugins`](../02-Claude-Code-CLI/settings-reference.md#enabledplugins) in their settings file.
- **Manifest name**: the prefix on the plugin’s skills, and the name `claude plugin details` takes.

When the two names differ and someone installs by the manifest name, Claude Code reports `Plugin "<manifest-name>" not found in marketplace "<marketplace>"`. Keep the two names the same. For more on how Claude Code uses the two names, see [Plugin loading reference](plugins-loading.md#find-where-a-plugin-came-from).


[​](#choose-a-plugin-source)

Choose a plugin source

Each plugin entry in `marketplace.json` has a `source` that tells Claude Code where to fetch that one plugin. Pick the source by where the plugin’s files are stored. The table lists the sources most marketplace owners use.

| Source        | Use it when                                                               | Minimal `source` value                                                                    |
|:--------------|:--------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|
| Relative path | The plugin’s files are inside the marketplace directory itself            | `"./plugins/my-first-plugin"`                                                             |
| `github`      | The plugin is a GitHub repository of its own                              | `{ "source": "github", "repo": "your-org/my-first-plugin" }`                              |
| `git-subdir`  | The plugin is a subdirectory of some other repository, such as a monorepo | `{ "source": "git-subdir", "url": "your-org/monorepo", "path": "tools/my-first-plugin" }` |

In a `git-subdir` source, `url` takes a git URL or an `owner/repo` GitHub shorthand. A plugin can also come from one of these source types:

- `url`: a git repository by URL, on any host
- `archive`: a zip file downloaded over HTTPS
- `npm`: an npm package
- `command`: a directory produced by running a command on the machine where the plugin is installed

For the fields of every source type, and for pinning a git-based source to a `ref` or `sha`, see [Plugin sources](plugins-marketplace-reference.md#plugin-sources).


[​](#validate-and-test)

Validate and test

As you add plugins, run `claude plugin validate ./my-marketplace` in your shell after every edit, and install from the marketplace on your own machine before you share it. Validation and installation catch different problems.


[​](#problems-that-validation-reports)

Problems that validation reports

`claude plugin validate` reads only files inside the marketplace directory. It reports:

- JSON syntax errors, as `json: Invalid JSON syntax: <reason>`
- Missing required fields, such as `owner: Invalid input`
- A marketplace or plugin name that breaks the naming rules in the [marketplace reference](plugins-marketplace-reference.md#top-level-fields)
- A relative `source` that contains `..`
- Unknown fields at the top level or in a plugin entry, as warnings
- Problems in the `plugin.json` of each relative-path plugin, as `plugins[N] plugin.json → <field>: <message>`

For every message `validate` can print, see [Validation messages](plugins-marketplace-reference.md#validation-messages). For its flags and exit codes, see [`plugin validate`](plugins-cli-reference.md#plugin-validate).


[​](#problems-that-surface-when-you-add-or-install)

Problems that surface when you add or install

Problems that `claude plugin validate` doesn’t report appear when you add the marketplace or install from it:

- **When you add the marketplace**: the exact [official marketplace names](plugins-marketplace-reference.md#reserved-names), such as `claude-plugins-official`, pass validation. When you add a marketplace with one of those names, Claude Code refuses it with a message that starts `The name '<name>' is reserved for official Anthropic marketplaces`.
- **When you install a plugin**:
  - Claude Code first fetches a `github`, `git-subdir`, or other remote source when you install the plugin, so a wrong `repo` or `path` appears then.
  - A relative `source` whose directory doesn’t exist also fails at install, with `Source path does not exist: <path>`.


[​](#test-an-edit-to-a-plugin)

Test an edit to a plugin

In [the walkthrough](#create-a-marketplace), you added `my-marketplace` from a local directory with a relative-path `source`. With that setup, Claude Code reads the plugin’s files directly from `my-marketplace/plugins/`. Your edits take effect at the next session start or when you run `/reload-plugins` in a session, with no change to the plugin’s `version`. People who install from your hosted marketplace get a copy in the plugin cache instead. For how they receive a new version, see [Keep users up to date](plugins-host-marketplace.md#keep-users-up-to-date).


[​](#remove-the-marketplace-to-start-over)

Remove the marketplace to start over

To remove everything and start over, run `claude plugin marketplace remove my-marketplace` in your shell. The command removes the marketplace and uninstalls its plugins.


[​](#host-your-marketplace)

Host your marketplace

Once you can install a plugin from the marketplace on your own machine, as in [Create a marketplace](#create-a-marketplace), push the marketplace directory to a git host. Your teammates then run `claude plugin marketplace add <owner>/<repo>` in their shell for a GitHub repository, or the same command with the repository URL. They then install a plugin by name as in [the walkthrough](#create-a-marketplace). For private-repository access, updates, versioning, and renaming or removing entries, see [Host and maintain a marketplace](plugins-host-marketplace.md).


[​](#next-steps)

Next steps

- [Host and maintain a marketplace](plugins-host-marketplace.md): pick a host, keep users up to date, and rename or remove plugins safely
- [Marketplace reference](plugins-marketplace-reference.md): `marketplace.json` fields and source types
- [Manage plugins for your organization](plugins-org.md): require your marketplace and its plugins on every machine
- [Suggest plugins by relevance](plugins-relevance.md): have Claude Code suggest a plugin from your marketplace when a session matches

---

## Recommend plugins for your org - Claude Code Docs

Source: https://code.claude.com/docs/en/plugin-relevance
Path: 08-Plugins-Skills/plugin-relevance.md

## On this page

- [How it works](#how-it-works)
- [Add relevance to a plugin entry](#add-relevance-to-a-plugin-entry)
- [Field reference](#field-reference)
  - [relevance](#relevance)
  - [relevance.signals](#relevance-signals)
- [Enable suggestions in managed settings](#enable-suggestions-in-managed-settings)
- [What the user sees](#what-the-user-sees)
- [Validate your marketplace](#validate-your-marketplace)
- [See also](#see-also)

Plugin distribution

# Recommend plugins for your org

Copy pageCopy page

Add a relevance block to marketplace plugin entries so Claude Code suggests them when a user’s work matches.

Copy pageCopy page

If you operate a plugin marketplace for your organization, you can have Claude Code suggest specific plugins to users based on what they are working on. Add a `relevance` block to a plugin’s entry in `marketplace.json`, then allowlist the marketplace in managed settings. When a user’s session matches one of the declared signals, Claude Code surfaces an install suggestion for that plugin. Marketplace-declared suggestions are opt-in per marketplace through [managed settings](../13-Enterprise-Admin/managed-settings.md). No marketplace’s `relevance` declarations produce suggestions until an administrator adds it to the allowlist, including the official Anthropic marketplace. Claude Code also includes one built-in suggestion that is independent of this allowlist; that tip and all marketplace-declared tips are disabled when [`spinnerTipsEnabled`](../02-Claude-Code-CLI/settings-reference.md#spinnertipsenabled) is set to `false`. This page is for marketplace operators and enterprise administrators. If you are looking to install plugins, see [Discover and install plugins](discover-plugins.md).


[​](#how-it-works)

How it works

Each plugin entry in `marketplace.json` can carry a `relevance` object. The object names a topic and one or more signals. A signal is a pattern that Claude Code tests against the current session, such as the working directory or files Claude has read. Signal matching happens locally on the user’s machine. The matching adds no network traffic and does not report which signals matched, or their values, to Anthropic or to the marketplace operator. When a signal matches and the plugin is not already installed, Claude Code shows the plugin in three places:

- **Spinner tip**: a “Working with *topic*? Install the *plugin* plugin” message with the `/plugin install` command appears below the spinner while Claude is responding.
- **Session-start suggestion**: if the `cwd` signal matches the working directory, a one-line `plugin suggestion: <name>@<marketplace> · /plugin` notification appears before the first turn.
- **`/plugin` Discover tab**: the plugin is pinned to the top of the Discover list with an annotation such as “suggested for this directory” or “suggested for stripe commands”.

The spinner tip and the session-start notification are part of the spinner-tips system. Claude Code disables both when `spinnerTipsEnabled` resolves to `false` across your settings files, or when `excludeDefault` resolves to `true` across the [`spinnerTipsOverride`](../02-Claude-Code-CLI/settings-reference.md#spinnertipsoverride) keys in user, `--settings`, and managed settings and those keys configure at least one tip or a `tipsFile`. The Discover-tab pin is independent of tip settings. Claude Code never installs a plugin automatically. The user always confirms.


[​](#add-relevance-to-a-plugin-entry)

Add relevance to a plugin entry

Add a `relevance` object to the plugin’s entry in your `marketplace.json`. The following example declares that the `terraform-helpers` plugin is relevant when Claude reads a `.tf` file or when Claude runs `terraform`:

```python
{
  "name": "acme-corp-plugins",
  "owner": { "name": "Acme Platform Team" },
  "plugins": [
    {
      "name": "terraform-helpers",
      "source": "./plugins/terraform-helpers",
      "description": "Acme conventions and helpers for Terraform",
      "relevance": {
        "topic": "Terraform",
        "signals": {
          "cli": ["terraform"],
          "filesRead": ["**/*.tf"]
        }
      }
    }
  ]
}
```

A plugin with a `relevance` block but no matching signal behaves like any other marketplace entry. It appears in the Discover list in its normal position and never surfaces as a spinner tip.


[​](#field-reference)

Field reference


[​](#relevance)

`relevance`

| Field     | Type   | Description                                                                                                                                                                                                                                                                                                                                                       |
|:----------|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `topic`   | string | Optional. The phrase that fills “Working with *topic*?” in the spinner tip. Often the product name, for example `Stripe`. Use a domain such as `design` when the plugin name does not read naturally as a topic. Defaults to the plugin name with each hyphen segment capitalized. The session-start notification does not use this value. Maximum 64 characters. |
| `signals` | object | Matchers that determine when the plugin is relevant. At least one signal is required for the plugin to be suggestible. See the table below.                                                                                                                                                                                                                       |


[​](#relevance-signals)

`relevance.signals`

| Field          | Type             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
|:---------------|:-----------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `cwd`          | array of strings | Glob patterns matched against the session’s working directory. Matched as an absolute path and, when inside a git repository, as a path relative to the repository root. Forward-slash normalized and case-insensitive. Every pattern matches the directory itself and everything under it, so `infra`, `infra/`, and `infra/**` behave identically. This is the only signal that can match at session start, before the first turn. Maximum 10 patterns of 256 characters each.                                                                                                                                                                                                                                                                                                                               |
| `cli`          | array of strings | Command names from shell commands Claude has run this session, for example `["stripe"]`. Applies on every platform: commands run on Windows through PowerShell or Git Bash are recorded the same way. Claude Code records one command name per shell tool invocation: the first token after any leading environment variable assignments and `sudo`. Compound commands contribute only their leading command, so `cd infra && terraform plan` records `cd`, not `terraform`. Exact match. Maximum 10 entries of 64 characters each.                                                                                                                                                                                                                                                                            |
| `hosts`        | array of strings | Hostnames seen in `http://` or `https://` URLs in Bash commands this session, for example `["api.stripe.com"]`. Bare lowercase hostname only: no scheme, port, or path. Exact case-insensitive match. Maximum 20 entries of 128 characters each.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `filesRead`    | array of strings | Glob patterns matched against the paths of files Claude has read this session, for example `["**/*.tf"]`. Forward-slash normalized and case-insensitive. Maximum 10 patterns of 256 characters each.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `manifestDeps` | array of objects | Dependencies declared in package manifests Claude has read this session. Each entry is `{ "file": "...", "pattern": "..." }`, where `file` is a regular expression matched against the manifest file’s path as recorded in session state, typically an absolute path, and `pattern` is a regular expression matched against that file’s contents. Anchor `file` at the end, for example `[/\\\\]package\\.json$` in JSON-escaped form, because a start-anchored pattern never matches an absolute path. Paths are not separator-normalized for this signal, so Windows paths use backslashes. Manifest files larger than 512 KB are skipped. Both values are JavaScript `RegExp` source strings of at most 256 characters. `file` matches case-insensitively. `pattern` is case-sensitive. Maximum 10 entries. |

The `cli`, `hosts`, `filesRead`, and `manifestDeps` signals need session history, so they can only match on the spinner tip and the Discover tab. The `filesRead` and `manifestDeps` signals test the session’s recorded file state, which also includes files Claude has written or edited and auto-loaded `CLAUDE.md` memory files. For these two signals, Claude Code skips paths under its own [configuration directory](../02-Claude-Code-CLI/claude-directory.md) and its temporary directories. The following example uses `manifestDeps` to suggest a Stripe plugin once Claude has read a `package.json` that depends on `stripe`. The `file` pattern uses `[/\\\\]` so it matches both forward-slash and backslash path separators, and `\\.` so the dot is literal. In JSON, each backslash in the regular expression is written twice.

```python
{
  "name": "stripe-helpers",
  "source": "./plugins/stripe-helpers",
  "relevance": {
    "topic": "Stripe",
    "signals": {
      "manifestDeps": [
        {
          "file": "[/\\\\]package\\.json$",
          "pattern": "\"stripe\"\\s*:"
        }
      ]
    }
  }
}
```

Claude Code ignores unknown fields under `relevance` and `relevance.signals` at load time, so older clients continue to load your marketplace.


[​](#enable-suggestions-in-managed-settings)

Enable suggestions in managed settings

Declaring `relevance` in `marketplace.json` is not enough on its own. An administrator must allowlist the marketplace in [managed settings](../13-Enterprise-Admin/managed-settings.md) before its suggestions appear to users. Add the marketplace name to `pluginSuggestionMarketplaces`. For any marketplace other than the official Anthropic marketplace, also declare the marketplace source in the same managed settings, either as that name’s entry in `extraKnownMarketplaces` or as an entry in `strictKnownMarketplaces`. The allowlisted name is ignored if the marketplace registered on the machine came from a different source. This prevents an unrelated source from registering under an allowlisted name to have its plugins suggested across your org. The following `managed-settings.json` registers an org marketplace from a GitHub repository and enables its suggestions:

```python
{
  "extraKnownMarketplaces": {
    "acme-corp-plugins": {
      "source": {
        "source": "github",
        "repo": "acme-corp/claude-plugins"
      }
    }
  },
  "pluginSuggestionMarketplaces": ["acme-corp-plugins"]
}
```

The official marketplace is exempt from the source-declaration requirement because its name can only register from the official Anthropic source. Allowlisting the name alone is sufficient:

```python
{
  "pluginSuggestionMarketplaces": ["claude-plugins-official"]
}
```


[​](#what-the-user-sees)

What the user sees

When a signal matches during a session, the spinner tip reads:

```python
Working with Terraform? Install the terraform-helpers plugin:
/plugin install terraform-helpers@acme-corp-plugins
```

At session start, a matching `cwd` signal surfaces the one-line notification:

```python
plugin suggestion: terraform-helpers@acme-corp-plugins · /plugin
```

A given plugin’s suggestion appears at most once every three sessions across the spinner tip and the session-start notification combined, and neither repeats once the plugin is installed. The session-start notification additionally stops appearing after the suggestion has been shown twice. In the `/plugin` Discover tab, the plugin is pinned above the other results with an annotation that names the matching signal, such as `suggested for this directory` or `suggested for terraform commands`. The Discover tab pins a given plugin once; later visits list it in normal order.


[​](#validate-your-marketplace)

Validate your marketplace

Run `claude plugin validate` against your marketplace directory to check the `relevance` block before publishing:

```python
claude plugin validate ./my-marketplace
```

The validator reports unknown keys under `relevance` and `relevance.signals` as warnings, flags a `relevance` value that is not an object, and rejects a `signals.hosts` entry that includes a scheme, port, or path.


[​](#see-also)

See also

- [Create and distribute a plugin marketplace](plugin-marketplaces.md): build the marketplace that hosts your plugins
- [Recommend your plugin from your CLI](plugin-hints.md): prompt users from your own CLI instead of from Claude Code’s session signals
- [All settings](../02-Claude-Code-CLI/settings-reference.md#pluginsuggestionmarketplaces): `pluginSuggestionMarketplaces` and `extraKnownMarketplaces`

---

## Anthropic's marketplaces - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/anthropic-marketplaces
Path: 08-Plugins-Skills/plugins-anthropic-marketplaces.md

## On this page

- [Anthropic’s marketplaces](#anthropic%E2%80%99s-marketplaces)
  - [The demo marketplace in anthropics/claude-code](#the-demo-marketplace-in-anthropics%2Fclaude-code)
- [Find plugins in the official marketplace](#find-plugins-in-the-official-marketplace)
- [Browse and install from Anthropic’s marketplaces](#browse-and-install-from-anthropic%E2%80%99s-marketplaces)
  - [Add the community or demo marketplace](#add-the-community-or-demo-marketplace)
- [Third-party marketplaces](#third-party-marketplaces)
- [Next steps](#next-steps)

Use plugins

# Anthropic's marketplaces

Copy pageCopy page

Anthropic’s official, community, and demo plugin marketplaces for Claude Code: their names, repositories, how you add each, and where to browse their plugins.

Copy pageCopy page

Anthropic publishes three general-purpose plugin marketplaces for Claude Code: [official](https://github.com/anthropics/claude-plugins-official), [community](https://github.com/anthropics/claude-plugins-community), and [demo](https://github.com/anthropics/claude-code). Each is a catalog of plugins in its own GitHub repository. When you install a plugin from one of them in a Claude Code session, you type the marketplace’s name after `@`, as in `/plugin install commit-commands@claude-plugins-official`. Use this page to distinguish the three marketplaces and to find where to check whether the official one holds a given plugin.

These cases are covered on other pages:

- **How to install a plugin**: see [Install plugins](discover-plugins.md)
- **A failed install**: see [Troubleshoot plugins](plugins-troubleshooting.md)

Go to the part of the page you need:

- To distinguish the three marketplaces by repository, marketplace name, and how you get each one, see [Anthropic’s marketplaces](#anthropic%E2%80%99s-marketplaces).
- To find a plugin in the official marketplace, see [Find plugins in the official marketplace](#find-plugins-in-the-official-marketplace).


[​](#anthropic’s-marketplaces)

Anthropic’s marketplaces

A marketplace is a catalog of plugins that a repository defines in its `.claude-plugin/marketplace.json` file. The official, community, and demo marketplaces each come from their own GitHub repository. Anthropic also publishes topic-specific marketplaces, such as `anthropics/skills` and `anthropics/knowledge-work-plugins`, which you add in a Claude Code session with `/plugin marketplace add <owner>/<repo>`. This table gives each marketplace’s repository and marketplace name, which is what you type after `@` when you install a plugin from that marketplace. The community marketplace’s name is `claude-community`, not its repository name.

|                  | Official                                                                                                                                                                                                                                                                                                                                                                                             | Community                                                                                              | Demo                                                                                      |
|:-----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------|
| Repository       | [`anthropics/claude-plugins-official`](https://github.com/anthropics/claude-plugins-official)                                                                                                                                                                                                                                                                                                        | [`anthropics/claude-plugins-community`](https://github.com/anthropics/claude-plugins-community)        | [`anthropics/claude-code`](https://github.com/anthropics/claude-code/tree/main/plugins)   |
| Marketplace name | `claude-plugins-official`                                                                                                                                                                                                                                                                                                                                                                            | `claude-community`                                                                                     | `claude-code-plugins`                                                                     |
| What’s in it     | Plugins Anthropic maintains, plus plugins from partners and other authors                                                                                                                                                                                                                                                                                                                            | Third-party plugins that their authors submitted to Anthropic                                          | A small set of example plugins that show what a plugin can contain                        |
| How you get it   | Claude Code adds it the first time you start an interactive terminal session, unless a [managed policy](plugins-org.md#allow-the-official-marketplace-and-your-own) or `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` blocks it. See [Marketplace `claude-plugins-official` not found](plugins-troubleshooting.md#marketplace-claude-plugins-official-not-found) if it’s missing | You add it in a Claude Code session with `/plugin marketplace add anthropics/claude-plugins-community` | You add it in a Claude Code session with `/plugin marketplace add anthropics/claude-code` |

If you wrote a plugin and want other people to install it, see [Publish a plugin](plugins-publish.md), which covers your own marketplace and submitting to Anthropic’s directory.


[​](#the-demo-marketplace-in-anthropics/claude-code)

The demo marketplace in `anthropics/claude-code`

If a tutorial or an older set of instructions tells you to run `/plugin marketplace add anthropics/claude-code`, that adds the demo marketplace, named `claude-code-plugins`. It isn’t the official marketplace, which Claude Code already added for you. Most of the demo marketplace’s plugins are also in the official marketplace under the same names. For example, `code-review`, `feature-dev`, `commit-commands`, and `security-guidance` are in both. Install those from `claude-plugins-official` so you don’t have two copies installed.


[​](#find-plugins-in-the-official-marketplace)

Find plugins in the official marketplace

The official marketplace, `claude-plugins-official`, is the one Claude Code adds for you. Most of what it lists comes from partners and other authors rather than from Anthropic: tool vendors publish plugins that connect Claude Code to their services, and Anthropic maintains a smaller set of its own, such as `commit-commands`, `code-review`, `feature-dev`, and the [language server plugins](plugins-code-intelligence.md). The catalog changes often, so this page doesn’t list it. To see what’s in it, use the **Discover** tab of `/plugin` in a Claude Code session, which you can search, or browse [Claude Marketplace](https://claude.com/marketplace/plugins) on the web.


[​](#browse-and-install-from-anthropic’s-marketplaces)

Browse and install from Anthropic’s marketplaces

You can search Anthropic’s marketplaces for a plugin in Claude Code, on the web, or on GitHub:

- **In Claude Code, by browsing**: run `/plugin` in an interactive session. Its **Discover** tab lists the plugins from the marketplaces you’ve added.
- **In Claude Code, by name**: run `/plugin install <name>` in a session, which looks the name up in the marketplaces you’ve added. If the plugin is in one of them, its details open in the `/plugin` panel, and nothing installs until you choose an [installation scope](discover-plugins.md#install-a-plugin) and confirm there. If it isn’t, you see `Plugin "<name>" not found in any marketplace`.
- **On the web**: search the full catalog on [Claude Marketplace](https://claude.com/marketplace/plugins), which shows install counts and marks some plugins **Anthropic verified**.
- **On GitHub**: open `.claude-plugin/marketplace.json` in the marketplace’s repository, such as [`anthropics/claude-plugins-official`](https://github.com/anthropics/claude-plugins-official). That file is the catalog itself.

Anthropic’s directory is separate from these marketplaces. The directory is the catalog on claude.ai, and `/plugin` doesn’t list it. A plugin you add from the directory on claude.ai reaches Claude Code through [account sync](plugins-loading.md#synced-plugins). To list your own plugin there, see [Submit to Anthropic’s directory](plugins-publish.md#submit-to-anthropics-directory). To install from the desktop app or from a script, or to see what a cloud session loads, see [Install plugins](discover-plugins.md).


[​](#add-the-community-or-demo-marketplace)

Add the community or demo marketplace

The community and demo marketplaces aren’t registered until you add them in a Claude Code session:

- **Community**: run `/plugin marketplace add anthropics/claude-plugins-community`, then install with the `@claude-community` suffix.
- **Demo**: run `/plugin marketplace add anthropics/claude-code`, then install with the `@claude-code-plugins` suffix.

If `claude-plugins-official` isn’t on the **Marketplaces** tab of `/plugin`, add it the same way with `/plugin marketplace add anthropics/claude-plugins-official`. For `not found` errors and marketplaces that won’t add, see [Troubleshoot plugins](plugins-troubleshooting.md#install-a-plugin).


[​](#third-party-marketplaces)

Third-party marketplaces

Many popular plugins aren’t in any Anthropic marketplace. They’re in their authors’ own marketplaces, usually a GitHub repository with a `.claude-plugin/marketplace.json` at its root. Anthropic doesn’t review third-party marketplaces, so read [Plugin security and trust](plugins-security.md) before you add one. To use a third-party marketplace, add its repository in a Claude Code session with `/plugin marketplace add <owner>/<repo>`, then install with `/plugin install <plugin>@<marketplace-name>`. The marketplace name is the `name` field of that `marketplace.json`, and Claude Code prints it once it has added the marketplace. For other ways to add a marketplace, see [Add a marketplace](discover-plugins.md#add-a-marketplace).


[​](#next-steps)

Next steps

- [Install and manage plugins](discover-plugins.md): install a plugin from one of these marketplaces and choose a scope
- [Plugin security and trust](plugins-security.md): what a plugin can do on your machine and how to review one before you install it
- [Code intelligence plugins](plugins-code-intelligence.md): install one of the official marketplace’s language-server plugins
- [Create a marketplace](plugin-marketplaces.md): run your own marketplace alongside Anthropic’s

---

## Recommend your plugin from your CLI - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/cli-hints
Path: 08-Plugins-Skills/plugins-cli-hints.md

## On this page

- [Emit the hint](#emit-the-hint)
- [Hint format](#hint-format)
- [Check when the prompt appears](#check-when-the-prompt-appears)
- [Preview what the user sees](#preview-what-the-user-sees)
- [Next steps](#next-steps)

Create plugins

# Recommend your plugin from your CLI

Copy pageCopy page

Prompt Claude Code users to install your official-marketplace plugin by emitting a claude-code-hint tag from your CLI or SDK.

Copy pageCopy page

If you maintain a CLI or SDK, your tool can prompt Claude Code users to install your plugin. When your CLI detects that it’s running inside Claude Code, have it write a one-line `<claude-code-hint />` tag to stderr. Claude Code removes the line from Bash and PowerShell tool output before the model sees the output, then shows the user a one-time install prompt. This page applies only if your plugin is listed in `claude-plugins-official` or another marketplace with one of Anthropic’s [official marketplace names](plugins-security.md#official-marketplace-names). The community marketplace, `claude-community`, isn’t one of them.

To publish a plugin, see [Publish and distribute a plugin](plugins-publish.md).


[​](#emit-the-hint)

Emit the hint

Emit the tag only when `CLAUDECODE` or `CLAUDE_CODE_CHILD_SESSION` is set, so it doesn’t appear when a person runs your CLI directly. Claude Code sets `CLAUDECODE=1` in the commands it runs through the Bash and PowerShell tools and in hook commands. On v2.1.172 and later it also sets `CLAUDE_CODE_CHILD_SESSION=1` there. The variables differ in which processes carry them:

- **`CLAUDECODE`**: set by every Claude Code version. IDE extensions also set it in their integrated terminals, so a gate on `CLAUDECODE` alone also emits the tag when a person runs your CLI themselves in one of those terminals
- **`CLAUDE_CODE_CHILD_SESSION`**: set only in subprocesses Claude Code itself starts. Use it when you can require v2.1.172 or later

The [environment variables reference](../02-Claude-Code-CLI/env-vars.md) has the details. The following examples gate on `CLAUDECODE` for the widest reach and emit a hint for a plugin named `example-cli` in the official marketplace:

Node.js

Python

Go

Shell

```python
if (process.env.CLAUDECODE) {
  process.stderr.write(
    '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',
  )
}
```

```python
import os, sys

if os.environ.get("CLAUDECODE"):
    print(
        '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />',
        file=sys.stderr,
    )
```

```python
if os.Getenv("CLAUDECODE") != "" {
    fmt.Fprintln(os.Stderr,
        `<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />`)
}
```

```python
if [ -n "$CLAUDECODE" ]; then
  printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fi
```

Replace `example-cli` with your plugin’s name in the official marketplace. You can emit the hint on every invocation, because Claude Code prompts for each plugin once. To check the emitter, run `CLAUDECODE=1 example-cli` in a terminal and confirm the tag line appears on stderr, then run `example-cli` without the variable and confirm nothing extra prints.


[​](#hint-format)

Hint format

The tag must occupy its own line; Claude Code ignores a tag embedded mid-line. The tag takes three attributes, all required:

| Attribute | Description                                       |
|:----------|:--------------------------------------------------|
| `v`       | Protocol version. `1` is the only supported value |
| `type`    | Hint kind. `plugin` is the only supported value   |
| `value`   | Plugin identifier in `name@marketplace` form      |

Values may be double-quoted or unquoted; an unquoted value can’t contain whitespace. Claude Code removes the line from the output even when `v` or `type` is unrecognized.


[​](#check-when-the-prompt-appears)

Check when the prompt appears

The prompt appears only in interactive terminal sessions. In `claude -p` runs, in subagent runs, and in hook command output, the tag is stripped and no prompt is shown. All of these checks must also pass:

- **Official and installable**: `value` names a plugin that Claude Code finds in its local copy of an official marketplace, that isn’t already installed, and that no policy blocks
- **Analytics on**: a session where Claude Code’s analytics are off never prompts, for example one with `DISABLE_TELEMETRY`, `DO_NOT_TRACK`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` set, or one on a third-party provider such as Amazon Bedrock, where the [automatic telemetry opt-out](../13-Enterprise-Admin/data-usage.md#default-behaviors-by-api-provider) applies
- **Frequency limits**: one prompt per session, one prompt ever per plugin regardless of the user’s answer, and none once 100 plugins have been prompted for on that machine
- **Not turned off**: the user hasn’t chosen **No, and don’t show plugin installation hints again**
- **Local, attended session**: the session’s workspace is local rather than on a cloud or remote machine, and the session isn’t running unattended. For example, a session started with `--cloud`, one serving Remote Control, or an agent-team teammate never prompts


[​](#preview-what-the-user-sees)

Preview what the user sees

When the checks in [Check when the prompt appears](#check-when-the-prompt-appears) pass, Claude Code shows a **Plugin recommendation** dialog like the following:

```python
─────────────────────────────────────────────────────────────
  Plugin recommendation

    The example-cli command suggests installing a plugin.

    Plugin: example-cli
    Marketplace: claude-plugins-official
    Description: Official integration for example-cli deployments

    Would you like to install it?
    ❯ 1. Yes, install
      2. No
      3. No, and don't show plugin installation hints again

─────────────────────────────────────────────────────────────
```

The dialog names the first word of the shell command Claude ran, so users can spot a mismatch. Each answer has one effect:

- **Yes, install**: installs the plugin at [user scope](discover-plugins.md)
- **No, and don’t show plugin installation hints again**: turns off future hint prompts for that user
- **No answer for 30 seconds**: counts as **No**


[​](#next-steps)

Next steps

- [Publish and distribute a plugin](plugins-publish.md): the routes for distributing a plugin, including the official marketplace, which the hint requires
- [Plugin commands reference](plugins-cli-reference.md#plugin-install): the shell command that installs the same plugin outside a session

---

## Plugin commands reference - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/cli-reference
Path: 08-Plugins-Skills/plugins-cli-reference.md

## On this page

- [claude plugin commands](#claude-plugin-commands)
  - [plugin init](#plugin-init)
  - [plugin install](#plugin-install)
  - [JSON result format](#plugin-json-result)
  - [Accept a displayed install command](#accept-a-displayed-install-command)
  - [plugin uninstall](#plugin-uninstall)
  - [What an uninstall deletes and keeps](#what-an-uninstall-deletes-and-keeps)
  - [plugin enable](#plugin-enable)
  - [plugin disable](#plugin-disable)
  - [plugin update](#plugin-update)
  - [plugin list](#plugin-list)
  - [JSON output](#json-output)
  - [plugin details](#plugin-details)
  - [plugin prune](#plugin-prune)
  - [plugin eval](#plugin-eval)
  - [plugin eval init](#plugin-eval-init)
  - [plugin tag](#plugin-tag)
  - [plugin validate](#plugin-validate)
  - [Validate a directory](#validate-a-directory)
  - [Output and exit codes](#output-and-exit-codes)
- [claude plugin marketplace commands](#claude-plugin-marketplace-commands)
  - [plugin marketplace add](#plugin-marketplace-add)
  - [plugin marketplace list](#plugin-marketplace-list)
  - [plugin marketplace remove](#plugin-marketplace-remove)
  - [plugin marketplace update](#plugin-marketplace-update)
- [/plugin in a session](#plugin-in-a-session)
- [/reload-plugins](#reload-plugins)
  - [Reload summary](#reload-summary)
  - [Reloads that change MCP tools](#reloads-that-change-mcp-tools)
  - [Sessions without an interactive terminal](#sessions-without-an-interactive-terminal)
- [Flags that load a plugin for one session](#flags-that-load-a-plugin-for-one-session)
- [Next steps](#next-steps)

Reference

# Plugin commands reference

Copy pageCopy page

Complete reference for the claude plugin shell commands, /plugin and /reload-plugins in a session, and the flags that load a plugin for one session.

Copy pageCopy page

You run plugin commands either as `claude plugin` from your shell or a script, or as `/plugin` and `/reload-plugins` inside a Claude Code session. This reference gives each command’s flags, defaults, output, and exit codes, along with the two flags that load a plugin for one session. Run `claude plugin --help` on your build to confirm which subcommands your version has.

These cases are covered on other pages:

- **Install and manage steps, and where `/plugin` runs**: see [Install and manage plugins](discover-plugins.md)
- **What a command changes on disk and which scope takes precedence**: see [Plugin loading reference](plugins-loading.md)
- **What an error message means**: see [Troubleshoot plugins](plugins-troubleshooting.md)


[​](#claude-plugin-commands)

claude plugin commands

Run `claude plugin <subcommand>` from your shell or a script, outside a Claude Code session. These subcommands install and manage plugins without opening the [`/plugin`](#plugin-in-a-session) panel. `claude plugins` is an alias for `claude plugin`. Every subcommand shares these exit codes, plugin arguments, and scope values:

- **Exit codes**: `0` on success and `1` on failure. `validate` adds exit `2` for an unexpected error, and `eval` adds the codes listed in [its section](#plugin-eval).
- **Plugin arguments**: a `<plugin>` argument is a plugin `name` or `name@marketplace`. When two marketplaces offer the same name, use the qualified form.
- **Scopes**: `--scope` takes `user`, `project`, or `local`, and names the settings file the command writes to. `update` also takes `managed`.


[​](#plugin-init)

plugin init

Scaffold a new plugin at `~/.claude/skills/<name>/`. It loads in your next session as `<name>@skills-dir` with no install step. `new` is an alias for `init`. For the create, test, and edit workflow that begins with this command, see [Create a plugin](plugins-create.md).

```python
claude plugin init <name> [options]
```

`<name>` becomes the directory name under `~/.claude/skills/` and the plugin’s `name` in its manifest. The command has no flag for another location. To scaffold inside a project instead, see [Create a plugin](plugins-create.md).

| Flag                     | Description                                                                                             |
|:-------------------------|:--------------------------------------------------------------------------------------------------------|
| `--description <text>`   | Manifest description                                                                                    |
| `--author <name>`        | Author name. Defaults to `git config user.name`                                                         |
| `--author-email <email>` | Author email. Defaults to `git config user.email`                                                       |
| `--with <components...>` | Also scaffold starter files for `skills`, `agents`, `hooks`, `mcp`, `lsp`, `output-style`, or `channel` |
| `-f, --force`            | Overwrite an existing `.claude-plugin/` at the target                                                   |

Scaffold a plugin with starter skill and hook files:

```python
claude plugin init my-helper --with skills hooks
```

Claude Code validates what it wrote and prints `Created plugin "my-helper" at ~/.claude/skills/my-helper`, followed by the id it loads as and the `claude plugin disable` command that turns it off. Claude Code exits `1` without writing when it can’t scaffold safely, and the message names the reason. These are common reasons:

- An unknown `--with` value
- An existing scaffold at the target without `--force`
- A managed setting that blocks skills-directory plugins


[​](#plugin-install)

plugin install

Install a plugin from a marketplace you’ve added. `i` is an alias for `install`.

```python
claude plugin install <plugin> [options]
```

Most plugins install without a prompt. For a plugin whose marketplace entry [runs a command to install it](plugins-host-marketplace.md) or [sets a `headersHelper` for its download](plugins-host-marketplace.md#how-users-accept-a-headershelper-command), Claude Code first prints the command and asks `Run this command now? [y/N]`.

| Flag                        | Description                                                                                                                                                                                                                                                                                         |
|:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-s, --scope <scope>`       | Installation scope: `user`, `project`, or `local`. Defaults to `user`                                                                                                                                                                                                                               |
| `--config <key=value>`      | Set a [`userConfig`](plugins-reference.md) option the plugin’s manifest declares. Repeat the flag for each option. Requires Claude Code v2.1.147 or later                                                                                                                            |
| `-y, --yes`                 | Accept the displayed install command without the `Run this command now?` prompt. Ignored when the command runs inside a Claude Code session, such as from the Bash tool or a hook. Requires Claude Code v2.1.229 or later                                                                           |
| `--accept-command <sha256>` | Accept the displayed install command whose `sha256` a previous [`--json` run](#plugin-json-result) reported in `shownCommand`, in place of `-y`. Can’t be combined with `-y`. See [Accept a displayed install command](#accept-a-displayed-install-command). Requires Claude Code v2.1.271 or later |
| `--json`                    | Print the result as one JSON object on the last line of stdout instead of the human-readable message, for use in scripts. See [JSON result format](#plugin-json-result). Requires Claude Code v2.1.268 or later                                                                                     |

Pass `-y` from your own terminal to accept the displayed command without the prompt. Here’s what happens without a TTY and when Claude runs the command:

- **stdin or stdout isn’t a TTY, and you pass neither `-y` nor `--accept-command`**: the install is refused. The output says the command was only displayed, and the exit code is `1`
- **Claude runs the command through its Bash tool**: `-y` is ignored. Run the command from your own terminal instead

Install a plugin for everyone who clones the project:

```python
claude plugin install formatter@my-marketplace --scope project
```

Claude Code prints `Successfully installed plugin: formatter@my-marketplace (scope: project)`. When nothing new is installed, the output says why:

- **Already installed at that scope**: the output is `Plugin "formatter@my-marketplace" is already installed (scope: project)` and the exit code is `0`
- **You decline a command-source prompt**: the output is `Aborted.` and the exit code is `1`
- **You decline a `headersHelper` prompt, or it can’t be confirmed without a TTY**: the output is `Aborted — the command was not run.` and the exit code is `1`


[​](#plugin-json-result)

JSON result format

When you pass `--json` to `plugin install`, the last line of stdout is one JSON object. Parse only that line, because Claude Code prints any command the marketplace declares ahead of it. Three fields are always present:

- `command`: the subcommand that ran, such as `install`
- `outcome`: `ok` or `failed`
- `message`: a human-readable description of the result

Other fields, such as `pluginId`, `scope`, and `failureCode`, appear only when they apply. The `--json` option on `plugin uninstall`, `plugin update`, `plugin enable`, and `plugin disable` prints the same object with that subcommand’s own fields. A usage error, such as an invalid `--scope`, prints no result line and exits `1` with the reason on stderr.


[​](#accept-a-displayed-install-command)

Accept a displayed install command

When a `--json` run displays a marketplace-declared command and doesn’t run it, the `failed` result also carries a `shownCommand` object. Its fields include the command as displayed, the plugin it belongs to, and the command’s `sha256`. To accept exactly that command, re-run with that `sha256` as `--accept-command` from your own terminal, because the flag has no effect inside a Claude Code session. Requires Claude Code v2.1.271 or later. The `sha256` counts as acceptance for exactly that command, plugin, and marketplace catalog. If any of them changed since the command was displayed, Claude Code doesn’t accept the `sha256` and shows the command again. A change that the run’s own marketplace refresh fetches also counts as such a change. If `shownCommand.acceptCommandMatched` is `false`, the `sha256` you passed doesn’t match the command now displayed. Review that command before re-running with its `sha256`.


[​](#plugin-uninstall)

plugin uninstall

Remove an installed plugin from one scope. `remove` and `rm` are aliases for `uninstall`.

```python
claude plugin uninstall <plugin> [options]
```

| Flag                  | Description                                                                                                                                                                                                    |
|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-s, --scope <scope>` | Uninstall from scope: `user`, `project`, or `local`. Defaults to `user`                                                                                                                                        |
| `--keep-data`         | Preserve the plugin’s persistent data directory, `~/.claude/plugins/data/<id>/`                                                                                                                                |
| `--prune`             | Also remove auto-installed [dependencies](plugins-dependencies.md) that no remaining plugin needs                                                                                                        |
| `-y, --yes`           | Skip the `--prune` confirmation prompt. Required with `--prune` when stdin or stdout isn’t a TTY                                                                                                               |
| `--json`              | Print the result as one JSON object on the last line of stdout, in the [same format as `plugin install --json`](#plugin-json-result). Can’t be combined with `--prune`. Requires Claude Code v2.1.268 or later |

Uninstall a plugin from project scope:

```python
claude plugin uninstall formatter@my-marketplace --scope project
```

Claude Code prints `Successfully uninstalled plugin: formatter (scope: project)`. When the plugin isn’t installed at that scope, the command prints a line that starts `Failed to uninstall plugin "formatter@my-marketplace":` and exits `1`. If the failure line continues with `"formatter" was not uninstalled:` and names a settings file, Claude Code couldn’t confirm that the scope’s settings no longer switch the plugin on, so the plugin stays installed with everything it saved. With `--json`, the result carries `failureCode: "settings_still_on"`. This settings check requires Claude Code v2.1.282 or later.


[​](#what-an-uninstall-deletes-and-keeps)

What an uninstall deletes and keeps

When you uninstall a plugin from the last scope it’s installed at, Claude Code also deletes the plugin’s stored [options and secrets](plugins-reference.md#user-configuration) and its data directory, `~/.claude/plugins/data/<id>/`. There are three exceptions:

- With `--keep-data`, the data directory stays
- When another installed plugin uses the same folder, such as one whose ID differs from this one only in letter case, the data directory stays
- When Claude Code can’t read the list of installed plugins back after it removes the plugin from that scope, the options, secrets, and data directory all stay, because the plugin may still be installed at another scope. The uninstall still succeeds. The message lists what stayed and how to delete it, and with `--json` the result carries `savedKept: "install_records_unreadable"`

With `--json`, `keptData` reports whether the directory stayed, and `/plugin` shows `· data preserved` when it did. For a directory that stays without `--keep-data`, this reporting requires Claude Code v2.1.281 or later. The `savedKept` field requires Claude Code v2.1.282 or later.


[​](#plugin-enable)

plugin enable

Enable a disabled plugin. For a [plugin synced from claude.ai](plugins-loading.md#synced-plugins), pass `<name>@synced` as the plugin.

```python
claude plugin enable <plugin> [options]
```

| Flag                  | Description                                                                                                                                                                  |
|:----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-s, --scope <scope>` | Scope to enable at: `user`, `project`, or `local`. Auto-detected when omitted                                                                                                |
| `--json`              | Print the result as one JSON object on the last line of stdout, in the [same format as `plugin install --json`](#plugin-json-result). Requires Claude Code v2.1.268 or later |

Without `--scope`, the command checks your settings files in the order local, project, user, and uses the first scope that mentions the plugin. If you pass a `--scope` where the plugin isn’t declared, the command either writes an override or fails:

- **A scope that [takes precedence](plugins-loading.md) over the declaring one**: Claude Code writes an override at the scope you passed. For example, `claude plugin disable formatter --scope local` turns off a project-enabled plugin for you alone
- **Any other scope**: the command fails with `Plugin "formatter" is installed at project scope, not user. Use --scope project or omit --scope to auto-detect.`

If the plugin is already enabled at the resolved scope, the command prints `Plugin "formatter" is already enabled` and exits `1`. With `--json`, the result has `"failureCode": "already_in_goal_state"` and `"alreadyInGoalState": true`, so a script can treat that case as success. When the plugin declares [dependencies](plugins-dependencies.md), Claude Code enables them too. The command fails in these cases:

- **A dependency is not installed**: enable fails and prints the `claude plugin install` command for each missing dependency
- **A dependency is blocked by your organization’s plugin policy**: enable fails and names the blocked dependency
- **A dependency is set to `false` at a scope with higher precedence than the target scope**: enable fails. Enable the dependency at that scope, or pass `--scope` to write there

Re-enable a plugin wherever it’s declared:

```python
claude plugin enable formatter
```

Claude Code prints `Successfully enabled plugin: formatter (scope: project)`, naming the scope it detected.


[​](#plugin-disable)

plugin disable

Disable a plugin without uninstalling it. For a [plugin synced from claude.ai](plugins-loading.md#synced-plugins), pass `<name>@synced` as the plugin.

```python
claude plugin disable [plugin] [options]
```

| Flag                  | Description                                                                                                                                                                  |
|:----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-a, --all`           | Disable every enabled plugin. Can’t be combined with a plugin name or `--scope`                                                                                              |
| `-s, --scope <scope>` | Scope to disable at: `user`, `project`, or `local`. Auto-detected when omitted                                                                                               |
| `--json`              | Print the result as one JSON object on the last line of stdout, in the [same format as `plugin install --json`](#plugin-json-result). Requires Claude Code v2.1.268 or later |

Without `--scope`, the scope is auto-detected in the same local, project, user order as [`plugin enable`](#plugin-enable). If you pass neither a plugin name nor `--all`, Claude Code prints `Please specify a plugin name or use --all to disable all plugins` and exits `1`. Disabling a plugin that is already disabled prints `Plugin "formatter" is already disabled` and exits `1`, as [`plugin enable`](#plugin-enable) does for an already-enabled plugin. The command fails for a plugin that is still required:

- **Another enabled plugin [depends on](plugins-dependencies.md) it**: the command fails and names the dependents to disable first
- **Your organization requires it as a synced plugin**: the command fails and saves nothing

Disable one plugin:

```python
claude plugin disable formatter
```

Claude Code prints `Successfully disabled plugin: formatter (scope: project)`.


[​](#plugin-update)

plugin update

Update a plugin to the latest version its marketplace offers. The new version loads in your next session, or after you run `/reload-plugins` in a running one.

```python
claude plugin update <plugin> [options]
```

| Flag                        | Description                                                                                                                                                                                                                                   |
|:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-s, --scope <scope>`       | Scope to update: `user`, `project`, `local`, or `managed`. Auto-detected when omitted                                                                                                                                                         |
| `-y, --yes`                 | Accept a changed install command from a [command-source](plugins-host-marketplace.md) plugin, without the prompt. Required when stdin or stdout isn’t a TTY, unless you pass `--accept-command`. Requires Claude Code v2.1.229 or later |
| `--accept-command <sha256>` | Accept the marketplace-declared command whose `sha256` a previous [`--json` run](#plugin-json-result) reported in `shownCommand`, in place of `-y`. Can’t be combined with `-y`. Requires Claude Code v2.1.271 or later                       |
| `--json`                    | Print the result as one JSON object on the last line of stdout, in the [same format as `plugin install --json`](#plugin-json-result). Requires Claude Code v2.1.268 or later                                                                  |

If you omit `--scope`, the command updates the plugin at the most specific scope it’s installed at for your current project, checking local, project, user, then managed. Before v2.1.281, the command used `user` when you omitted `--scope`, so updating a plugin installed only at project or local scope failed with `Plugin "<name>" is not installed at scope user`. On those versions, pass `--scope`. `managed` is the one scope you can update but not install to. For admin-installed plugins, see [Manage plugins for your organization](plugins-org.md). Update a plugin:

```python
claude plugin update formatter@my-marketplace
```

Claude Code prints `Checking for updates for plugin "formatter@my-marketplace"…`, then the result. When nothing is newer, it prints `formatter is already at the latest version (1.0.0).` and exits `0`. You can pass a bare plugin name, which the command matches against your installed plugins. When installed plugins from different marketplaces share the name, the command refuses the update and lists the qualified `plugin-name@marketplace-name` commands to run instead. Updating by bare name requires Claude Code v2.1.246 or later.


[​](#plugin-list)

plugin list

List installed plugins with their version, scope, and status.

```python
claude plugin list [options]
```

| Flag          | Description                                                                                          |
|:--------------|:-----------------------------------------------------------------------------------------------------|
| `--json`      | Print the list as JSON                                                                               |
| `--available` | Also list plugins your marketplaces offer that you haven’t installed. Has no effect without `--json` |

Claude Code groups the human-readable output by how each plugin loads:

- **`Installed plugins:`**: plugins you installed from a marketplace
- **`Session-only plugins (--plugin-dir / --plugin-url):`**: plugins loaded by those flags in the same command, as in `claude --plugin-dir ./my-plugin plugin list`
- **`Skills-directory plugins (.claude/skills/*):`**: plugins Claude Code found in a skills directory
- **`Synced from claude.ai`**: [plugins synced from your claude.ai account](plugins-loading.md#synced-plugins)

With nothing in any group, Claude Code prints `` No plugins installed. Use `claude plugin install` to install a plugin. ``


[​](#json-output)

JSON output

With `--json`, Claude Code prints an array with one object per installation. Each object carries the fields below. `id`, `version`, `scope`, `enabled`, and `installPath` are always present, and the others appear only when they apply.

| Field          | Type             | Description                                                                                                                                                                                                                                   |
|:---------------|:-----------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`           | string           | `name@marketplace` for installs, `name@inline` for session-only plugins, `name@skills-dir` for skills-directory plugins, `name@synced` for plugins synced from claude.ai                                                                      |
| `version`      | string           | For a marketplace install, the [version Claude Code computed](plugins-loading.md#versions-and-updates) at install. For a session-only, skills-directory, or synced plugin, the manifest’s `version`, or `unknown` when it declares none |
| `scope`        | string           | `user`, `project`, `local`, or `managed` for installs; `user` or `project` for skills-directory plugins; `session` for session-only plugins; `synced` for plugins synced from claude.ai                                                       |
| `enabled`      | boolean          | Whether the plugin is enabled in your merged settings                                                                                                                                                                                         |
| `installPath`  | string           | Directory the plugin loads from                                                                                                                                                                                                               |
| `installedAt`  | string           | ISO timestamp of the install. Marketplace installs only                                                                                                                                                                                       |
| `lastUpdated`  | string           | ISO timestamp of the last update. Marketplace installs only                                                                                                                                                                                   |
| `projectPath`  | string           | Project the install belongs to. `project` and `local` scope only                                                                                                                                                                              |
| `mcpServers`   | object           | The plugin’s MCP server definitions, when a marketplace-installed plugin has any                                                                                                                                                              |
| `errors`       | array of strings | Load errors, when the plugin failed to load                                                                                                                                                                                                   |
| `notes`        | array of strings | Authoring warnings for a plugin that loaded and works                                                                                                                                                                                         |
| `errorDetails` | array of objects | One object per `errors` entry, giving its diagnostic `type` and the names it refers to, such as the plugin, marketplace, server, or file. Requires Claude Code v2.1.268 or later                                                              |
| `noteDetails`  | array of objects | The same detail objects for each `notes` entry. Requires Claude Code v2.1.268 or later                                                                                                                                                        |

With `--json --available`, Claude Code prints one object instead of an array. Its `installed` field holds the array of installed-plugin objects, and its `available` field holds one object per uninstalled marketplace plugin with the fields below.

| Field             | Type             | Description                                                                                                                 |
|:------------------|:-----------------|:----------------------------------------------------------------------------------------------------------------------------|
| `pluginId`        | string           | `name@marketplace`                                                                                                          |
| `name`            | string           | The plugin’s name in the marketplace                                                                                        |
| `marketplaceName` | string           | The marketplace that offers it                                                                                              |
| `source`          | string or object | The marketplace entry’s [source](plugins-marketplace-reference.md): a string for a relative path, an object otherwise |
| `description`     | string           | The entry’s description, when it has one                                                                                    |
| `version`         | string           | The entry’s version, when it declares one                                                                                   |
| `installCount`    | number           | Install count, when Claude Code has one for the plugin                                                                      |


[​](#plugin-details)

plugin details

Show a plugin’s component inventory and its projected token cost. The plugin must be loaded: installed, found in a skills directory, or passed with `--plugin-dir` or `--plugin-url` in the same command. The `<name>` is a plugin `name` or `name@marketplace`.

```python
claude plugin details <name>
```

The command takes no flags beyond `--help`. Show what an installed plugin contributes:

```python
claude plugin details formatter
```

Claude Code prints the plugin’s name, version, description, and source, then these sections:

- **`Component inventory`**: the plugin’s skills, agents, hooks, MCP servers, and LSP servers
- **`Projected token cost`**: the always-on tokens the plugin adds to every session
- **`Per-component (rounded)`**: always-on and on-invoke estimates for each skill, agent, and command. Omitted when the plugin has none

For what the two cost figures mean, see [Measure plugin cost and usage](plugins-measure.md). For a plugin that isn’t loaded, Claude Code prints `` Plugin "formatter" not found. Run `claude plugin list` to see installed plugins, or pass --plugin-dir <path> to load one from disk. `` and exits `1`.


[​](#plugin-prune)

plugin prune

Remove auto-installed [dependencies](plugins-dependencies.md) that no installed plugin needs anymore. The command never removes a plugin you installed yourself. `autoremove` is an alias for `prune`.

```python
claude plugin prune [options]
```

| Flag                  | Description                                                             |
|:----------------------|:------------------------------------------------------------------------|
| `-s, --scope <scope>` | Prune at scope: `user`, `project`, or `local`. Defaults to `user`       |
| `--dry-run`           | List what would be removed without removing it                          |
| `-y, --yes`           | Skip the confirmation prompt. Required when stdin or stdout isn’t a TTY |

Preview what a prune would remove:

```python
claude plugin prune --dry-run
```

Claude Code lists the orphaned dependencies and ends with `(dry run — nothing removed)`. With none to remove, it prints a line that starts `Nothing to prune`. Without `--dry-run`, the command removes the orphaned dependencies only after you confirm at the prompt or pass `-y`. The exit code is `0` whatever you answer at the prompt. What `prune` does depends on whether a terminal is attached and whether you pass `-y`:

| Terminal and flags               | What happens                                                                                    |
|:---------------------------------|:------------------------------------------------------------------------------------------------|
| Interactive terminal, no `-y`    | Lists the orphaned dependencies and asks `Remove? [y/N]`                                        |
| Any terminal, `-y`               | Removes them and prints `Removed N auto-installed plugins: <names>`                             |
| Non-TTY stdin or stdout, no `-y` | Prints the list and `` Not a TTY — run `claude plugin prune -y` to remove. ``, removing nothing |


[​](#plugin-eval)

plugin eval

Run a plugin’s [eval cases](plugin-evals.md) and report scored results. Requires Claude Code v2.1.269 or later. Each case is a prompt plus graders. Claude Code runs it several times in an isolated session with only the target plugin loaded, and by default also without the plugin so the report shows the difference. See [Test plugins with evals](plugin-evals.md) for the case format, graders, results, and CI usage.

```python
claude plugin eval [target] [options]
```

The optional `target` defaults to the current directory and takes any of these forms:

- A plugin directory
- A single `prompt.md` or `case.yaml` file
- An installed plugin as `name` or `name@marketplace`
- `name@skills-dir`

Put the target before `--tag`, `--allow-tools`, and `--json`. Each of these options takes the words that follow it as its value, so a target written after one of them is read as a tag, a tool name, or the JSON output path instead of as the target. This table lists the options most runs use. Run `claude plugin eval --help` for the complete set, including `--case`, `--tag`, `--output-dir`, `--report`, `--allow-real-servers`, `--keep-temp`, and `--verbose`.

| Option                     | Description                                                                                                                                                          | Default                                                                        |
|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------|
| `--runs <n>`               | Runs per case in each [arm](plugin-evals.md#compare-against-a-no-plugin-baseline)                                                                              | Each case’s `runs`, else 3                                                     |
| `-j, --concurrency <n>`    | Agent sessions to run at once, 1 to 8. They share your rate limit                                                                                                    | `1`                                                                            |
| `--model <model>`          | Model for the agent under test                                                                                                                                       | Each case’s `model`, else `ANTHROPIC_MODEL` if set, else Claude Code’s default |
| `--judge-model <model>`    | Model for `llm` and `baseline` graders                                                                                                                               | A small fast model                                                             |
| `--ablation <mode>`        | `none` or `with-without`. See [Score against the no-plugin baseline](plugin-evals.md#compare-against-a-no-plugin-baseline)                                     | Decided per case, as that section describes                                    |
| `--threshold <0..1>`       | Exit 1 if any case scores below this                                                                                                                                 | `1.0`                                                                          |
| `--max-cost-usd <usd>`     | Stop before the next run once spend reaches this, exit 2, and report partial results                                                                                 | No limit                                                                       |
| `--allow-tools <tools...>` | Grant tools beyond the read-only set, such as `Bash`, `Write`, `Edit`, or `"mcp__plugin_<plugin>_<server>__*"`. See [Grant tools](plugin-evals.md#grant-tools) |                                                                                |
| `--scaffold`               | Run each case’s [`scaffold_script`](plugin-evals.md#add-setup-or-history-with-case-yaml)                                                                       | Off                                                                            |
| `--trust-plugin`           | Skip the first-run trust prompt, for CI. See [What a run can access](plugin-evals.md#security)                                                                 | Off                                                                            |
| `--mocks <mode>`           | `record` or `off`. See [Mock MCP servers](plugin-evals.md#mock-mcp-servers)                                                                                    | `record`                                                                       |
| `--eval-dir <dir>`         | Directory below the plugin that holds the cases                                                                                                                      | The manifest’s `experimental.evals`, else `evals`                              |
| `--json [path]`            | Print the [result document](plugin-evals.md#json-result) to stdout, or write it to a `.json` path                                                              |                                                                                |
| `--no-publish`             | Keep the HTML report local                                                                                                                                           |                                                                                |

The exit code reports how the run ended. To act on it in a pipeline, see [Run evals in CI](plugin-evals.md#run-evals-in-ci).

| Exit code | Meaning                                                        |
|:----------|:---------------------------------------------------------------|
| `0`       | Every case meets the threshold                                 |
| `1`       | A failing case, a load error, or an untrusted plugin directory |
| `2`       | A partial run                                                  |
| `130`     | Interrupted                                                    |
| `143`     | Terminated                                                     |


[​](#plugin-eval-init)

plugin eval init

Create an eval suite for the plugin in the current directory. Requires Claude Code v2.1.269 or later. See [Create your first eval suite](plugin-evals.md#create-your-first-eval-suite).

```python
claude plugin eval init [name] [options]
```

Run the command from the plugin’s root folder, the directory that holds `.claude-plugin/plugin.json` or the skill’s `SKILL.md`. To scaffold the suite in another directory on purpose, pass `--eval-dir`. In a terminal, the command opens an interactive Claude Code session for an authoring interview. In the interview, Claude does the following:

1.  Reads the plugin
2.  Asks you what it should do well
3.  Proposes cases and graders
4.  Writes the case files
5.  Runs the cases and reviews the grades with you to check that the graders score the way you would

With `--bare`, or without a terminal, the command writes a blank single-case template instead. When Claude runs the command from inside a Claude Code session, the command prints the interview instructions for that session to follow rather than writing a template. The optional `name` is a case name. It’s required with `--bare` or without a terminal, because the command writes the blank template for that case. A case name starts with a letter or digit and contains only letters, digits, `.`, `_`, and `-`. On every platform, the command also refuses names that Windows can’t store, such as `con` or a name ending in `.`. The command accepts these options:

| Option              | Description                                                                                       | Default                                           |
|:--------------------|:--------------------------------------------------------------------------------------------------|:--------------------------------------------------|
| `--bare`            | Write a blank `prompt.md` and `graders/criteria.md` for `<name>` instead of running the interview |                                                   |
| `-i, --interactive` | Require the interview. Fails without a terminal instead of writing a template                     |                                                   |
| `--eval-dir <dir>`  | Directory below the current directory to write cases into                                         | The manifest’s `experimental.evals`, else `evals` |


[​](#plugin-tag)

plugin tag

Create an annotated git tag named `<name>--v<version>` for a plugin release. Before tagging, the command checks that the plugin’s `plugin.json` and any marketplace entry that lists it agree on the version. For when to tag a release, see [Publish a plugin](plugins-publish.md).

```python
claude plugin tag [path] [options]
```

The `[path]` is the plugin directory, defaulting to the current directory. The command finds the marketplace entry by walking up from that directory to a `.claude-plugin/marketplace.json` that lists the plugin.

| Flag                  | Description                                                                         |
|:----------------------|:------------------------------------------------------------------------------------|
| `--push`              | Push the tag to `--remote` after creating it                                        |
| `--dry-run`           | Print what would be tagged without creating the tag                                 |
| `-f, --force`         | Skip the dirty-working-tree and tag-already-exists checks                           |
| `-m, --message <msg>` | Tag annotation message. `%s` stands for the version. Defaults to `<name> <version>` |
| `--remote <name>`     | Remote to push to with `--push`. Defaults to `origin`                               |

Preview the tag for a plugin in a marketplace checkout:

```python
claude plugin tag plugins/formatter --dry-run
```

Claude Code prints the plan:

- The plugin name
- The version and which file it came from
- The matching marketplace entry, when there is one
- The tag name
- The `git tag` and `git push` commands it would run

Without `--dry-run`, Claude Code prints `Created tag formatter--v1.0.0` and either `Pushed to origin` or the push command to run yourself. If the push fails, the tag is still created locally and the command exits with an error. The command exits `1` and prints the reason when it can’t tag safely. Common reasons are:

- No `version` in `plugin.json` or the marketplace entry
- The tag already exists
- The working tree is dirty


[​](#plugin-validate)

plugin validate

Validate a plugin manifest, a marketplace manifest, or the skills, agents, and commands in a directory, and exit with a code a CI job can act on. For the create, test, and edit workflow, see [Create a plugin](plugins-create.md). For what the validator checks in each manifest, see the [plugin manifest reference](plugins-reference.md) and the [marketplace reference](plugins-marketplace-reference.md).

```python
claude plugin validate <path> [options]
```

| Flag       | Description                                                                                                                                           |
|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--strict` | Treat warnings as errors, so unrecognized fields and missing metadata that the runtime tolerates fail the run. Requires Claude Code v2.1.145 or later |
| `--json`   | Output the validation report as one JSON object with the same exit codes. Requires Claude Code v2.1.259 or later                                      |

Validate a plugin before committing it:

```python
claude plugin validate ./my-plugin --strict
```


[​](#validate-a-directory)

Validate a directory

The `<path>` is a manifest file or a directory. Given a directory, Claude Code picks what to validate by what it finds there:

- `.claude-plugin/marketplace.json`, when it exists
- Otherwise `.claude-plugin/plugin.json`
- Otherwise the component files, chosen by the directory’s name. Validating component files without a manifest requires Claude Code v2.1.233 or later:
  - A directory named `skills`, `agents`, or `commands`: the files inside it
  - A directory named `.claude`: the `skills`, `agents`, and `commands` directories inside it
  - Any other directory: those three directories under its `.claude`

Claude Code doesn’t follow symlinks inside the directory you name. What it does depends on where the link is:

- **A linked `skills`, `agents`, or `commands` directory under the plugin or `.claude` root**: Claude Code warns that nothing in it was read.
- **A linked entry inside a `skills`, `agents`, or `commands` directory**: Claude Code skips it and warns, per directory, how many entries it skipped that a session would load.
- **The `skills`, `agents`, or `commands` directory you name is itself a symlink, or its parent `.claude` directory is**: Claude Code reports an error and checks nothing in it. Name the real directory instead.

A few files are not read by a validation run:

- **A `SKILL.md` at the plugin root**: when you run `claude plugin validate` against a plugin directory, Claude Code doesn’t check a `SKILL.md` at the plugin root
- **A `CLAUDE.md` at the plugin root**: in a plugin run, Claude Code also warns about a `CLAUDE.md` at the plugin root
- **Plugin files in a marketplace run**: from a marketplace directory, Claude Code doesn’t open the plugins’ skill, agent, command, or hook files, or the MCP server files they bundle. To find errors in those files, validate each plugin directory


[​](#output-and-exit-codes)

Output and exit codes

Claude Code prints the file it validated, any errors and warnings with their paths, and a verdict line. The exit code follows the verdict:

| Exit code | Verdict line                                                                    | Meaning                                                    |
|:----------|:--------------------------------------------------------------------------------|:-----------------------------------------------------------|
| `0`       | `Validation passed` or `Validation passed with warnings`                        | The manifest loads. With `--strict`, no warnings either    |
| `1`       | `Validation failed` or `Validation failed (--strict treats warnings as errors)` | An error, or a warning under `--strict`                    |
| `2`       | `Unexpected error during validation: <reason>`                                  | The validator itself failed, such as on an unreadable path |

With `--json`, Claude Code writes the report to stdout as one JSON object with these top-level fields:

- `success`: the same verdict the exit code gives
- `strict`: whether the run treated warnings as errors
- `target`: the resolved path Claude Code validated
- `manifest`: the manifest’s own result, or `null` for a run without a manifest
- `contents`: per-file results, each naming its `file` and carrying `errors`, `warnings`, and `notes` arrays

On exit `2`, the command writes nothing to stdout. The error message goes to stderr.


[​](#claude-plugin-marketplace-commands)

claude plugin marketplace commands

Run `claude plugin marketplace <subcommand>` from your shell to add, list, refresh, and remove the marketplaces you install plugins from.

- **Exit codes**: these subcommands follow the [exit-code convention](#claude-plugin-commands) of the plugin commands
- **Scopes**: their `--scope` flag has no `-s` short form

For what a marketplace is and how Claude Code caches it, see [Plugin loading reference](plugins-loading.md).


[​](#plugin-marketplace-add)

plugin marketplace add

Add a marketplace from a GitHub repository, a git URL, a hosted `marketplace.json`, or a local path, and declare it in a settings file. After you add it, Claude Code installs any [dependencies](plugins-dependencies.md) that your installed plugins were missing.

```python
claude plugin marketplace add <source> [options]
```

| Flag                  | Description                                                                                                                                                                   |
|:----------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--scope <scope>`     | Settings file to declare the marketplace in: `user`, `project`, or `local`. Defaults to `user`                                                                                |
| `--sparse <paths...>` | Limit the git checkout to these directories, for monorepos. `github` and `git` sources only                                                                                   |
| `--claudeai`          | Read the argument as the name of a [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai) instead of a source. Requires Claude Code v2.1.273 or later |

`<source>` takes any of the forms in the table below, and its form decides the source type and how Claude Code fetches the marketplace. For the resulting source object, see the [marketplace reference](plugins-marketplace-reference.md).

| You type                                                                                                              | Source type | How Claude Code fetches it                                                                               |
|:----------------------------------------------------------------------------------------------------------------------|:------------|:---------------------------------------------------------------------------------------------------------|
| `owner/repo`, `owner/repo#ref`, or `owner/repo@ref`                                                                   | `github`    | Clones the GitHub repository, pinned to `ref` when given. Owner and repo must follow GitHub naming rules |
| `user@host:path[.git][#ref]`                                                                                          | `git`       | Clones over SSH                                                                                          |
| An `http://` or `https://` URL that ends in `.git[#ref]` or contains `/_git/`, such as `https://example.com/repo.git` | `git`       | Clones the URL, including Azure DevOps URLs                                                              |
| `https://github.com/owner/repo` or `https://gitlab.com/namespace/project`, or the same over `http://`                 | `git`       | Clones the URL after appending `.git`                                                                    |
| Any other `http://` or `https://` URL, including a self-hosted git host without `.git`                                | `url`       | Fetches the URL as a `marketplace.json`. To clone a repository there instead, append `.git`              |
| `./path`, `../path`, `/path`, or `~/path` to a directory                                                              | `directory` | Reads the directory in place. On Windows, `.\`, `..\`, and `C:\` forms also work                         |
| The same path forms, to a `.json` file                                                                                | `file`      | Reads the file in place                                                                                  |

For a host whose clone URLs don’t carry the `.git` suffix, such as AWS CodeCommit, add the marketplace as a git entry in [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) instead. Claude Code clones a git entry whether or not its URL ends in `.git`. Claude Code also clones a `gitlab.com` URL with nested subgroups, such as `https://gitlab.com/group/subgroup/project`. Add a marketplace and share it with the project:

```python
claude plugin marketplace add your-org/your-marketplace --scope project
```

Claude Code prints `Successfully added marketplace: your-marketplace (declared in project settings)`, using the `name` from the marketplace’s own manifest. A repeat add or an invalid source prints one of these results instead:

- **Marketplace already on disk**: the output is `Marketplace 'your-marketplace' already on disk — declared in project settings` and the exit code is `0`
- **Unrecognized source**: the output is `Invalid marketplace source format. Try: owner/repo, https://..., or ./path` and the exit code is `1`
- **Bare host such as `gitlab.example.com/team/plugins`**: the add fails as an invalid `owner/repo` shorthand, and the message tells you to add `https://` or use a local path

Add a [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai) by the name printed in the `From claude.ai:` section of `claude plugin marketplace list`:

```python
claude plugin marketplace add --claudeai claudeai-organization-library
```

With `--claudeai`, the command refuses `--scope` and `--sparse`. The marketplace is hosted for your account, not declared in a settings file, so you can’t share it through a project’s `.claude/settings.json`.


[​](#plugin-marketplace-list)

plugin marketplace list

List every marketplace you’ve added, with its source.

```python
claude plugin marketplace list [options]
```

| Flag     | Description            |
|:---------|:-----------------------|
| `--json` | Print the list as JSON |

Claude Code prints `Configured marketplaces:` and one `Source:` line per marketplace, or `No marketplaces configured`. With `--json`, Claude Code prints an array with one object per marketplace, carrying the fields below. Every field is a string.

| Field             | Description                                                            |
|:------------------|:-----------------------------------------------------------------------|
| `name`            | The marketplace’s name                                                 |
| `source`          | `github`, `git`, `url`, `directory`, `file`, or `claudeai`             |
| `repo`            | `owner/repo`. `github` sources only                                    |
| `url`             | The clone or fetch URL. `git` and `url` sources only                   |
| `path`            | The local path. `directory` and `file` sources only                    |
| `ref`             | The pinned branch or tag. `github` and `git` sources, only when pinned |
| `installLocation` | Where Claude Code cached the marketplace                               |

An added [claude.ai marketplace](discover-plugins.md#add-from-claude-ai) has no local clone, so its entry carries its claude.ai identifiers, `marketplaceId` and `organizationUuid`, in place of `installLocation`. It also carries `scope` when one is recorded, and `status`. If your terminal sessions [sync plugins from your claude.ai account](plugins-loading.md#synced-plugins), the text listing ends with a `From claude.ai:` section. That section names the marketplaces claude.ai lists for your account that you haven’t added, both git-based and hosted. It requires Claude Code v2.1.273 or later. To add a marketplace from that section, see [Add a marketplace from claude.ai](discover-plugins.md#add-from-claude-ai). The `--json` output covers configured marketplaces only and leaves the section out.


[​](#plugin-marketplace-remove)

plugin marketplace remove

Remove a marketplace’s declaration from your settings. `rm` is an alias for `remove`.

When you remove a marketplace from the last scope that declares it, Claude Code also deletes its cache and uninstalls every plugin you installed from it. It also deletes their saved [options and secrets](plugins-reference.md#user-configuration) and [data](plugins-components.md#path-variables-and-persistent-data) where it can.To refresh a marketplace without losing its plugins, run `plugin marketplace update` instead.

```python
claude plugin marketplace remove <name> [options]
```

The `<name>` is the marketplace name that `plugin marketplace list` shows, not the source you passed to `add`.

| Flag              | Description                                                                                                                                     |
|:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------|
| `--scope <scope>` | Remove the declaration from one settings scope: `user`, `project`, or `local`. Without it, Claude Code removes the declaration from every scope |

Remove a marketplace from every scope:

```python
claude plugin marketplace remove your-marketplace
```

Claude Code prints `Successfully removed marketplace: your-marketplace`. When the command uninstalls plugins, the output lists them under a line such as `Also uninstalled 2 plugins from this marketplace:`. To use one of them again, add the marketplace back and reinstall the plugin. If you scope to a settings file that doesn’t declare the marketplace, the command fails with `Marketplace 'your-marketplace' is not declared in project settings. Omit --scope to remove it from all scopes.`


[​](#plugin-marketplace-update)

plugin marketplace update

Refresh one marketplace, or every marketplace, from its source to fetch new plugins and versions. A marketplace added with a branch or tag `ref` updates to the latest commit of that ref, not the repository’s default branch.

```python
claude plugin marketplace update [name]
```

The command takes no flags beyond `--help`. Refresh one marketplace:

```python
claude plugin marketplace update your-marketplace
```

Claude Code prints `Successfully updated marketplace: your-marketplace`. When you omit the name, it prints a count such as `Successfully updated 2 marketplaces`. With no marketplaces added, it prints `No marketplaces configured` and exits `0`.


[​](#plugin-in-a-session)

/plugin in a session

Inside an interactive session, `/plugin` opens the plugin panel. Each subcommand opens the panel on a tab, runs an action there, or prints a result inline. `/plugins` and `/marketplace` are aliases for `/plugin`. You can run these commands only in an interactive terminal session. In a non-interactive run such as `claude -p`, Claude Code replies that `/plugin` isn’t available in this environment. For which surfaces have `/plugin`, how to install without it, and what each panel tab shows, see [Install and manage plugins](discover-plugins.md). A `<plugin>` is a plugin `name` or `name@marketplace`. The table below lists every session form. The shell subcommands `init`, `update`, `details`, `prune`, `eval`, and `eval init` have no session form.

| Command                                             | Aliases                                        | What it does                                                                                                                                                                                                                                                                                                                                                  |
|:----------------------------------------------------|:-----------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/plugin`                                           |                                                | Opens the panel on the **Discover** tab. Any unrecognized first word after `/plugin` does the same                                                                                                                                                                                                                                                            |
| `/plugin help`                                      | `/plugin --help`, `/plugin -h`                 | Shows the usage list of `/plugin` subcommands                                                                                                                                                                                                                                                                                                                 |
| `/plugin list [--enabled|--disabled]`               | `ls`                                           | Prints your marketplace-installed plugins inline, with version, scope, and status. A filter flag shows only that state. A plugin whose enable state hasn’t been applied yet is marked `— run /reload-plugins to apply`. Requires Claude Code v2.1.163 or later                                                                                                |
| `/plugin install`                                   | `i`                                            | Opens the **Discover** tab                                                                                                                                                                                                                                                                                                                                    |
| `/plugin install <plugin>`                          | `i`                                            | Opens the plugin’s details in the **Discover** tab. With `name@marketplace`, opens them in that marketplace’s list                                                                                                                                                                                                                                            |
| `/plugin install <source>`                          | `i`                                            | Reports a [marketplace not found](plugins-troubleshooting.md#marketplace-not-found) error and installs nothing when the target is a path, URL, or `owner/repo`, even a source you’ve already added. To install from a source, see [Add a marketplace and install in one command](discover-plugins.md#add-a-marketplace-and-install-in-one-command) |
| `/plugin install <plugin> --marketplace <source>`   | `i`                                            | Adds the marketplace at `<source>` when you haven’t added it yet, asking you to confirm first, then opens the plugin’s details. See [Add a marketplace and install in one command](discover-plugins.md#add-a-marketplace-and-install-in-one-command). Requires Claude Code v2.1.275 or later                                                             |
| `/plugin manage`                                    |                                                | Opens the **Installed** tab                                                                                                                                                                                                                                                                                                                                   |
| `/plugin stats`                                     |                                                | Opens the **Stats** tab, in sessions where [`/skill-doctor`](skills.md#find-unused-skills) is available. Anywhere else it opens the panel on the **Discover** tab                                                                                                                                                                                       |
| `/plugin enable <plugin>`                           |                                                | Opens the **Installed** tab at the plugin and enables it                                                                                                                                                                                                                                                                                                      |
| `/plugin disable <plugin>`                          |                                                | Opens the **Installed** tab at the plugin and disables it                                                                                                                                                                                                                                                                                                     |
| `/plugin uninstall <plugin>`                        |                                                | Opens the **Installed** tab at the plugin and uninstalls it                                                                                                                                                                                                                                                                                                   |
| `/plugin configure <plugin>`                        | `config`                                       | Opens the plugin’s [`userConfig`](plugins-reference.md) dialog, or reports that the plugin declares none. Requires Claude Code v2.1.147 or later                                                                                                                                                                                               |
| `/plugin validate <path>`                           |                                                | Prints the same report as `claude plugin validate`, inline                                                                                                                                                                                                                                                                                                    |
| `/plugin tag [path] [--push] [--dry-run] [--force]` |                                                | Creates the release tag as `claude plugin tag` does. Accepts `--push`, `--dry-run`, and `--force` or `-f`; with any other flag or an extra argument, Claude Code prints usage instead                                                                                                                                                                         |
| `/plugin marketplace`                               | `market`                                       | Does nothing visible. Pass `add`, `list`, `update`, or `remove`                                                                                                                                                                                                                                                                                               |
| `/plugin marketplace add [source]`                  | `market add`                                   | With a source, adds it and reports the result. Without one, opens the **Add marketplace** input                                                                                                                                                                                                                                                               |
| `/plugin marketplace list`                          | `market list`                                  | Prints your marketplace names inline                                                                                                                                                                                                                                                                                                                          |
| `/plugin marketplace update [name]`                 | `market update`                                | Opens the **Marketplaces** tab. With a name, refreshes that marketplace there                                                                                                                                                                                                                                                                                 |
| `/plugin marketplace remove [name]`                 | `market remove`, `market rm`, `marketplace rm` | Opens the **Marketplaces** tab. With a name, removes that marketplace there                                                                                                                                                                                                                                                                                   |

If you name a plugin that isn’t installed in the current project in `/plugin enable`, `disable`, `uninstall`, or `configure`, Claude Code prints `Plugin "<plugin>" is not installed in this project` instead of acting.


[​](#reload-plugins)

/reload-plugins

Apply pending plugin changes to the running session without restarting it. Pending changes are plugins you installed, updated, enabled, disabled, or edited on disk since the session started. When you close the `/plugin` panel with pending changes you made in it, Claude Code runs `/reload-plugins` for you. Run it yourself after plugin changes that happen outside the panel, such as a `claude plugin` command you ran in another terminal.

```python
/reload-plugins [--force]
```

| Flag      | Description                                                                                       |
|:----------|:--------------------------------------------------------------------------------------------------|
| `--force` | Apply the reload even when it would invalidate the prompt cache. `force` without dashes works too |


[​](#reload-summary)

Reload summary

Claude Code reloads every active plugin and prints one summary line, `Reloaded: N plugins · N skills · N agents · N hooks · N plugin MCP servers · N plugin LSP servers`, omitting the plugin MCP server count in a session without an interactive terminal. When any plugin failed, the summary adds `N errors during load. Run /plugin for details.` The skills count covers every skill a plugin provides, both its `commands/` entries and its `SKILL.md` skills. The agents count is the number of agents loaded in the session, including ones that don’t come from plugins. When a reloaded plugin’s [dependencies](plugins-dependencies.md) are missing, Claude Code installs them, reloads again, and appends `(+ N dependencies: <names>) resolved` to the summary.


[​](#reloads-that-change-mcp-tools)

Reloads that change MCP tools

When the reload would add or remove a plugin MCP server or the `LSP` tool, and that change would invalidate the [prompt cache](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin), Claude Code doesn’t apply the reload. It prints a line such as `This reload changes MCP tools (<server>) — your next message will re-read the whole conversation instead of using the cache. Run /reload-plugins --force to apply.` Pass `--force` to apply it anyway.


[​](#sessions-without-an-interactive-terminal)

Sessions without an interactive terminal

`/reload-plugins` also runs in sessions without an interactive terminal, such as the desktop app, the Agent SDK, and [non-interactive mode](../02-Claude-Code-CLI/headless.md) with `-p`. Requires Claude Code v2.1.260 or later. In those sessions, the command runs only when you type it into the session yourself, such as in the `-p` prompt or the desktop app’s prompt box. When it arrives another way, such as through [Remote Control](../02-Claude-Code-CLI/remote-control.md) or a message relayed from Slack, the command replies `/reload-plugins isn't available over a remote connection in this session.` and reloads nothing. The reload in those sessions doesn’t connect or disconnect plugin MCP servers. Those changes take effect in your next session.


[​](#flags-that-load-a-plugin-for-one-session)

Flags that load a plugin for one session

Two `claude` flags load a plugin for one session only, without installing it. Both are repeatable. Plugin authors use them to test a plugin before publishing. For the load-edit-reload workflow, see [Develop without a marketplace](plugins-create.md#develop-without-a-marketplace).

| Flag                  | Description                                                                                                                                                                | Example                                                                     |
|:----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------|
| `--plugin-dir <path>` | Load a plugin from a directory or a `.zip` archive of one. A folder of plugins loads each child folder that holds a `.claude-plugin/plugin.json`. Each flag takes one path | `claude --plugin-dir ./my-plugin --plugin-dir ./other.zip`                  |
| `--plugin-url <url>`  | Fetch a plugin `.zip` archive from a URL. Repeat the flag, or pass several URLs space-separated in one quoted value                                                        | `claude --plugin-url "https://example.com/a.zip https://example.com/b.zip"` |

A plugin that either flag loads is a session-only plugin. [`claude plugin list`](#plugin-list) shows it only when the same flag precedes the subcommand, as in `claude --plugin-dir ./my-plugin plugin list`. The plugin appears as `<name>@inline` under a heading that begins `Session-only plugins`, and `--json` reports its `scope` as `session`. When a session-only plugin shares a name with an installed plugin, Claude Code loads the session-only copy for that session and skips the installed one. The installed copy loads instead if you disabled the session-only copy with `claude plugin disable <name>@inline`, or if managed settings lock that plugin name. For the precedence, see [Plugin loading reference](plugins-loading.md). An administrator can reject both flags, and folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](../02-Claude-Code-CLI/env-vars.md#variables) variable, with the managed [`disableSideloadFlags`](../02-Claude-Code-CLI/settings-reference.md#disablesideloadflags) setting. Claude Code then prints that the flag is disabled by your organization’s managed settings and exits `1` without starting. From the Agent SDK, the [`plugins`](../05-Agent-SDK/agent-sdk-plugins.md) option is the equivalent of `--plugin-dir`.


[​](#next-steps)

Next steps

- [Install and manage plugins](discover-plugins.md): the same operations as steps, with what you see at each one
- [Plugin loading reference](plugins-loading.md): what each command changes on disk and which scope takes effect
- [Troubleshoot plugins](plugins-troubleshooting.md): install, marketplace, load, and validation error messages with their fixes
- [Plugin manifest reference](plugins-reference.md): the fields `claude plugin validate` checks

---

## Code intelligence plugins - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/code-intelligence
Path: 08-Plugins-Skills/plugins-code-intelligence.md

## On this page

- [Install a code intelligence plugin](#install-a-code-intelligence-plugin)
- [See what Claude gains](#see-what-claude-gains)
  - [Read the diagnostics yourself](#read-the-diagnostics-yourself)
- [Accept or dismiss the recommendation dialog](#accept-or-dismiss-the-recommendation-dialog)
  - [When the recommendation dialog appears](#when-the-recommendation-dialog-appears)
  - [Respond to the recommendation dialog](#respond-to-the-recommendation-dialog)
  - [Turn recommendations back on](#turn-recommendations-back-on)
- [Troubleshoot code intelligence](#troubleshoot-code-intelligence)
- [Add a language without an official plugin](#add-a-language-without-an-official-plugin)
- [Next steps](#next-steps)

Use plugins

# Code intelligence plugins

Copy pageCopy page

Install a language server plugin so Claude sees type errors after edits and navigates code by symbol, and answer the LSP plugin recommendation dialog.

Copy pageCopy page

A code intelligence plugin gives Claude the live diagnostics and go-to-definition that your editor has, so Claude catches type errors and missing imports that its own edits introduce before you run your build, and finds definitions and references by symbol instead of by text search. Each plugin connects Claude Code to a language server for one language through the Language Server Protocol (LSP). You install the plugin from Anthropic’s official marketplace and the language server binary on your machine.

Code intelligence plugins work in terminal sessions. In [cloud sessions](../02-Claude-Code-CLI/claude-code-on-the-web.md), Claude Code doesn’t start plugin language servers, so Claude gets no diagnostics or code navigation there. To write your own language server plugin, or to connect a language server that has no plugin, see [LSP servers in plugin components](plugins-components.md#lsp-servers).

To get started, find your language in the table under [Install a code intelligence plugin](#install-a-code-intelligence-plugin). The plugins in that table come from Anthropic’s [official plugin marketplace](plugins-anthropic-marketplaces.md). If you already saw an **LSP plugin recommendation** dialog, see [Accept or dismiss the recommendation dialog](#accept-or-dismiss-the-recommendation-dialog) for what each choice does.


[​](#install-a-code-intelligence-plugin)

Install a code intelligence plugin

A code intelligence plugin tells Claude Code which command starts the language server and which file extensions it handles. It doesn’t include the language server. Install the language server binary first, then the plugin, then confirm the server starts.

1

Install the language server binary

Find your language in the table below and install the binary in its row. If your language isn’t listed, see [Add a language without an official plugin](#add-a-language-without-an-official-plugin).

| Language                  | Plugin                                                                                                           | Binary                          |
|:--------------------------|:-----------------------------------------------------------------------------------------------------------------|:--------------------------------|
| C/C++                     | [`clangd-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/clangd-lsp)               | `clangd`                        |
| C#                        | [`csharp-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/csharp-lsp)               | `csharp-ls`                     |
| Go                        | [`gopls-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/gopls-lsp)                 | `gopls`                         |
| Java                      | [`jdtls-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/jdtls-lsp)                 | `jdtls`                         |
| Kotlin                    | [`kotlin-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/kotlin-lsp)               | `kotlin-lsp`                    |
| Liquid                    | [`liquid-lsp`](https://github.com/Shopify/liquid-skills/tree/main/plugins/liquid-lsp)                            | `shopify`, from the Shopify CLI |
| Lua                       | [`lua-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/lua-lsp)                     | `lua-language-server`           |
| PHP                       | [`php-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/php-lsp)                     | `intelephense`                  |
| Python                    | [`pyright-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/pyright-lsp)             | `pyright-langserver`            |
| Ruby                      | [`ruby-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/ruby-lsp)                   | `ruby-lsp`                      |
| Rust                      | [`rust-analyzer-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/rust-analyzer-lsp) | `rust-analyzer`                 |
| Swift                     | [`swift-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/swift-lsp)                 | `sourcekit-lsp`                 |
| TypeScript and JavaScript | [`typescript-lsp`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/typescript-lsp)       | `typescript-language-server`    |

Anthropic maintains every plugin in the table except `liquid-lsp`, which Shopify maintains and the official marketplace lists.To find the command that installs the binary, follow the plugin’s link in the table to its README. For TypeScript, that command is `npm install -g typescript-language-server typescript`.After you install the binary, confirm it’s on the `PATH` of the shell you start `claude` from, for example with `which typescript-language-server`, or `Get-Command typescript-language-server` in PowerShell.

2

Install the plugin

To install the plugin listed for your language in the step 1 table, run `/plugin install` in a Claude Code session, replacing `typescript-lsp` with that plugin’s name:

```python
/plugin install typescript-lsp@claude-plugins-official
```

A confirmation message says whether the plugin is active now or needs `/reload-plugins`. If the install fails with `Marketplace "claude-plugins-official" not found`, see the [troubleshooting entry for that error](plugins-troubleshooting.md#marketplace-claude-plugins-official-not-found). To control where the plugin is installed, or to run the install from your shell instead of inside Claude Code, see [Install plugins](discover-plugins.md).

3

Confirm the server starts

The language server starts the first time Claude edits a file with one of the plugin’s extensions. To see it work, ask Claude to introduce a type error in a file of that language and then fix it. Then check the conversation for a diagnostics line:

- **A diagnostics line appears**: `Found N new diagnostic issues in M files (ctrl+o to expand)` under the edit that introduced the error means the server started.
- **No diagnostics line appears**: run `/plugin` and open the **Errors** tab. A row reading `Executable not found in $PATH: "<binary>"` names the binary to install. If the tab has no such row, see [Troubleshoot code intelligence](#troubleshoot-code-intelligence).

After you install a missing binary, Claude Code tries again the next time Claude edits a matching file. If you installed the binary into a directory that isn’t on the `PATH` of the shell you started `claude` from, start a new session from a shell where it is.


[​](#see-what-claude-gains)

See what Claude gains

With a language server running, Claude gains diagnostics and code navigation:

- **Diagnostics after edits**: each time Claude edits or writes a file the server handles, Claude gets the errors and warnings the server reports. It sees a type error, missing import, or syntax error it introduced without running a compiler.
- **Code navigation**: Claude gets an `LSP` tool that looks up symbols through the server instead of searching text for them. The tool is read-only. For what Claude can look up with the tool and how permissions apply to it, see [LSP tool behavior](../02-Claude-Code-CLI/tools-reference.md#lsp-tool-behavior).


[​](#read-the-diagnostics-yourself)

Read the diagnostics yourself

After Claude edits a file the server handles, the conversation shows only the `Found N new diagnostic issues` summary. To read the issues themselves, press **Ctrl+O**.


[​](#accept-or-dismiss-the-recommendation-dialog)

Accept or dismiss the recommendation dialog

If a language server binary is already on your `PATH` and the plugin that uses it isn’t installed, Claude Code offers to install the plugin for you in a dialog titled **LSP plugin recommendation**.


[​](#when-the-recommendation-dialog-appears)

When the recommendation dialog appears

The **LSP plugin recommendation** dialog can appear after Claude edits a file. These conditions decide whether it appears and which plugin it offers:

- **A plugin matches the file**: one of the marketplaces you’ve added, or the official marketplace Claude Code registered for you, lists a code intelligence plugin for that file’s extension, and the plugin’s binary is installed.
- **Official first**: when more than one marketplace offers a plugin for the extension, the dialog offers the official marketplace’s plugin.
- **Once per session**: the dialog appears at most once in a session, for the first matching file Claude edits.
- **Not for cloud sessions**: the dialog never appears when your terminal is attached to a cloud session, such as one you started with [`claude --cloud`](../02-Claude-Code-CLI/claude-code-on-the-web.md#from-terminal-to-cloud).


[​](#respond-to-the-recommendation-dialog)

Respond to the recommendation dialog

The **LSP plugin recommendation** dialog names the plugin and offers these choices:

- **Yes, install**: Claude Code installs the plugin for your user account and prints `<plugin> installed · restart to apply`. Start a new session to load the server.
- **No, not now**: the dialog closes, and a later session can offer the plugin again. Pressing **Esc** does the same.
- **Never for this plugin**: the dialog stops appearing for that plugin and still appears for others.
- **Disable all LSP recommendations**: the dialog stops appearing for every language.

If you don’t choose an option, Claude Code closes it after 30 seconds and counts that as ignored. The count is kept across sessions. After five ignored dialogs, Claude Code stops recommending plugins, the same as if you’d chosen **Disable all LSP recommendations**.


[​](#turn-recommendations-back-on)

Turn recommendations back on

The **LSP plugin recommendation** dialog stops appearing after you choose **Disable all LSP recommendations** or ignore it five times.

- **Disabled or ignored five times**: to turn it back on in either case, remove the `lspRecommendationDisabled` and `lspRecommendationIgnoredCount` keys from `~/.claude.json`, Claude Code’s own configuration file.
- **Never for this plugin**: if you chose **Never for this plugin** and want that plugin offered again, remove its `name@marketplace` id from the `lspRecommendationNeverPlugins` list in the same file.


[​](#troubleshoot-code-intelligence)

Troubleshoot code intelligence

The plugins troubleshooting page covers the symptoms specific to code intelligence plugins under [Language server doesn’t start, uses too much memory, or reports wrong diagnostics](plugins-troubleshooting.md#language-server-doesnt-start):

- **The language server doesn’t start**: you see `Executable not found in $PATH` in the **Errors** tab of `/plugin`, or Claude never reports diagnostics for the language.
- **High memory use**: memory use increases while the server indexes the project.
- **False positive diagnostics in a monorepo**: diagnostics report imports as unresolved when they aren’t.


[​](#add-a-language-without-an-official-plugin)

Add a language without an official plugin

If your language isn’t in the [table of official plugins](#install-a-code-intelligence-plugin), you can still connect a language server.

1.  Write a plugin with an `.lsp.json` file that names the server command and the file extensions it handles.
2.  Then load the plugin with [`--plugin-dir`](plugins-cli-reference.md#flags-that-load-a-plugin-for-one-session) or publish it to a marketplace.

For the file’s fields and a worked example, see [LSP servers in plugin components](plugins-components.md#lsp-servers).


[​](#next-steps)

Next steps

- [LSP servers in plugin components](plugins-components.md#lsp-servers): write the `.lsp.json` for a language server that has no official plugin
- [Install and manage plugins](discover-plugins.md): scopes, updates, and uninstalling
- [Troubleshoot plugins](plugins-troubleshooting.md): load errors beyond the language-server ones on this page
- [Find plugins in the official marketplace](plugins-anthropic-marketplaces.md#find-plugins-in-the-official-marketplace): where to browse the rest of the official marketplace

---

## Code Review | Claude by Anthropic

Source: https://www.claude.com/plugins/code-review
Path: 08-Plugins-Skills/plugins-code-review.md

# Code Review

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

- 

  Install in
  Claude Code
- 

  Made by[Anthropic](https://anthropic.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-review)
- 

  Installs438,525

Automates pull request code review using multiple specialized agents working in parallel. Five independent reviewers analyze your changes from different angles: CLAUDE.md compliance checking, bug detection, git history context analysis, previous PR comment review, and code comment verification. Each finding is scored on a 0-100 confidence scale, and only high-confidence issues (default threshold: 80) are posted as comments, dramatically reducing false positives and review noise.

The plugin intelligently filters out PRs that don't need review—closed, draft, automated, or already-reviewed pull requests are automatically skipped. Comments include direct GitHub links with full SHA hashes and line number ranges for easy navigation to the exact code in question.

**How to use:** Run `/code-review` on any PR branch to launch the full automated review. The system will analyze your changes, score potential issues, and post actionable feedback directly to GitHub. You can customize the confidence threshold or focus areas (security, performance, accessibility) by editing the command configuration.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Code Simplifier | Claude by Anthropic

Source: https://www.claude.com/plugins/code-simplifier
Path: 08-Plugins-Skills/plugins-code-simplifier.md

# Code Simplifier

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

- 

  Install in
  Claude Code
- 

  Made by[Anthropic](https://anthropic.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-simplifier)
- 

  Installs346,763

Code Simplifier is an autonomous agent that refines and simplifies your code for improved clarity, consistency, and maintainability. It focuses on recently modified code sections, making targeted improvements while preserving all original functionality and behavior.

The agent follows established coding standards including ES modules, function declarations with explicit returns, and React best practices. It reduces nesting depth, eliminates redundant code, improves variable and function naming, and replaces nested ternaries with clearer conditional structures like switch statements.

**How to use:** The agent works proactively on your recently modified code. You can also ask it directly to review specific files or code sections with prompts like "simplify this component" or "refine the recently changed functions for clarity."

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Add components to a plugin - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/components
Path: 08-Plugins-Skills/plugins-components.md

## On this page

- [Explore the plugin directory](#explore-the-plugin-directory)
- [Add each kind of component](#add-each-kind-of-component)
  - [Skills](#skills)
  - [Commands](#commands)
  - [Define commands in the manifest](#define-commands-in-the-manifest)
  - [Agents](#agents)
  - [Organize agents in subfolders](#organize-agents-in-subfolders)
  - [Frontmatter fields in plugin agents](#frontmatter-fields-in-plugin-agents)
  - [Hooks](#hooks)
  - [When plugin hooks fire](#when-plugin-hooks-fire)
  - [Environment, quoting, and matching MCP tools](#environment-quoting-and-matching-mcp-tools)
  - [MCP servers](#mcp-servers)
  - [Reach users on claude.ai and Cowork](#reach-users-on-claude-ai-and-cowork)
  - [Server names, tool names, and reloads](#server-names-tool-names-and-reloads)
  - [Include a packaged MCPB server](#include-a-packaged-mcpb-server)
  - [LSP servers](#lsp-servers)
  - [Executables](#executables)
  - [Default settings](#default-settings)
  - [Themes and output styles](#themes-and-output-styles)
  - [Channels](#channels)
  - [Monitors](#monitors)
- [Ask the user for configuration values](#user-configuration)
  - [When the configuration dialog appears](#when-the-configuration-dialog-appears)
- [Reference plugin paths and store data](#path-variables-and-persistent-data)
  - [Install dependencies into the data directory](#install-dependencies-into-the-data-directory)
- [Next steps](#next-steps)

Create plugins

# Add components to a plugin

Copy pageCopy page

Add skills, hooks, MCP servers, and every other component type to a Claude Code plugin, with an example that validates for each.

Copy pageCopy page

A Claude Code plugin is built from components, such as skills, agents, hooks, and MCP servers. Each component has a default folder in the plugin, an optional manifest key in `.claude-plugin/plugin.json` that replaces or adds to that folder, and a name the user sees. For each key’s full field table, see the [manifest reference](plugins-reference.md#fields). Use this page to add a component to a plugin that already loads. After you add a component, run `/reload-plugins` in a running session or start a new one so Claude Code loads it. To check the component’s file before loading it, run [`claude plugin validate .`](plugins-cli-reference.md#plugin-validate) in your shell from the plugin directory.

These cases are covered on other pages:

- **Building your first plugin**: start with [Create a plugin](plugins-create.md)
- **Installing someone else’s plugin**: see [Install plugins](discover-plugins.md)
- **Your plugin’s users are on claude.ai or in Cowork**: a different set of components loads there. See [Plugin structure and testing](https://claude.com/docs/plugins/build) and the [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app)


[​](#explore-the-plugin-directory)

Explore the plugin directory

The explorer shows an example plugin, `my-plugin`, that has one of every kind of component in its default location:

- A review skill and an `about` command
- A security-review subagent
- A hook that formats files after Claude edits them, and the `scripts/` folder it calls
- A log monitor
- An output style and a color theme
- A route-audit workflow
- A `hello-plugin` executable
- Default settings
- A local MCP server and a Go language server

Each file is the smallest valid example of its format, there to show the shape rather than to be useful: a real skill or agent carries full instructions and often supporting files, and a real hook or monitor does real work. The sections after the explorer use the same files as their examples and link to fuller ones. Select a file or folder to read what it’s for, see what goes in it, and find the section that covers it.


[​](#add-each-kind-of-component)

Add each kind of component

Each section below covers one kind of component: where its files go in the plugin, an example that validates, what the user sees once the plugin loads, and the manifest key that changes the default location. Add the ones your plugin needs; none is required.


[​](#skills)

Skills

A [skill](skills.md) is a `SKILL.md` file that Claude can load when its description matches the task. The user can also run it as a command. Save each skill in its own directory under `skills/`:

```python
my-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    └── review/
        └── SKILL.md
```

Give the `SKILL.md` a `description` so Claude knows when to use it:

skills/review/SKILL.md

```python
---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.
```

After you load the plugin, `/my-plugin:review` runs the skill. The command name and who can invoke it follow these rules:

- **Command name**: `/<plugin>:<directory>`, so `skills/review/SKILL.md` in `my-plugin` is `/my-plugin:review`. If you set `name` in the frontmatter, it replaces the last segment and the plugin prefix stays. See [how a skill gets its command name](skills.md#how-a-skill-gets-its-command-name)
- **Who invokes it**: Claude, the user, or both, controlled by frontmatter. See [Control who invokes a skill](skills.md#control-who-invokes-a-skill)

You can also place skills outside the default `skills/` directory:

- **Additional directories**: list them in the `skills` manifest key. They add to the default `skills/` scan rather than replacing it, unlike `commands` and `agents`
- **A single skill at the plugin root**: with no `skills/` directory and no `skills` manifest key, a `SKILL.md` at the plugin root loads as one skill. Set `name` in its frontmatter, because otherwise a marketplace install names the skill after its [cache directory](plugins-loading.md#find-plugins-on-disk) rather than your plugin

To include instructions in a plugin, write them as a skill. Claude Code doesn’t load a `CLAUDE.md` at the plugin root, and `claude plugin validate` warns `CLAUDE.md at the plugin root is not loaded as project context`. For frontmatter fields and supporting files, see [Skills](skills.md).


[​](#commands)

Commands

A command is a single Markdown file the user runs by name, such as `/my-plugin:about`.

Commands are the older format, and [skills](#skills) supersede them for new work. A skill runs by name the same way, and it can also carry supporting files in its directory. Keep `commands/` for files you’re moving over from `.claude/commands/`.

Save a command at `commands/<file>.md` and it becomes `/<plugin>:<file>`. A subdirectory adds a segment, so `commands/db/migrate.md` is `/my-plugin:db:migrate`. Command files take the same frontmatter as skills.


[​](#define-commands-in-the-manifest)

Define commands in the manifest

You only need this if you want to keep command files somewhere other than `commands/`, or to define a short command inside `plugin.json` without a separate Markdown file. Set the `commands` manifest key, and Claude Code reads it instead of scanning `commands/`. The key takes a path, an array of paths, or an object that maps each command name to either a `source` file or inline `content`. This manifest defines `/my-plugin:about` inline, with no Markdown file:

.claude-plugin/plugin.json

```python
{
  "name": "my-plugin",
  "commands": {
    "about": {
      "content": "Summarize what this repository does in three sentences.",
      "description": "Summarize the repository"
    }
  }
}
```

Load the plugin and run `/my-plugin:about` in the session to confirm it loaded. For the full key syntax, see [`commands`](plugins-reference.md#commands).


[​](#agents)

Agents

A [subagent](../09-Agents-Patterns/sub-agents.md) is a separate assistant, with its own instructions and context window, that Claude can delegate a task to. Each Markdown file under `agents/` defines one:

agents/security-reviewer.md

```python
---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
```

This agent is named `my-plugin:security-reviewer`, and the user can [invoke it explicitly](../09-Agents-Patterns/sub-agents.md#invoke-subagents-explicitly) with `@agent-my-plugin:security-reviewer`. The name form is `<plugin>:<name>`, where `<name>` comes from the frontmatter, or from the file name when there is none. The `agents` manifest key replaces the `agents/` scan.


[​](#organize-agents-in-subfolders)

Organize agents in subfolders

You can put plugin agent files in subfolders of `agents/`. Claude Code [loads them recursively](../09-Agents-Patterns/sub-agents.md#choose-the-subagent-scope) and joins the plugin name, each subfolder name, and the file name with colons to form the agent’s scoped name. For example, `agents/review/security.md` in a plugin named `my-plugin` loads as `my-plugin:review:security`. Two settings change that name:

- Frontmatter `name`: it replaces only the file name, so `name: audit` in `agents/review/security.md` loads as `my-plugin:review:audit`
- Manifest [`agents`](plugins-reference.md#fields) field: a file you list there loads without subfolder names, so `"agents": "./custom/review/security.md"` loads as `my-plugin:security`


[​](#frontmatter-fields-in-plugin-agents)

Frontmatter fields in plugin agents

A plugin agent’s frontmatter follows these rules:

- **Supported fields**: `name`, `description`, `model`, `effort`, `maxTurns`, `tools`, `disallowedTools`, `skills`, `memory`, `background`, `omitClaudeMd`, `isolation`, `color`, and the `cacheTtl` key of `experimental`. The only valid `isolation` value is `"worktree"`. See [supported frontmatter fields](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields) for what each one does
- **Ignored fields**: `permissionMode`, `hooks`, `mcpServers`, and `initialPrompt`. An agent file can’t add hooks or MCP servers on its own, so add those as plugin [hooks](#hooks) and [MCP servers](#mcp-servers) instead
- **Frontmatter that doesn’t parse**: the agent still loads with every field ignored. It’s named after the file, and its description reads `Agent from my-plugin plugin`. Run [`claude plugin validate`](plugins-cli-reference.md#plugin-validate) in your shell to find these files

For what each field does and the precedence rules, see [Subagents](../09-Agents-Patterns/sub-agents.md#supported-frontmatter-fields).


[​](#hooks)

Hooks

A [hook](../07-Hooks/hooks-guide.md) runs something automatically at a point in Claude Code’s lifecycle, such as after every file edit: a shell command, an HTTP request, an MCP tool call, a prompt to a model, or a subagent. Save the plugin’s hooks in `hooks/hooks.json` at the plugin root, under a top-level `"hooks"` key, in the same shape as the `hooks` object in `settings.json`. That lets you copy an existing settings hook in unchanged. This hook runs a bundled script after every `Write` or `Edit`:

hooks/hooks.json

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

Save the script at `scripts/format.sh` and make it executable. Load the plugin and ask Claude to edit a file. A `PostToolUse` hook that exits 0 shows nothing in the transcript, so confirm it ran with [debug logging](../07-Hooks/hooks.md#debug-hooks) or by what the script itself changes. Hooks in `hooks/hooks.json` and in the `hooks` manifest key both load. For every event and its payload, see [Hook events](../07-Hooks/hooks.md#hook-events).


[​](#when-plugin-hooks-fire)

When plugin hooks fire

A plugin’s hooks don’t wait for one of the plugin’s skills or commands to be used. Claude Code registers them when a session loads the plugin, and they fire on their events from then on. To limit when a hook runs, narrow its `matcher`. If a hook never fires, see [hooks that don’t fire](plugins-troubleshooting.md#failed-to-load-hooks-from-and-hooks-that-dont-fire).


[​](#environment-quoting-and-matching-mcp-tools)

Environment, quoting, and matching MCP tools

The hook’s environment, the quoting of `${CLAUDE_PLUGIN_ROOT}`, and matchers for the plugin’s own MCP tools work as follows:

- **Environment**: every hook process receives `CLAUDE_PLUGIN_ROOT` and `CLAUDE_PLUGIN_DATA` in its environment, plus `CLAUDE_PLUGIN_OPTION_<KEY>` for each [user configuration](#user-configuration) value, so your script can read them from there
- **Quoting**: when `command` has no `args`, it runs through a shell, so wrap the `${CLAUDE_PLUGIN_ROOT}` path in double quotes, as the `hooks/hooks.json` example under [Hooks](#hooks) does, to keep the expanded path one shell word. When you pass `args` instead, each element is passed as one argument with no shell and needs no quoting. See [exec form and shell form](../07-Hooks/hooks.md#exec-form-and-shell-form)
- **Matching the plugin’s own MCP tools**: a tool from an [MCP server this plugin declares](#mcp-servers) is named `mcp__plugin_<plugin>_<server>__<tool>`, so write that full name in the matcher. A matcher on the server name alone never fires. See [Match MCP tools](../07-Hooks/hooks.md#match-mcp-tools)


[​](#mcp-servers)

MCP servers

An MCP server gives Claude tools from an external system. Declare it in `.mcp.json` at the plugin root, in the same shape as a [project `.mcp.json`](../06-MCP-Tools/General/mcp.md#project-scope). This `.mcp.json` declares one server named `db`:

.mcp.json

```python
{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}
```

You can also omit the `mcpServers` wrapper and put `db` at the top level of the file. Load the plugin and run `/mcp` to confirm the server appears as `plugin:my-plugin:db`. `claude plugin validate` checks `.mcp.json` and reports a server entry that Claude Code would drop at load time as an error. Requires Claude Code v2.1.281 or later. For where a bad entry shows up at load time, see [MCP servers that don’t start](plugins-troubleshooting.md#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start). The `mcpServers` manifest key takes an inline server map, a path to a JSON file, or an array of those. When a manifest server has the same name as one in `.mcp.json`, the manifest server replaces it.


[​](#reach-users-on-claude-ai-and-cowork)

Reach users on claude.ai and Cowork

A local stdio server, such as the `db` server under [MCP servers](#mcp-servers), runs in Claude Code and in a Cowork session that runs on your machine in the Claude Desktop app, but not on claude.ai. To reach users there too, reference a remote server by its `https://` URL, which claude.ai and Cowork offer to the user as a connector, as [Bundle an MCP connector with its skill](https://claude.com/docs/plugins/build#bundle-an-mcp-connector-with-its-skill) shows.


[​](#server-names-tool-names-and-reloads)

Server names, tool names, and reloads

The server’s names, variable substitution, and reload behavior follow these rules:

- **Server name**: `plugin:<plugin>:<server>`, so the `db` server in `my-plugin` is `plugin:my-plugin:db` in `/mcp`. Use the same form to name the server in an [`mcp_tool` hook](../07-Hooks/hooks.md#mcp-tool-hook-fields)
- **Tool names**: `mcp__plugin_<plugin>_<server>__<tool>`, so a `query` tool on that `db` server is `mcp__plugin_my-plugin_db__query`. That is the name to use in [permission rules](../02-Claude-Code-CLI/permissions.md) and [hook matchers](#hooks)
- **Substitution**: `${CLAUDE_PLUGIN_ROOT}` and the other [path variables](#path-variables-and-persistent-data) are substituted in `command`, `args`, and `env`. No quoting is needed in `args`, because each element is passed as one argument
- **Reload**: when the user runs `/reload-plugins` and [the reload applies](plugins-cli-reference.md#reloads-that-change-mcp-tools), a server whose configuration is unchanged keeps its connection. A server whose configuration changed reconnects, and one you removed disconnects


[​](#include-a-packaged-mcpb-server)

Include a packaged MCPB server

The `mcpServers` key also accepts a packaged server as an [MCPB file](https://github.com/modelcontextprotocol/mcpb), whose extension is `.mcpb` or the older `.dxt`. Point the key at the file, as a path inside the plugin or an `https://` URL:

.claude-plugin/plugin.json

```python
{
  "name": "my-plugin",
  "mcpServers": "./servers/db.mcpb"
}
```

The server takes its name from the `name` in the bundle’s manifest. For transports and authentication, see [MCP](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers).


[​](#lsp-servers)

LSP servers

An LSP server gives Claude diagnostics and code navigation for a language. If an [official code intelligence plugin](plugins-code-intelligence.md) already covers your language, install that instead of writing one. Otherwise declare the server in `.lsp.json` at the plugin root:

.lsp.json

```python
{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}
```

The file maps each server name directly to its configuration, with no wrapper object around the map. `command` is the binary’s name, with its arguments in `args`. `extensionToLanguage` needs at least one extension, each starting with `.`. `claude plugin validate` doesn’t read this file. When any entry is invalid, the whole file is skipped at load and `Invalid LSP server config for ".lsp.json"` appears in the `/plugin` **Errors** tab. Your plugin configures the connection but doesn’t install the server binary, and each file extension gets one server:

- **Missing binary**: Claude Code starts `command` by name from the user’s `PATH`. When the binary isn’t there, the server fails to start and `claude --debug` logs `LSP server <name> failed to start`
- **Extension conflicts**: when two enabled servers claim the same extension, the first registered handles those files and the other isn’t used for them, whether the servers come from one plugin or two. The `/plugin` **Errors** tab shows the warning `LSP server "<name>" is not used for <ext> files`

The `lspServers` manifest key takes the same map inline, a path to a JSON file, or an array of those, and its servers add to the ones in `.lsp.json`. When a manifest server has the same name as one in `.lsp.json`, the manifest server replaces it. For `transport`, timeouts, restarts, and the other fields, see [`lspServers`](plugins-reference.md#lspservers). Send log output to stderr, not stdout. Claude Code reads a server’s stdout as protocol messages only, and accepts message headers up to 64 KiB and a message body up to 32 MiB. Claude Code disconnects a server that exceeds either limit or writes non-protocol output to stdout, and counts the disconnect as a crash for `restartOnCrash` and `maxRestarts`. When you run with `--debug`, Claude Code writes an error naming the cause to the debug log.


[​](#executables)

Executables

Files in `bin/` at the plugin root are on the `PATH` of the Bash tool’s shell while the plugin is enabled, so Claude can run them as bare commands. Add an executable script:

bin/hello-plugin

```python
#!/bin/bash
echo "hello from my-plugin"
```

Make it executable with `chmod +x bin/hello-plugin` and load the plugin. When you ask Claude to run `hello-plugin`, the Bash tool result shows the script’s output. Plugin `bin/` directories come after the user’s own `PATH` entries, so a plugin can’t shadow `git`, `ls`, or another system command. claude.ai and Cowork don’t install a plugin that has a top-level `bin/` directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory).


[​](#default-settings)

Default settings

To set defaults that apply while the plugin is enabled, add a `settings.json` at the plugin root, or put the same object inline in the `settings` manifest key. Two keys take effect, `agent` and `subagentStatusLine`, and every other key is dropped. Set `agent` to run one of the plugin’s own agents as the main thread:

settings.json

```python
{
  "agent": "security-reviewer"
}
```

Load the plugin and start a session. Claude then answers in the main conversation with the `security-reviewer` agent’s system prompt and model. For everything the key controls, see the [`agent` setting](../02-Claude-Code-CLI/settings-reference.md#agent). When the same key is set in more than one place, these rules decide which value applies:

- **File over manifest**: when both exist and `settings.json` sets at least one supported key, `settings.json` applies and the manifest’s `settings` is ignored
- **User settings over plugin defaults**: across settings sources, plugin defaults are the lowest layer, so a user’s own `agent` in `~/.claude/settings.json` overrides yours
- **Two plugins set the same key**: the value from the plugin loaded last applies, and `claude --debug` logs `overrides setting`

For the `subagentStatusLine` shape, see [subagent status lines](../02-Claude-Code-CLI/statusline.md#subagent-status-lines).


[​](#themes-and-output-styles)

Themes and output styles

A plugin can include color themes and output styles. Both appear in the same pickers as the user’s own. For either one, setting the manifest key replaces the folder scan.

| Component    | Save as                   | Format                                                                                                                           | Appears in                            | Manifest key          |
|:-------------|:--------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------|:----------------------|
| Theme        | `themes/<slug>.json`      | The [custom theme file](../02-Claude-Code-CLI/terminal-config.md#create-a-custom-theme) format users write in `~/.claude/themes/`                | `/theme`, under the file’s `name`     | `experimental.themes` |
| Output style | `output-styles/<name>.md` | The [custom output style](../02-Claude-Code-CLI/output-styles.md#create-a-custom-output-style) format, with `name` and `description` frontmatter | `/output-style`, as `<plugin>:<name>` | `outputStyles`        |

Plugin themes are read-only, so when a user edits one in `/theme`, the edit is saved as a copy in their own themes directory. This theme recolors the prompt accent and error text on the dark preset:

themes/dracula.json

```python
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}
```


[​](#channels)

Channels

A [channel](../02-Claude-Code-CLI/channels.md) lets an outside system such as a chat app send messages into a session. In a plugin, a channel is one of the MCP servers plus a `channels` entry that binds to it and can prompt for its own configuration. This manifest binds a channel to a `telegram` server and asks for a bot token:

.claude-plugin/plugin.json

```python
{
  "name": "my-plugin",
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}
```

`server` must match a key in `mcpServers`. The per-channel `userConfig` takes the same shape as the [top-level `userConfig` key](#user-configuration). For what the server must implement and how users enable a channel plugin, see [Package as a plugin](../02-Claude-Code-CLI/channels-reference.md#package-as-a-plugin) in the channels reference. For the field table, see [`channels`](plugins-reference.md#channels).


[​](#monitors)

Monitors

A monitor is a shell command that runs in the background for the whole session. What it prints reaches Claude as notifications, so Claude can react to a log or a status change without being asked to watch it. Save the entries in `monitors/monitors.json`:

monitors/monitors.json

```python
[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]
```

The command runs in a shell, in the working directory the session started in. A monitor’s command is limited in where it starts and what it can reference:

- **Interactive sessions only**: plugin monitors start in an interactive session and never in non-interactive mode with the `-p` flag. They also start only where the [Monitor tool](../02-Claude-Code-CLI/tools-reference.md#monitor-tool) is available
- **No user configuration**: `command` gets the [path variables](#path-variables-and-persistent-data) and `${ENV_VAR}` from the environment, but never `${user_config.*}`. A monitor that references one doesn’t start, and monitor processes don’t receive `CLAUDE_PLUGIN_OPTION_<KEY>` either
- **Disabling mid-session**: if you disable a plugin mid-session, Claude Code doesn’t stop monitors that are already running. They stop when the session ends

The `experimental.monitors` manifest key takes the same array inline or a path to a JSON file, and is read instead of `monitors/monitors.json`. For the `when` trigger and the other fields, see [`monitors`](plugins-reference.md#monitors).


[​](#user-configuration)

Ask the user for configuration values

Declare the values your plugin needs from the user in the `userConfig` manifest key, so users don’t edit `settings.json` themselves. Each option appears in a dialog with its `title` as the label and its `description` beneath it. Set `"sensitive": true` for a token or password. The dialog then masks the input, and the value is stored in secure storage rather than `settings.json`. This manifest asks for an endpoint and a token:

.claude-plugin/plugin.json

```python
{
  "name": "my-plugin",
  "userConfig": {
    "api_url": {
      "type": "string",
      "title": "API URL",
      "description": "Base URL of your team's API"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for your team's API",
      "sensitive": true
    }
  }
}
```


[​](#when-the-configuration-dialog-appears)

When the configuration dialog appears

The dialog appears only in the interactive `/plugin` interface. It opens for any option that isn’t set yet when the user does any of the following:

- Installs the plugin in `/plugin`
- Runs `/plugin install <plugin>@<marketplace>` inside a session
- Enables the plugin from the **Installed** tab in `/plugin`

To open the same dialog at any time, the user runs `/plugin configure <plugin>@<marketplace>`. The `claude plugin install` shell command never prompts for `userConfig` values. To set values from the shell, pass each one as `--config KEY=VALUE`. When options remain unset, the command prints a `userConfig options not yet set` line that names both ways to set them. [The `userConfig` dialog never appears](plugins-troubleshooting.md#the-userconfig-dialog-never-appears) quotes the line. For the option fields, where each value is stored, how a component references a saved value, and which fields reject `${user_config.*}`, see [User configuration](plugins-reference.md#user-configuration).


[​](#path-variables-and-persistent-data)

Reference plugin paths and store data

You don’t know where your plugin will be installed, so refer to its files and data through these variables rather than fixed paths. They’re substituted in skill, command, and agent content, in hook and monitor commands, and in MCP and LSP server configurations. They’re also exported to hook, MCP, and LSP processes:

- **`${CLAUDE_PLUGIN_ROOT}`**: the plugin’s install directory. Each version has its own [cache directory](plugins-loading.md#find-plugins-on-disk), so the path changes when the plugin updates. Don’t write state there
- **`${CLAUDE_PLUGIN_DATA}`**: a directory that survives updates, for `node_modules`, virtual environments, and caches. It resolves to `~/.claude/plugins/data/<id>/` and is created when first referenced
- **`${CLAUDE_PROJECT_DIR}`**: the project root, the same value hooks receive

In the data directory path, `<id>` is the plugin identifier with every character other than letters, digits, `_`, and `-` replaced by `-`, so `my-plugin@my-marketplace` becomes `my-plugin-my-marketplace`. On Windows, the substituted paths use forward slashes so a shell doesn’t read backslashes as escapes.


[​](#install-dependencies-into-the-data-directory)

Install dependencies into the data directory

For a marketplace-installed plugin, Claude Code installs eligible [Node.js package dependencies](plugins-loading.md#node-js-package-dependencies) automatically when it caches the plugin, so you may not need to install them yourself. When you do, this `SessionStart` hook installs `node_modules` into `${CLAUDE_PLUGIN_DATA}` on first run and again after an update changes `package.json`:

hooks/hooks.json

```python
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
          }
        ]
      }
    ]
  }
}
```

After the first session, `~/.claude/plugins/data/<id>/node_modules` exists. An MCP server can then set `NODE_PATH` to `${CLAUDE_PLUGIN_DATA}/node_modules` in its `env`. For which fields substitute which variable, see [Environment variables](plugins-reference.md#environment-variables).


[​](#next-steps)

Next steps

- [Plugin manifest reference](plugins-reference.md): `plugin.json` fields, path rules, and the standard layout
- [Test plugins with evals](plugin-evals.md): check that the components you added change Claude’s behavior the way you intend
- [Publish and distribute a plugin](plugins-publish.md): version the plugin and put it in a marketplace
- [Troubleshoot plugins](plugins-troubleshooting.md): what to do when a component doesn’t load or a hook doesn’t fire

---

## Context7 | Claude by Anthropic

Source: https://www.claude.com/plugins/context7
Path: 08-Plugins-Skills/plugins-context7.md

# Context7

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

- 

  Install in
  Claude Code
- 

  Made by[Upstash](https://upstash.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/context7)
- 

  Installs417,801

Context7 is an MCP server that delivers up-to-date, version-specific documentation and code examples directly into your prompts. It solves a common problem with LLMs: outdated training data leading to hallucinated APIs and deprecated code patterns. Instead of relying on stale information, Context7 pulls current documentation straight from source repositories.

The plugin provides two main tools: **resolve-library-id** for matching library names to Context7-compatible identifiers, and **query-docs** for retrieving documentation for specific libraries. You can even target specific versions by mentioning them in your prompt.

**How to use:** Simply add "use context7" to any prompt where you need current documentation. For example: "Create a Next.js middleware that checks for a valid JWT in cookies. use context7" or "Configure a Cloudflare Worker script to cache JSON API responses. use context7". You can also specify exact libraries with "use library /supabase/supabase for API and docs".

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Create a Claude Code plugin - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/create
Path: 08-Plugins-Skills/plugins-create.md

## On this page

- [Decide when to use a plugin](#decide-when-to-use-a-plugin)
- [Create your first plugin](#create-your-first-plugin)
  - [Share your plugin](#share-the-plugin)
  - [Plugin layout](#plugin-layout)
- [Develop without a marketplace](#develop-without-a-marketplace)
  - [Load a plugin for one session](#load-a-directory-or-archive-for-one-session)
  - [From a directory or .zip](#from-a-directory-or-zip)
  - [From a folder of plugins](#load-a-folder-of-plugins)
  - [From a URL](#fetch-an-archive-from-a-url-for-one-session)
  - [From an environment variable](#from-an-environment-variable)
  - [Make a plugin load in every session](#scaffold-a-plugin-that-loads-every-session)
  - [Scaffold the plugin with claude plugin init](#scaffold-the-plugin-with-claude-plugin-init)
  - [Name the plugin’s skills](#skill-names-in-a-scaffolded-plugin)
  - [Stop loading the plugin](#stop-loading-the-plugin)
  - [Share the plugin through a repository](#load-a-plugin-for-everyone-in-one-repository)
- [Test and debug](#test-and-debug)
  - [A component path isn’t found](#a-component-path-isn%E2%80%99t-found)
  - [--plugin-dir at a marketplace root doesn’t load the plugins under plugins/](#plugin-dir-at-a-marketplace-root-doesn%E2%80%99t-load-the-plugins-under-plugins%2F)
  - [The plugin loads but its skills are missing](#the-plugin-loads-but-its-skills-are-missing)
  - [The userConfig dialog never appears](#the-userconfig-dialog-never-appears)
  - [Check that the plugin changes Claude’s behavior](#check-that-the-plugin-changes-claude%E2%80%99s-behavior)
- [Convert an existing .claude/ setup](#convert-an-existing-claude-setup)
- [Next steps](#next-steps)

Create plugins

# Create a Claude Code plugin

Copy pageCopy page

Build your first Claude Code plugin from an empty directory, test it without a marketplace, and convert an existing .claude/ setup.

Copy pageCopy page

A plugin is a directory of skills, agents, hooks, and MCP servers, plus a `plugin.json` file, called the manifest, that names the plugin. Claude Code loads the directory as one unit, so you can share it with teammates, install it in several projects, or publish it to a marketplace. This page is for people writing their own plugins.

These cases are covered on other pages:

- **Installing someone else’s plugin**: see [Install plugins](discover-plugins.md)
- **Not sure you need a plugin**: see [Decide whether you need a plugin](plugins.md#decide-whether-you-need-a-plugin) on the overview
- **Your plugin’s users are on claude.ai or in Cowork**: the same folder installs there with a different subset of components. See [Plugin structure and testing](https://claude.com/docs/plugins/build) and the [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app)

Start from the section that matches what you already have:

- **Nothing yet**: follow [Create your first plugin](#create-your-first-plugin), then [Develop without a marketplace](#develop-without-a-marketplace) and [Test and debug](#test-and-debug).
- **Files under `.claude/` already**: do the first-plugin walkthrough once to learn the layout, then follow [Convert an existing `.claude/` setup](#convert-an-existing-claude-setup).


[​](#decide-when-to-use-a-plugin)

Decide when to use a plugin

Skills, agents, hooks, and MCP servers all work standalone in your project or home directory. Keep that standalone setup while it serves one project or only you. Make a plugin when you want to share the setup with teammates, install it in several projects, or publish versioned releases. When you move standalone skills, agents, hooks, and MCP config into a plugin, their location and names change:

- **Where the files go**: under the plugin’s own directory, called the plugin root, as `skills/`, `agents/`, `hooks/hooks.json`, and `.mcp.json`.
- **How they’re named**: plugin skills and agents get the plugin name as a prefix, such as `/my-plugin:hello`, so two plugins can each provide a `hello` skill without colliding.

To move an existing setup into a plugin, see [Convert an existing `.claude/` setup](#convert-an-existing-claude-setup).


[​](#create-your-first-plugin)

Create your first plugin

In this walkthrough, you create a plugin whose only component is one skill, a greeting, and run it with `--plugin-dir`, which loads a plugin for one session without installing it. A plugin can hold any mix of [components](plugins-components.md), such as skills, agents, hooks, and MCP servers, and none is required; one skill is the smallest example that shows the layout. You need Claude Code [installed and signed in](../01-Getting-Started/quickstart.md#step-1-install-claude-code). Open a terminal in the directory where you want to keep the plugin, such as `~/projects`, and run the commands in these steps from it. You can keep a plugin anywhere, because you pass its path to Claude Code when you start a session.

1

Create the plugin directory

Create the plugin directory, with a `.claude-plugin/` folder inside it to hold the manifest:

```python
mkdir -p my-first-plugin/.claude-plugin
```

2

Write the manifest

The [manifest](plugins-reference.md) is a JSON file named `plugin.json` that tells Claude Code the plugin’s name and describes it. Save this one as `my-first-plugin/.claude-plugin/plugin.json`:

my-first-plugin/.claude-plugin/plugin.json

```python
{
  "name": "my-first-plugin",
  "description": "A greeting plugin to learn the basics",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}
```

The four fields do this:

- **`name`**: required. It identifies the plugin and becomes the prefix on every skill and agent the plugin provides. Don’t put spaces in it.
- **`description`**: the text users see for the plugin in `/plugin`.
- **`version`**: optional. Setting it keeps users on that version until you change it; [Release a new version](plugins-host-marketplace.md#release-a-new-version) says when to set or omit it.
- **`author`**: who to credit. `name` is required inside it; `email` and `url` are optional.

Every other field is on the [manifest reference](plugins-reference.md#fields).Only `plugin.json` goes inside `.claude-plugin/`. The skill you add next goes directly under `my-first-plugin/`, next to that folder.

3

Add a skill

This plugin’s one component is a skill. Each skill is a directory under `skills/` that contains a `SKILL.md` file. Create the skill’s directory:

```python
mkdir -p my-first-plugin/skills/hello
```

Then create `my-first-plugin/skills/hello/SKILL.md` with this content:

my-first-plugin/skills/hello/SKILL.md

```python
---
name: hello
description: Greet the user with a friendly message
disable-model-invocation: true
---

Greet the user warmly and ask how you can help them today.
```

The `disable-model-invocation: true` line means Claude doesn’t run the skill on its own, so only you trigger it. Remove that line from a skill you want Claude to run on its own. The skill’s command combines the plugin name and the skill’s name, so you run this one as `/my-first-plugin:hello`. For the other frontmatter fields, see the [skill frontmatter reference](skills.md#frontmatter-reference).

4

Validate the plugin

Check the manifest and the skill’s frontmatter before you run anything:

```python
claude plugin validate ./my-first-plugin
```

The command prints the manifest path it checked and `✔ Validation passed`. If it prints `✘ Validation failed` instead, each line above that result line names the field to fix. Look up each message under [`claude plugin validate` reports errors](plugins-troubleshooting.md#claude-plugin-validate-reports-errors).

5

Run Claude Code with the plugin

Start a session with the plugin loaded:

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

Once Claude Code starts, run the skill:

```python
/my-first-plugin:hello
```

Claude replies with a greeting.

The plugin loads only in sessions you start with `--plugin-dir`. To keep working on it without the flag, or to test a `.zip` build, see [Develop without a marketplace](#develop-without-a-marketplace). To have Claude scaffold and check a larger plugin with you, [install](discover-plugins.md#install-a-plugin) Anthropic’s `plugin-dev` plugin from the `claude-plugins-official` marketplace, which adds skills and agents for writing components such as skills, hooks, and MCP servers and for validating the finished plugin. Once it’s installed, run `/plugin-dev:create-plugin` followed by a description of the plugin you want, and Claude walks you through designing, creating, and validating it.


[​](#share-the-plugin)

Share your plugin

A plugin you built with [Create your first plugin](#create-your-first-plugin) exists only on your machine. When it’s ready for other people, there are three ways to get it to them:

- **Send it to a few people directly**: give them the plugin’s directory or a `.zip` of it, and nothing needs to be published. See [Share a plugin without a marketplace](plugins-publish.md#share-a-plugin-without-a-marketplace).
- **List it in your own marketplace**: teammates add your marketplace once and install the plugin by name, and they receive your updates. See [Publish through your own marketplace](plugins-publish.md#publish-through-your-own-marketplace).
- **Submit it to Anthropic’s directory**: after it passes review, people can add it on claude.ai and in Cowork, and it reaches Claude Code through their account. See [Submit to Anthropic’s directory](plugins-publish.md#submit-to-anthropics-directory).


[​](#plugin-layout)

Plugin layout

Each kind of [component](plugins-components.md), such as skills, agents, hooks, and MCP servers, goes in a fixed directory under the plugin root, which is the directory you pass to `--plugin-dir`. Add only the directories you use. To click through a complete plugin directory and read what each file does, open the [plugin explorer](plugins-components.md#explore-the-plugin-directory). The table lists the directories most plugins start with, and the [full layout](plugins-reference.md#standard-layout) lists the rest.

| Location                     | Contents                                                                                                                          |
|:-----------------------------|:----------------------------------------------------------------------------------------------------------------------------------|
| `.claude-plugin/plugin.json` | The manifest. When you load a plugin with `--plugin-dir` and it has no manifest, Claude Code names the plugin after its directory |
| `skills/`                    | One `<name>/SKILL.md` directory per skill                                                                                         |
| `commands/`                  | Flat Markdown files, the older form of skills. Use `skills/` for new plugins                                                      |
| `agents/`                    | One Markdown file per subagent                                                                                                    |
| `hooks/hooks.json`           | Hook configuration: a top-level `"hooks"` key whose value has the same shape as `hooks` in a settings file                        |
| `.mcp.json`                  | MCP server definitions                                                                                                            |

Only `plugin.json` goes inside `.claude-plugin/`. Components saved there don’t load.The plugin root is the plugin’s own directory, not `~/.claude/` itself. A `.mcp.json` saved at `~/.claude/.mcp.json` doesn’t load.


[​](#develop-without-a-marketplace)

Develop without a marketplace

You don’t need a [marketplace](plugins.md#get-plugins-from-a-marketplace) to run a plugin you’re writing. Load it directly from disk or a URL instead:

- [`--plugin-dir`](#load-a-directory-or-archive-for-one-session): loads a directory or `.zip` archive for one session.
- [`--plugin-url`](#fetch-an-archive-from-a-url-for-one-session): fetches a `.zip` archive from a URL for one session.
- [`claude plugin init`](#scaffold-a-plugin-that-loads-every-session): scaffolds a plugin under `~/.claude/skills/` that loads every session.

If two plugins loaded in different ways share a name, see [Name conflicts](plugins-loading.md#name-conflicts) for which one Claude Code keeps.


[​](#load-a-directory-or-archive-for-one-session)

Load a plugin for one session

You can load a plugin for a single session in three ways: from a directory or `.zip` archive on disk with `--plugin-dir`, from a URL with `--plugin-url`, or from an environment variable when you can’t add a flag. Each plugin loads for that session only, and nothing is written to your settings for it. When you edit the plugin’s files during the session, run `/reload-plugins` to load the changes.


[​](#from-a-directory-or-zip)

From a directory or `.zip`

When you start `claude` from your shell, pass `--plugin-dir` with the plugin’s root directory or a `.zip` archive of it. Repeat the flag to load several plugins:

```python
claude --plugin-dir ./my-first-plugin --plugin-dir ./other-plugin.zip
```


[​](#load-a-folder-of-plugins)

From a folder of plugins

To load several plugins from one place, pass a folder that holds them, such as `--plugin-dir ./plugins`. Loading a folder of plugins requires Claude Code v2.1.265 or later. If the folder has no `.claude-plugin/` directory and no plugin components at its top level, Claude Code treats it as a folder of plugins. Each immediate subfolder that has a `.claude-plugin/plugin.json` manifest then loads as a separate plugin. Everything else in the folder is skipped without an error, including a subfolder that has no manifest. If a plugin in the folder doesn’t load, check that its subfolder has a `.claude-plugin/plugin.json`. You can also pass a folder that keeps a `.claude-plugin/marketplace.json` beside its plugin folders. As long as that `.claude-plugin/` directory holds no `plugin.json`, the plugin folders still load. Nothing is installed or enabled from the marketplace file, because Claude Code doesn’t read it. Loading plugins from such a folder requires Claude Code v2.1.281 or later. In an interactive session, you can also add and remove plugins in the folder after startup:

- A subfolder you add loads as a new plugin once its manifest exists.
- When you remove a subfolder, its plugin unloads.

A message appears in the session for each of these changes. If loading or unloading a plugin mid-conversation would [invalidate the prompt cache](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin), the change is held instead, and the message tells you to run `/reload-plugins` to apply it.


[​](#fetch-an-archive-from-a-url-for-one-session)

From a URL

When you start `claude` from your shell, pass `--plugin-url` with the address of a `.zip` archive, such as a build artifact your CI publishes:

```python
claude --plugin-url https://example.com/my-first-plugin.zip
```

Claude Code downloads the archive at startup. To load several, repeat the flag or pass the URLs space-separated in one quoted argument. Point the flag only at archives you control or trust. If Claude Code can’t fetch the archive, or the archive is invalid, it starts without the plugin and records a plugin load error that you can review in the `/plugin` manager’s **Errors** tab.


[​](#from-an-environment-variable)

From an environment variable

To load plugins in a session where you can’t add the `--plugin-dir` flag, list their absolute paths in the [`CLAUDE_CODE_PLUGIN_DIRS`](../02-Claude-Code-CLI/env-vars.md#variables) environment variable instead. Claude Code loads each path as it loads a `--plugin-dir` path. These plugins load in addition to any you pass with `--plugin-dir`. [Project and local settings can’t set this variable](../02-Claude-Code-CLI/settings-reference.md#variables-claude-code-ignores-in-env). `CLAUDE_CODE_PLUGIN_DIRS` requires Claude Code v2.1.280 or later. Managed settings can turn off `--plugin-dir` and `CLAUDE_CODE_PLUGIN_DIRS`. See [Flags that load a plugin for one session](plugins-cli-reference.md#flags-that-load-a-plugin-for-one-session). To test a plugin together with a plugin it depends on, see [Test a plugin and its dependency locally](plugins-dependencies.md#test-a-plugin-and-its-dependency-locally).


[​](#scaffold-a-plugin-that-loads-every-session)

Make a plugin load in every session

Your personal skills directory is `~/.claude/skills/`. Claude Code loads any folder there that contains a `.claude-plugin/plugin.json` as a plugin in every session, with no flag and no install step. `claude plugin init` scaffolds one of these plugins for you.


[​](#scaffold-the-plugin-with-claude-plugin-init)

Scaffold the plugin with `claude plugin init`

`claude plugin init` writes a starter plugin under `~/.claude/skills/`. Requires Claude Code v2.1.157 or later. Scaffold one from your shell:

```python
claude plugin init my-tool
```

The command creates `~/.claude/skills/my-tool/` with a `.claude-plugin/plugin.json` and a root `SKILL.md`. It prints `✔ Created plugin "my-tool" at ~/.claude/skills/my-tool` followed by `It will auto-load next session as my-tool@skills-dir. Run /reload-plugins to load it now.` Pass `--with skills` to have `claude plugin init` scaffold a skill under `skills/` for you. The other `--with` values are on the [plugin commands reference](plugins-cli-reference.md#plugin-init).


[​](#skill-names-in-a-scaffolded-plugin)

Name the plugin’s skills

The root skill at `~/.claude/skills/my-tool/SKILL.md` is also a personal skill, so you invoke it as `/my-tool`, not `/my-tool:my-tool`. Skills you add under `skills/` inside the plugin get the plugin-name prefix, such as `/my-tool:example`.


[​](#stop-loading-the-plugin)

Stop loading the plugin

To stop loading a scaffolded plugin, delete its directory, or run `claude plugin disable my-tool@skills-dir` in your shell with the `my-tool@skills-dir` name that `claude plugin init` printed. In the ID `my-tool@skills-dir`, `skills-dir` stands where a marketplace name would, because the plugin loads from your skills directory rather than from a marketplace.


[​](#load-a-plugin-for-everyone-in-one-repository)

Share the plugin through a repository

`claude plugin init` writes the plugin to your personal skills directory at `~/.claude/skills/`, so it loads for you in every project. To make a plugin load for everyone in one repository, create the same layout yourself at `<project>/.claude/skills/<name>/`, including its `.claude-plugin/plugin.json`. See [Plugins shared through a repository](plugins-loading.md#plugins-shared-through-a-repository) for the conditions under which Claude Code loads it.


[​](#test-and-debug)

Test and debug

When a change to your plugin doesn’t show up, work through these checks in order. Each one tells you what Claude Code did with the plugin:

1.  In your shell, run `claude plugin validate <path>`. It checks the manifest and the frontmatter of every skill, agent, and command file, and exits `0` on `Validation passed`. Add `--strict` to fail on warnings too. Exit codes and directory handling are on the [plugin commands reference](plugins-cli-reference.md#plugin-validate).
2.  In the running session, run `/reload-plugins` to apply edits you made on disk. It prints one `Reloaded:` line with counts. Then confirm a skill loaded by typing its `/plugin-name:skill` command, or by finding the plugin in the `/plugin` **Installed** tab.
3.  In the same session, run `/plugin`. The **Installed** tab lists your plugin and, in the plugin’s details, the components Claude Code found. The **Errors** tab lists what failed to load and why, such as a path in your manifest that doesn’t exist.
4.  Back in your shell, run `claude plugin list`. It prints session-only and skills-directory plugins in their own sections with `Status: ✔ loaded` or the load error. To include the plugin you’re developing, pass `--plugin-dir` with its path before `plugin list`.

To check an MCP server, run `/mcp` in the session to see the server’s status. When the server is healthy, `/mcp` lists it as connected. If it isn’t, see [MCP servers that don’t start](plugins-troubleshooting.md#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start). To check a hook, trigger the event it matches. For example, ask Claude to edit a file to trigger a `PostToolUse` hook. Then read the [debug log](../07-Hooks/hooks.md#debug-hooks), which shows which hooks matched, their exit codes, and their output. The next sections cover the failures you’re most likely to hit while developing, and the [troubleshooting page](plugins-troubleshooting.md#build-a-plugin) has the full entry for each.


[​](#a-component-path-isn’t-found)

A component path isn’t found

The **Errors** tab of `/plugin` shows `<component> path not found: <path>`, for example `commands path not found`. A component path in your manifest, such as `commands`, `skills`, `agents`, or `hooks`, points at nothing. Fix the path or create the directory, then run `/reload-plugins` in the session. See [`commands path not found`](plugins-troubleshooting.md#commands-path-not-found).


[​](#plugin-dir-at-a-marketplace-root-doesn’t-load-the-plugins-under-plugins/)

`--plugin-dir` at a marketplace root doesn’t load the plugins under `plugins/`

`--plugin-dir` takes the plugin’s root directory, the one that contains `.claude-plugin/plugin.json` and the component directories such as `skills/`. If you point it at a marketplace root instead, Claude Code doesn’t read `marketplace.json`, so a plugin under `plugins/` doesn’t load, and you see no error. Point the flag at one plugin’s folder, or add the marketplace. See [the troubleshooting entry](plugins-troubleshooting.md#plugin-dir-loads-a-plugin-with-no-components).


[​](#the-plugin-loads-but-its-skills-are-missing)

The plugin loads but its skills are missing

The `skills/` directory is inside `.claude-plugin/`, or a `skills` entry in the manifest points at a file. Move `skills/` to the plugin root, point each `skills` entry at a directory that contains `SKILL.md`, and run `/reload-plugins` in the session. See [Plugin loads but its skills are missing](plugins-troubleshooting.md#plugin-loads-but-its-skills-are-missing).


[​](#the-userconfig-dialog-never-appears)

The `userConfig` dialog never appears

The dialog for your plugin’s [`userConfig`](plugins-components.md#user-configuration) options is part of installing through `/plugin` in a session. Loading with `--plugin-dir` doesn’t show it, and neither does `claude plugin install` in the shell. With the plugin loaded, run `/plugin configure <plugin-name>` in the session to open it. See [The `userConfig` dialog never appears](plugins-troubleshooting.md#the-userconfig-dialog-never-appears).


[​](#check-that-the-plugin-changes-claude’s-behavior)

Check that the plugin changes Claude’s behavior

A plugin that loads without errors can still fail to steer Claude the way you intend. `claude plugin eval`, which you run in your shell, runs your test cases with and without the plugin and scores the difference. See [Test plugins with evals](plugin-evals.md), starting with [Create your first eval suite](plugin-evals.md#create-your-first-eval-suite).


[​](#convert-an-existing-claude-setup)

Convert an existing `.claude/` setup

If you already have skills, agents, or hooks under a project’s `.claude/` directory, you can move them into a plugin without rewriting them. Run the commands in these steps from the project root, which is the directory that contains `.claude/`, because the `cp` paths are relative to it.

1

Create the plugin structure

Create the plugin directory and its `.claude-plugin/` folder alongside `.claude/`. You can move the plugin anywhere afterwards.

```python
mkdir -p my-plugin/.claude-plugin
```

Create `my-plugin/.claude-plugin/plugin.json`:

my-plugin/.claude-plugin/plugin.json

```python
{
  "name": "my-plugin",
  "description": "Migrated from standalone configuration",
  "version": "1.0.0"
}
```

2

Copy your existing files

Copy each configuration directory you have to the plugin root, and skip the command for any directory you don’t have.

```python
cp -r .claude/commands my-plugin/
```

```python
cp -r .claude/agents my-plugin/
```

```python
cp -r .claude/skills my-plugin/
```

Run `ls -a my-plugin` to confirm that each directory you copied appears next to `.claude-plugin`.

3

Move your hooks

If you have hooks in `.claude/settings.json` or `.claude/settings.local.json`, create a hooks directory:

```python
mkdir -p my-plugin/hooks
```

Create `my-plugin/hooks/hooks.json` and copy the `hooks` object from your settings file into it. The format is the same.This example shows the shape with one hook that runs a linter on each file Claude writes or edits. Replace the example with your own `hooks` object.

my-plugin/hooks/hooks.json

```python
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }]
      }
    ]
  }
}
```

4

Test the migrated plugin

Load the plugin for a session:

```python
claude --plugin-dir ./my-plugin
```

Check each component under its new name:

- **Skills**: run `/my-plugin:deploy` for a skill that was `/deploy`.
- **Subagents**: ask Claude to use the `my-plugin:reviewer` agent for an agent that was `reviewer`.
- **Hooks**: trigger the event each hook matches.

If something is missing, work through [Test and debug](#test-and-debug).

While the originals are still under `.claude/`, they stay loaded alongside the plugin’s copies:

- **Skills and agents**: the two sets don’t collide, because the plugin’s skills and agents carry the `my-plugin:` prefix. `/deploy` and `/my-plugin:deploy` both work, and Claude sees `reviewer` and `my-plugin:reviewer` as two subagents.
- **Hooks**: hooks have no prefix, so a hook that is in both your settings file and `hooks/hooks.json` runs twice each time its event fires.

After you’ve confirmed the plugin works, delete the originals from `.claude/` and remove the `hooks` object from your settings file.


[​](#next-steps)

Next steps

- [Plugin components](plugins-components.md): add agents, hooks, MCP servers, LSP servers, and user configuration to your plugin
- [Test plugins with evals](plugin-evals.md): write eval cases and run them with `claude plugin eval` to check how reliably the plugin guides Claude’s behavior
- [Publish a plugin](plugins-publish.md): version it, put it in a marketplace, and submit it for review
- [Plugin structure and testing](https://claude.com/docs/plugins/build): the same plugin folder installs on claude.ai and in Cowork. Some components are Claude Code-only, and the [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app) lists which load on each surface
- [Plugin manifest reference](plugins-reference.md): every `plugin.json` field, path rule, and directory
- [Skills](skills.md): write the skills your plugin provides
- [Anthropic’s plugins in the claude-code repository](https://github.com/anthropics/claude-code/tree/main/plugins): complete worked examples of the layout on this page, such as `feature-dev` and `code-review`

---

## Plugin dependencies - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/dependencies
Path: 08-Plugins-Skills/plugins-dependencies.md

## On this page

- [Declare dependencies](#declare-dependencies)
  - [Declare a dependency with a version constraint](#declare-a-dependency-with-a-version-constraint)
  - [Bundle plugins for a team](#bundle-plugins-for-a-team)
  - [Depend on a plugin from another marketplace](#depend-on-a-plugin-from-another-marketplace)
  - [Test a plugin and its dependency locally](#test-a-plugin-and-its-dependency-locally)
- [Release a plugin that others depend on](#tag-plugin-releases-for-version-resolution)
  - [Create a release tag](#create-a-release-tag)
  - [Constrain a dependency that has a non-git source](#constrain-a-dependency-that-has-a-non-git-source)
- [How dependencies behave for your users](#how-dependencies-behave-for-your-users)
  - [How a constraint resolves against tags](#how-a-constraint-resolves-against-tags)
  - [Confirm the resolved version](#confirm-the-resolved-version)
  - [Combine constraints from several plugins](#combine-constraints-from-several-plugins)
- [See also](#see-also)

Create plugins

# Plugin dependencies

Copy pageCopy page

Declare the plugins your plugin depends on, with version ranges such as ^1.2, and see how Claude Code installs, resolves, and prunes them.

Copy pageCopy page

A plugin dependency is another plugin that your plugin relies on, such as one whose MCP server or skill it calls. Each dependency tracks the latest version its marketplace provides unless you declare a version constraint, a semantic-version range such as `^2.0` or `~2.1.0` that you’ve tested against. This page is for plugin authors who declare dependencies in `plugin.json` and for marketplace maintainers who tag releases.

These cases are covered on other pages:

- **Installing a plugin that has dependencies**: see [Manage installed plugins](discover-plugins.md#manage-installed-plugins)
- **Reading a dependency error**: see [Dependency errors](plugins-troubleshooting.md#dependency-errors)
- **Declaring the npm and Bun packages that your plugin’s own code needs**: see [Node.js package dependencies](plugins-loading.md#node-js-package-dependencies)

To add a constraint, start at [Declare a dependency with a version constraint](#declare-a-dependency-with-a-version-constraint). If you maintain a plugin that others depend on, [tag your releases](#tag-plugin-releases-for-version-resolution) so their constraints can resolve.


[​](#declare-dependencies)

Declare dependencies

Without a version constraint, a dependency moves to each new release its marketplace publishes the next time users update. If that release renames an MCP tool your plugin calls, your plugin breaks for everyone who updates. With a constraint such as `~2.1.0` on a dependency from a git-backed source, users who have your plugin installed keep receiving `2.1.x` patches of the dependency and never move to `2.2`. To upgrade on your own schedule, test against a newer release and then publish a new version of your plugin with a wider constraint.


[​](#declare-a-dependency-with-a-version-constraint)

Declare a dependency with a version constraint

List dependencies in the `dependencies` array of your plugin’s `.claude-plugin/plugin.json`. The following manifest declares one unversioned dependency and one constrained dependency:

.claude-plugin/plugin.json

```python
{
  "name": "deploy-kit",
  "version": "3.1.0",
  "dependencies": [
    "audit-logger",
    { "name": "secrets-vault", "version": "~2.1.0" }
  ]
}
```

An entry can be a string: the plugin name alone, such as `"audit-logger"` in this manifest, or `"name@marketplace"` to resolve it in another marketplace. With a bare string, your plugin depends on whatever version that plugin’s marketplace provides. To set a version constraint, use an object with these fields, each a string:

| Field         | Description                                                                                                                                                                                                                                                                                      |
|:--------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`        | The dependency’s plugin name, as it appears in its marketplace entry. Claude Code looks it up in the same marketplace as the declaring plugin unless you set `marketplace`. Required.                                                                                                            |
| `version`     | A [semantic-version range](https://github.com/npm/node-semver#ranges) such as `~2.1.0`, `^2.0`, `>=1.4`, or `=2.1.0`. The dependency installs at the highest git tag that satisfies this range, so the dependency’s maintainer must [tag releases](#tag-plugin-releases-for-version-resolution). |
| `marketplace` | A different marketplace to resolve `name` in. An allowlist controls cross-marketplace dependencies, described in [Depend on a plugin from another marketplace](#depend-on-a-plugin-from-another-marketplace).                                                                                    |

A range doesn’t match pre-release versions such as `2.0.0-beta.1` unless you opt in with a pre-release suffix such as `^2.0.0-0`.


[​](#bundle-plugins-for-a-team)

Bundle plugins for a team

To let engineers install a curated set of plugins with one command, publish a plugin whose manifest contains a `name` and a `dependencies` array. A plugin manifest needs only `name`, so this is a valid plugin, and installing it installs every dependency. For example, a platform team can publish role-specific bundles in an internal marketplace so engineers run one `claude plugin install` instead of installing each plugin separately:

.claude-plugin/plugin.json

```python
{
  "name": "backend-standard",
  "version": "1.0.0",
  "description": "Standard plugin set for backend engineers",
  "dependencies": [
    "secrets-vault",
    "deploy-kit",
    { "name": "db-migrate", "version": "^3.0" },
    "oncall-runbook"
  ]
}
```

To add a plugin to the standard set later, publish a new `backend-standard` version with the extra dependency. When the marketplace doesn’t [auto-update by default](plugins-loading.md#which-marketplaces-and-plugins-auto-update), engineers either turn on auto-update for the marketplace or update manually:

- **Turn on auto-update for the marketplace**: the next auto-update moves the bundle to the new version and installs any dependencies it adds.
- **Update manually**: run `claude plugin update backend-standard` in a shell, then `/reload-plugins` in an open session to install the newly added dependencies.

For the engineer-side steps, see [Keep plugins updated](discover-plugins.md#keep-plugins-updated). To deploy a bundle to everyone in an organization, an administrator adds it to `enabledPlugins` in managed settings. See [Pre-install and require plugins](plugins-org.md#pre-install-and-require-plugins).


[​](#depend-on-a-plugin-from-another-marketplace)

Depend on a plugin from another marketplace

By default, Claude Code doesn’t install a dependency from a different marketplace than the declaring plugin’s own, unless the user already has that dependency installed and enabled at the same scope. This default prevents one marketplace from silently installing plugins from a source the user hasn’t reviewed. To allow the install, add the target marketplace’s name to `allowCrossMarketplaceDependenciesOn` in the root marketplace’s `marketplace.json`. The root marketplace is the one that hosts the plugin the user is installing. Only the root marketplace’s allowlist applies. The following `marketplace.json` allows `deploy-kit` to depend on a plugin from `your-shared-marketplace`:

.claude-plugin/marketplace.json

```python
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "allowCrossMarketplaceDependenciesOn": ["your-shared-marketplace"],
  "plugins": [
    {
      "name": "deploy-kit",
      "source": "./deploy-kit",
      "dependencies": [
        { "name": "audit-logger", "marketplace": "your-shared-marketplace" }
      ]
    }
  ]
}
```

If `allowCrossMarketplaceDependenciesOn` is missing or doesn’t include the target marketplace, Claude Code doesn’t install the dependency. When the dependency is declared in the marketplace entry, the install itself is refused with a message that starts `Dependency "audit-logger@your-shared-marketplace" (required by deploy-kit@your-marketplace) is in marketplace "your-shared-marketplace", which is not in the allowlist` and names the field to set. When it’s declared in `plugin.json`, the install completes without the dependency and your plugin then fails to load. The allowlist check doesn’t apply to a dependency that is already enabled. If a user installs `audit-logger` from `your-shared-marketplace` themselves first, at the same scope, `deploy-kit` then installs without any change to the allowlist.


[​](#test-a-plugin-and-its-dependency-locally)

Test a plugin and its dependency locally

If you’re developing a plugin and the plugin it depends on at the same time, start Claude Code from your shell and load both with [`--plugin-dir`](plugins-cli-reference.md#flags-that-load-a-plugin-for-one-session):

```python
claude --plugin-dir ./my-dependency --plugin-dir ./my-plugin
```

The local copy of the dependency satisfies your plugin’s dependency entry, so you don’t need to install the dependency from its marketplace.

- **No `version` needed**: the local `plugin.json` doesn’t need a `version` either, because a [version constraint](#declare-a-dependency-with-a-version-constraint) isn’t checked against a local copy.
- **Entries that name a marketplace**: an entry that names a marketplace also matches the local copy on Claude Code v2.1.242 or later.

Until you install the dependency from its marketplace, your plugin stops loading whenever the local copy is disabled or absent:

- **You disabled the local copy**: your plugin is disabled at the next plugin load, with an error that ends `is disabled — enable it or remove the dependency`. When the error names the dependency as `<name>@inline`, that identifier refers to the `--plugin-dir` copy.
- **You started a session without the dependency’s `--plugin-dir` flag**: the error reports the dependency as not installed. Pass the flag again, or install the dependency from its marketplace.

When both plugins are in one parent folder, you can pass that folder to `--plugin-dir` once. If the folder isn’t itself a plugin, Claude Code loads each child folder that has a `.claude-plugin/plugin.json`. Requires Claude Code v2.1.265 or later.


[​](#tag-plugin-releases-for-version-resolution)

Release a plugin that others depend on

If you maintain a plugin that other plugins depend on with a version constraint, tag its releases so those constraints can resolve. A constraint resolves against git tags on the repository that hosts the plugin. Tag the repository that the plugin’s [plugin source](plugins-marketplace-reference.md#plugin-sources) in `marketplace.json` points at:

- **`github`, `url`, or `git-subdir` source**: the plugin’s own repository, so the plugin’s author creates the tags
- **Relative path such as `./plugins/secrets-vault`**: the marketplace repository, so the marketplace maintainer creates the tags


[​](#create-a-release-tag)

Create a release tag

Tag each release as `<plugin-name>--v<version>`, where `<version>` matches the `version` field in that commit’s `plugin.json`. The plugin-name prefix lets one marketplace repository host several plugins with independent version histories. Create the tag from the plugin directory, with an `origin` remote configured to receive the pushed tag, using [`claude plugin tag`](plugins-cli-reference.md#plugin-tag):

```python
claude plugin tag --push
```

The command builds the tag name from the plugin’s manifest. Before creating the tag, it runs these checks:

- Validates the plugin
- Checks that `plugin.json` and the marketplace entry agree on the version, when the plugin directory is inside a marketplace checkout
- Requires a clean working tree under the plugin directory
- Refuses if the tag already exists

A successful run prints `Created tag secrets-vault--v2.1.0`. With `--push`, it also prints `Pushed to origin`. Without `--push`, it prints the `git push` command to run yourself. Pass `--dry-run` to see the plan without creating anything. The [`claude plugin tag` reference](plugins-cli-reference.md#plugin-tag) lists the remaining flags. You can also run `git tag secrets-vault--v2.1.0` directly, as long as you keep the `version` in `plugin.json` and in the marketplace entry in sync yourself.


[​](#constrain-a-dependency-that-has-a-non-git-source)

Constrain a dependency that has a non-git source

Tag-based resolution applies only to git-backed sources. For a dependency with an `npm`, `archive`, or `command` [plugin source](plugins-marketplace-reference.md#plugin-sources), the constraint doesn’t control which version is fetched. It’s still checked when the plugin loads, and the dependent plugin is disabled if the installed version doesn’t satisfy it. For `npm`, `archive`, and `command` sources, the version checked is the `version` in the dependency’s `plugin.json`. Set one there before you constrain that dependency, because a `plugin.json` that sets no version satisfies no constraint. Claude Code never installs a dependency with a `command` source itself, so users [install it first](plugins-marketplace-reference.md#command-plugin-source). It also never runs a dependency’s [`headersHelper`](plugins-host-marketplace.md#authenticate-archive-downloads), so users also install a dependency whose marketplace entry sets one before they install your plugin. Besides `claude plugin install`, these operations also install any missing declared dependency, and the `command` and `headersHelper` limits apply to them too:

- `/reload-plugins`
- Auto-update of the dependent plugin’s marketplace
- Re-running `claude plugin install` on the dependent plugin
- `claude plugin marketplace add`


[​](#how-dependencies-behave-for-your-users)

How dependencies behave for your users

These sections describe how Claude Code resolves, checks, and combines the constraints you declare once your plugin is installed alongside others.


[​](#how-a-constraint-resolves-against-tags)

How a constraint resolves against tags

When a user installs a plugin that declares `{ "name": "secrets-vault", "version": "~2.1.0" }`, the dependency installs from the highest `secrets-vault--v` tag that satisfies `~2.1.0` on the repository that hosts `secrets-vault`. When no tag satisfies the range, the install either fails or uses the marketplace’s current copy:

- **Plugin with its own repository**: the install fails with a message containing `Dependency "secrets-vault@your-marketplace" has no git tag satisfying`.
- **Plugin referenced by a relative path**: the install uses the marketplace’s current copy instead, and the constraint is checked when the plugin loads. If that copy is outside the range, the dependent plugin stays disabled and `claude plugin list` shows `Requires "secrets-vault@your-marketplace" ~2.1.0, installed 3.0.0`.

For a plugin the marketplace references by a relative path, a marketplace you added as a local folder path also resolves constraints against that folder’s git tags, when the folder is a git repository. This requires Claude Code v2.1.196 or later. A local folder that isn’t a git repository has no tags, so Claude Code installs the dependency from the folder’s current contents instead.


[​](#confirm-the-resolved-version)

Confirm the resolved version

To confirm which version a constraint resolved to, run `claude plugin list` in your shell. A tag-resolved dependency shows its version with a 12-character commit suffix, such as `2.1.0-8713c5b11005`. Constraint checks use the tag’s version rather than the `version` in `plugin.json`, even if `plugin.json` at that commit lags behind. If you force-move a tag to a different commit, the next install fetches that commit’s content instead of reusing a stale cached copy. See [Versions and updates](plugins-loading.md#versions-and-updates) for how a plugin’s version becomes its cache key.


[​](#combine-constraints-from-several-plugins)

Combine constraints from several plugins

When several installed plugins constrain the same dependency, the dependency resolves to the highest version that satisfies all of their ranges. Common combinations resolve like this:

| Plugin A requires | Plugin B requires | Result                                                                                                                          |
|:------------------|:------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| `^2.0`            | `>=2.1`           | One install at the highest `2.x` tag at or above `2.1.0`. Both plugins load.                                                    |
| `~2.1`            | `~3.0`            | Installing plugin B fails with a `has conflicting version requirements` message. Plugin A and the dependency stay as they were. |
| `=2.1.0`          | none              | The dependency stays at `2.1.0`. Auto-update skips newer versions while plugin A is installed.                                  |

Auto-update fetches a constrained dependency at the highest git tag that satisfies every installed plugin’s range, rather than at the marketplace’s latest version. If the installed plugins’ ranges don’t overlap, auto-update leaves that dependency at its current version, and the `/plugin` **Errors** tab shows an entry naming the constraining plugin. If they overlap but no tag falls in the range, auto-update fetches the marketplace’s current copy and skips the update when that copy’s `version` falls outside any installed plugin’s range. When a user uninstalls the last plugin that constrains a dependency, the dependency is no longer constrained to a version range and resumes tracking its marketplace entry on the next update.


[​](#see-also)

See also

- [`claude plugin prune`](plugins-cli-reference.md#plugin-prune): remove auto-installed dependencies no plugin needs anymore
- [Host a marketplace](plugins-host-marketplace.md): release channels and recommending other plugins

---

## Feature Dev | Claude by Anthropic

Source: https://www.claude.com/plugins/feature-dev
Path: 08-Plugins-Skills/plugins-feature-dev.md

# Feature Dev

Anthropic verified

Feature development workflow with agents for exploration, design, and review

- 

  Install in
  Claude Code
- 

  Made by[Anthropic](https://anthropic.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/feature-dev)
- 

  Installs256,017

A structured 7-phase workflow for building features systematically. Rather than jumping into code, this plugin guides you through understanding the existing codebase, clarifying requirements, designing architecture thoughtfully, and conducting quality reviews before and after implementation.

The plugin deploys three specialized agents: **code-explorer** traces execution paths and maps architecture layers to understand existing patterns; **code-architect** proposes multiple implementation approaches with clear trade-offs; and **code-reviewer** catches bugs, security issues, and convention violations with confidence-scored findings.

**How to use:** Run `/feature-dev` followed by a description of what you want to build. For example: `/feature-dev Add user authentication with OAuth` or simply `/feature-dev` to start the guided workflow. The plugin will walk you through discovery, codebase exploration, clarifying questions, architecture design, implementation, quality review, and a final summary.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Frontend Design | Claude by Anthropic

Source: https://www.claude.com/plugins/frontend-design
Path: 08-Plugins-Skills/plugins-frontend-design.md

# Frontend Design

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

- 

  Install in
  Claude Code
- 

  Made by[Anthropic](https://anthropic.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/frontend-design)
- 

  Installs1,134,112

Generate distinctive, production-grade frontend interfaces that stand out from generic AI-generated designs. This plugin enables Claude to create polished code with bold aesthetic choices, distinctive typography and color palettes, high-impact animations, and context-aware visual details.

The plugin establishes a design framework before coding—identifying purpose, audience, and a specific aesthetic direction (brutalist, maximalist, retro-futuristic, luxury, playful, etc.). It intentionally avoids common patterns like generic system fonts, predictable purple gradients, and cookie-cutter components.

Key design areas include thoughtful typography with unexpected font pairings, orchestrated motion and scroll-triggered interactions, spatial composition with asymmetry and grid-breaking elements, and visual depth through gradients, textures, and layered effects.

**How to use:** Simply ask Claude to build frontend interfaces and this skill activates automatically. Try prompts like "Create a dashboard for a music streaming app", "Build a landing page for an AI security startup", or "Design a settings panel with dark mode support".

## Other plugins

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## GitHub | Claude by Anthropic

Source: https://www.claude.com/plugins/github
Path: 08-Plugins-Skills/plugins-github.md

# GitHub

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

- 

  Install in
  Claude Code
- 

  Made by[GitHub](https://github.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/github)
- 

  Installs319,381

The GitHub plugin connects Claude Code directly to GitHub's platform through the official GitHub MCP server. Manage repositories, issues, pull requests, and workflows without leaving your development environment. Browse code, analyze commits, and understand project structure across all your accessible repositories.

Key capabilities include creating and updating issues and pull requests, reviewing code with AI assistance, monitoring GitHub Actions workflows, analyzing build failures, and managing releases. The plugin also provides security features like examining code scanning findings and reviewing Dependabot alerts.

**How to use:** After connecting your GitHub account, interact naturally with your repositories. Try prompts like "Create an issue for the login bug in my-app repo", "Review the latest PR on my project", "Show me failed GitHub Actions runs", "Search for repositories about machine learning", or "List open issues assigned to me". The plugin handles authentication and API calls automatically.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Host and maintain a marketplace - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/host-marketplace
Path: 08-Plugins-Skills/plugins-host-marketplace.md

## On this page

- [Host your marketplace](#host-your-marketplace)
  - [Register the marketplace for everyone in a repository](#register-the-marketplace-for-everyone-in-a-repository)
  - [Avoid relative-path entries in a URL-hosted marketplace](#avoid-relative-path-entries-in-a-url-hosted-marketplace)
  - [Stay within the download limits for hosted files](#stay-within-the-download-limits-for-hosted-files)
  - [Edit plugins in place on a shared directory](#edit-plugins-in-place-on-a-shared-directory)
  - [Keep plugin files out of Git LFS](#keep-plugin-files-out-of-git-lfs)
  - [Share files within a marketplace with symlinks](#share-files-within-a-marketplace-with-symlinks)
- [Distribute through organization settings](#distribute-through-organization-settings)
- [Grant access to a private marketplace](#grant-access-to-a-private-marketplace)
  - [Serve users who have no git-host account](#serve-users-who-have-no-git-host-account)
  - [What background auto-update does with credentials](#what-background-auto-update-does-with-credentials)
- [Roll out to a whole company](#roll-out-to-a-whole-company)
- [Keep users up to date](#keep-users-up-to-date)
  - [Turn on auto-update](#turn-on-auto-update)
  - [Release a new version](#release-a-new-version)
  - [Hold users on one version](#hold-users-on-one-version)
  - [Change the command of a command source](#change-the-command-of-a-command-source)
- [Run release channels](#run-release-channels)
- [Rename or remove a plugin](#rename-or-remove-a-plugin)
  - [Migrate users with a renames map](#migrate-users-with-a-renames-map)
  - [Uninstall removed plugins from users’ machines](#uninstall-removed-plugins-from-users%E2%80%99-machines)
- [Authenticate archive downloads](#authenticate-archive-downloads)
  - [Add a headersHelper to a plugin entry](#add-a-headershelper-to-a-plugin-entry)
  - [Write the headersHelper command](#write-the-headershelper-command)
  - [When Claude Code skips a headersHelper command or drops its output](#when-claude-code-skips-a-headershelper-command-or-drops-its-output)
  - [How users accept a headersHelper command](#how-users-accept-a-headershelper-command)
  - [Installs and updates that refuse a command instead of asking](#installs-and-updates-that-refuse-the-command-instead-of-asking)
  - [When a marketplace url source’s command runs](#when-a-marketplace-url-sources-command-runs)
- [Depend on and recommend other plugins](#depend-on-and-recommend-other-plugins)
- [Work around what a marketplace can’t do](#work-around-what-a-marketplace-can%E2%80%99t-do)
- [Next steps](#next-steps)

Run a marketplace

# Host and maintain a marketplace

Copy pageCopy page

Publish a plugin marketplace where users can reach it, grant access to a private one, and release updates and renames without breaking installs.

Copy pageCopy page

Hosting a marketplace means putting your `marketplace.json` catalog where other people can add it with `/plugin marketplace add`, install its plugins, and keep receiving your changes after you push. This page is for the person who operates a marketplace.

These cases are covered on other pages:

- **You haven’t written the catalog file yet**: start with [Create a marketplace](plugin-marketplaces.md)
- **You’re an admin requiring, restricting, or pre-installing marketplaces across your organization’s machines**: read [Manage plugins for your organization](plugins-org.md)

Start with [Host your marketplace](#host-your-marketplace) to pick a host and the command your users run. Read [Keep users up to date](#keep-users-up-to-date) before your first release. Read [Rename or remove a plugin](#rename-or-remove-a-plugin) before you change a plugin’s `name`.


[​](#host-your-marketplace)

Host your marketplace

You can host the marketplace on GitHub, on another git host, as a hosted `marketplace.json` URL, or in a directory on a shared filesystem. Send your users the add command for your host and tell them what they need on their machine:

| Host                                                             | Users run, in a Claude Code session                                    | What users need                                                                                                                                |
|:-----------------------------------------------------------------|:-----------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------|
| GitHub                                                           | `/plugin marketplace add your-org/your-marketplace`                    | `git`, and for a private repository the access described under [Grant access to a private marketplace](#grant-access-to-a-private-marketplace) |
| GitLab, Bitbucket, GitHub Enterprise Server, or another git host | `/plugin marketplace add https://gitlab.example.com/team/plugins.git`  | `git`, and access to the host from their machine. Send the full URL, because `owner/repo` shorthand always means github.com                    |
| A hosted `marketplace.json` URL                                  | `/plugin marketplace add https://plugins.example.com/marketplace.json` | HTTPS access to the URL. Users don’t need `git` for the catalog itself                                                                         |
| A directory on a shared filesystem                               | `/plugin marketplace add /Volumes/shared/claude-plugins`               | Read access to the path                                                                                                                        |

To pin a branch or tag of a GitHub or git-URL marketplace, tell users to append `#<ref>`, as in `your-org/your-marketplace#stable`. The [plugin commands reference](plugins-cli-reference.md#plugin-marketplace-add) lists every form the command accepts. A successful add prints `Successfully added marketplace: your-marketplace`. Claude Code takes that name from the `name` field in your `marketplace.json`, not from the repository name. Users then install a plugin by its entry’s `name` and the marketplace’s `name`, as in `/plugin install code-formatter@your-marketplace`.


[​](#register-the-marketplace-for-everyone-in-a-repository)

Register the marketplace for everyone in a repository

To share the marketplace with everyone who works in one repository, run `claude plugin marketplace add your-org/your-marketplace --scope project` there once from your shell and commit the `.claude/settings.json` it writes. Claude Code then registers the marketplace for each teammate who [trusts the folder](plugins-org.md#require-plugins-per-repository).


[​](#avoid-relative-path-entries-in-a-url-hosted-marketplace)

Avoid relative-path entries in a URL-hosted marketplace

When users add your marketplace as a bare `marketplace.json` URL, Claude Code downloads only that file. An entry in your `plugins` array whose `source` is a relative path such as `./plugins/formatter` then fails at install with [`its marketplace entry path does not stay inside the marketplace directory`](plugins-troubleshooting.md#plugins-with-relative-paths-fail-in-url-based-marketplaces). Give every entry a source that can be fetched on its own, such as a `github` repository or an `archive` URL, or host the marketplace in a git repository so Claude Code clones the whole tree.


[​](#stay-within-the-download-limits-for-hosted-files)

Stay within the download limits for hosted files

When users add your marketplace as a `marketplace.json` URL, or install an entry with an [`archive`](plugins-marketplace-reference.md#archive-plugin-source) source, Claude Code downloads the file from your server. The download fails past the limits in this table, so size your files and configure your server to stay inside them.

| File                                               | Largest download | Time for your server to respond | Redirects                                                                                                                                                                |
|:---------------------------------------------------|:-----------------|:--------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `marketplace.json` from a `url` marketplace source | 5 MiB            | 10 seconds                      | A redirect to a different origin must use `https://` and can’t point at a loopback, link-local, or cloud-metadata host, so a redirect from `https://` to `http://` fails |
| Zip from an `archive` plugin source                | 256 MiB          | 120 seconds                     | At most five. Every redirect target must use `https://` and can’t point at a loopback, link-local, or cloud-metadata host                                                |

A request that a redirect sends to a different origin carries none of the headers you configured on the marketplace source or the plugin entry. After an archive downloads, the install fails when the zip exceeds any of these extraction limits:

- **Entries**: 100,000 files and directories
- **File size**: 512 MiB for any one file, uncompressed
- **Total size**: 1 GiB uncompressed
- **Compression ratio**: uncompressed content 50 times the size of the zip


[​](#edit-plugins-in-place-on-a-shared-directory)

Edit plugins in place on a shared directory

When users add your marketplace from a shared directory, Claude Code reads plugins with relative-path sources directly from that directory instead of copying them. Users see your edits when they next start a session or run `/reload-plugins`, without an update step or a version bump.


[​](#keep-plugin-files-out-of-git-lfs)

Keep plugin files out of Git LFS

Keep the files your plugins need out of [Git LFS](https://git-lfs.com). When users add a marketplace hosted in a git repository, or install a git-based plugin it lists, Claude Code clones that marketplace or plugin repository onto their machine. The clone never downloads LFS content, so LFS-tracked files arrive as pointer files.


[​](#share-files-within-a-marketplace-with-symlinks)

Share files within a marketplace with symlinks

To share files between your plugin and other parts of the same marketplace, create symbolic links inside your plugin directory. When Claude Code copies the plugin into its cache, it handles each symlink by where the target resolves:

- **Within the plugin’s own directory**: the symlink is preserved as a relative symlink in the cache, so it keeps resolving to the copied target at runtime.
- **Elsewhere within the same marketplace**: the symlink is dereferenced. The target’s content is copied into the cache in its place. This lets a meta-plugin’s `skills/` directory link to skills defined by other plugins in the marketplace.
- **Outside the marketplace**: the symlink is skipped for security.

For plugins installed from a local path, or from a [`command` source](plugins-marketplace-reference.md#command-plugin-source) whose `mode` is the default `copy`, Claude Code preserves only symlinks that resolve within the plugin’s own directory and skips all others. The following command creates a link from inside a marketplace plugin to a shared skill defined by a sibling plugin. On Windows, use `mklink /D` from an elevated Command Prompt or enable Developer Mode:

```python
ln -s ../../shared-plugin/skills/foo ./skills/foo
```


[​](#distribute-through-organization-settings)

Distribute through organization settings

On a Team or Enterprise plan, you can also distribute the marketplace through [**Organization settings \> Plugins & skills**](https://claude.ai/admin-settings/skills?tab=inventory) on claude.ai instead of hosting it somewhere users add it themselves. Organization sync reads the repository through your organization’s GitHub or GitLab connection on claude.ai, so your users’ git credentials aren’t involved. Organization sync is stricter about the repository than `/plugin marketplace add` is:

- **Marketplace repository**: on github.com and gitlab.com, it must be private or internal
- **Plugin sources**: organization sync accepts only some [source types](plugins-marketplace-reference.md#plugin-sources)
- **Top-level `bin/` directory**: claude.ai rejects a plugin that has one and syncs the rest of the marketplace. The error message starts with `Plugin contains a top-level bin/ directory`. Keep executables in another directory, such as `scripts/`, and reference them as `${CLAUDE_PLUGIN_ROOT}/scripts/<name>` from your hooks or MCP server configs

[Sync your organization’s plugins from a repository](https://claude.com/docs/plugins/org-sync) on claude.com lists the accepted sources, the GitLab setup, and the `bin/` error, and [Manage plugins for your organization](https://claude.com/docs/plugins/admin) covers the admin workflow.


[​](#grant-access-to-a-private-marketplace)

Grant access to a private marketplace

When a user adds, installs from, or updates your marketplace, Claude Code runs `git` on their machine with interactive prompts turned off and relies on whatever credentials that machine already holds. Claude Code has no git token of its own, and `marketplace.json` has no field for one. You choose whether the clone runs over SSH or HTTPS by the form of the add command you send users:

- **GitHub `owner/repo`**: Claude Code probes `ssh -T git@github.com` and clones over SSH when the probe succeeds. If the probe fails, or the SSH clone itself fails, it clones over HTTPS. Users on machines without a GitHub SSH key can set `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1` to skip the probe and clone over HTTPS.
- **`git@host:path.git`**: SSH.
- **`https://example.com/repo.git`**: HTTPS.

Tell users what each protocol needs on their machine:

- **SSH**: the key must work without a passphrase prompt, for example because it’s loaded in `ssh-agent`. The host must already be in `known_hosts`.
- **HTTPS**: Claude Code leaves the user’s git credential helper enabled but forbids it from prompting. A credential the helper already stores works; one it would have to ask for fails. On GitHub, `gh auth login` followed by `gh auth setup-git` stores one.

For a GitHub Enterprise Server host, users need git access to that host from their machine. See [Plugin marketplaces on GHES](../02-Claude-Code-CLI/github-enterprise-server.md#plugin-marketplaces-on-ghes) for what each Claude Code surface needs to reach a GHES-hosted marketplace. If you distribute through **Organization settings \> Plugins & skills** on claude.ai instead, your users’ git credentials aren’t involved. See [Distribute through organization settings](#distribute-through-organization-settings).


[​](#serve-users-who-have-no-git-host-account)

Serve users who have no git-host account

Users without a git-host account can add a marketplace you serve as a `marketplace.json` URL or from a shared directory, but they can install only the plugins whose entry sources they can also reach. An entry that points at a private `github` repository still fails at install for them, because Claude Code fetches it with the same non-interactive `git` it uses for a git-hosted marketplace. These entry sources need no git account:

- **`archive`**: a zip downloaded over HTTPS. Users need neither `git` nor an account, only network access to the URL. Requires Claude Code v2.1.224 or later. Pin each archive with `sha256` so Claude Code refuses a changed download. To send credentials with the download, see [Authenticate archive downloads](#authenticate-archive-downloads).
- **A public git repository**: Claude Code clones a public `url` or `git-subdir` source over HTTPS without credentials when the entry gives an `https://` URL. For a `github` source, or a `git-subdir` source written as `owner/repo`, users without a GitHub SSH key set `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`.

For a team on one network, a `directory` marketplace on a shared filesystem also works without git accounts. Users need only read access to the path.


[​](#what-background-auto-update-does-with-credentials)

What background auto-update does with credentials

Background auto-update is Claude Code’s unattended refresh of marketplaces and installed plugins after a session starts. It’s off for your marketplace until a user or admin turns it on, as covered under [Keep users up to date](#keep-users-up-to-date). When it’s on for a private marketplace, the background check for new commits uses the user’s configured git credential helpers and never prompts. Each kind of remote and helper gives a different result:

- **SSH remotes**: a key loaded in `ssh-agent` authenticates the check.
- **HTTPS remotes with a stored credential**: a helper that can supply a stored credential without prompting authenticates the check. Git Credential Manager, the macOS Keychain helper, and `git-credential-store` work this way once they hold a credential for the host.
- **HTTPS remotes with a helper that needs to prompt**: the helper can’t answer in the background. The update fails quietly and the existing checkout stays in place, so the user’s plugins keep working from the last synced state.

After the check, Claude Code does one of the following:

- **The checkout is up to date**: Claude Code leaves it as it is.
- **The check finds new commits, or fails because it can’t reach or authenticate to the remote**: Claude Code clones the marketplace again and replaces the existing checkout with the new clone. If that clone fails, the existing checkout stays in place. The re-clone can [time out on large repositories](plugins-troubleshooting.md#git-clone-timed-out-after-120s).

To keep a private marketplace current, a user can do either of the following:

- **Store a credential**: sign in to the credential helper first so it holds a credential for the host. For GitHub, run `gh auth login`, then `gh auth setup-git`.
- **Keep the checkout on failure**: if the user sets `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1`, Claude Code keeps the existing checkout without attempting the re-clone when the background check can’t reach or authenticate to the remote. Plugins keep working from the last synced state.

If a user sets `GITHUB_TOKEN` or another provider token in the environment, that alone doesn’t authenticate the background check. A token takes effect through a credential helper, such as the `gh` CLI’s helper, which reads `GH_TOKEN` and `GITHUB_TOKEN`.


[​](#roll-out-to-a-whole-company)

Roll out to a whole company

Rolling a plugin out to a company involves you as the marketplace owner, an administrator who controls managed settings, and each person who uses Claude Code. You can run the rollout without the administrator, in which case each person adds the marketplace and installs the plugin themselves.

| Who                        | What they do                                                                                                                                                          | Where it’s covered                                                                                                                                                  |
|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| You, the marketplace owner | Keep the catalog in a repository only the company can read, send the add command for your host, and say what each person needs on their machine                       | [Host your marketplace](#host-your-marketplace) and [Grant access to a private marketplace](#grant-access-to-a-private-marketplace)                                 |
| An administrator           | Registers the marketplace and turns its plugins on for everyone with `extraKnownMarketplaces` and `enabledPlugins` in managed settings, and sets `autoUpdate` there   | [Require a marketplace and its plugins](plugins-org.md#require-a-marketplace-and-its-plugins) and [Set update policy](plugins-org.md#set-update-policy) |
| Each person                | Needs read access to a private git repository, with credentials already stored on their machine. Without an administrator, they also run the add and install commands | [Add a private marketplace](discover-plugins.md#add-a-private-marketplace)                                                                                     |

For people who have no git-host account, these sections each cover one way to reach them:

- **Entry sources that need no git account**: [Serve users who have no git-host account](#serve-users-who-have-no-git-host-account)
- **A pre-populated plugins directory**: [Seed containers and CI](plugins-org.md#seed-containers-and-ci), which also serves users who have no git-host account
- **claude.ai organization settings**: [Distribute through organization settings](#distribute-through-organization-settings), where your users’ git credentials aren’t involved


[​](#keep-users-up-to-date)

Keep users up to date

Your changes reach users through background auto-update, once it’s turned on for your marketplace, or when users update the plugin themselves. In both cases a user gets a new copy of a plugin only when its computed version changes, as described under [Release a new version](#release-a-new-version).


[​](#turn-on-auto-update)

Turn on auto-update

Background auto-update is off for your marketplace by default, and `marketplace.json` has no field to turn it on. A user or an admin turns it on:

- **Tell users to turn it on**: each user goes to **Marketplaces** in `/plugin`, selects your marketplace, and selects **Enable auto-update**.
- **Ask an admin to set it**: if an admin sets `"autoUpdate": true` on your marketplace’s `extraKnownMarketplaces` entry in managed settings, it’s on for everyone who receives those settings. See [Set update policy](plugins-org.md#set-update-policy).

Without auto-update, users receive your changes when they run `/plugin marketplace update <name>` in a session or `claude plugin update <plugin>@<name>` in the shell. For what users see when an update reaches them, see [When auto-update runs](plugins-loading.md#when-auto-update-runs).


[​](#release-a-new-version)

Release a new version

To release a new version to users, change the plugin’s `version`. Users get a new copy only when the plugin’s computed version differs from the one they have. That version comes from `plugin.json` first, then from the marketplace entry, per [Versions and updates](plugins-loading.md#versions-and-updates). A plugin that users [load in place](plugins-loading.md#find-plugins-on-disk) from a marketplace they added as a local directory isn’t controlled by `version`. It loads your current files at every session start, whatever its version string says. For every install other than an in-place load or one from a `command` source, either increase `version` on each release or omit it:

- **Bump `version` on each release**: users stay on their cached copy until the string changes. If you set `"version": "1.0.0"` and push new commits without changing it, users don’t receive them.
- **Omit `version`**: users track your commits instead. Leave `version` out of both `plugin.json` and the marketplace entry.

Don’t set `version` in both `plugin.json` and the marketplace entry. If you do, Claude Code uses the `plugin.json` value without warning, and `claude plugin validate` reports the mismatch as `Entry declares version "<a>" but <path>/plugin.json says "<b>"`.


[​](#hold-users-on-one-version)

Hold users on one version

One marketplace serves one version of each plugin at a time, so you hold users on a version by choosing what each entry points at:

- **`ref` and `sha` on the plugin entry**: `ref` names a branch or tag and `sha` names a commit for a `github`, `url`, or `git-subdir` source. See [Plugin sources](plugins-marketplace-reference.md#plugin-sources).
- **`#<ref>` on the add command**: users who add `your-org/your-marketplace#stable` get that branch or tag of the catalog. For two release lines at once, see [Run release channels](#run-release-channels).
- **`<plugin>--v<version>` tags**: a dependency’s version range resolves against these tags. See [Release a plugin that others depend on](plugins-dependencies.md#tag-plugin-releases-for-version-resolution).

[Release a new version](#release-a-new-version) says when a changed entry reaches users.


[​](#change-the-command-of-a-command-source)

Change the command of a command source

If you change the `command` of a [`command` source](plugins-marketplace-reference.md#command-plugin-source), or switch its `mode`, each user has to accept the new command before Claude Code runs it. Claude Code runs only the exact command a user accepted when they installed or last updated the plugin. After a user’s copy of your marketplace picks up the change, that user sees the following:

- **No more background runs**: the [once-per-session run](plugins-loading.md#when-a-command-source-re-runs) of the command stops for that user, so the tool’s new output doesn’t reach them.
- **An entry in the `/plugin` Errors tab**: the entry shows the new command and the `claude plugin update` command to run.

Tell users to run the `claude plugin update` command that entry shows, in a terminal. Claude Code shows them the new command and asks them to accept it.


[​](#run-release-channels)

Run release channels

To offer stable and early-access tracks, host two marketplaces whose entries point at different refs of the same plugin, and let each user add the one they want. Claude Code has no release-channel concept, and one marketplace serves one version of each plugin at a time. Give the two `marketplace.json` files different `name` values. Claude Code identifies a marketplace by its `name`, so a user can’t have two marketplaces with the same name registered at once. With these two catalogs, users who add `stable-tools` install `code-formatter` from the `stable` branch, and users who add `latest-tools` install it from `latest`:

```python
{
  "name": "stable-tools",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": { "source": "github", "repo": "your-org/code-formatter", "ref": "stable" } }
  ]
}
```

```python
{
  "name": "latest-tools",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": { "source": "github", "repo": "your-org/code-formatter", "ref": "latest" } }
  ]
}
```

Give the two refs different `plugin.json` versions, or omit `version` so the commit SHA distinguishes them. Updates are detected by comparing versions, so a ref that moves without a version change leaves users on the cached copy. To assign the channels to user groups instead of letting users choose, an admin gives each group the matching `extraKnownMarketplaces` entry, as described under [Set update policy](plugins-org.md#set-update-policy).


[​](#rename-or-remove-a-plugin)

Rename or remove a plugin

A plugin’s `name` is its identifier. Users reference it in the `enabledPlugins` and `pluginConfigs` settings keys and in `/plugin install`, so changing it breaks every existing install. To change the label users see in `/plugin` without breaking anything, set `displayName` in `plugin.json` and keep `name` unchanged.


[​](#migrate-users-with-a-renames-map)

Migrate users with a renames map

When you must change a `name`, add a top-level `renames` map to `marketplace.json` so Claude Code migrates existing users instead of reporting [`Plugin "<name>" not found in marketplace`](plugins-troubleshooting.md#plugin-not-found-in-marketplace). Do the same when you remove an entry from `plugins`. Automatic migration requires Claude Code v2.1.193 or later. Map each former name to its current name, or to `null` when the plugin is gone. This marketplace renames `formatter` to `code-formatter` and records that `legacy-linter` was removed:

```python
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": "./plugins/code-formatter" }
  ],
  "renames": {
    "formatter": "code-formatter",
    "legacy-linter": null
  }
}
```

After you push, a user who still has the old name enabled sees one of these results:

- **Renamed entry**: the plugin loads under its new name. `claude plugin list` and the plugin’s details under `/plugin` show `Renamed to "code-formatter" in the "your-marketplace" marketplace` once, and Claude Code rewrites the old key to the new one in `enabledPlugins` and `pluginConfigs` in the user, project, and local settings scopes.
- **`null` entry**: the old key is dropped from those scopes and the user sees `Removed from the "your-marketplace" marketplace`.
- **Enabled in managed settings**: the plugin still loads under its new name, but Claude Code can’t rewrite managed settings, so the notice recurs until an admin updates `enabledPlugins` there.

For a marketplace users added from a git repository or URL, a renamed plugin reports [`Plugin "<name>" not cached at <path>`](plugins-troubleshooting.md#plugin-not-cached-at) until the user runs `/plugin install code-formatter@your-marketplace` once in a session. Treat `renames` as append-only history. Keep old entries after everyone has migrated. When you rename again, add a second entry rather than editing the first, because Claude Code follows the chain from the oldest name. In your shell, run `claude plugin validate .` after editing the map. It rejects a chain that cycles or that ends anywhere other than `null` or a name in `plugins`, with `renames.<name>: chain does not resolve`.


[​](#uninstall-removed-plugins-from-users’-machines)

Uninstall removed plugins from users’ machines

To uninstall a removed plugin from users’ machines rather than leave a copy behind, set `"forceRemoveDeletedPlugins": true` at the top level of `marketplace.json`. Without the field, a removed plugin stays installed and reports `Plugin "<name>" not found in marketplace` when a session loads it. With it, Claude Code does the following at each session start:

1.  Compares what users installed from your marketplace against the entries and the `renames` map, and treats any plugin that is neither listed nor renamed as removed.
2.  Uninstalls each removed plugin from the user, project, and local scopes. Plugins that only managed settings installed stay in place.
3.  Lists each removed plugin under a **Flagged** heading in `/plugin` with the status `Removed from marketplace`.


[​](#authenticate-archive-downloads)

Authenticate archive downloads

To authenticate an [`archive`](plugins-marketplace-reference.md#archive-plugin-source) download, such as a download from a private registry, set the HTTP headers Claude Code sends with it. You can set `headers` in either of these places:

- **The marketplace’s `url` source**: the `url` source you registered the marketplace from, such as an [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) entry.
- **The plugin’s entry**: on Claude Code v2.1.238 or later, you can set it on the plugin’s `marketplace.json` entry instead, beside `source`.

In either place, set a `headersHelper` command instead of `headers` when the value is short-lived, such as a token your registry generates on request. Claude Code runs the command and sends the JSON object it prints as that place’s headers. Requires Claude Code v2.1.238 or later. The [marketplace reference](plugins-marketplace-reference.md#plugin-entries) lists the `headers` and `headersHelper` entry fields. The place you choose decides which downloads get the headers and when Claude Code runs the command:

| Place                    | Downloads that get the headers                                                             | When Claude Code runs a `headersHelper` set there                                                                                                                   |
|:-------------------------|:-------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Marketplace `url` source | Archive downloads on the marketplace URL’s origin, meaning the same scheme, host, and port | Before each fetch of the marketplace’s `marketplace.json` and before each archive download on that origin. Claude Code reuses one run’s output for up to 60 seconds |
| Plugin entry             | That entry’s download only                                                                 | Only when a user installs or updates that one plugin by itself and [accepts the command](#how-users-accept-a-headershelper-command)                                 |

Where both places set a header of the same name, Claude Code sends the entry’s value. Within one place, a header the command prints overrides a header of the same name listed in `headers`.


[​](#add-a-headershelper-to-a-plugin-entry)

Add a headersHelper to a plugin entry

This entry sets `headersHelper` beside `source`. It also sets [`"strict": false`](plugins-marketplace-reference.md#strict-mode), which Claude Code requires of a `marketplace.json` entry that sets `headersHelper`:

```python
{
  "name": "my-plugin",
  "description": "Formatting commands for internal services",
  "strict": false,
  "source": {
    "source": "archive",
    "url": "https://registry.example.com/plugins/my-plugin-2.1.0.zip"
  },
  "headersHelper": "/opt/bin/mint-registry-token.sh"
}
```

To check the entry, run `claude plugin install my-plugin@your-marketplace` in your shell. Claude Code shows you the command and the archive URL, and downloads the zip after you accept.


[​](#write-the-headershelper-command)

Write the headersHelper command

Whether you set `headersHelper` on a marketplace’s `url` source or on a plugin entry, write the command to meet these requirements:

- **Command text**: at most 500 characters of printable ASCII, with no run of four or more spaces.
- **Output**: print one JSON object of header names and string values on stdout, then exit 0 within 10 seconds.
- **Shell and working directory**: Claude Code runs the command through `sh`, or through `cmd.exe` on Windows. The working directory is the configuration directory, which is `~/.claude` or [`CLAUDE_CONFIG_DIR`](../02-Claude-Code-CLI/env-vars.md#variables). Give an absolute path or a command on `PATH`, because a relative path resolves against that directory, not the user’s project.
- **Variables Claude Code removes**: when the command is set in a `marketplace.json` entry, or in a project’s `.claude/settings.json` or `.claude/settings.local.json`, Claude Code removes from the environment every variable whose name looks like a credential, by the [same rule it applies to an MCP `headersHelper`](../06-MCP-Tools/General/mcp.md#which-variables-a-helper-can-read). `ANTHROPIC_API_KEY` and `MY_REGISTRY_TOKEN` are both removed, so have the command read its credential from a file or a credential store. This removal doesn’t apply to a command set in user settings, a `--settings` file, or managed settings.
- **Variables Claude Code sets**: `CLAUDE_CODE_MARKETPLACE_URL` and `CLAUDE_CODE_MARKETPLACE_NAME` for a `url` source’s command, and `CLAUDE_CODE_PLUGIN_NAME` and `CLAUDE_CODE_PLUGIN_ARCHIVE_URL` for an entry’s command. `CLAUDE_CODE_MARKETPLACE_NAME` is unset on the first fetch after a user adds a marketplace by URL, because that fetch is what supplies the name.

A command that mints a bearer token prints an object like this one:

```python
{"Authorization": "Bearer eyJhbGciOiJSUzI1NiJ9"}
```


[​](#when-claude-code-skips-a-headershelper-command-or-drops-its-output)

When Claude Code skips a headersHelper command or drops its output

A `headersHelper` command doesn’t run, or headers from `headers` or from the command’s output are dropped, when one of the following applies:

- **Command fails**: if the command exits non-zero, runs past 10 seconds, or prints anything other than a JSON object of string values, the fetch or download the command was run for doesn’t happen.
- **Marketplace URL doesn’t start with `https://`**: that `url` source’s command doesn’t run, and requests carry only the headers listed in its `headers` field.
- **Redirect leaves the origin**: when a download is redirected off the archive URL’s origin, the redirected request carries no `headers` values or command output from either the marketplace `url` source or the plugin entry.
- **Entry sets a routing or identity header**: Claude Code drops request-routing and client-identity names such as `Host`, `Cookie`, and `X-Forwarded-*` from an entry’s `headers` and command output, and keeps authentication names such as `Authorization`. Every `marketplace.json` entry is filtered this way. For an inline plugin entry in settings, see [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces).
- **Command set in an `--add-dir` directory’s settings**: the command is ignored, on a `url` source and on an [inline plugin entry](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) alike, and only that file’s `headers` are sent.
- **Managed settings block the command**: setting [`disableCommandPluginSources`](../02-Claude-Code-CLI/settings-reference.md#disablecommandpluginsources) to `true` blocks `headersHelper` commands, and [`allowManagedHooksOnly`](../02-Claude-Code-CLI/settings-reference.md#allowmanagedhooksonly) blocks them too unless `disableCommandPluginSources` is explicitly `false`. Under either block, Claude Code still runs the command for a marketplace that managed settings themselves declare.


[​](#how-users-accept-a-headershelper-command)

How users accept a headersHelper command

A user accepts a plugin entry’s command each time they install or update that one plugin by itself. They do that from the plugin’s own view in `/plugin`, or with `claude plugin install` or `claude plugin update`. Claude Code shows the command and the archive URL, and runs the command only after the user accepts. In a non-interactive shell, pass [`--yes`](plugins-cli-reference.md#plugin-install) to accept the command. To accept only the command that a previous `--json` run displayed, pass [`--accept-command`](plugins-cli-reference.md#plugin-install) with the `sha256` the run reported. Claude Code runs only the command it showed, for the archive URL it showed. If the entry’s command or archive URL changed in between, Claude Code refuses the install or update. A change in the query string alone doesn’t count.


[​](#installs-and-updates-that-refuse-the-command-instead-of-asking)

Installs and updates that refuse a command instead of asking

On any operation other than a single-plugin install or update, Claude Code neither runs an entry’s command nor downloads its archive. The plugin stays at its installed version or stays uninstalled, and the user sees one of these results:

- **Installing several plugins at once, from a plugin suggestion, or as another plugin’s dependency**: Claude Code refuses the plugin that has the command and directs the user to that plugin’s own view in `/plugin`. The other plugins in a bulk install still install. A plugin that depends on the refused plugin fails to install until the user installs the refused plugin by itself.
- **Background auto-update, or session start for a plugin whose archive was never downloaded**: Claude Code lists the plugin in the `/plugin` Errors tab so the user knows to install or update it themselves.


[​](#when-a-marketplace-url-sources-command-runs)

When a marketplace `url` source’s command runs

You declare a marketplace `url` source’s `headersHelper` in a settings file, such as an [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) entry, rather than in the catalog the marketplace publishes. Claude Code therefore doesn’t ask the user to accept it on each install or update. Instead, the settings file that declares it decides when Claude Code runs it:

| Settings file                                                                 | When Claude Code runs the command                                                                                                                                                                                                                 |
|:------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| User settings, a `--settings` file, or a managed settings file on the machine | Without asking, including during a background marketplace refresh                                                                                                                                                                                 |
| A project’s `.claude/settings.json` or `.claude/settings.local.json`          | Only after the user accepts the [workspace trust dialog](../02-Claude-Code-CLI/permissions.md#what-runs-before-you-trust-a-folder) for that folder itself. A `-p` or SDK session doesn’t count as accepting it, and neither does trust granted to a parent folder |
| Server-managed settings                                                       | In an interactive session, only after the user approves the delivered settings in the [security approval dialog](../13-Enterprise-Admin/server-managed-settings.md#security-approval-dialogs)                                                                      |

For an [inline plugin entry](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) in one of these files, Claude Code requires the same folder trust or settings approval as for a marketplace-level command in that file, and the user also accepts the entry’s command on each install or update.


[​](#depend-on-and-recommend-other-plugins)

Depend on and recommend other plugins

An entry can declare dependencies on other plugins.

- **Version ranges**: a dependency can carry a semver range.
- **Cross-marketplace dependencies**: a dependency from another marketplace installs only when your marketplace lists that marketplace in `allowCrossMarketplaceDependenciesOn`.

For version ranges, the `<plugin>--v<version>` git-tag convention they resolve against, and cross-marketplace trust, see [Plugin dependencies](plugins-dependencies.md). To have Claude Code suggest a plugin when a project matches it, add a `relevance` block to the entry with the signals that identify the project. Users see suggestions from your marketplace only when an admin lists it in `pluginSuggestionMarketplaces`. For the signals and the enablement step, see [Plugin relevance](plugins-relevance.md).


[​](#work-around-what-a-marketplace-can’t-do)

Work around what a marketplace can’t do

Some things owners ask for have no field in `marketplace.json`. Here is the nearest option for each:

- **Restrict what else users install**: the marketplace allowlist is a managed setting, `strictKnownMarketplaces`. See [Restrict what users can install](plugins-org.md#restrict-what-users-can-install).
- **Install or enable a plugin without the user asking**: no entry field installs a plugin. Managed `enabledPlugins` does that for a fleet; see [Pre-install and require plugins](plugins-org.md#pre-install-and-require-plugins).
- **Show different entries to different users**: entries carry no audience field, and every user who adds the marketplace sees the whole catalog. Host separate marketplaces for separate audiences.
- **Mark a plugin deprecated**: there is no deprecation state. The option is to remove the entry, map its name to `null` in `renames`, and optionally set `forceRemoveDeletedPlugins`.
- **Turn on auto-update for your users**: each user turns it on under **Marketplaces** in `/plugin`, or an admin sets `autoUpdate` in managed settings. See [Turn on auto-update](#turn-on-auto-update).
- **Carry git credentials**: no marketplace field holds a git token. Access to a git-hosted marketplace or plugin follows the user’s git setup, per [Grant access to a private marketplace](#grant-access-to-a-private-marketplace). For `archive` sources, an entry can set [`headers` or `headersHelper`](#authenticate-archive-downloads) instead.


[​](#next-steps)

Next steps

- [Marketplace reference](plugins-marketplace-reference.md): `marketplace.json` fields, source types, and validation messages
- [Manage plugins for your organization](plugins-org.md): require, restrict, or seed your marketplace across your organization’s machines
- [Plugin dependencies](plugins-dependencies.md): tag releases so plugins that depend on yours can resolve versions
- [Troubleshoot plugins](plugins-troubleshooting.md): the errors your users see when adding or updating from your marketplace

---

## Plugin loading reference - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/loading
Path: 08-Plugins-Skills/plugins-loading.md

## On this page

- [Check which stage a plugin reached](#check-which-stage-a-plugin-reached)
  - [Plugins and marketplaces that aren’t on disk at session start](#plugins-and-marketplaces-that-aren%E2%80%99t-on-disk-at-session-start)
- [Find where a plugin came from](#find-where-a-plugin-came-from)
  - [Entry name and manifest name](#entry-name-and-manifest-name)
  - [Plugins shared through a repository](#plugins-shared-through-a-repository)
  - [Plugins synced from claude.ai](#synced-plugins)
  - [Sync timing in terminal sessions](#sync-timing-in-terminal-sessions)
  - [Sign-in requirements for terminal sync](#sign-in-requirements-for-terminal-sync)
  - [Control which synced plugins load](#control-which-synced-plugins-load)
- [Find where a plugin is enabled](#find-where-a-plugin-is-enabled)
  - [Disabled in user settings but still loads](#disabled-in-user-settings-but-still-loads)
  - [Enabled in project settings but not installed](#enabled-in-project-settings-but-not-installed)
- [Find plugins on disk](#find-plugins-on-disk)
  - [In-place and copied plugins](#in-place-and-copied-plugins)
  - [Paths that escape the plugin directory](#paths-that-escape-the-plugin-directory)
  - [Cleanup of previous versions](#cleanup-of-previous-versions)
  - [Node.js package dependencies](#node-js-package-dependencies)
  - [When the dependency install runs](#when-the-dependency-install-runs)
  - [Limits on the dependency install](#limits-on-the-dependency-install)
  - [When the dependency install fails or is skipped](#when-the-dependency-install-fails-or-is-skipped)
- [Versions and updates](#versions-and-updates)
  - [How Claude Code computes the version](#how-claude-code-computes-the-version)
  - [When Claude Code refreshes a marketplace before an install](#when-claude-code-refreshes-a-marketplace-before-an-install)
  - [When auto-update runs](#when-auto-update-runs)
  - [Which marketplaces and plugins auto-update](#which-marketplaces-and-plugins-auto-update)
  - [When a command source re-runs](#when-a-command-source-re-runs)
- [Name conflicts](#name-conflicts)
  - [Keep a session-only plugin from loading](#keep-a-session-only-plugin-from-loading)
- [Next steps](#next-steps)

Troubleshooting

# Plugin loading reference

Copy pageCopy page

Trace where Claude Code loads each plugin from, which settings file decides whether it loads, and why an update changed nothing.

Copy pageCopy page

Use this page when a plugin didn’t load, loaded a different copy than you expected, or didn’t pick up an update, and you want to see which source, settings scope, or file on disk decided that. It gives the rules Claude Code applies when a session starts and each time you run `/reload-plugins`. You can also ask Claude to read this page and diagnose your setup.

These cases are covered on other pages:

- **Install, enable, disable, and update steps**: see [Install and manage plugins](discover-plugins.md)
- **You have a specific error message**: see [Troubleshoot plugins](plugins-troubleshooting.md)

Start with [Check which stage a plugin reached](#check-which-stage-a-plugin-reached) for the three stages an installed plugin passes through, or go to the section that matches what you’re seeing:

- A plugin you turned off still loads: [Find where a plugin is enabled](#find-where-a-plugin-is-enabled)
- An update changed nothing: [Versions and updates](#versions-and-updates)
- You’re looking at the files under `~/.claude/plugins/`: [Find plugins on disk](#find-plugins-on-disk)
- A `--plugin-dir` plugin didn’t load, or a same-named plugin loaded instead: [Name conflicts](#name-conflicts)


[​](#check-which-stage-a-plugin-reached)

Check which stage a plugin reached

An `enabledPlugins` entry becomes a plugin you can use in stages: your settings declare it, Claude Code fetches it to disk, and the running session loads it. When a plugin doesn’t behave as a settings file suggests, check which stage it reached:

- **Declared, in settings**: `enabledPlugins` says which plugins should be on, and `extraKnownMarketplaces` says which marketplaces should exist. When you run `claude plugin marketplace add`, Claude Code writes the marketplace to `extraKnownMarketplaces` in your user settings as well as to disk
- **Fetched, on disk under `~/.claude/plugins/`**: the records of what Claude Code has fetched, and the fetched files themselves:
  - `known_marketplaces.json` records each marketplace Claude Code has fetched, with its `source`, `installLocation`, `lastUpdated`, and `autoUpdate`. There is one `known_marketplaces.json` per user, so a marketplace you add in one project is available in every project
  - `installed_plugins.json` records each install with its `scope`, `installPath`, and `version`
  - `cache/` holds the plugin files
- **Loaded, in the running session**: the plugin set Claude Code loaded at startup or at the last `/reload-plugins`. Changes to settings or to disk don’t reach this layer until you run `/reload-plugins` or start a new session. That is why `claude plugin update` ends with `Restart to apply changes.` and background updates prompt you with `Run /reload-plugins to apply`


[​](#plugins-and-marketplaces-that-aren’t-on-disk-at-session-start)

Plugins and marketplaces that aren’t on disk at session start

Plugins load at session start from `installed_plugins.json` and the cache without using the network. After the session starts, Claude Code checks the declared marketplaces in the background:

- **A marketplace that settings declare but `known_marketplaces.json` lacks**: Claude Code clones it, then reloads plugins and downloads enabled plugins that aren’t cached yet
- **A declared marketplace whose source changed in settings**: Claude Code re-fetches it from the new source and shows `Plugins changed. Run /reload-plugins to activate.`

An enabled plugin that neither path fetched and that has no usable cache directory shows `Plugin "<name>" not cached at <path>` in the `/plugin` **Errors** tab, and `claude plugin list` adds `— run /plugin to refresh` to the same line. For the fix, see [`Plugin "<name>" not cached at <path>`](plugins-troubleshooting.md#plugin-not-cached-at).


[​](#find-where-a-plugin-came-from)

Find where a plugin came from

Every plugin has an id of the form `<name>@<origin>`, which is what you see in settings files and in `claude plugin list --json`. The part after `@` tells you where Claude Code found the plugin:

| ID ends in       | How the plugin got there                                                                                                                                                                                     | How you turn it on or off                                                                                                                                           |
|:-----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `@<marketplace>` | You installed it from a marketplace you added                                                                                                                                                                | `"<name>@<marketplace>": true` or `false` under `enabledPlugins` in a settings file                                                                                 |
| `@inline`        | You started Claude Code with `--plugin-dir` or `--plugin-url`, set [`CLAUDE_CODE_PLUGIN_DIRS`](../02-Claude-Code-CLI/env-vars.md#variables), or an Agent SDK app passed the `plugins` option. It loads for that session only | On for the session unless the manifest sets `defaultEnabled: false` or a settings file sets `"<name>@inline": false`                                                |
| `@skills-dir`    | You saved a plugin directory that has a `.claude-plugin/plugin.json` under `~/.claude/skills/` or the project’s `.claude/skills/`                                                                            | The manifest’s `defaultEnabled`, unless a settings file sets `"<name>@skills-dir"` to `true` or `false`                                                             |
| `@synced`        | You or your organization turned it on for your claude.ai account, and Claude Code [downloaded it](#synced-plugins)                                                                                           | On unless the manifest sets `defaultEnabled: false` or a settings file sets `"<name>@synced": false`. A plugin your organization marks as required loads regardless |

For a marketplace plugin, `<name>` is the entry name in `marketplace.json`; for `@inline` and `@skills-dir` it’s the `name` in the plugin’s manifest. The origin names in this table are reserved, so no marketplace can be named `inline`, `skills-dir`, or `synced`.


[​](#entry-name-and-manifest-name)

Entry name and manifest name

A marketplace plugin has two names, and they can differ:

- **The entry name in `marketplace.json`**: the install and enable key. It’s what you write in `enabledPlugins`, what the cache directory is named after, and what `claude plugin list` shows
- **The `name` in the manifest**: what the plugin’s components are namespaced under, and what [name conflicts](#name-conflicts) compare


[​](#plugins-shared-through-a-repository)

Plugins shared through a repository

To share a plugin through a repository, list it under `enabledPlugins` in `.claude/settings.json` or place it under `.claude/skills/`. Claude Code doesn’t scan a project’s `.claude/plugins/` directory. A cloud session doesn’t add the marketplaces a repository lists under [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces), because that requires the workspace trust dialog, which a cloud session never shows. A project-scope skills-directory plugin loads only from the `.claude/skills/` of the session’s [primary working directory](../02-Claude-Code-CLI/permissions.md#working-directories), and only after you accept the [workspace trust dialog](../02-Claude-Code-CLI/permissions.md#what-runs-before-you-trust-a-folder) for that folder. It doesn’t [search parent directories up to the repository root](skills.md#discovery-from-parent-and-nested-directories) the way plain skills and commands do. If you launch from a subdirectory, a plugin at the repository root doesn’t load. Launch from the repository root instead, or [move the session there with `/cd`](../02-Claude-Code-CLI/permissions.md#move-the-session-to-another-directory) on v2.1.246 or later. A project-scope plugin is checked into the repository and reaches every collaborator who clones it. Because that content comes from the repository rather than from you, it loads only after the same trust check that applies to project allow rules in `.claude/settings.json`. Trusting a parent folder or running with `-p` isn’t enough. Components that run code are restricted further:

- MCP servers it declares go through the [same per-server approval](../06-MCP-Tools/General/mcp.md) as a project `.mcp.json`
- MCP servers it declares as an [MCP bundle](plugins-reference.md#mcpservers), a `.mcpb` or `.dxt` file, or from a file outside the plugin directory are skipped. Declare them inline or in a `.mcp.json` inside the plugin directory
- [Background monitors](plugins-components.md#monitors) do not load

Personal-scope plugins have none of these restrictions. For how to write `--plugin-dir` and skills-directory plugins, see [Create plugins](plugins-create.md).


[​](#synced-plugins)

Plugins synced from claude.ai

A plugin you turn on for your claude.ai account also loads in Claude Code, alongside the plugins you install from marketplaces. That includes plugins your organization turns on for its members. Each of these plugins loads as `<name>@synced`, with no marketplace and no [install record](#check-which-stage-a-plugin-reached). In terminal sessions, a synced plugin’s skills, agents, hooks, MCP servers, and LSP servers all load, with the same trust as a marketplace plugin you installed. For the components Cowork loads, see the [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app) on claude.com. Synced plugins load in Cowork sessions and in terminal sessions where you sign in with your claude.ai account:

- **[Cowork](../15-Claude-AI-Features/product-cowork.md)**: Claude Code downloads them into the session’s own environment when the session starts
- **Terminal sessions**: each time you start Claude Code, it syncs once in the background, downloading new and updated plugins and removing the ones that you or your organization turned off. Syncing in terminal sessions requires Claude Code v2.1.273 or later


[​](#sync-timing-in-terminal-sessions)

Sync timing in terminal sessions

Because the terminal sync runs in the background, it can finish after your session has started. When it adds, updates, or removes a synced plugin in an interactive session, you see `Plugins changed. Run /reload-plugins to activate.` Run `/reload-plugins` to load the change in that session, or leave it for the next time you start Claude Code. If you enable a plugin on claude.ai while a session is running, the plugin downloads the next time you start Claude Code.


[​](#sign-in-requirements-for-terminal-sync)

Sign-in requirements for terminal sync

In your terminal, plugins sync only in sessions where you sign in with your claude.ai account. Claude Code neither downloads nor loads synced plugins in these terminal sessions, even after you sign in with `/login`:

- A session where `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, or an `apiKeyHelper` script supplies the credential in place of that sign-in
- A session that doesn’t [fetch feature flags from Anthropic](../02-Claude-Code-CLI/env-vars.md#features-that-need-feature-flag-fetching), such as one where you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`
- A session in [bare mode](../02-Claude-Code-CLI/headless.md#start-faster-with-bare-mode) or one you start with `--safe-mode`
- A session you start with a [`--setting-sources`](../02-Claude-Code-CLI/cli-reference.md#cli-flags) list that leaves out `user`

If you signed in on an earlier version of Claude Code, that sign-in doesn’t cover plugins until Claude Code renews it in the background. To get access sooner, run `/login` again. Plugin sync then starts the next time you start Claude Code.


[​](#control-which-synced-plugins-load)

Control which synced plugins load

You can turn synced plugins off one at a time, except a plugin your organization requires, or turn off every synced plugin on the machine:

- **One plugin**: `claude plugin disable <name>@synced` in your shell and the `/plugin` **Installed** tab in a session both save `"<name>@synced": false` in your user-level [`enabledPlugins`](../02-Claude-Code-CLI/settings-reference.md#enabledplugins). To keep the plugin out of a project in every environment, set the same key in the project’s committed `.claude/settings.json`
- **Every synced plugin on a machine**: set [`syncClaudeAiPlugins`](../02-Claude-Code-CLI/settings-reference.md#syncclaudeaiplugins) to `false` in your user settings, or your organization sets it in [managed settings](../13-Enterprise-Admin/managed-settings.md). Claude Code stops downloading, and the next time you start it, it moves the plugins it already synced to `~/.claude/plugins/.trash/` and no longer loads them. If your organization turns off Skills on claude.ai, plugins stop syncing too
- **A plugin your organization requires**: a plugin that your organization marks as required on claude.ai loads even if you disabled it earlier. `claude plugin disable` refuses it with `Plugin "<name>@synced" is required by your organization and can't be disabled here. Contact your admin to change it.`, and `claude plugin list` marks it `required by your org`

For removing a plugin on claude.ai, see [Manage installed plugins](discover-plugins.md#manage-installed-plugins).


[​](#find-where-a-plugin-is-enabled)

Find where a plugin is enabled

You can set an `enabledPlugins` entry in any of six sources. The table lists them from lowest precedence to highest, and who each one applies to. For the settings files themselves, see [Settings files and who they affect](../02-Claude-Code-CLI/settings.md#where-settings-live).

| Source      | Where you set it                                                                                  | Reaches                                                                                                   |
|:------------|:--------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------|
| `--add-dir` | `.claude/settings.json` or `.claude/settings.local.json` in a directory you pass with `--add-dir` | This session only. Only a `true` value has an effect, and every other source overrides it                 |
| `user`      | `~/.claude/settings.json`                                                                         | You, in every project                                                                                     |
| `project`   | `.claude/settings.json`                                                                           | Everyone who clones the repository                                                                        |
| `local`     | `.claude/settings.local.json`                                                                     | You, in this repository only                                                                              |
| `flag`      | The `--settings` value you pass at launch                                                         | This session only                                                                                         |
| `managed`   | [Managed settings](../13-Enterprise-Admin/managed-settings.md)                                                     | Every user the policy covers. `true` force-enables and `false` blocks, and no other source overrides them |

These sources merge key by key. For each plugin id, the value that applies is the one from the highest-precedence source that mentions the id. A source that doesn’t mention the id leaves the value from the lower-precedence source in effect.


[​](#disabled-in-user-settings-but-still-loads)

Disabled in user settings but still loads

If you set a plugin to `false` in `~/.claude/settings.json` and it still loads, a `true` in a higher-precedence source is overriding it. The plugin’s row in `claude plugin list` and in `/plugin` shows `Disabled in ~/.claude/settings.json but still loads — project settings enable it, which overrides your user setting`. The message names the source that overrode you: `project`, `project, gitignored` for `.claude/settings.local.json`, `cli flag`, or `managed`. To opt out of a project-enabled plugin on your machine, set the id to `false` in `.claude/settings.local.json`, which has higher precedence than the project file.


[​](#enabled-in-project-settings-but-not-installed)

Enabled in project settings but not installed

When a plugin’s only `true` is in the project’s `.claude/settings.json`, Claude Code doesn’t fetch it onto a machine where it isn’t installed, unless its marketplace entry has a [relative-path source](plugins-marketplace-reference.md#plugin-sources) or a [seed directory](plugins-org.md#seed-containers-and-ci) already holds it. Instead, the `/plugin` **Errors** tab shows `Plugin "<name>" is enabled in project settings but isn't installed here`. A relative-path plugin needs no install record because it loads from the marketplace itself. Claude Code fetches a plugin with an external source only when one of these sources sets it to `true`:

- Your user settings
- A `.claude/settings.local.json` that git doesn’t track
- The `--settings` flag
- Managed settings


[​](#find-plugins-on-disk)

Find plugins on disk

Claude Code keeps plugin files and state records under one plugins root, which is `~/.claude/plugins` unless you set [`CLAUDE_CODE_PLUGIN_CACHE_DIR`](../02-Claude-Code-CLI/env-vars.md). Every path in the table is relative to that root.

| Path                                                                                                   | What it holds                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
|:-------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `cache/<marketplace>/<plugin>/<version>/`                                                              | One directory per installed version of a marketplace plugin. `<plugin>` is the marketplace entry name and `<version>` is the [resolved version](#versions-and-updates). `${CLAUDE_PLUGIN_ROOT}` points at this directory                                                                                                                                                                                                                                                                                                        |
| `data/<plugin-id>/`                                                                                    | The plugin’s persistent directory, exposed as `${CLAUDE_PLUGIN_DATA}`. For how `<plugin-id>` is formed, see [Path variables and persistent data](plugins-components.md#path-variables-and-persistent-data). Claude Code creates it when a plugin component first uses it and keeps it across updates. By default, Claude Code deletes it when you uninstall the plugin from its last scope. For `--keep-data` and the other cases where it stays, see [plugin uninstall](plugins-cli-reference.md#plugin-uninstall) |
| `marketplaces/<name>/`                                                                                 | The clone or download of a marketplace added from GitHub, another Git host, or a URL. A marketplace added from a local `file` or `directory` source has no copy here, and its `installLocation` in `known_marketplaces.json` is the path you gave                                                                                                                                                                                                                                                                               |
| `synced/`                                                                                              | The plugins Claude Code [synced from your claude.ai account](#synced-plugins)                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `.trash/`                                                                                              | Plugins that the claude.ai sync removed, such as after you turn one off on claude.ai or stop syncing                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `installed_plugins.json` and `known_marketplaces.json`                                                 | The records of what Claude Code has installed and which marketplaces it has fetched, described under [Check which stage a plugin reached](#check-which-stage-a-plugin-reached). A [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai) is recorded in `known_marketplaces_claudeai.json` instead                                                                                                                                                                                                      |
| `flagged-plugins.json`                                                                                 | Plugins Claude Code uninstalled because their marketplace delisted them. They appear in the **Flagged** section of `/plugin`; see [Host a marketplace](plugins-host-marketplace.md)                                                                                                                                                                                                                                                                                                                                       |
| `installed_plugins.set-aside.<date>.<hash>.json` and `installed_plugins.unreadable.<date>.<hash>.kept` | Dated copies Claude Code keeps before it drops install records that no version of Claude Code can use or rebuilds an unreadable `installed_plugins.json`. See [the recovery notes](plugins-troubleshooting.md#installed-plugins-json-could-not-be-read-and-was-rebuilt). They age out on the [`cleanupPeriodDays`](../02-Claude-Code-CLI/settings-reference.md#cleanupperioddays) schedule                                                                                                                                                |

Because `${CLAUDE_PLUGIN_ROOT}` points at a version directory, a plugin’s root path changes with every version. Keep a plugin’s durable files in `${CLAUDE_PLUGIN_DATA}` instead.


[​](#in-place-and-copied-plugins)

In-place and copied plugins

Claude Code loads some plugins in place from where you keep them and copies the rest into the cache, according to their origin:

- **`--plugin-dir` and skills-directory plugins**: the directory loads in place and is never copied. A `--plugin-url` archive or a `--plugin-dir` `.zip` is extracted into a session temp directory first
- **Relative-path plugins in a marketplace you added from a local directory**: the plugin loads in place from its path inside the marketplace folder. Your edits to the source directory take effect at the next session start or `/reload-plugins`, and you don’t need to increase the version. The plugin’s hook processes and MCP and LSP servers receive a `CLAUDE_PLUGIN_ROOT` that points at the source directory. For its Node.js package dependencies, see [When the dependency install runs](#when-the-dependency-install-runs)
- **`command`-source plugins in [link mode](plugins-marketplace-reference.md#command-plugin-source)**: the directory the command printed loads in place, through links in the cache entry
- **Every other marketplace plugin**: Claude Code copies the plugin into `cache/<marketplace>/<plugin>/<version>/` at install and loads that copy. Files outside the plugin directory aren’t copied, so when a script inside a copied plugin reads a path above the plugin root, such as `../shared`, it doesn’t find them


[​](#paths-that-escape-the-plugin-directory)

Paths that escape the plugin directory

Whether a plugin loads in place or from a cached copy, Claude Code doesn’t let it declare components outside its own directory. It rejects a component path that resolves outside the plugin root, whether the path is declared in `plugin.json` or in a marketplace entry:

- **A path that points outside the plugin as written**, such as `../shared-utils`
- **A symlink that leads outside the plugin**, other than [links between plugins within one marketplace](plugins-host-marketplace.md#share-files-within-a-marketplace-with-symlinks)
- **On macOS and Linux, a path that contains a backslash anywhere in it**, even when the path stays inside the plugin. Components declared with backslash paths therefore load on Windows only, so write component paths with forward slashes, such as `./commands/deploy.md`

A rejected path appears as a [`path escapes plugin directory`](../02-Claude-Code-CLI/errors.md#path-escapes-plugin-directory) error, and the plugin loads without that component.


[​](#cleanup-of-previous-versions)

Cleanup of previous versions

When you update or uninstall a plugin, Claude Code writes an `.orphaned_at` marker into the previous version directory. It removes that directory in a background cleanup 14 days later, so a session that already loaded the old version keeps running. The sweep runs only while `installed_plugins.json` records at least one install. After you uninstall your last plugin, orphaned directories stay until you install another.


[​](#node-js-package-dependencies)

Node.js package dependencies

When Claude Code copies a plugin into the cache, it also installs the plugin’s Node.js package dependencies there, so the plugin’s hooks and MCP servers can load them. This section covers the npm and Bun packages a plugin declares in its own `package.json`. For plugins that depend on other plugins, see [plugin dependency versions](plugins-dependencies.md).


[​](#when-the-dependency-install-runs)

When the dependency install runs

Claude Code runs the install inside the copied version directory each time it creates one:

- When you install a plugin
- When Claude Code updates a plugin to a new version
- At session start when an enabled plugin isn’t cached yet, such as on a new machine

For a relative-path plugin [loaded in place](#in-place-and-copied-plugins) from a local-directory marketplace, Claude Code doesn’t install the dependencies into the source directory. Install them there yourself, or from a hook into [`${CLAUDE_PLUGIN_DATA}`](plugins-components.md#path-variables-and-persistent-data). The install runs only when the plugin’s root directory contains both a `package.json` and a supported lockfile. The lockfile decides which command Claude Code runs:

| Lockfile                                     | Command                                          |
|:---------------------------------------------|:-------------------------------------------------|
| `bun.lock` or `bun.lockb`                    | `bun install --frozen-lockfile --ignore-scripts` |
| `npm-shrinkwrap.json` or `package-lock.json` | `npm ci --ignore-scripts`                        |

If a plugin contains more than one of these lockfiles, Claude Code uses the first match, checking in order: `bun.lock`, `bun.lockb`, `npm-shrinkwrap.json`, `package-lock.json`. Claude Code skips the install for Yarn and pnpm lockfiles and for a `bunfig.toml` beside the Bun lockfile:

- If your plugin has only a `yarn.lock` or `pnpm-lock.yaml`, replace it with an npm lockfile
- If a `bunfig.toml` is in the same directory as the Bun lockfile, remove the `bunfig.toml`, or replace the Bun lockfile with an npm lockfile

Include an npm lockfile to reach the most users. Claude Code runs the matched lockfile’s package manager from the user’s PATH and doesn’t try the other lockfile instead if that package manager is missing. For a plugin distributed through an npm source, use `npm-shrinkwrap.json`, because npm excludes `package-lock.json` from published packages.


[​](#limits-on-the-dependency-install)

Limits on the dependency install

Claude Code constrains this dependency install so that no code from the plugin or its packages executes during it, and bounds how long it can run:

- **Frozen resolution**: Bun and npm install exactly what the lockfile pins, and fail rather than re-resolve versions when `package.json` and the lockfile disagree
- **No lifecycle scripts**: `--ignore-scripts` keeps `preinstall`, `install`, and `postinstall` scripts from running, so dependencies that build native modules in those scripts download but don’t compile during this install
- **60-second timeout**: Claude Code stops an install that runs longer and treats it as failed

Claude Code fetches an npm-source plugin before this dependency install, and none of the package’s own install scripts run during the fetch. See [npm plugin source](plugins-marketplace-reference.md#npm-plugin-source). You can’t turn the automatic install off. No setting or environment variable disables it. In restricted networks, see the [network access requirements](../13-Enterprise-Admin/network-config.md#network-access-requirements) for the hosts to allow.


[​](#when-the-dependency-install-fails-or-is-skipped)

When the dependency install fails or is skipped

A failed or skipped install never blocks the plugin, and each case leaves a different sign:

- A failed install, or one skipped because of a Yarn or pnpm lockfile or a `bunfig.toml`, appears as a warning in the `claude --debug` output
- A plugin with a `package.json` and no lockfile is skipped without a log entry
- A timed-out install can leave a partial `node_modules` tree in the cached copy

When the automatic install can’t provide a dependency, install it from a hook into the [persistent data directory](plugins-components.md#path-variables-and-persistent-data). That includes packages that need their lifecycle scripts to build, Python dependencies, and plugins locked with Yarn or pnpm.


[​](#versions-and-updates)

Versions and updates

If a plugin’s author pushed new commits and `claude plugin update` prints `<name> is already at the latest version (<version>).`, the version Claude Code computes for the plugin is unchanged, so nothing changes on disk. Claude Code computes a version for every plugin it installs, and that version is how it detects an update. `claude plugin update` and background auto-update compute the version again and skip the plugin when it matches what `installed_plugins.json` records. The version also names the plugin’s cache directory. A manifest that pins `"version"` is one way the computed version stays the same across commits. See [How Claude Code computes the version](#how-claude-code-computes-the-version) for the resolution order. A plugin [loaded in place](#in-place-and-copied-plugins) from a local-directory marketplace loads its current source files at every session start, whatever its version string says. For a plugin from a [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai), the version claude.ai records for the plugin is its version, and the manifest’s `version` isn’t read.


[​](#how-claude-code-computes-the-version)

How Claude Code computes the version

For a marketplace you added by source, Claude Code picks the rule by the `source` type of the plugin’s marketplace entry. The [marketplace reference](plugins-marketplace-reference.md#plugin-sources) lists the source types. For every source type in that list except `command`:

1.  The `version` field in the plugin’s manifest comes first
2.  Then the `version` field in the plugin’s marketplace entry
3.  When neither is set, the version comes from the source type:

| Source type                                                                                | Version when no `version` field is set                                                                                                               |
|:-------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------|
| `github`, `url`, or `git-subdir`                                                           | The commit SHA of the source, shortened to 12 characters. A `git-subdir` version also carries a hash of the subdirectory path                        |
| `archive`                                                                                  | The SHA-256 digest, shortened to 12 characters: the `sha256` pin in the marketplace entry, or the digest of the downloaded file when there is no pin |
| Relative path inside a Git-hosted marketplace                                              | The commit SHA of the installed directory                                                                                                            |
| Local directory, when neither the plugin directory nor its marketplace is a git repository | `unknown`                                                                                                                                            |
| `npm`                                                                                      | `unknown`                                                                                                                                            |

Claude Code doesn’t take the version from a repository that encloses the install path, such as a git-managed `~/.claude`. For a `command` source, Claude Code always derives the version from what the command produced: a 12-character hash on its own, or `<manifest version>-<hash>` when the manifest sets one. The marketplace entry’s `version` is ignored for command sources. For what the hash covers, see [Copy mode and link mode](plugins-marketplace-reference.md#copy-mode-and-link-mode). Because the manifest comes first, a manifest that pins `"version": "1.0.0"` keeps every user on the cached copy until its author changes the string, however many commits they push. To let users track commits instead, leave `version` out of both the manifest and the entry. [Host a marketplace](plugins-host-marketplace.md) covers which choice fits which release setup.


[​](#when-claude-code-refreshes-a-marketplace-before-an-install)

When Claude Code refreshes a marketplace before an install

When you install a plugin, Claude Code looks it up in its local copy of the marketplace catalog. You can run `/plugin install` in a session or `claude plugin install` in your shell, and name the plugin with or without its marketplace. The table shows which of those combinations refresh the local copy.

| Plugin name        | Command                                      | What Claude Code refreshes                                                   |
|:-------------------|:---------------------------------------------|:-----------------------------------------------------------------------------|
| `name@marketplace` | `/plugin install` or `claude plugin install` | The named marketplace, before the lookup                                     |
| `name` alone       | `/plugin install`                            | Only marketplaces that have auto-update on, and only after the lookup misses |
| `name` alone       | `claude plugin install`                      | Nothing. It reads the cached catalogs without refreshing                     |

The refresh before a `name@marketplace` install doesn’t depend on the marketplace’s auto-update setting or on `DISABLE_AUTOUPDATER`. When the refresh fails, the install proceeds from the cached catalog and `claude plugin install` reports `marketplace not refreshed`. Claude Code skips the refresh before a `name@marketplace` install when:

- The marketplace was added from a local `file` or `directory` source, or is defined inline in settings with a [`settings` source](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces)
- A [seed directory](../02-Claude-Code-CLI/env-vars.md) supplies the marketplace
- Claude Code refreshed the marketplace within the last 30 seconds
- You set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`
- [Managed settings](plugins-org.md#restrict-what-users-can-install) block the marketplace, in which case Claude Code also refuses the install


[​](#when-auto-update-runs)

When auto-update runs

In an interactive session, after you send your first message, Claude Code waits a random delay of up to ten minutes. It then refreshes every marketplace with auto-update on and updates the plugins installed from them on disk. The running session keeps the versions it loaded, and you see `Plugin updated: <name> · Run /reload-plugins to apply`. Whether or not you reload, the new versions load on your next launch.


[​](#which-marketplaces-and-plugins-auto-update)

Which marketplaces and plugins auto-update

Whether a marketplace auto-updates follows the first of these that is set:

1.  **`autoUpdate` on its `extraKnownMarketplaces` entry** in a settings file
2.  **`autoUpdate` on its `known_marketplaces.json` entry**, which the **Enable auto-update** toggle under `/plugin` **Marketplaces** writes. When a settings file also declares the marketplace under `extraKnownMarketplaces`, the toggle writes `autoUpdate` to that settings entry as well
3.  **The default**: on for Anthropic’s official marketplaces such as `claude-plugins-official`, off for `knowledge-work-plugins` and `first-party-plugins`, on for [marketplaces added from claude.ai](discover-plugins.md#add-from-claude-ai), and off for every other marketplace

If you set `DISABLE_UPDATES=1`, `DISABLE_AUTOUPDATER=1`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1`, the whole pass is off and the **Enable auto-update** toggle is hidden, unless you also set `FORCE_AUTOUPDATE_PLUGINS=1`. The [environment variables reference](../02-Claude-Code-CLI/env-vars.md) covers each variable’s wider effect. Auto-update also skips a plugin whose marketplace entry declares a `headersHelper`. [Installs and updates that refuse a command instead of asking](plugins-host-marketplace.md#installs-and-updates-that-refuse-the-command-instead-of-asking) explains when such a plugin appears in the `/plugin` **Errors** tab and how you update it from there. When a copied plugin updates mid-session, hook commands, monitors, MCP servers, and LSP servers keep using the previous version’s path. Run `/reload-plugins` to switch hooks, MCP servers, and LSP servers to the new path. Monitors require a session restart.


[​](#when-a-command-source-re-runs)

When a command source re-runs

Plugins with a `command` source don’t wait for the [auto-update pass](#when-auto-update-runs). The printed directory reflects the tool’s state at the time the command ran, so Claude Code runs the [command you accepted](plugins-host-marketplace.md#change-the-command-of-a-command-source) again at these times:

- Every time you install or update the plugin
- Once per session for each enabled command-sourced plugin, in the background, shortly after the session starts. This run doesn’t depend on the marketplace’s auto-update setting or on `DISABLE_AUTOUPDATER`
- At startup or on `/reload-plugins`, when an enabled plugin’s installed version is missing from the plugin cache

Claude Code skips the two background runs when you set [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](../02-Claude-Code-CLI/env-vars.md). Explicit installs and updates still run the command with that variable set. When the command’s hashed output has changed, Claude Code installs the result as a new version and reloads it in the running interactive session, switching [the same components that `/reload-plugins` switches](plugins-cli-reference.md#reload-plugins). You see a notification that the plugin was reloaded. If reloading in place would invalidate the session’s prompt cache, Claude Code instead prompts you to run `/reload-plugins`, which [warns about the cache cost and applies when rerun with `--force`](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin).


[​](#name-conflicts)

Name conflicts

When enabled plugins from different origins share a manifest name, this order decides which one loads, from highest precedence to lowest:

1.  A plugin whose id appears in managed settings `enabledPlugins`, as `true` or `false`. A `--plugin-dir` copy whose manifest name matches the id’s name part isn’t loaded, and you see `--plugin-dir copy of "<name>" ignored: plugin is locked by managed settings`
2.  An enabled `--plugin-dir`, `--plugin-url`, or `CLAUDE_CODE_PLUGIN_DIRS` plugin. It replaces a same-named installed marketplace plugin or skills-directory plugin:
    - **An installed marketplace plugin**: replaced silently. `claude plugin list` still shows the marketplace row as enabled, because that row reflects your settings. Only the log Claude Code writes under `~/.claude/debug/` when you start with `--debug` records `Plugin "<name>" from --plugin-dir overrides installed version`
    - **A skills-directory plugin**: replaced with a `/plugin` **Errors** tab row that reads `Not loaded — the name "<name>" is already taken by a session-only plugin (--plugin-dir / --plugin-url), which takes precedence`
3.  An installed marketplace plugin. A skills-directory plugin of the same name gets the same `Not loaded` row, naming the installed plugin
4.  A skills-directory plugin. Between two of these, the copy under `~/.claude/skills/` loads and the project’s `.claude/skills/` copy is dropped, with a row that says which path shadowed it
5.  A plugin [synced from claude.ai](#synced-plugins). When an enabled plugin from any other origin matches its name, Claude Code loads that plugin and reports the synced copy as not loaded. To use the claude.ai copy instead, disable your own copy

Because the order compares manifest names, a `--plugin-dir` plugin named `hello-plugin` replaces `hello@example-marketplace` when that plugin’s manifest also says `"name": "hello-plugin"`.


[​](#keep-a-session-only-plugin-from-loading)

Keep a session-only plugin from loading

To keep a `--plugin-dir` plugin from shadowing anything, or to turn one off when a parent process passes the flag for you, set its id to `false` in any settings file. For a plugin whose manifest name is `hello-plugin`, the entry is `"enabledPlugins": {"hello-plugin@inline": false}`. A disabled session-only plugin doesn’t shadow, so the marketplace or skills-directory copy loads instead.


[​](#next-steps)

Next steps

- [Install and manage plugins](discover-plugins.md): the install, enable, disable, and update steps themselves
- [Troubleshoot plugins](plugins-troubleshooting.md): error messages by the stage that produces them
- [Plugin commands reference](plugins-cli-reference.md): the flags and commands named on this page
- [Manage plugins for your organization](plugins-org.md): the managed settings that force-enable or block plugins

---

## Marketplace reference - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/marketplace-reference
Path: 08-Plugins-Skills/plugins-marketplace-reference.md

## On this page

- [Marketplace file](#marketplace-file)
  - [Reserved names](#reserved-names)
- [Top-level fields](#top-level-fields)
- [Plugin entries](#plugin-entries)
  - [How an entry combines with plugin.json](#entry-and-plugin-json)
  - [Hooks in an entry](#hooks-in-an-entry)
  - [Display fields](#display-fields)
  - [Strict mode](#strict-mode)
- [Plugin sources](#plugin-sources)
  - [Relative path plugin source](#relative-path-plugin-source)
  - [Bare names under pluginRoot](#bare-names-under-pluginroot)
  - [github plugin source](#github-plugin-source)
  - [url plugin source](#url-plugin-source)
  - [git-subdir plugin source](#git-subdir-plugin-source)
  - [npm plugin source](#npm-plugin-source)
  - [archive plugin source](#archive-plugin-source)
  - [command plugin source](#command-plugin-source)
  - [What the command must do](#what-the-command-must-do)
  - [Output that fails the install or update](#output-that-fails-the-install-or-update)
  - [Copy mode and link mode](#copy-mode-and-link-mode)
- [Marketplace sources](#marketplace-sources)
  - [Fields by type](#fields-by-type)
  - [Source values valid only in policy lists](#source-values-valid-only-in-policy-lists)
  - [Source objects in settings](#source-objects-in-settings)
- [Validation messages](#validation-messages)
  - [Invalid input on a source](#invalid-input-on-a-source)
  - [Failures that validation doesn’t catch](#failures-that-validation-doesn%E2%80%99t-catch)
- [Next steps](#next-steps)

Reference

# Marketplace reference

Copy pageCopy page

Complete reference for marketplace.json fields, plugin entries, and the plugin and marketplace source objects, with where each is valid.

Copy pageCopy page

`marketplace.json` is the file that defines a plugin marketplace. It contains the marketplace’s name, its owner, and one entry per plugin. Each entry’s plugin source says where Claude Code fetches that plugin from. A marketplace source is a separate object that says where Claude Code fetches the marketplace file itself. You write one in settings, or Claude Code builds one when you run `claude plugin marketplace add`. This reference is for marketplace maintainers who need an exact field name or value, and for administrators who need to know which `source` values are valid in [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces), [`strictKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#strictknownmarketplaces), and [`blockedMarketplaces`](plugins-org.md#restrict-what-users-can-install).

These cases are covered on other pages:

- **Building or hosting a marketplace**: see [Create a marketplace](plugin-marketplaces.md) and [Host and maintain a marketplace](plugins-host-marketplace.md)
- **Allowlist and blocklist recipes**: see [Manage plugins for your organization](plugins-org.md)

Find the section for what you’re writing or reading:

- **The marketplace file**: [Top-level fields](#top-level-fields) and [Plugin entries](#plugin-entries)
- **An entry’s `source`**: [Plugin sources](#plugin-sources)
- **A `source` object in settings**: [Marketplace sources](#marketplace-sources)
- **Output from [`claude plugin validate <path>`](plugins-cli-reference.md)**: [Validation messages](#validation-messages), which maps each message to the field it names


[​](#marketplace-file)

Marketplace file

Save the marketplace file at `.claude-plugin/marketplace.json` in your marketplace’s directory. If you keep the file somewhere else in the repository, users have to declare the marketplace in [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) with `path` set on its source, because `claude plugin marketplace add` has no option for it. The directory that contains `.claude-plugin/` is called the marketplace root, and every relative plugin source resolves from it, not from `.claude-plugin/`. Each user registers one marketplace per `name`, so a user can’t have two marketplaces with the same name registered at once. Claude Code ignores an unknown top-level key or plugin-entry key rather than rejecting it, so a typo loads silently. `claude plugin validate` reports each unknown key as a warning.


[​](#reserved-names)

Reserved names

You can’t give your marketplace any of the following names:

- **Official marketplace names**: `claude-code-marketplace`, `claude-code-plugins`, `claude-plugins-official`, `anthropic-marketplace`, `anthropic-plugins`, `agent-skills`, `anthropic-agent-skills`, `life-sciences`, `knowledge-work-plugins`, `claude-for-legal`, `claude-for-financial-services`, `financial-services-plugins`, `first-party-plugins`, and `claude-tag-plugins`. Reserved unless the marketplace comes from a `github` or `git` [marketplace source](#marketplace-sources) under `github.com/anthropics/`.
- **Community marketplace names**: `claude-community`, `claude-plugins-community`, and `healthcare`. Reserved under the same rule as the official names.
- **Plugin directory names**: `anthropic-plugin-directory` and `claude-plugin-directory`. Reserved under the same rule as the official names.
- **Names that impersonate an official marketplace**: names such as `official-claude-plugins` or `claude-plugins-v2`, and any name containing a non-ASCII character. The error is `Marketplace name impersonates an official Anthropic/Claude marketplace`. A control or bidirectional-formatting character in a name also reports `Marketplace name cannot contain control or bidirectional-formatting characters`. A marketplace already registered under such a name stops loading, along with its plugins.
- **Another spelling of a reserved name**: a name that differs from a reserved name only by a trailing dot, or by a symbol other than an underscore in place of a hyphen, so `claude.code.plugins` counts as `claude-code-plugins`. Adding the marketplace fails with [`is another spelling of "<reserved>", a reserved marketplace name`](../02-Claude-Code-CLI/errors.md#marketplace-name-is-another-spelling-of-a-reserved-name), and a marketplace already registered under one stops loading. This check requires Claude Code v2.1.280 or later.
- **Names Claude Code uses for plugins that don’t come from a marketplace**: `inline` for plugins loaded with [`--plugin-dir`](../02-Claude-Code-CLI/cli-reference.md), `builtin` for built-in plugins, `skills-dir` for plugins auto-loaded from [`.claude/skills/`](skills.md), and `synced` for plugins synced from your claude.ai account. `claude-plugin-test` is also reserved. `skills-dir` also appears as `{"source": "skills-dir"}` in `strictKnownMarketplaces` and `blockedMarketplaces`, described under [Source values valid only in policy lists](#source-values-valid-only-in-policy-lists).
- **`npm`, `pip`, `uv`, `cargo`, `github`, and `gh`**: reserved in any casing. This check requires Claude Code v2.1.275 or later.
- **Names starting with `claudeai-`**: reserved for marketplaces hosted on claude.ai. `claude plugin marketplace add` refuses any other marketplace that uses one with `Cannot add marketplace "<name>": names starting with "claudeai-" are reserved for marketplaces hosted on claude.ai`.

When a registered marketplace stops loading because its name imitates an official one, `claude plugin list` and `/plugin` report `Claude Code refuses the marketplace name "<name>"`. The message tells you to remove the marketplace. Removing it also uninstalls its plugins and deletes their saved data. This named refusal message requires Claude Code v2.1.282 or later.


[​](#top-level-fields)

Top-level fields

The table lists every key Claude Code reads from `marketplace.json`. `name`, `owner`, and `plugins` are required.

| Field                                      | Type             | Description                                                                                                                                                                                                                                                                                                                             |
|:-------------------------------------------|:-----------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`                                     | string           | Marketplace identifier: letters, digits, `.`, `_`, and `-`, starting with a letter or digit, and no `..`. It forms the half after `@` of every [plugin id](plugins-loading.md#find-where-a-plugin-came-from) installed from the marketplace, so `claude plugin validate` fails other names. See [Reserved names](#reserved-names) |
| `owner`                                    | object           | Maintainer information. `name` is required; `email` and `url` are optional                                                                                                                                                                                                                                                              |
| `plugins`                                  | array            | [Plugin entries](#plugin-entries). Each entry is validated on its own, so one invalid entry doesn’t fail the marketplace                                                                                                                                                                                                                |
| `$schema`                                  | string           | JSON Schema URL for editor autocomplete. Ignored at load time                                                                                                                                                                                                                                                                           |
| `description`                              | string           | Marketplace description shown to users. `claude plugin validate` warns when it’s missing                                                                                                                                                                                                                                                |
| `version`                                  | string           | Marketplace manifest version                                                                                                                                                                                                                                                                                                            |
| `metadata.description`, `metadata.version` | string           | Alternate location for `description` and `version`                                                                                                                                                                                                                                                                                      |
| `metadata.pluginRoot`                      | string           | Directory that bare plugin source names resolve under. See [Relative path plugin source](#relative-path-plugin-source). Requires Claude Code v2.1.239 or later                                                                                                                                                                          |
| `forceRemoveDeletedPlugins`                | boolean          | When `true`, a plugin you remove from `plugins` is uninstalled on users’ machines. See [Host and maintain a marketplace](plugins-host-marketplace.md)                                                                                                                                                                             |
| `allowCrossMarketplaceDependenciesOn`      | array of strings | Marketplace names whose plugins may be installed as dependencies of this marketplace’s plugins. When you install a plugin, only the list in that plugin’s own marketplace applies, for its whole dependency chain. See [Plugin dependencies](plugins-dependencies.md)                                                             |
| `renames`                                  | object           | Map from a former plugin `name` to its current name, or to `null` for a plugin you removed. Requires Claude Code v2.1.193 or later. See [Host and maintain a marketplace](plugins-host-marketplace.md)                                                                                                                            |


[​](#plugin-entries)

Plugin entries

Each object in the top-level `plugins` array of `marketplace.json` names a plugin and says where to fetch it. `name` and `source` are required. An entry also accepts every [`plugin.json` field](plugins-reference.md), such as `description`, `version`, `author`, `commands`, and `hooks`. For when those fields apply, see [How an entry combines with plugin.json](#entry-and-plugin-json). The table lists the entry’s own fields and the manifest fields whose meaning changes in an entry.

| Field            | Type             | Description                                                                                                                                                                                                                                                                                                            |
|:-----------------|:-----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`           | string           | Plugin identifier: letters, digits, `.`, `_`, and `-`, starting with a letter or digit. `claude plugin validate` fails other names, which Claude Code can’t install. Users type it before `@` when they install, even when the plugin’s own `plugin.json` sets a different `name`                                      |
| `source`         | string or object | Where to fetch the plugin. See [Plugin sources](#plugin-sources)                                                                                                                                                                                                                                                       |
| `description`    | string           | Shown in [`/plugin`](discover-plugins.md) listings and details                                                                                                                                                                                                                                                    |
| `version`        | string           | Version string for the plugin. When `plugin.json` also sets `version`, `plugin.json` takes precedence and `claude plugin validate` warns. See [Plugin loading reference](plugins-loading.md)                                                                                                                     |
| `category`       | string           | Free-form category for organizing the catalog                                                                                                                                                                                                                                                                          |
| `tags`           | array of strings | Free-form tags for search                                                                                                                                                                                                                                                                                              |
| `strict`         | boolean          | Default `true`. Whether `plugin.json` is the definitive source for the plugin’s components. See [Strict mode](#strict-mode)                                                                                                                                                                                            |
| `relevance`      | object           | Signals that tell Claude Code when to suggest the plugin. See [Recommend plugins for your org](plugins-relevance.md)                                                                                                                                                                                             |
| `dependencies`   | array            | Plugins that must be enabled for this one to work. Each item is `"name"`, `"name@marketplace"`, or an object. See [Plugin dependencies](plugins-dependencies.md)                                                                                                                                                 |
| `defaultEnabled` | boolean          | Default `true`. Whether the plugin starts enabled when the user hasn’t set it in [`enabledPlugins`](../02-Claude-Code-CLI/settings-reference.md#enabledplugins). The entry value takes precedence over `plugin.json`                                                                                                                   |
| `displayName`    | string           | Human-readable name shown in the UI. When neither the entry nor the plugin’s `plugin.json` sets one, users see the plugin’s `name`                                                                                                                                                                                     |
| `metadata`       | object           | Free-form object for your own fields. Claude Code doesn’t read it. Requires Claude Code v2.1.222 or later                                                                                                                                                                                                              |
| `headers`        | object           | HTTP headers Claude Code sends when it downloads this entry’s [archive](#archive-plugin-source). A header set here replaces a header of the same name from the marketplace source’s [`headers`](#fields-by-type). Requires Claude Code v2.1.238 or later                                                               |
| `headersHelper`  | string           | Command that prints this entry’s archive-download headers as one JSON object, for a credential that expires. The entry must also set [`"strict": false`](#strict-mode). Requires Claude Code v2.1.238 or later. See [Authenticate archive downloads](plugins-host-marketplace.md#authenticate-archive-downloads) |


[​](#entry-and-plugin-json)

How an entry combines with plugin.json

The entry’s fields apply differently to a fetched plugin that has its own `.claude-plugin/plugin.json` and to one that doesn’t:

- **No `plugin.json`**: the entry is the manifest regardless of `strict`. Every manifest field in the entry applies, including [`mcpServers`, `lspServers`, `userConfig`, and `channels`](plugins-reference.md).
- **`plugin.json` present**: `plugin.json` is the manifest. [Strict mode](#strict-mode) decides whether the entry’s six component fields, `commands`, `agents`, `skills`, `hooks`, `outputStyles`, and `themes`, are combined with it or rejected as a conflict. Entry `mcpServers`, `lspServers`, `userConfig`, and `channels` don’t apply. Declare them in `plugin.json`.


[​](#hooks-in-an-entry)

Hooks in an entry

Write entry `hooks` as an inline object that maps hook event names to matcher arrays. If you write a file path or an array instead, `claude plugin validate` passes it. Those hooks never run, and Claude Code reports a `not yet supported in a marketplace entry` error for the plugin. Put file-based hooks in the plugin’s own [`hooks/hooks.json`](plugins-components.md) or `plugin.json`.


[​](#display-fields)

Display fields

Both the entry and the plugin’s own `plugin.json` can set the display fields `displayName`, `description`, `author`, `homepage`, `repository`, `license`, and `keywords`. Users see these values in plugin listings and details, before and after install:

- For a field you set on the entry, users see the entry’s value, even when `plugin.json` sets a different one.
- For a field the entry leaves unset, users see the `plugin.json` value.

Before install, Claude Code can read `plugin.json` only for entries with a [relative-path source](#relative-path-plugin-source), whose plugin files are inside the marketplace itself. For an entry with any other source type, users see only the entry’s own fields until they install the plugin.


[​](#strict-mode)

Strict mode

`strict` decides what happens when the fetched plugin has its own `plugin.json` and the entry also declares any of the [component fields](#entry-and-plugin-json): `commands`, `agents`, `skills`, `hooks`, `outputStyles`, or `themes`. With `strict: true`, the default, Claude Code appends the entry’s component fields to `plugin.json`, except `hooks`, whose matchers replace the manifest’s per event. With `strict: false`, an entry that declares any component field is a conflict, and the plugin fails to load. The table shows each combination of `strict`, `plugin.json`, and the entry’s component fields.

| `strict`            | `plugin.json` | Entry component fields | Result                                                                                                                                                                                                                                   |
|:--------------------|:--------------|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| any                 | absent        | any                    | The entry is the manifest                                                                                                                                                                                                                |
| `true`, the default | present       | any                    | `plugin.json` is the authority. Claude Code appends the entry’s component fields to it, except `hooks`, whose matchers [replace the manifest’s per event](plugins-reference.md#how-entry-fields-combine-with-plugin-json) |
| `false`             | present       | none                   | `plugin.json` is the manifest, as with `true`                                                                                                                                                                                            |
| `false`             | present       | one or more            | Conflict. The plugin fails to load with `Plugin <name> has conflicting manifests: both plugin.json and marketplace entry specify components`                                                                                             |


[​](#plugin-sources)

Plugin sources

A plugin entry’s `source` says where Claude Code fetches that one plugin from. It’s either a relative path string or an object whose own `source` key names the type, so an entry looks like `"source": { "source": "github", "repo": "your-org/formatter" }`. The table lists each plugin source type and its fields.

| Type          | Fields                           | Notes                                                                                                                                                                                                                          |
|:--------------|:---------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Relative path | the string itself                | A directory inside the marketplace, resolved from the marketplace root. Must start with `./`, unless you write a [bare name under `metadata.pluginRoot`](#relative-path-plugin-source). `"."` on its own means the root itself |
| `github`      | `repo`, `ref`, `sha`             | GitHub repository in `owner/repo` form                                                                                                                                                                                         |
| `url`         | `url`, `ref`, `sha`              | Any git repository by URL                                                                                                                                                                                                      |
| `git-subdir`  | `url`, `path`, `ref`, `sha`      | One subdirectory of a git repository, fetched with a sparse partial clone                                                                                                                                                      |
| `npm`         | `package`, `version`, `registry` | npm package, fetched with your npm client and unpacked without running install scripts                                                                                                                                         |
| `archive`     | `url`, `sha256`                  | Zip archive over HTTPS. Requires Claude Code v2.1.224 or later                                                                                                                                                                 |
| `command`     | `command`, `timeout`, `mode`     | Directory printed by a command Claude Code runs on the user’s machine. Requires Claude Code v2.1.229 or later                                                                                                                  |

The names `url` and `github` are also [marketplace source](#marketplace-sources) types, where `url` means a direct link to a `marketplace.json` file rather than a git repository. `git` exists only as a marketplace source, and `npm` exists as both. `git-subdir`, `archive`, and `command` exist only as plugin sources. Use a relative path for a plugin in a subdirectory of the marketplace repository itself. Use `git-subdir` for a subdirectory of some other repository. `github`, `url`, and `git-subdir` sources share the `ref` and `sha` fields:

- **`ref`**: a branch or tag. Defaults to the repository’s default branch.
- **`sha`**: a full 40-character lowercase commit SHA. When you set both `ref` and `sha`, Claude Code checks out `sha`. On most git hosts, including GitHub, GitLab, and Bitbucket, this means installation succeeds even if the branch or tag named by `ref` has since been deleted upstream, as long as the commit is still reachable from the repository. Some servers, such as AWS CodeCommit, don’t support fetching commits by SHA. On those servers the `ref` must still exist and the pinned commit must be reachable from it.

For how each type is fetched, cached, and versioned, see [Plugin loading reference](plugins-loading.md).


[​](#relative-path-plugin-source)

Relative path plugin source

The path resolves from the marketplace root. `./plugins/formatter` is `<root>/plugins/formatter` even though the marketplace file is in `<root>/.claude-plugin/`. A path containing `..` fails validation. On macOS and Linux, Claude Code refuses an entry path that contains a backslash anywhere after the leading `./`, so write the path with forward slashes.

```python
{ "name": "formatter", "source": "./plugins/formatter" }
```

A relative path resolves only when Claude Code has the marketplace’s files, so check the [marketplace source](#marketplace-sources) type:

- **`github`, `git`, `file`, and `directory`**: Claude Code has the marketplace’s files.
- **`url`**: Claude Code fetches only `marketplace.json`, so relative paths can’t resolve. Give each plugin an object source instead, such as `github` or `git-subdir`.
- **`settings`**: relative paths are rejected outright.


[​](#bare-names-under-pluginroot)

Bare names under pluginRoot

A bare name is a single directory name with no `/`, such as `"formatter"`. To write bare names instead of `./` paths, set [`metadata.pluginRoot`](#top-level-fields) to the directory they resolve under. With `"pluginRoot": "./plugins"`, `"source": "formatter"` resolves to `./plugins/formatter`. Requires Claude Code v2.1.239 or later. `metadata.pluginRoot` has these limits:

- It must itself be a relative path inside the marketplace.
- It has no effect on a source that already starts with `./`.
- A source that contains a `/`, such as `team-a/formatter`, isn’t a bare name and still needs the `./` prefix, even when `metadata.pluginRoot` is set.


[​](#github-plugin-source)

github plugin source

`repo` takes `owner/repo`. `ref` and `sha` are optional.

```python
{
  "name": "formatter",
  "source": {
    "source": "github",
    "repo": "your-org/formatter",
    "ref": "v2.0.0",
    "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
  }
}
```


[​](#url-plugin-source)

url plugin source

`url` is a full git URL: `https://`, `http://`, `file://`, or `git@`. A `.git` suffix isn’t required, so Azure DevOps and AWS CodeCommit URLs work as written. This type doesn’t take `owner/repo` shorthand.

```python
{
  "name": "formatter",
  "source": {
    "source": "url",
    "url": "https://gitlab.example.com/your-group/formatter.git",
    "ref": "main"
  }
}
```


[​](#git-subdir-plugin-source)

git-subdir plugin source

`url` accepts a full git URL or GitHub `owner/repo` shorthand. `path` is the subdirectory that holds the plugin, and Claude Code downloads only that subdirectory.

```python
{
  "name": "formatter",
  "source": {
    "source": "git-subdir",
    "url": "https://github.com/your-org/monorepo.git",
    "path": "tools/formatter"
  }
}
```


[​](#npm-plugin-source)

npm plugin source

An `npm` source takes these fields:

- `package`: a package name, or a scoped name such as `@your-org/formatter`
- `version`: a version or range
- `registry`: a registry URL for a package that isn’t on the default registry

Claude Code fetches the package with your npm client. The package’s install scripts, such as `preinstall` or `postinstall`, never run, and its dependencies aren’t installed during the fetch. If the package has a supported lockfile beside its `package.json`, Claude Code installs those [Node.js package dependencies](plugins-loading.md#node-js-package-dependencies) in a separate step, also with scripts disabled.

```python
{
  "name": "formatter",
  "source": {
    "source": "npm",
    "package": "@your-org/formatter",
    "version": "^2.0.0",
    "registry": "https://npm.example.com"
  }
}
```


[​](#archive-plugin-source)

archive plugin source

`url` must use `https://` and can’t point at a loopback, link-local, or cloud-metadata host. For the size, timeout, redirect, and extraction limits on the download, see [Stay within the download limits for hosted files](plugins-host-marketplace.md#stay-within-the-download-limits-for-hosted-files). The plugin root may be at the top of the zip or one directory down. `sha256` is the archive’s digest as 64 hex characters, uppercase or lowercase. When you set it, Claude Code refuses a download that doesn’t match.

```python
{
  "name": "formatter",
  "source": {
    "source": "archive",
    "url": "https://artifacts.example.com/formatter-2.0.0.zip",
    "sha256": "6bfa50e3d2e00c052b46abe51fff89346ac803e45771f76dcf6df1ab74cca5e1"
  }
}
```


[​](#command-plugin-source)

command plugin source

Use a `command` source when a tool installed on the user’s machine produces the plugin directory, such as an IDE that renders its plugin for the toolchain the user has selected. Claude Code runs the command when the user installs or updates the plugin, and [again once per session](plugins-loading.md#when-a-command-source-re-runs), so users get the tool’s changed output without reinstalling. A `command` source takes these fields:

- `command`: a shell command that prints the plugin directory’s absolute path as one line and exits 0. Claude Code shows users the whole string for review before it runs. Write it as printable ASCII, at most 500 characters, with no run of four or more spaces.
- `timeout`: a whole number of seconds from 1 to 600. Defaults to 60.
- `mode`: `copy`, the default, or `link`. See [Copy mode and link mode](#copy-mode-and-link-mode).

```python
{
  "name": "formatter",
  "source": {
    "source": "command",
    "command": "my-tool claude-plugin-path",
    "timeout": 120
  }
}
```

For how users accept the command, see [Install from your shell](discover-plugins.md#install-from-your-shell). For what users see after you change it, see [Change the command of a command source](plugins-host-marketplace.md#change-the-command-of-a-command-source). Administrators turn command sources off with [`disableCommandPluginSources`](../02-Claude-Code-CLI/settings-reference.md#disablecommandpluginsources).


[​](#what-the-command-must-do)

What the command must do

Write the command to meet these requirements:

- **Shell and working directory**: Claude Code runs the command through `sh`, or through `cmd.exe` on Windows, from the user’s home directory. Give an absolute path or a command on `PATH`.
- **Output**: print exactly one line on stdout, the absolute path of the plugin directory, and exit 0 within `timeout` seconds.
- **Directory contents**: the directory holds the complete plugin by the time the command exits. The path can differ from one run to the next.


[​](#output-that-fails-the-install-or-update)

Output that fails the install or update

The install or update fails when the command exits non-zero, runs longer than `timeout`, or prints anything other than one absolute path. It also fails when the printed directory is one of these:

- **No plugin content**: the printed directory has no plugin content at its top level, such as a `.claude-plugin/` directory or a `skills/`, `commands/`, `agents/`, or `hooks/` directory.
- **The session’s own directory**: the printed directory is the one Claude Code was started in, or one of its parents.
- **A network path**: on Windows, the printed path is a UNC path.
- **Too large to copy**: in copy mode, the directory is larger than 256 MiB or has more than 20,000 entries.


[​](#copy-mode-and-link-mode)

Copy mode and link mode

`mode` decides whether Claude Code copies the printed directory or uses it in place:

- **`copy`**: Claude Code copies the directory into the plugin cache and derives the [plugin version](plugins-loading.md#how-claude-code-computes-the-version) from a hash of the copied files. Your tool can delete or rewrite the directory after the command exits. A re-run that produces identical files counts as up to date.
- **`link`**: Claude Code fills the plugin’s cache entry with a link to each top-level entry of the printed directory and loads the files in place. Nothing is copied, file contents aren’t hashed, and the size limits don’t apply. Use it for a directory too large to copy, such as a rendered SDK export.

A link-mode plugin has these requirements:

- **Keep the directory in place**: Claude Code loads the plugin through the links at every startup, so the printed directory must stay where it is for as long as the plugin stays installed.
- **Print a different path to signal new content**: the version comes from the printed directory’s real path and its top-level entries, not from the files inside them.
- **Keep top-level symlinks inside the directory**: the install fails if a top-level entry is a symlink that points outside the printed directory.
- **Include `node_modules`**: Claude Code skips the [Node.js package dependency install](plugins-loading.md#node-js-package-dependencies) for a link-mode plugin, so print a directory that already contains the packages the plugin needs.
- **Sessions started inside the directory**: a session started in the printed directory or anywhere below it doesn’t load the plugin.
- **Not on Windows**: Claude Code refuses to install a link-mode plugin on Windows. Declare `"mode": "copy"` there.


[​](#marketplace-sources)

Marketplace sources

A marketplace source says where Claude Code fetches a `marketplace.json` from. The CLI builds one for you when you add a marketplace, and you write one yourself in settings:

- **[`claude plugin marketplace add`](plugins-cli-reference.md)**: Claude Code builds the source from the string you pass.
- **[`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces)**: you write the source yourself as the `source` object.
- **[`strictKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#strictknownmarketplaces) and [`blockedMarketplaces`](plugins-org.md#restrict-what-users-can-install)**: administrators write sources in these two policy lists. `strictKnownMarketplaces` is the allowlist and `blockedMarketplaces` is the blocklist.

The type names `url`, `git`, and `github` mean something different in a marketplace source than in a [plugin source](#plugin-sources):

| Type name | As a marketplace source                                                                       | As a plugin source                                                       |
|:----------|:----------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------|
| `url`     | A direct link to a `marketplace.json` file, with fields `url`, `headers`, and `headersHelper` | A git repository to clone, with fields `url`, `ref`, and `sha`           |
| `git`     | A git repository to clone, with fields `url`, `ref`, `path`, and `sparsePaths`                | Doesn’t exist                                                            |
| `github`  | A GitHub repository, with fields `repo`, `ref`, `path`, and `sparsePaths`                     | A GitHub repository, with fields `repo`, `ref`, and `sha`, and no `path` |

The table lists every marketplace source type with its fields, the `claude plugin marketplace add` input that produces it, and what it does in each of the three settings keys.

| Type          | Fields                               | `marketplace add` input                                                                                                                                             | `extraKnownMarketplaces`                                     | `strictKnownMarketplaces`                                                                                                                                                                                                 | `blockedMarketplaces`                                                  |
|:--------------|:-------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------|
| `url`         | `url`, `headers`, `headersHelper`    | An `http://` or `https://` URL that doesn’t match a git form                                                                                                        | Loads                                                        | Allows the same URL                                                                                                                                                                                                       | Blocks the same URL                                                    |
| `github`      | `repo`, `ref`, `path`, `sparsePaths` | `owner/repo`, `owner/repo@ref`, or `owner/repo#ref`                                                                                                                 | Loads                                                        | Allows the same `repo`, `ref`, and `path`. `repo` may be `owner/*`                                                                                                                                                        | Blocks the same, and a `git` URL to the same repository                |
| `git`         | `url`, `ref`, `path`, `sparsePaths`  | A `user@host:path` URL, or an `http://` or `https://` URL that ends in `.git`, contains `/_git/`, or names a github.com or gitlab.com repository. `#ref` pins a ref | Loads                                                        | Allows the same URL, `ref`, and `path`                                                                                                                                                                                    | Blocks the same, and other spellings of the same github.com repository |
| `npm`         | `package`                            | Not produced                                                                                                                                                        | Fails to load: `NPM marketplace sources not yet implemented` | Parses but matches nothing, because nothing registers an `npm` marketplace                                                                                                                                                | Parses but matches nothing                                             |
| `file`        | `path`                               | A path to a `.json` file                                                                                                                                            | Loads                                                        | Allows the same path                                                                                                                                                                                                      | Blocks the same path                                                   |
| `directory`   | `path`                               | A path to a directory                                                                                                                                               | Loads                                                        | Allows the same path                                                                                                                                                                                                      | Blocks the same path                                                   |
| `settings`    | `name`, `plugins`, `owner`           | Not produced                                                                                                                                                        | Loads                                                        | Allows an entry with the same `name` and identical `plugins`                                                                                                                                                              | Blocks the same `name`                                                 |
| `skills-dir`  | none                                 | Not produced                                                                                                                                                        | Fails to load: `Unsupported marketplace source type`         | Keeps [skills-directory plugins](plugins-org.md#keep-skills-directory-plugins-loading) loading while an allowlist is set. See [Source values valid only in policy lists](#source-values-valid-only-in-policy-lists) | Stops skills-directory plugins from loading                            |
| `hostPattern` | `hostPattern`                        | Not produced                                                                                                                                                        | Fails to load: `Unsupported marketplace source type`         | Allows `github`, `git`, and `url` sources whose host matches                                                                                                                                                              | Blocks those sources                                                   |
| `pathPattern` | `pathPattern`                        | Not produced                                                                                                                                                        | Fails to load: `Unsupported marketplace source type`         | Allows `file` and `directory` sources whose `path` matches                                                                                                                                                                | Blocks those sources                                                   |


[​](#fields-by-type)

Fields by type

The table lists each marketplace source field that has a default, a constraint, or a meaning specific to its type.

| Field           | Types           | Description                                                                                                                                                                                                                                                                                                                                                    |
|:----------------|:----------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `url`           | `url`           | Link to the `marketplace.json` file. Claude Code downloads only that file, so the marketplace’s plugins can’t use [relative-path sources](#relative-path-plugin-source). See [Stay within the download limits for hosted files](plugins-host-marketplace.md#stay-within-the-download-limits-for-hosted-files) for the size, timeout, and redirect limits |
| `url`           | `git`           | The git repository to clone                                                                                                                                                                                                                                                                                                                                    |
| `headers`       | `url`           | Map of HTTP headers Claude Code sends with the fetch, for authenticated hosts                                                                                                                                                                                                                                                                                  |
| `headersHelper` | `url`           | Command that prints headers whose values are too short-lived to list in `headers`. Requires Claude Code v2.1.238 or later. See [Authenticate archive downloads](plugins-host-marketplace.md#authenticate-archive-downloads)                                                                                                                              |
| `repo`          | `github`        | In `marketplace add` and `extraKnownMarketplaces`, `repo` must name one repository. `marketplace add` rejects `owner/*` as not a valid `owner/repo` shorthand; in `extraKnownMarketplaces` Claude Code takes it literally and the clone fails                                                                                                                  |
| `ref`           | `github`, `git` | Branch or tag. Defaults to the repository’s default branch                                                                                                                                                                                                                                                                                                     |
| `path`          | `github`, `git` | The marketplace file’s path inside the repository. Defaults to `.claude-plugin/marketplace.json`                                                                                                                                                                                                                                                               |
| `path`          | `file`          | The marketplace file itself. Claude Code reads it in place and takes the directory two levels up as the marketplace root, so keep the file at `<root>/.claude-plugin/marketplace.json`                                                                                                                                                                         |
| `path`          | `directory`     | The marketplace root, the directory that contains `.claude-plugin/marketplace.json`                                                                                                                                                                                                                                                                            |
| `sparsePaths`   | `github`, `git` | Array of directories for a sparse checkout, such as `[".claude-plugin", "plugins"]`. `claude plugin marketplace add --sparse` sets it                                                                                                                                                                                                                          |
| `skipLfs`       | `github`, `git` | Accepted and has no effect. See [Keep plugin files out of Git LFS](plugins-host-marketplace.md#keep-plugin-files-out-of-git-lfs)                                                                                                                                                                                                                         |
| `name`          | `settings`      | Must equal the `extraKnownMarketplaces` key and can’t be a [reserved name](#reserved-names)                                                                                                                                                                                                                                                                    |
| `plugins`       | `settings`      | The inline catalog, with no hosted file. Each item takes `name`, `source`, `description`, `version`, `strict`, `headers`, and `headersHelper`. Write each item’s `source` as an object type, because a relative path has no repository to resolve against                                                                                                      |


[​](#source-values-valid-only-in-policy-lists)

Source values valid only in policy lists

`hostPattern`, `pathPattern`, `skills-dir`, and the `owner/*` form of `repo` are valid only in the two policy lists, `strictKnownMarketplaces` and `blockedMarketplaces`:

- **`hostPattern` and `pathPattern`**: regular expressions Claude Code tests against a source before it fetches from it.
- **`skills-dir`**: not a source. If you set `strictKnownMarketplaces` at all, [skills-directory plugins](plugins-org.md#keep-skills-directory-plugins-loading) stop loading until you add `{"source": "skills-dir"}` to that list.
- **`owner/*`**: as a `github` `repo` value, matches every repository under exactly that GitHub owner. Requires Claude Code v2.1.223 or later.

For match order, exact-`ref` semantics, and recipes, see [Manage plugins for your organization](plugins-org.md).


[​](#source-objects-in-settings)

Source objects in settings

An `extraKnownMarketplaces` value is a map from marketplace name to an object with `source`. This entry registers a marketplace from a git repository at its `main` branch:

```python
{
  "extraKnownMarketplaces": {
    "your-marketplace": {
      "source": {
        "source": "git",
        "url": "https://git.example.com/your-org/your-marketplace.git",
        "ref": "main"
      }
    }
  }
}
```

`strictKnownMarketplaces` and `blockedMarketplaces` are arrays of source objects. This allowlist admits one GitHub owner and one internal host:

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "your-org/*" },
    { "source": "hostPattern", "hostPattern": "^git\\.example\\.com$" }
  ]
}
```


[​](#validation-messages)

Validation messages

`claude plugin validate <path>` takes the marketplace root or the marketplace file itself. It prints errors and warnings. For exit codes and `--strict`, see [plugin validate](plugins-cli-reference.md#plugin-validate). A message names a plugin entry by its index, written as `plugins.1.source` or `plugins[1].source`. A message prefixed with an entry index and `plugin.json →`, such as `plugins[2] plugin.json →`, is about that plugin’s own files. [`claude plugin validate` reports errors](plugins-troubleshooting.md#claude-plugin-validate-reports-errors) lists those messages with their fixes. Warnings that mention Claude Desktop flag names that Claude Desktop rejects. The table maps marketplace-level messages to the field each is about.

| Message                                                                                                                                                                                                                                          | Level   | Field                                                                                                                |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------------------------------------------------------------------------------------------------------------------|
| `Marketplace must have a name`                                                                                                                                                                                                                   | Error   | `name` is empty                                                                                                      |
| `Marketplace name cannot contain spaces. Use kebab-case (e.g., "my-marketplace")`                                                                                                                                                                | Error   | `name`                                                                                                               |
| `Marketplace name cannot contain path separators (/ or \), ".." sequences, or be "."`                                                                                                                                                            | Error   | `name`                                                                                                               |
| `Marketplace name impersonates an official Anthropic/Claude marketplace`                                                                                                                                                                         | Error   | `name`. See [Reserved names](#reserved-names)                                                                        |
| `Marketplace name cannot contain control or bidirectional-formatting characters`                                                                                                                                                                 | Error   | `name` contains a control character, such as an escape or a newline, or a Unicode bidirectional-formatting character |
| `Marketplace name "inline" is reserved for --plugin-dir session plugins`, and the `builtin`, `skills-dir`, `synced`, `claude-plugin-test`, `npm`, `pip`, `uv`, `cargo`, `github`, and `gh` variants                                              | Error   | `name`                                                                                                               |
| `Author name cannot be empty`                                                                                                                                                                                                                    | Error   | `owner.name`                                                                                                         |
| `Plugin name cannot contain spaces. Use kebab-case (e.g., "my-plugin")`                                                                                                                                                                          | Error   | `plugins[i].name`                                                                                                    |
| `Plugin name cannot contain control or bidirectional-formatting characters`                                                                                                                                                                      | Error   | `plugins[i].name`                                                                                                    |
| `Claude Code cannot install plugins from marketplace "x". Each part of a plugin id (plugin@marketplace) may use only the letters a-z and A-Z, digits, ".", "_" and "-", and must start with a letter or digit. Change the marketplace's "name".` | Error   | `name`                                                                                                               |
| `Claude Code cannot install plugin "x". Each part of a plugin id (plugin@marketplace) may use only the letters a-z and A-Z, digits, ".", "_" and "-", and must start with a letter or digit. Change this entry's "name".`                        | Error   | `plugins[i].name`                                                                                                    |
| `Duplicate plugin name "x" found in marketplace`                                                                                                                                                                                                 | Error   | Two entries share a `name`                                                                                           |
| `plugins.i.source: Invalid input`                                                                                                                                                                                                                | Error   | The entry’s `source` matches no type. See [Invalid input on a source](#invalid-input-on-a-source)                    |
| `plugins[i].source: Path contains "..": <path>`                                                                                                                                                                                                  | Error   | A relative `source` that escapes the marketplace root                                                                |
| `source.source: 'unsupported' is a parse-time placeholder and cannot be authored`                                                                                                                                                                | Error   | `plugins[i].source`                                                                                                  |
| `Plugin "x" sets headersHelper but is not "strict": false`                                                                                                                                                                                       | Error   | `plugins[i].headersHelper`, on an `archive` entry                                                                    |
| `chain does not resolve (<reason>) — target must be a name in plugins[], a key in renames, or null`                                                                                                                                              | Error   | `renames.<old>`                                                                                                      |
| `target "x" is not a valid plugin name (PluginIdSchema)`                                                                                                                                                                                         | Error   | `renames.<old>`                                                                                                      |
| `Unknown field 'x'. Claude Code ignores it at load time.`                                                                                                                                                                                        | Warning | The named key at the top level, under `metadata`, in an entry, or under an entry’s `relevance`                       |
| `Marketplace has no plugins defined`                                                                                                                                                                                                             | Warning | `plugins` is empty                                                                                                   |
| `Plugin "x" sets headers/headersHelper, which only apply to "archive" sources; they have no effect on this entry.`                                                                                                                               | Warning | `plugins[i].headers` or `plugins[i].headersHelper`, on an entry whose `source` isn’t `archive`                       |
| `Plugin "x" fetches its archive with a headersHelper but sets no sha256 pin`                                                                                                                                                                     | Warning | `plugins[i].source.sha256`                                                                                           |
| `Header "x" is a request-routing/identity header that catalog entries may not set; Claude Code drops it at download time.`                                                                                                                       | Warning | `plugins[i].headers.<name>`                                                                                          |
| `Local source "x" is or traverses a symlink, so <path> was not read`                                                                                                                                                                             | Warning | `plugins[i].source`                                                                                                  |
| `No marketplace description provided. Adding a description helps users understand what this marketplace offers`                                                                                                                                  | Warning | `description`                                                                                                        |
| `Entry declares version "x" but <path>/plugin.json says "y". At install time, plugin.json wins`                                                                                                                                                  | Warning | `plugins[i].version`, on a relative-path entry                                                                       |
| `'relevance' must be an object containing topic and signals; got <type>. It will be ignored at load time.`                                                                                                                                       | Warning | `plugins[i].relevance`                                                                                               |
| `'metadata' must be a free-form object; got <type>. It will be ignored at load time.`                                                                                                                                                            | Warning | `plugins[i].metadata`                                                                                                |
| `'experimental' must be an object containing component declarations; got <type>. It will be ignored at load time.`                                                                                                                               | Warning | `plugins[i].experimental`                                                                                            |
| `Marketplace name "x" is reserved in Claude Desktop`                                                                                                                                                                                             | Warning | `name` is `org`, `org-provisioned`, or `unknown`. Claude Desktop rejects the marketplace                             |
| `Marketplace name "x" is not accepted by Claude Desktop (letters, digits, ".", "_", "-"; must start alphanumeric; max 128 chars)`                                                                                                                | Warning | `name`. Claude Desktop rejects the marketplace                                                                       |
| `Plugin name "x" is not accepted by Claude Desktop (letters, digits, ".", "_", "-"; must start alphanumeric; max 128 chars)`                                                                                                                     | Warning | `plugins[i].name`. Claude Desktop drops the entry                                                                    |


[​](#invalid-input-on-a-source)

Invalid input on a source

`Invalid input` on a `source` means the object matched no source type. Check for these causes:

- A relative path that doesn’t start with `./`, other than `"."` or a [bare name under `metadata.pluginRoot`](#relative-path-plugin-source)
- An `npm` `package` containing `..`
- A `source` type that isn’t one of the [plugin sources](#plugin-sources)
- A known type with a required field missing or of the wrong type, such as `github` without `repo`


[​](#failures-that-validation-doesn’t-catch)

Failures that validation doesn’t catch

`claude plugin validate` doesn’t report every failure. An entry `hooks` written as a file path or array passes validation, and the error appears only when the plugin loads, as [Hooks in an entry](#hooks-in-an-entry) describes. Errors fetching a `source` also appear only after install, not in validation. [`claude plugin list`](plugins-cli-reference.md) shows a plugin that failed to load with its error, and [Troubleshoot plugins](plugins-troubleshooting.md) covers the load-time strings.


[​](#next-steps)

Next steps

- [Create a marketplace](plugin-marketplaces.md): build a marketplace from these fields and install from it locally
- [Host and maintain a marketplace](plugins-host-marketplace.md): where to put the file and how users receive changes
- [Plugin manifest reference](plugins-reference.md): the `plugin.json` fields an entry can override
- [Manage plugins for your organization](plugins-org.md): allowlist and blocklist recipes that use these source values

---

## Measure plugin cost and usage - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/measure
Path: 08-Plugins-Skills/plugins-measure.md

## On this page

- [Measure what a plugin costs](#measure-what-a-plugin-costs)
  - [Lower the always-on figure](#lower-the-always-on-figure)
  - [Cost shown to users before install](#cost-shown-to-users-before-install)
- [Check whether a plugin is used](#check-whether-a-plugin-is-used)
  - [Not used recently in /plugin](#not-used-recently-in-%2Fplugin)
  - [Find skills that never run](#find-skills-that-never-run)
  - [Unused plugins in /doctor](#unused-plugins-in-%2Fdoctor)
  - [Usage share in /usage](#usage-share-in-%2Fusage)
- [Measure across a fleet](#measure-across-a-fleet)
  - [OpenTelemetry events for plugin installs and use](#pick-the-opentelemetry-event-for-each-question)
  - [Redacted plugin names in your backend](#redacted-plugin-names-in-your-backend)
  - [Query the Analytics API](#query-the-analytics-api)
- [Next steps](#next-steps)

Create plugins

# Measure plugin cost and usage

Copy pageCopy page

Measure a Claude Code plugin’s token cost, find out whether people still use it, and pick the telemetry events for organization-wide plugin questions.

Copy pageCopy page

Every session where a plugin is enabled includes the names and descriptions of its skills, agents, and commands in Claude’s context, and those tokens count against the user’s usage whether or not the plugin gets used. This page shows how to see that number for a plugin, how to reduce it if you maintain the plugin, and where usage shows up so you can tell whether a plugin is still being used. This page is for plugin authors and maintainers. If you administer Claude Code for an organization, [Measure across a fleet](#measure-across-a-fleet) covers the same questions across every machine.

These cases are covered on other pages:

- **Testing how reliably the plugin changes Claude’s behavior**: see [Test plugins with evals](plugin-evals.md)
- **Trimming your own session’s context**: see [Manage installed plugins](discover-plugins.md#manage-installed-plugins) and the [context window](../02-Claude-Code-CLI/context-window.md) page

Start with [Measure what a plugin costs](#measure-what-a-plugin-costs).


[​](#measure-what-a-plugin-costs)

Measure what a plugin costs

To see what a plugin adds to Claude’s context, run [`claude plugin details`](plugins-cli-reference.md#plugin-details) with the plugin’s name. You run it in your shell, not at the prompt of a running Claude Code session. The plugin has to be loaded: installed, in a skills directory, or passed with `--plugin-dir` in the same command, as in `claude --plugin-dir ./formatter plugin details formatter`. This example reads an installed plugin named `formatter` that has two skills, a command, an agent, a hook, and an MCP server:

```python
claude plugin details formatter
```

```python
formatter 1.0.0
  Description: Formats and lints code on save
  Source: formatter@my-marketplace

Component inventory
  Skills (3)  format-all, format-code, lint-fix
  Agents (1)  style-reviewer
  Hooks (1)  PostToolUse  (harness-only — no model context cost)
  MCP servers (1)  formatter-tools  (tool schemas resolved at runtime; not counted)
  LSP servers (0)

Projected token cost
  Always-on:   ~146 tok   added to every session

Per-component (rounded)
  component       always-on  on-invoke
  format-code           ~40        ~30
  lint-fix              ~50        ~30
  style-reviewer        ~40        ~40
  format-all           < 20        ~30

  On-invoke cost is paid each time a skill or agent fires.
  Token counts are estimates and may differ from actual usage.
```

Each part of the output answers a different question:

- **Component inventory**: what Claude Code found in the plugin. Commands are counted with skills, so `format-all` appears under `Skills`. Hooks and MCP servers get no cost estimate and no per-component row; to see what a plugin’s MCP tools add, run `/context` in a session with the plugin enabled and read the `MCP tools` category.
- **Always-on**: the tokens that the names and descriptions of the plugin’s skills, agents, and commands add to every session where the plugin is enabled, whether or not anything runs. This is the number every user carries, and the one to reduce.
- **Per-component**: each row splits one skill, agent, or command into its always-on share and its on-invoke cost, which is the body that loads only when that component runs. Use the always-on column to find which component contributes most.


[​](#lower-the-always-on-figure)

Lower the always-on figure

If you maintain the plugin, these changes reduce what it adds to every session. If you only use it, your options are to disable or uninstall it; see [Manage installed plugins](discover-plugins.md#manage-installed-plugins). The always-on figure counts each component’s name plus its `description` and `when_to_use` frontmatter. To lower it:

- Shorten skill and agent descriptions.
- Split a large plugin so users install only the components they need.

A skill’s description is also what Claude matches a request against, so a shorter one can stop the skill triggering. After you trim descriptions, check triggering with a [`tool_used: Skill` grader](plugin-evals.md#create-your-first-eval-suite) in your eval suite. For what each component type contributes, see [plugin components](plugins-components.md).


[​](#cost-shown-to-users-before-install)

Cost shown to users before install

Plugins in the official marketplace show their cost to users before install. In `/plugin`, when a user browses a marketplace’s plugin list and selects a plugin, the details pane shows a **Context cost** section with an `Every turn:` line and a `When invoked:` line. When the always-on figure is 2,000 tokens or more, the `Every turn:` line appears highlighted. A plugin in your own marketplace has no **Context cost** section.


[​](#check-whether-a-plugin-is-used)

Check whether a plugin is used

Claude Code doesn’t report a plugin’s usage back to its author. Usage is recorded on the machine of each person who installed the plugin, so what you can learn depends on your relationship to those people:

- **You administer Claude Code for their organization**: the OpenTelemetry events and the Analytics API count installs and skill activations across every machine. See [Measure across a fleet](#measure-across-a-fleet).
- **They’re teammates you can ask**: each user’s own Claude Code shows them whether they still use the plugin, in four places: the [`/plugin` panel](#not-used-recently-in-/plugin), [`/skill-doctor`](#find-skills-that-never-run), [`/doctor`](#unused-plugins-in-/doctor), and [`/usage`](#usage-share-in-/usage). All four are commands the user runs at the Claude Code prompt in a session on their own machine.
- **Neither**: you have no usage signal from Claude Code for that plugin.

For usage of a plugin listed in Anthropic’s directory, see [Track published plugin usage](https://claude.com/docs/connectors/building/after-publishing#track-published-plugin-usage) on claude.com.


[​](#not-used-recently-in-/plugin)

Not used recently in `/plugin`

On the **Installed** tab of `/plugin`, a plugin the user installed from a marketplace moves under a **Not used recently** header once it has gone unused for at least 14 days and 10 sessions. The plugin’s details also show a `Last used:` line. For what users do with that header and line, see [Find plugins you no longer use](discover-plugins.md#find-plugins-you-no-longer-use). The **Not used recently** header never appears for:

- Plugins loaded with `--plugin-dir` or from a skills directory
- Plugins enabled through managed settings, or mounted from a [seed directory](plugins-org.md#seed-containers-and-ci)
- Plugins that include a theme, output style, monitor, or workflow, because those are in use without a tracked invocation

A plugin’s [language server](plugins-components.md#lsp-servers) counts as used when it delivers diagnostics or answers a code navigation request, so an LSP plugin whose server is active in your sessions isn’t listed as unused. When the user’s organization sets [`strictKnownMarketplaces`](plugins-org.md#restrict-what-users-can-install), neither the header nor the `Last used:` line appears.


[​](#find-skills-that-never-run)

Find skills that never run

Run `/skill-doctor` to see what each of your skills costs and how often it gets used. It flags skills that are in Claude’s skill listing but have never been invoked, including skills from plugins. In an interactive session, the report opens in the `/plugin` manager’s **Stats** tab. See [Find unused skills](skills.md#find-unused-skills) for what the report covers and where it’s available.


[​](#unused-plugins-in-/doctor)

Unused plugins in `/doctor`

The `/doctor` checkup lists each user-installed skill, MCP server, and plugin, and recommends disabling the ones that were not used. See [`/doctor` in the commands reference](../02-Claude-Code-CLI/commands.md#all-commands).


[​](#usage-share-in-/usage)

Usage share in `/usage`

On a Pro, Max, Team, or Enterprise plan, the `/usage` breakdown attributes recent usage to skills, subagents, plugins, and MCP servers as a share of the total. See [Using the `/usage` command](../17-Billing-Plans/costs.md#using-the-/usage-command).


[​](#measure-across-a-fleet)

Measure across a fleet

If you administer Claude Code for an organization, you can measure plugin cost and usage across every machine from either of these sources:

- **OpenTelemetry events**: Claude Code exports these to your own backend once you [configure an exporter](../13-Enterprise-Admin/monitoring-usage.md). See [OpenTelemetry events for plugin installs and use](#pick-the-opentelemetry-event-for-each-question).
- **Analytics API**: served from Anthropic’s records, with no exporter needed. See [Query the Analytics API](#query-the-analytics-api).


[​](#pick-the-opentelemetry-event-for-each-question)

OpenTelemetry events for plugin installs and use

These OpenTelemetry events and attributes answer each plugin question from your backend:

| Question                                          | OpenTelemetry event or attribute                                                                                                                              |
|:--------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Which plugins get installed, and from where       | [`claude_code.plugin_installed`](../13-Enterprise-Admin/monitoring-usage.md#plugin-installed-event), one per install                                                           |
| Which plugins are active in how many sessions     | [`claude_code.plugin_loaded`](../13-Enterprise-Admin/monitoring-usage.md#plugin-loaded-event), one per enabled plugin at session start                                         |
| Which skills activate, and which plugin owns them | [`claude_code.skill_activated`](../13-Enterprise-Admin/monitoring-usage.md#skill-activated-event), with `plugin.name` and `marketplace.name` for plugin skills                 |
| What a plugin’s hooks report                      | [`claude_code.hook_plugin_metrics`](../13-Enterprise-Admin/monitoring-usage.md#hook-plugin-metrics-event), emitted only for hooks in official-marketplace plugins              |
| What a plugin costs in API spend                  | `plugin.name` and `marketplace.name` on the [cost counter](../13-Enterprise-Admin/monitoring-usage.md#cost-counter), set when the active skill or subagent belongs to a plugin |


[​](#redacted-plugin-names-in-your-backend)

Redacted plugin names in your backend

Plugins from the official marketplace report their plugin name and marketplace name to your backend verbatim. Every other plugin’s name is redacted or omitted by default, including a plugin from your organization’s own marketplace. The plugin’s [trust tier](plugins-security.md#find-plugins-in-telemetry) decides which. To get real names on some events, set the [`OTEL_LOG_TOOL_DETAILS`](../13-Enterprise-Admin/monitoring-usage.md#common-configuration-variables) environment variable to `1` on the machines that export telemetry, for example in the `env` block of the same [managed settings](../13-Enterprise-Admin/monitoring-usage.md#administrator-configuration) that configure the exporter:

| Event                                 | Default                                                                                            | With `OTEL_LOG_TOOL_DETAILS=1`                      |
|:--------------------------------------|:---------------------------------------------------------------------------------------------------|:----------------------------------------------------|
| `plugin_loaded`                       | `plugin.name` and `marketplace.name` are the literal string `third-party`                          | Real names                                          |
| `plugin_installed`, `skill_activated` | `plugin.name` and `marketplace.name` omitted; on `skill_activated`, `skill.name` is `custom_skill` | Real names                                          |
| Cost counter                          | `plugin.name` is `third-party`; `marketplace.name` absent                                          | Real `plugin.name`; `marketplace.name` still absent |

On `plugin_loaded`, `plugin_id_hash` still identifies each plugin by default, so you can count distinct third-party plugins.


[​](#query-the-analytics-api)

Query the Analytics API

On the Enterprise plan, the Analytics API answers “which plugins does my organization install and invoke” from Anthropic’s records, with no exporter needed. [`GET /v1/organizations/analytics/plugins`](../04-API-Reference/Admin/http-beta-organization-analytics-plugins-list.md) returns per-plugin, per-day install and invocation counts across Claude Code and Cowork, which you can group by user, RBAC group, or product. Plugin activity that reaches Anthropic without a plugin name appears in one aggregate `third-party` row. [Find plugins in telemetry](plugins-security.md#find-plugins-in-telemetry) says which plugins Claude Code reports by name. Authenticate the request with an API key that has the `read:analytics` scope, which a Primary Owner creates as described under [Access data programmatically](../13-Enterprise-Admin/analytics.md#access-data-programmatically). See the [endpoint reference](../04-API-Reference/Admin/http-beta-organization-analytics-plugins-list.md) for the parameters and response fields.


[​](#next-steps)

Next steps

- [Test plugins with evals](plugin-evals.md): measure how reliably the plugin steers Claude, not only what it costs
- [Lower the always-on figure](#lower-the-always-on-figure): what to change in the plugin to reduce its per-turn cost
- [Plugin security and trust](plugins-security.md#find-plugins-in-telemetry): which telemetry fields carry plugin names and when they’re redacted
- [Monitoring usage](../13-Enterprise-Admin/monitoring-usage.md): the full OpenTelemetry event reference

---

## Manage Claude Code plugins for your organization - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/org
Path: 08-Plugins-Skills/plugins-org.md

## On this page

- [Pre-install and require plugins](#pre-install-and-require-plugins)
  - [Choose a delivery mechanism](#choose-a-delivery-mechanism)
  - [Which managed source applies on a machine](#which-managed-source-applies-on-a-machine)
  - [Require a marketplace and its plugins](#require-a-marketplace-and-its-plugins)
  - [Require plugins per repository](#require-plugins-per-repository)
  - [When each surface applies the plugin keys](#when-each-surface-applies-the-plugin-keys)
  - [Confirm the rollout](#confirm-the-rollout)
- [Seed containers and CI](#seed-containers-and-ci)
- [Restrict what users can install](#restrict-what-users-can-install)
  - [Control matrix](#control-matrix)
  - [Aliases for the marketplace keys](#aliases-for-the-marketplace-keys)
  - [Allowlist with strictKnownMarketplaces](#allowlist-with-strictknownmarketplaces)
  - [How entries match](#how-entries-match)
  - [Keep skills-directory plugins loading](#keep-skills-directory-plugins-loading)
  - [Marketplaces hosted on claude.ai](#marketplaces-hosted-on-claude-ai)
  - [Lock every source out](#lock-every-source-out)
  - [Blocklist with blockedMarketplaces](#blocklist-with-blockedmarketplaces)
  - [Allow the official marketplace and your own](#allow-the-official-marketplace-and-your-own)
- [Set update policy](#set-update-policy)
  - [Turn auto-update on or off per marketplace](#turn-auto-update-on-or-off-per-marketplace)
  - [Turn updates off for the whole fleet](#turn-updates-off-for-the-whole-fleet)
  - [Assign release channels to user groups](#assign-release-channels-to-user-groups)
- [Recommend plugins](#recommend-plugins)
- [Audit and review](#audit-and-review)
  - [OpenTelemetry events](#opentelemetry-events)
  - [Analytics API](#analytics-api)
- [Plan for what managed settings can’t enforce](#plan-for-what-managed-settings-can%E2%80%99t-enforce)
- [Troubleshoot policy](#troubleshoot-policy)
- [Next steps](#next-steps)

Manage plugins for your organization

# Manage Claude Code plugins for your organization

Copy pageCopy page

Control which plugins Claude Code installs and allows across your organization through managed settings.

Copy pageCopy page

Managed settings let you decide which plugins Claude Code installs and allows on every machine in your organization. Users can’t override them. You deliver them either as [server-managed settings](../13-Enterprise-Admin/server-managed-settings.md) from the claude.ai admin console or as endpoint-managed settings through MDM or a `managed-settings.json` file. Most controls on this page take effect only from managed settings. This page is for administrators, and the settings here govern Claude Code.

These cases are covered on other pages:

- **Installing plugins for yourself**: start at [Install plugins](discover-plugins.md)
- **Controlling which plugins members can use in claude.ai and Cowork**: see [Manage plugins for your organization](https://claude.com/docs/plugins/admin) on claude.com
- **Rolling one plugin out to claude.ai, Cowork, and Claude Code together**: see [Choose a rollout route](https://claude.com/docs/plugins/org-rollout#choose-a-rollout-route) on claude.com
- **The plugins page in claude.ai’s admin settings**: [**Organization settings \> Plugins & skills**](https://claude.ai/admin-settings/skills?tab=inventory) turns plugins on for members’ claude.ai accounts, and those reach Claude Code as [synced plugins](plugins-loading.md#synced-plugins). It doesn’t set any of the keys on this page

The sections follow the order most rollouts take: [require plugins](#pre-install-and-require-plugins) for everyone or per repository, [seed containers and CI](#seed-containers-and-ci), [restrict](#restrict-what-users-can-install) what users can add on their own, [set update policy](#set-update-policy), then [audit](#audit-and-review) what’s installed. To review every policy key in one place, see the [control matrix](#control-matrix).


[​](#pre-install-and-require-plugins)

Pre-install and require plugins

A marketplace is a catalog of plugins that Claude Code fetches from a git repository, a URL, or a local path. Once you register a marketplace on a machine, Claude Code can install plugins from it. To install plugins for a fleet, set two keys together in [managed settings](../13-Enterprise-Admin/managed-settings.md), the policy file or server-delivered policy that every machine in your organization reads: `extraKnownMarketplaces` registers a marketplace on each machine, and `enabledPlugins` names the plugins to install and enable from it. [Choose a delivery mechanism](#choose-a-delivery-mechanism) covers how managed settings reach each machine.


[​](#choose-a-delivery-mechanism)

Choose a delivery mechanism

Managed settings reach a machine through one of three delivery mechanisms:

- **Server-managed settings**: set the plugin keys as JSON at [**Organization settings \> Claude Code \> Managed settings**](https://claude.ai/admin-settings/claude-code). Requires an [Owner role](../13-Enterprise-Admin/server-managed-settings.md#access-control) in your Claude organization. A cloud session fetches these settings before it installs plugins.
- **MDM policies**: on macOS, deliver a plist whose top-level keys are the settings keys. On Windows, store the whole JSON document as a string in a registry value. The plist domain and the registry key are in [Where each mechanism stores the policy](../13-Enterprise-Admin/managed-settings.md#where-each-mechanism-stores-the-policy).
- **Managed settings file**: place a `managed-settings.json` at the platform’s system path. You can also add files to the `managed-settings.d/` drop-in directory beside it. The file paths per platform are in [Where each mechanism stores the policy](../13-Enterprise-Admin/managed-settings.md#where-each-mechanism-stores-the-policy), and the drop-in merge rules are in [Split a file-based policy across teams](../13-Enterprise-Admin/managed-settings.md#split-a-file-based-policy-across-teams).

Use server-managed settings if you have a Claude for Teams or Enterprise organization on claude.ai and your devices aren’t all under MDM. Otherwise use an MDM policy or the managed settings file. For the trade-off, see [Choose between server-managed and endpoint-managed settings](../13-Enterprise-Admin/server-managed-settings.md#choose-between-server-managed-and-endpoint-managed-settings).


[​](#which-managed-source-applies-on-a-machine)

Which managed source applies on a machine

By default, only one of these three sources applies on a machine. Claude Code uses the first that delivers a policy key, checking server-managed settings first, then MDM policies, then the managed settings file. If server-managed settings deliver even one unrelated policy key, Claude Code ignores the plugin keys in an MDM policy or managed settings file on that machine, apart from the [keys it reads from every source](../13-Enterprise-Admin/managed-settings.md#keys-read-from-every-admin-source). To apply every source instead, set [`managedSourcesBehavior`](../13-Enterprise-Admin/managed-settings.md#compose-every-managed-source) to `"merge"`. [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#how-claude-code-combines-managed-sources) also lists the keys Claude Code reads from every source in both modes.


[​](#require-a-marketplace-and-its-plugins)

Require a marketplace and its plugins

Add the marketplace under `extraKnownMarketplaces`, keyed by the marketplace’s own `name` from its `marketplace.json`. Then add each plugin under `enabledPlugins` as `plugin-name@marketplace-name`. Each marketplace entry carries a `source` object with a `source` field naming the type, such as `github`. This managed settings example registers an organization marketplace and force-enables two plugins from it:

```python
{
  "extraKnownMarketplaces": {
    "your-marketplace": {
      "source": { "source": "github", "repo": "your-org/your-marketplace" },
      "autoUpdate": true
    }
  },
  "enabledPlugins": {
    "code-formatter@your-marketplace": true,
    "deploy-helper@your-marketplace": true
  }
}
```

After the settings reach a machine, Claude Code registers the marketplace and installs the two plugins at the start of the user’s next session. Users see them in `/plugin`, and disabling one at their own scope doesn’t stop it from loading, because managed settings take precedence over every other scope. To block a plugin at every scope and hide it from the marketplace listing, set it to `false` in the managed `enabledPlugins` instead. Adjust the `autoUpdate` and `source` fields for your marketplace:

- **`autoUpdate`**: `true` keeps the marketplace and its plugins refreshing in the background, and `false` turns that off. See [Set update policy](#set-update-policy).
- **`source`**: `github` is one of several source types. A `git` source takes a `url` for GitLab or an internal host, and a `url` source takes the address of a hosted `marketplace.json`. Every source shape is in the [marketplace reference](plugins-marketplace-reference.md).

If the marketplace is a private git repository, each user needs read access to it. The clone of a git-based marketplace runs with git on the user’s machine, using stored credentials and no prompts. For users without git-host accounts, use a [seed](#seed-containers-and-ci) instead. A managed entry also overrides a same-name marketplace entry or `--plugin-dir` copy from another source:

- **Marketplaces**: a managed marketplace entry replaces a lower-precedence entry with the same name, and the two entries’ fields don’t merge.
- **`--plugin-dir` copies**: `--plugin-dir` loads a plugin from a local directory for one session. For what happens when that copy’s name matches a plugin your managed `enabledPlugins` names, see [Name conflicts](plugins-loading.md#name-conflicts).

Anthropic’s official marketplace `claude-plugins-official` needs no `extraKnownMarketplaces` entry when `enabledPlugins` sets one of its plugins to `true`. That `name@claude-plugins-official` entry declares the marketplace by itself, wherever these keys apply. If you enable none of its plugins and still want it registered on every machine, give it an explicit entry, as [Allow the official marketplace and your own](#allow-the-official-marketplace-and-your-own) does.


[​](#require-plugins-per-repository)

Require plugins per repository

To cover one repository’s contributors instead of your whole fleet, set `extraKnownMarketplaces` and `enabledPlugins` in that repository’s `.claude/settings.json`. The `extraKnownMarketplaces` entries apply only in a folder the contributor has trusted, and in an untrusted folder Claude Code ignores them without a message:

- **Interactive sessions**: Claude Code registers the marketplace only after the contributor accepts the [workspace trust dialog](../02-Claude-Code-CLI/permissions.md#what-runs-before-you-trust-a-folder) for that folder.
- **[Non-interactive `-p` runs](../02-Claude-Code-CLI/headless.md)**: the entries apply only in a folder whose trust the user already accepted interactively, or whose `hasTrustDialogAccepted` flag you set in `~/.claude.json`.

A plugin that the marketplace lists by a relative path loads from the marketplace copy once the repository’s `extraKnownMarketplaces` entries apply. A plugin whose marketplace entry points at an external source instead, such as the plugin’s own GitHub repository, doesn’t install from the repository’s settings alone. Each contributor sees `Plugin "<name>" is enabled in project settings but isn't installed` until they run `claude plugin install <name>@<marketplace> --scope project`, as [Install plugins](discover-plugins.md) describes. If you use a local `directory` or `file` source with a relative path, the path resolves against your repository’s main checkout. When you run Claude Code from a git worktree, the path still points at the main checkout, so all worktrees share the same marketplace location. To roll out a bundle of plugins with dependencies, put the bundle plugin in `enabledPlugins`, as [Plugin dependencies](plugins-dependencies.md) describes.


[​](#when-each-surface-applies-the-plugin-keys)

When each surface applies the plugin keys

The table shows when each kind of Claude Code session applies `extraKnownMarketplaces` and `enabledPlugins`, from managed settings and from a repository’s `.claude/settings.json`. For the Desktop app and the IDE extensions, see [Install a plugin](discover-plugins.md#install-a-plugin).

| Surface               | Managed `extraKnownMarketplaces` and `enabledPlugins`                                                                                                                                                                                                                                                                                    | Repository `.claude/settings.json`                                                                |
|:----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------|
| Terminal, interactive | Applied at session start on every machine that receives the settings                                                                                                                                                                                                                                                                     | `extraKnownMarketplaces` applied after trust; `enabledPlugins` applied at session start           |
| `-p` and CI           | Applied at session start, with installs running in the background                                                                                                                                                                                                                                                                        | `extraKnownMarketplaces` in trusted folders only; `enabledPlugins` applied                        |
| Cloud sessions        | In an Anthropic-hosted environment, only server-managed settings reach the session, which waits for them before it installs plugins. MDM policies and managed settings files stay on the user’s machine. For a self-hosted environment, see [Where and when a policy applies](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies) | See the **Cloud session** tab under [Install a plugin](discover-plugins.md#install-a-plugin) |

In a `-p` or CI run, marketplaces and plugins install in the background, so a plugin can be missing from the first turn. Set `CLAUDE_CODE_SYNC_PLUGIN_INSTALL=1` to make the run wait for the install before its first query.


[​](#confirm-the-rollout)

Confirm the rollout

Check that the marketplace and plugins arrived on a machine or in a CI run:

- **On one machine**: start Claude Code and run `/plugin`. The marketplace and the plugins are listed.
- **In CI**: run `claude -p` with `--output-format stream-json --verbose`. The `init` event lists the loaded plugins under `plugins`.


[​](#seed-containers-and-ci)

Seed containers and CI

For container images and CI runners that can’t clone at runtime, pre-populate a plugins directory at build time and point `CLAUDE_CODE_PLUGIN_SEED_DIR` at it. Claude Code registers the seed’s marketplaces at startup and loads plugin caches from the seed in place, without cloning. A seed also serves users who have no git-host account.

In CI/CD environments, configure a git credential helper before installing plugins from private repositories. On GitHub Actions, export a token with read access to the marketplace repository as `GH_TOKEN`, then run `gh auth setup-git`. The default workflow token can only access the workflow’s own repository, so a private marketplace in another repository needs a personal access token or app token.

1

Install into the seed at build time

Set `CLAUDE_CODE_PLUGIN_CACHE_DIR` to the seed path so the marketplace and plugins install there instead of `~/.claude/plugins`:

```python
CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin marketplace add your-org/your-marketplace
CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin install code-formatter@your-marketplace
```

The seed has the same layout as `~/.claude/plugins`: `known_marketplaces.json`, `marketplaces/<name>/`, and `cache/<marketplace>/<plugin>/<version>/`. You can mount the seed at a different path than you built it at.

2

Point the runtime at the seed

Set `CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/claude-seed` in the container’s environment. To use several seeds, separate their paths with `:` on Unix or `;` on Windows. Claude Code uses the first seed that contains a given marketplace or plugin cache.

3

Enable the plugins

The plugins in a seed aren’t enabled on their own. Set `enabledPlugins` for each seed plugin you want loaded, in managed settings or in the repository’s `.claude/settings.json`.

To verify a seed, run `claude -p` with `--output-format stream-json --verbose` in the image. In the `init` event’s `plugins` list, each loaded plugin’s `path` is under the seed, such as `/opt/claude-seed/cache/your-marketplace/code-formatter/1.0.0`. Seed marketplaces follow these rules:

- **Read-only**: Claude Code never writes to the seed and forces `autoUpdate` off for seed marketplaces.
- **Seed entries take precedence**: on each startup, a marketplace declared in the seed overwrites the user’s entry of the same name. Users opt out of a seed plugin with `claude plugin disable`, not by removing the marketplace.
- **Update and remove fail**: `claude plugin marketplace update <name>` and `remove` without `--scope` on a seed marketplace fail with a message that names the seed directory.
- **Policy still applies**: the [allowlist and blocklist](#restrict-what-users-can-install) check a seed marketplace’s recorded source too. Allow the source you built the seed from.

For fleets with no outbound git access, combine a seed with `directory` or `file` marketplace sources on a shared mount. Set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` as well, which also turns off [plugin auto-update](plugins-loading.md#when-auto-update-runs). If a proxy is available, see [Proxy configuration](../13-Enterprise-Admin/network-config.md#proxy-configuration) for the variables to set.


[​](#restrict-what-users-can-install)

Restrict what users can install

The managed `strictKnownMarketplaces` allowlist and `blockedMarketplaces` blocklist decide which marketplace sources plugins may come from. A marketplace’s source is the git repository, URL, or local path that Claude Code fetches it from. Both lists match the source of the marketplace a plugin comes from, not the plugin’s own entry inside that marketplace. For the common lockdown, which allows the official marketplace and your own, see [Allow the official marketplace and your own](#allow-the-official-marketplace-and-your-own). Pair it with [`disableSideloadFlags`](#control-matrix) so users can’t load plugins from a local directory or URL either. Both lists apply before anything downloads and again at session start:

- **Before a download**: the lists apply when a user adds a marketplace and on every install, update, refresh, and auto-update.
- **At session start**: the lists apply again to plugins that are already installed, so an installed plugin whose marketplace source no longer matches doesn’t load. `/plugin` lists it with `Marketplace "<name>" is not in the allowed marketplace list` or `Marketplace "<name>" is blocked by enterprise policy`.

Where the two lists are enforced depends on where you set them:

- **The claude.ai admin console**: Claude Code enforces both lists in the sessions that [read server-managed settings](../13-Enterprise-Admin/managed-settings.md#where-and-when-a-policy-applies). claude.ai also checks them when anyone in your organization adds a new marketplace from a git repository on claude.ai, or from **Customize** in the Claude Desktop app outside its Code tab. That covers a marketplace a member adds for their own account and one added for the whole organization under [**Organization settings \> Plugins**](https://claude.ai/admin-settings/plugins). claude.ai refuses a repository that the allowlist doesn’t admit or that the blocklist names. It doesn’t re-check a marketplace that was added in either place before you set the lists, and it doesn’t check uploaded plugins.
- **A managed settings file, OS-level policy, or other managed source**: Claude Code enforces both lists where it reads that source. claude.ai doesn’t read it.

While any allowlist is set, or a blocklist names any source other than [`skills-dir`](#blocklist-with-blockedmarketplaces), a plugin whose marketplace Claude Code can’t find doesn’t load. `/plugin` shows the policy error for it rather than a not-found error. The common case is a stale `enabledPlugins` entry for a marketplace nobody registered.


[​](#control-matrix)

Control matrix

The table lists each plugin policy key, what it enforces, and what it can’t do.

| Key                                                                           | What it enforces                                                                                                                                                                                                                                                        | What it can’t do                                                                                                                                                                                                     |
|:------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `strictKnownMarketplaces`                                                     | Allowlist of marketplace sources. `[]` blocks every source, including the official marketplace. Alias: `allowedMarketplaces`                                                                                                                                            | Doesn’t register a marketplace, restrict entries inside an allowed marketplace, or block `--plugin-dir`                                                                                                              |
| `blockedMarketplaces`                                                         | Blocklist of marketplace sources, checked before the allowlist                                                                                                                                                                                                          | Doesn’t block a marketplace already registered from a source it doesn’t match                                                                                                                                        |
| `syncClaudeAiPlugins`                                                         | Set `false` to stop Claude Code downloading and loading the plugins [synced from claude.ai](plugins-loading.md#synced-plugins) for each user’s account. Requires Claude Code v2.1.273 or later                                                                    | Doesn’t turn off one synced plugin. For that, set `"<name>@synced": false` in [`enabledPlugins`](../02-Claude-Code-CLI/settings-reference.md#enabledplugins)                                                                         |
| `enabledPlugins`                                                              | `true` force-enables, `false` blocks at every scope and hides the plugin                                                                                                                                                                                                | Doesn’t install a plugin whose marketplace isn’t registered or allowed                                                                                                                                               |
| `disableSideloadFlags`                                                        | Rejects `--plugin-dir`, `--plugin-url`, `--agents`, the Agent SDK `plugins` option, and non-SDK `--mcp-config` at startup, and rejects folders named in the [`CLAUDE_CODE_PLUGIN_DIRS`](../02-Claude-Code-CLI/env-vars.md#variables) variable the same way                              | Doesn’t restrict `.mcp.json`, `claude mcp add`, or SDK-provided servers. Pair it with [`allowedMcpServers`](../06-MCP-Tools/General/managed-mcp.md)                                                                                    |
| `disableCommandPluginSources`                                                 | Blocks plugins with a `command` source from installing, updating, or loading. A `command` source is one whose plugin directory is produced by running a command on the machine. When unset, it takes the value of `allowManagedHooksOnly`                               | Doesn’t affect other source types                                                                                                                                                                                    |
| `allowManagedHooksOnly`                                                       | Restricts which hooks run. See [`allowManagedHooksOnly`](../02-Claude-Code-CLI/settings-reference.md#allowmanagedhooksonly)                                                                                                                                                             | Doesn’t trust hooks from plugins users enable themselves                                                                                                                                                             |
| `strictPluginOnlyCustomization`                                               | Blocks skills, agents, hooks, and MCP servers that don’t come from a plugin, managed settings, or Claude Code’s built-ins. Set `true` to cover all four types, or an array of `skills`, `agents`, `hooks`, and `mcp` values such as `["skills", "hooks"]` to cover some | Doesn’t restrict which plugins users install. Pair it with `strictKnownMarketplaces`                                                                                                                                 |
| `pluginSuggestionMarketplaces`                                                | Marketplaces whose plugins may appear as install suggestions. See [Recommend plugins](#recommend-plugins)                                                                                                                                                               | Doesn’t affect the built-in tips                                                                                                                                                                                     |
| `pluginTrustMessage`                                                          | Appends your text to the trust warning that `/plugin` shows before a plugin installs                                                                                                                                                                                    | Doesn’t change the warning’s own text                                                                                                                                                                                |
| `allowedChannelPlugins`                                                       | Replaces the default list of plugins allowed to push channel messages. Requires `channelsEnabled: true`                                                                                                                                                                 | See [Restrict which channel plugins can run](../02-Claude-Code-CLI/channels.md#restrict-which-channel-plugins-can-run)                                                                                                               |
| [`CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1`](../02-Claude-Code-CLI/env-vars.md) | Stops interactive terminal sessions from auto-registering the official marketplace                                                                                                                                                                                      | Doesn’t remove a marketplace already registered. The allowlist and blocklist gate the same auto-registration without it. A machine that started once with it set doesn’t resume auto-registration after you unset it |

Every key in the table is a managed setting, apart from `enabledPlugins`, `syncClaudeAiPlugins`, and `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL`:

- **`enabledPlugins`**: you can set it in any scope, and managed settings lock it.
- **`syncClaudeAiPlugins`**: each user can also set it in their own user or local settings. See its [scope in the settings reference](../02-Claude-Code-CLI/settings-reference.md#syncclaudeaiplugins).
- **`CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL`**: this is an environment variable that you deliver through the managed `env` block shown under [Turn updates off for the whole fleet](#turn-updates-off-for-the-whole-fleet).

Each settings key here has an entry in the [settings reference](../02-Claude-Code-CLI/settings-reference.md).


[​](#aliases-for-the-marketplace-keys)

Aliases for the marketplace keys

`strictKnownMarketplaces` can also be spelled `allowedMarketplaces`, and `extraKnownMarketplaces` can also be spelled `additionalMarketplaces`.

- **Version**: the aliases require Claude Code v2.1.232 or later, and older clients ignore them. In a file that a mixed fleet reads, keep the canonical names.
- **Both spellings set**: when a file sets both spellings, the canonical key’s value applies.


[​](#allowlist-with-strictknownmarketplaces)

Allowlist with `strictKnownMarketplaces`

Set the allowlist to a list of these source objects. Most entries match exactly, `hostPattern` and `pathPattern` entries match as regular expressions, and `github` owner wildcards match by owner:

- **`github`**: `{ "source": "github", "repo": "your-org/approved-plugins" }`, with optional `ref` and `path`.
- **`github` owner wildcard**: `{ "source": "github", "repo": "your-org/*" }` matches every repository under that owner. The `*` must stand for the whole repository name. Claude Code ignores entries such as `*/plugins` and `your-org/tools-*` as invalid, so they match nothing. Requires Claude Code v2.1.223 or later.
- **`git`**: `{ "source": "git", "url": "https://gitlab.example.com/tools/plugins.git" }`, with optional `ref` and `path`.
- **`url`**: `{ "source": "url", "url": "https://plugins.example.com/marketplace.json" }`, with optional `headers`.
- **`file` and `directory`**: `{ "source": "file", "path": "/opt/marketplace/marketplace.json" }` or `{ "source": "directory", "path": "/opt/marketplace/plugins" }`, with absolute paths.
- **`hostPattern`**: `{ "source": "hostPattern", "hostPattern": "^github\\.example\\.com$" }`, matched against the host of `github`, `git`, and `url` sources. The pattern matches anywhere in the hostname, so anchor it with `^` and `$` as shown to match the whole host. A `github` source always counts as `github.com`. Use a `hostPattern` entry for a GitHub Enterprise Server or GitLab host where developers create their own marketplaces. The [GHES page](../02-Claude-Code-CLI/github-enterprise-server.md#allowlist-ghes-marketplaces-in-managed-settings) has the worked example.
- **`pathPattern`**: `{ "source": "pathPattern", "pathPattern": "^/opt/approved/" }`, matched against the `path` of `file` and `directory` sources. The pattern matches anywhere in the path, so start it with `^` to pin a directory prefix. `".*"` allows every local path.
- **`skills-dir`**: `{ "source": "skills-dir" }` keeps [skills-directory plugins](#keep-skills-directory-plugins-loading) loading while an allowlist is set, and matches no marketplace.


[​](#how-entries-match)

How entries match

A `url` entry matches on its `url` value; `headers` aren’t compared. For `github` and `git` entries, the `repo` or `url`, the `ref`, and the `path` must all match, or be absent on both sides:

- An entry without `ref` doesn’t cover a source with `ref: "main"`.
- An entry for `your-org/your-marketplace` doesn’t cover a `git` URL that clones the same repository.
- A trailing slash, a `.git` suffix, or `ssh://` in place of `https://` is a different value. When a marketplace can be cloned by more than one URL, prefer a `hostPattern` entry.

Owner-wildcard entries follow the exact rules for `ref` and match any `path` inside the repository unless the entry pins one. Wildcard matching is case-sensitive on the allowlist.


[​](#keep-skills-directory-plugins-loading)

Keep skills-directory plugins loading

Skills-directory plugins are the plugins users keep under `~/.claude/skills/` or a project’s `.claude/skills/` in folders that carry a `.claude-plugin/plugin.json`. If you set any allowlist without a `{ "source": "skills-dir" }` entry, they stop loading. Plain [skills](skills.md), meaning a `SKILL.md` without that manifest, keep loading.


[​](#marketplaces-hosted-on-claude-ai)

Marketplaces hosted on claude.ai

The allowlist and blocklist match a [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai) by its host. To allow or block one, add a `hostPattern` entry that matches `claude.ai` to `strictKnownMarketplaces` or `blockedMarketplaces`. On the allowlist, such an entry admits your organization’s claude.ai marketplaces and the claude.ai default marketplaces, but not a marketplace made of a member’s own claude.ai uploads or one whose scope claude.ai didn’t state. Requires Claude Code v2.1.273 or later.


[​](#lock-every-source-out)

Lock every source out

An empty allowlist, `[]`, locks every marketplace source out, including the official marketplace. This lockdown doesn’t cover the plugins [synced from claude.ai](plugins-loading.md#synced-plugins), which Claude Code downloads from each user’s account rather than from a marketplace. To stop those as well, set [`syncClaudeAiPlugins`](../02-Claude-Code-CLI/settings-reference.md#syncclaudeaiplugins) to `false` in managed settings, or turn off Skills for your organization on claude.ai.


[​](#blocklist-with-blockedmarketplaces)

Blocklist with `blockedMarketplaces`

`blockedMarketplaces` takes the same source objects as [`strictKnownMarketplaces`](#allowlist-with-strictknownmarketplaces) and is checked first, so a source on both lists is blocked. Blocklist matching is wider than allowlist matching:

- Git URLs are canonicalized, so the `git@` and `https://` forms, `.git` suffixes, and trailing slashes of one `github.com` repository all match the same entry.
- A `github` entry also blocks the equivalent `git` URL, and the other way around.
- For an `owner/*` entry, the owner comparison is case-insensitive.
- An entry without `ref` or `path` blocks every ref and path of the repositories it matches.

This entry blocks every repository under one GitHub owner:

```python
{
  "blockedMarketplaces": [
    { "source": "github", "repo": "untrusted-org/*" }
  ]
}
```

The `url` entries in `blockedMarketplaces` also apply when a user adds an `https://` repository URL that Claude Code [clones rather than fetches](plugins-cli-reference.md#plugin-marketplace-add), such as a bare `github.com` or `gitlab.com` repository URL. The user can’t add that URL if an entry names it. The match ignores the `.git` suffix and any ref the user appends after `#`. Requires Claude Code v2.1.232 or later. A `{ "source": "skills-dir" }` entry here stops [skills-directory plugins](#keep-skills-directory-plugins-loading) from loading, from both `~/.claude/skills/` and a project’s `.claude/skills/`. A blocklist that names only that entry doesn’t count as an active restriction, so it doesn’t [stop plugins whose marketplace Claude Code can’t find](#restrict-what-users-can-install) from loading.


[​](#allow-the-official-marketplace-and-your-own)

Allow the official marketplace and your own

Most organizations allow the official marketplace and their own, and register both so every machine has them. This managed settings policy allows both marketplaces, registers both, force-enables two plugins, and rejects `--plugin-dir`:

```python
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "anthropics/claude-plugins-official" },
    { "source": "github", "repo": "your-org/*" },
    { "source": "skills-dir" }
  ],
  "extraKnownMarketplaces": {
    "claude-plugins-official": {
      "source": { "source": "github", "repo": "anthropics/claude-plugins-official" }
    },
    "your-marketplace": {
      "source": { "source": "github", "repo": "your-org/your-marketplace" }
    }
  },
  "enabledPlugins": {
    "code-formatter@your-marketplace": true,
    "deploy-helper@your-marketplace": true
  },
  "disableSideloadFlags": true
}
```

On a machine with this policy, adding any source outside the list, for example `/plugin marketplace add https://example.com/other-marketplace.git`, fails with a message containing `is blocked by enterprise policy` followed by the allowed sources. `claude --plugin-dir ./x` exits with a message naming `disableSideloadFlags`. The `{ "source": "skills-dir" }` entry keeps [skills-directory plugins](#keep-skills-directory-plugins-loading) loading under this allowlist. Remove that entry and they stop loading. Register both marketplaces with explicit `extraKnownMarketplaces` entries, as this policy does, rather than relying on the allowlist or on the official marketplace registering itself:

- **The allowlist doesn’t register anything**: an `extraKnownMarketplaces` entry does, and it must itself pass the allowlist. Claude Code refuses to register a managed marketplace whose source the allowlist doesn’t match.
- **The official marketplace registers itself only in an interactive terminal session**: even there, it registers only when the allowlist permits it. A `-p` run or a terminal attached to a cloud session never registers it.
- **A blocked attempt is remembered**: if a machine ever ran under a policy that blocked the official marketplace, Claude Code records the blocked attempt and doesn’t retry after the policy changes. An `[]` lockdown is one such policy. That machine registers it again only through an `extraKnownMarketplaces` entry such as the one in this policy, an `enabledPlugins` entry for one of its plugins, or a manual `/plugin marketplace add`.


[​](#set-update-policy)

Set update policy

You can set update policy per marketplace, for the whole fleet, or per user group through release channels.


[​](#turn-auto-update-on-or-off-per-marketplace)

Turn auto-update on or off per marketplace

Plugin auto-update runs in the background after startup for marketplaces that have it turned on. For which marketplaces have it on by default, see [When auto-update runs](plugins-loading.md#when-auto-update-runs). To decide for the fleet, set `"autoUpdate": true` or `false` on a managed `extraKnownMarketplaces` entry:

- If the managed entry sets the field, Claude Code refuses the user’s `/plugin` toggle with an error that starts `Auto-update for '<name>' is set by`.
- If the managed entry leaves the field unset, the user’s toggle persists.


[​](#turn-updates-off-for-the-whole-fleet)

Turn updates off for the whole fleet

To turn plugin auto-update off for every marketplace, set `DISABLE_AUTOUPDATER` in the managed `env` block, as this example does. The same variable also stops Claude Code’s own updates:

```python
{
  "env": {
    "DISABLE_AUTOUPDATER": "1"
  }
}
```

To stop Claude Code’s own updates but keep plugin auto-update, add `"FORCE_AUTOUPDATE_PLUGINS": "1"` to the same block. The other [environment variables that stop plugin auto-update](plugins-loading.md#when-auto-update-runs) work the same way. `DISABLE_AUTOUPDATER` doesn’t cover plugins with a [`command` source](plugins-marketplace-reference.md#command-plugin-source). Claude Code re-runs each enabled one’s command every session and installs the output when it changed. For what stops those runs, see [When a command source re-runs](plugins-loading.md#when-a-command-source-re-runs).


[​](#assign-release-channels-to-user-groups)

Assign release channels to user groups

To run stable and early-access channels, host two marketplaces that point at different refs of the same plugins. Then give each user group its own marketplace through either separate endpoint-managed settings or a gateway policy. Server-managed settings from the admin console [apply to every user in your organization](../13-Enterprise-Admin/server-managed-settings.md#current-limitations), so they can’t assign different settings to different groups.

- Deploy separate [endpoint-managed settings](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms), such as a managed settings file or an MDM profile, to each group’s devices. To check whether the per-group file or profile applies on a device that also has an organization-wide source, see [How Claude Code combines managed sources](../13-Enterprise-Admin/managed-settings.md#precedence-within-the-managed-tier).
- Define one [Claude apps gateway policy](../13-Enterprise-Admin/claude-apps-gateway-config.md#managed) per group. The gateway applies the first policy whose match rule fits a user, so order the policies so that each user reaches their group’s policy. That policy’s `extraKnownMarketplaces` map doesn’t merge with any other policy’s, so list every marketplace the group needs in it, not only its channel marketplace.

With either mechanism, the stable group receives this configuration:

```python
{
  "extraKnownMarketplaces": {
    "stable-tools": {
      "source": { "source": "github", "repo": "your-org/stable-tools" }
    }
  }
}
```

The early-access group receives `latest-tools` instead. To set up the two marketplaces, see [Run release channels](plugins-host-marketplace.md#run-release-channels).


[​](#recommend-plugins)

Recommend plugins

Marketplace owners can attach `relevance` signals to entries so Claude Code suggests the plugin when a project matches. Suggestions from a marketplace appear only when it’s registered on the user’s machine, you list its name in `pluginSuggestionMarketplaces` in managed settings, and you declare its source in the same policy. Declare the source either as the marketplace’s `extraKnownMarketplaces` entry or as an allowlist entry. The official marketplace needs only the name. See [Enable suggestions in managed settings](plugins-relevance.md#enable-suggestions-in-managed-settings).


[​](#audit-and-review)

Audit and review

OpenTelemetry events and the Analytics API tell you what your fleet installs and runs. For what a plugin can run on a machine and what each trust tier permits, read [Plugin security](plugins-security.md) before you approve a marketplace.


[​](#opentelemetry-events)

OpenTelemetry events

`claude_code.plugin_installed` records each install, and `claude_code.plugin_loaded` records each enabled plugin at session start. Both events redact or omit third-party plugin and marketplace names unless you set `OTEL_LOG_TOOL_DETAILS=1`, as [Redacted plugin names in your backend](plugins-measure.md#redacted-plugin-names-in-your-backend) shows. Field lists are under [Plugin installed event](../13-Enterprise-Admin/monitoring-usage.md#plugin-installed-event) and [Plugin loaded event](../13-Enterprise-Admin/monitoring-usage.md#plugin-loaded-event).


[​](#analytics-api)

Analytics API

On the Enterprise plan, `GET /v1/organizations/analytics/plugins` returns per-plugin, per-day install and invocation counts across Claude Code and Cowork. You can group the counts by user or RBAC group. Plugin activity that reaches Anthropic without a plugin name appears in one aggregate `third-party` row. See the [endpoint reference](../04-API-Reference/Admin/http-beta-organization-analytics-plugins-list.md) and [Access data programmatically](../13-Enterprise-Admin/analytics.md#access-data-programmatically) for the key it needs.


[​](#plan-for-what-managed-settings-can’t-enforce)

Plan for what managed settings can’t enforce

These requests from security reviews have no dedicated key in the current settings schema. The nearest existing controls are:

- **Per-user or per-group targeting**: every plugin key applies to every user who receives the settings. Server-managed settings deliver one configuration per organization. For per-group policy, use separate endpoint-managed settings or gateway policies, as under [Assign release channels to user groups](#assign-release-channels-to-user-groups).
- **Restricting entries inside an allowed marketplace**: the allowlist matches marketplace sources. To block one plugin from an allowed marketplace, set it to `false` in managed `enabledPlugins`.
- **Hiding `/plugin`**: no key disables the command. The nearest equivalent combines an allowlist naming only your marketplace, managed `enabledPlugins` entries for the plugins you supply, and `disableSideloadFlags`.
- **Gating `--plugin-dir` through the allowlist**: the allowlist doesn’t cover `--plugin-dir`. `disableSideloadFlags` does.
- **Enforcing the claude.ai plugin toggles through these keys**: [**Organization settings \> Plugins & skills**](https://claude.ai/admin-settings/skills?tab=inventory) doesn’t set the keys on this page. What members and your organization turn on there reaches the CLI as [synced plugins](plugins-loading.md#synced-plugins), which have their own controls.


[​](#troubleshoot-policy)

Troubleshoot policy

If plugin policy doesn’t behave as expected on a machine, check for these symptoms first:

- **The managed file didn’t parse**: when a `managed-settings.json` isn’t valid JSON, Claude Code refuses to start and prints [an error naming the file](../02-Claude-Code-CLI/errors.md#managed-settings-document-could-not-be-parsed). A file that parses but has one invalid entry keeps the rest of its policy. See [Invalid entries in managed settings](../13-Enterprise-Admin/managed-settings.md#invalid-entries-in-managed-settings).
- **The managed source didn’t load**: run `/status` and look for `Enterprise managed settings` in the `Setting sources` line. If it’s missing, the source didn’t load.
- **A user reports `blocked by enterprise policy`**: the message names the marketplace or its source. For an allowlist, it also lists the allowed sources. The user-facing entries are on [Troubleshoot plugins](plugins-troubleshooting.md).
- **A plugin the user disabled in `~/.claude/settings.json` still loads**: another settings source re-enabled it, such as a managed `enabledPlugins` entry that force-enables it. `/plugin` and `claude plugin list` show `Disabled in ~/.claude/settings.json but still loads` with that settings source.


[​](#next-steps)

Next steps

- [Marketplace reference](plugins-marketplace-reference.md#marketplace-sources): the `source` values `extraKnownMarketplaces`, `strictKnownMarketplaces`, and `blockedMarketplaces` accept
- [Host and maintain a marketplace](plugins-host-marketplace.md): run the marketplace your policy points at
- [Plugin security and trust](plugins-security.md): what a plugin can do on a machine and how to review one before installing
- [Server-managed settings](../13-Enterprise-Admin/server-managed-settings.md): deliver these keys from the claude.ai admin console
- [Troubleshoot plugins](plugins-troubleshooting.md#blocked-by-your-organization): the messages users see when policy blocks them

---

## Playwright | Claude by Anthropic

Source: https://www.claude.com/plugins/playwright
Path: 08-Plugins-Skills/plugins-playwright.md

# Playwright

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

- 

  Install in
  Claude Code
- 

  Made by[Microsoft](https://microsoft.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/external_plugins/playwright)
- 

  Installs319,887

Playwright MCP enables Claude to automate browser interactions through structured accessibility data rather than screenshots. This provides fast, lightweight browser automation without requiring vision models—Claude works directly with the page's accessibility tree for deterministic, reliable interactions.

Key capabilities include navigating to URLs, clicking elements, filling forms, handling file uploads, managing browser dialogs, taking screenshots, generating PDFs, and running custom Playwright scripts. The server also provides tab management, network request inspection, console message retrieval, and comprehensive test assertion tools for end-to-end testing workflows.

**How to use:** Ask Claude to perform browser tasks naturally. Try prompts like "Navigate to example.com and take a screenshot", "Fill out the login form with username test@email.com", "Click the Submit button and wait for the confirmation message", or "Run an end-to-end test that verifies the checkout flow works correctly". Claude will use the appropriate browser automation tools to complete these tasks.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Publish and distribute a plugin - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/publish
Path: 08-Plugins-Skills/plugins-publish.md

## On this page

- [Choose how to distribute](#choose-how-to-distribute)
- [Prepare your plugin for release](#prepare-your-plugin-for-release)
- [Share a plugin without a marketplace](#share-a-plugin-without-a-marketplace)
  - [Ship a plugin with your own tool](#ship-a-plugin-with-your-own-tool)
- [Publish through your own marketplace](#publish-through-your-own-marketplace)
  - [Add the marketplace file to your repository](#add-the-marketplace-file-to-your-repository)
  - [Control who can install](#control-who-can-install)
  - [Tell users how to install](#tell-users-how-to-install)
  - [Ship updates to users](#ship-updates-to-users)
- [Submit to Anthropic’s directory](#submit-to-anthropics-directory)
  - [How a listed plugin reaches Claude Code users](#how-a-listed-plugin-reaches-claude-code-users)
- [Ship updates, renames, and removals](#ship-updates-renames-and-removals)
  - [Release a new version](#release-a-new-version)
  - [Tag a release](#tag-a-release)
  - [Rename or remove a plugin](#rename-or-remove-a-plugin)
- [Declare dependencies](#declare-dependencies)
- [Next steps](#next-steps)

Create plugins

# Publish and distribute a plugin

Copy pageCopy page

Publish a Claude Code plugin through your own marketplace or Anthropic’s directory, with a pre-release checklist and how users get updates.

Copy pageCopy page

Publishing a Claude Code plugin means listing it in a marketplace, a JSON catalog that lists plugins and where to fetch each one, so that other people can install it by name and receive your updates. You can run your own marketplace or submit your plugin to Anthropic’s directory. To share a plugin without publishing it, send people the plugin’s directory or a `.zip` of it to load themselves. This page is for the author of a working plugin who is ready to share it.

These cases are covered on other pages:

- **Your plugin isn’t finished yet**: start with [Create a plugin](plugins-create.md)
- **You maintain a CLI or SDK with a plugin in an official marketplace**: see [Recommend your plugin from your CLI](plugins-cli-hints.md)

Start with [Choose how to distribute](#choose-how-to-distribute) to compare the distribution options. If you already know your route, go to [Prepare your plugin for release](#prepare-your-plugin-for-release), then follow your route’s section for what to tell your users and how they receive your updates.


[​](#choose-how-to-distribute)

Choose how to distribute

Choose a distribution option based on who needs to install the plugin:

| Route                                                         | Who can install                                                                                                                                          | What you need                                                                                  | Do users get your updates automatically?     |
|:--------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:---------------------------------------------|
| [No marketplace](#share-a-plugin-without-a-marketplace)       | The people you send the plugin folder or a `.zip` of it                                                                                                  | The plugin’s folder                                                                            | None. They load the copy you sent            |
| [Your own marketplace](#publish-through-your-own-marketplace) | Anyone who can reach the repository, which can be a private one your team can clone                                                                      | A git repository or other host with a `.claude-plugin/marketplace.json` that lists your plugin | Off                                          |
| [Anthropic’s directory](#submit-to-anthropics-directory)      | People who add it on claude.ai or in Cowork. It also loads in their Claude Code sessions through [account sync](plugins-loading.md#synced-plugins) | A GitHub repository holding the plugin and a paid claude.ai plan to submit from                | Yes, after the version you push is published |

Auto-update is a per-marketplace setting on the user’s side that fetches new versions in the background.


[​](#prepare-your-plugin-for-release)

Prepare your plugin for release

The name, the version, validation, and an install from a marketplace decide whether a release works for the people who install it. Check them before the first release and again before each later one.

1

Choose a permanent name

Users install, enable, and configure your plugin by `name@marketplace`, so a renamed plugin is a different plugin to every existing install. Choose a kebab-case name such as `deploy-helper`, because `claude plugin validate` warns on other forms, and treat it as permanent. Set `displayName` in `plugin.json` for the label users see.

2

Decide how you'll version

If you set `version` in `plugin.json` and later push commits without changing it, `claude plugin update` prints `<name> is already at the latest version (1.0.0).` and users keep the old copy. Either increment `version` on every release, or omit it in a git-hosted marketplace so Claude Code uses the commit SHA instead. See [Versions and updates](plugins-loading.md#versions-and-updates).

3

Validate

In your shell, run `claude plugin validate --strict ./your-plugin`. A clean run prints `✔ Validation passed`.

- **In CI**: keep `--strict`, which also fails the run with exit code 1 on warnings such as an unknown manifest field or a missing `version`. Drop `--strict` if you chose to omit `version` in the previous step.
- **Paths**: validation reports component paths that don’t start with `./`. Inside hook commands and MCP server configs, refer to files as `${CLAUDE_PLUGIN_ROOT}/...`. See [path rules](plugins-reference.md#path-rules).

4

Install it from a local marketplace

In your shell, add a local marketplace that lists the plugin with `claude plugin marketplace add ./path-to-marketplace`, install the plugin from it, and start a session to confirm it loads.

- For the smallest marketplace that works, see [Create a marketplace](plugin-marketplaces.md).
- To know whether an install loads your source directory or a cached copy, see [In-place and copied plugins](plugins-loading.md#in-place-and-copied-plugins).

5

Fill in the metadata users see

Set `description`, `author`, `homepage`, and `repository` in `plugin.json`, and add a `README.md` at the plugin root. `homepage` must parse as a URL. The [manifest reference](plugins-reference.md#fields) lists every field.

6

Run your eval suite

If you have an eval suite, run `claude plugin eval` in your shell. It runs the plugin’s test cases and scores the results, which catches regressions when you change the plugin. See [Test plugins with evals](plugin-evals.md).


[​](#share-a-plugin-without-a-marketplace)

Share a plugin without a marketplace

If the plugin is in a git repository, people can clone it and load the checkout, or start Claude Code from their shell with `--plugin-url` pointed at a `.zip` you attach to a release. To get your next version they pull or download again. If it isn’t in a repository, send them the directory or a `.zip` of it. They load it in one of two ways:

- **For one session**: they start Claude Code from their shell with `claude --plugin-dir ./deploy-helper`, where the path is the clone, the unzipped folder, or the `.zip` itself. See [Flags that load a plugin for one session](plugins-cli-reference.md#flags-that-load-a-plugin-for-one-session).
- **For every session**: they move the plugin directory, with its `.claude-plugin/plugin.json`, under `~/.claude/skills/` so Claude Code [loads it in every session](plugins-loading.md#find-where-a-plugin-came-from).

Adding a `.claude-plugin/marketplace.json` to that same repository is what lets people install by name and update with a command; see [Publish through your own marketplace](#publish-through-your-own-marketplace).


[​](#ship-a-plugin-with-your-own-tool)

Ship a plugin with your own tool

If you maintain a CLI or SDK, publish the plugin in a marketplace and have your installer or post-install message run or print the two commands a user needs: `claude plugin marketplace add <source>`, then `claude plugin install <name>@<marketplace>`. For in-session discovery when someone uses your tool, see [Recommend your plugin from your CLI](plugins-cli-hints.md).


[​](#publish-through-your-own-marketplace)

Publish through your own marketplace

Your own marketplace is a `.claude-plugin/marketplace.json` file that lists your plugin, added to a git repository. Once the file is in the repository, the plugin is published, with no submission form. You can keep the file in the plugin’s own repository or in a separate one.


[​](#add-the-marketplace-file-to-your-repository)

Add the marketplace file to your repository

To publish from the plugin’s own repository, save the marketplace file beside `plugin.json` in `.claude-plugin/`, with one entry whose `source` is `"./"`, the repository root. Give the entry the same `name` as `plugin.json`, per [Keep the entry name and the manifest name the same](plugin-marketplaces.md#keep-the-entry-name-and-the-manifest-name-the-same):

.claude-plugin/marketplace.json

```python
{
  "name": "your-marketplace",
  "owner": { "name": "Your Name" },
  "plugins": [
    { "name": "deploy-helper", "source": "./" }
  ]
}
```

In your shell, run `claude plugin validate .` in the repository to check the file before you push. [Create a marketplace](plugin-marketplaces.md) covers the layout with several plugins in one repository.


[​](#control-who-can-install)

Control who can install

Anyone who can clone the repository can install from it, so if the repository is private, the marketplace is private too. For hosts other than a git repository, see [Host a marketplace](plugins-host-marketplace.md). To reach everyone at a company, including people who don’t use git, see [Roll out to a whole company](plugins-host-marketplace.md#roll-out-to-a-whole-company).


[​](#tell-users-how-to-install)

Tell users how to install

Tell your users to add the marketplace and then install the plugin from their shell, replacing the source and names with yours:

- Add the marketplace once: `claude plugin marketplace add your-org/your-marketplace`, where the argument is a GitHub `owner/repo` shorthand, a URL, or a path
- Install the plugin: `claude plugin install deploy-helper@your-marketplace`
- Or do both from inside a session: `/plugin install deploy-helper --marketplace your-org/your-marketplace`. Requires Claude Code v2.1.275 or later. See [Add a marketplace and install in one command](discover-plugins.md#add-a-marketplace-and-install-in-one-command)


[​](#ship-updates-to-users)

Ship updates to users

Users receive a release when they ask for it or when auto-update is on for your marketplace:

- **On request**: `claude plugin update deploy-helper@your-marketplace` in the user’s shell refreshes the marketplace and installs the new copy when your plugin’s version has changed
- **Auto-update**: off by default for your marketplace. See [Turn on auto-update](plugins-host-marketplace.md#turn-on-auto-update). Once on, it does the same as `claude plugin update` on a delay after the session starts

[Install plugins](discover-plugins.md) covers the user-side commands, and [when auto-update runs](plugins-loading.md#when-auto-update-runs) covers the timing.


[​](#submit-to-anthropics-directory)

Submit to Anthropic’s directory

Anthropic’s directory is the catalog people browse on claude.ai and in Cowork to add plugins and connectors. One listing there reaches people on claude.ai, in Cowork, and in Claude Code. You submit from the developer portal at [claude.ai/directory/manage](https://claude.ai/directory/manage); [Prepare for review](https://claude.com/docs/directory/publish#prepare-for-review) on claude.com describes what happens to each version before it’s published. Submitting requires a paid claude.ai plan. On Pro and Max you submit from your own account. On Team and Enterprise, an Owner can submit, and on Enterprise an Owner can also grant the **Directory** permission to other members through a custom role under **Organization settings \> Roles**. See [Confirm you can submit to the directory](https://claude.com/docs/directory/publish#confirm-you-can-submit-to-the-directory). The submission steps, the checks each version must pass, and what happens after you publish are documented on claude.com, because they’re the same whichever surface your users are on:

- [Publish to the directory](https://claude.com/docs/directory/publish#before-you-submit-to-the-directory): what you can submit and who can submit it
- [Submit a plugin](https://claude.com/docs/plugins/submit#submit-a-plugin): the portal steps and [updating a published plugin](https://claude.com/docs/plugins/submit#update-a-published-plugin)
- [Plugin pre-submission checklist](https://claude.com/docs/plugins/pre-submission-checklist#run-the-checks-before-you-submit): the checks to run and fix before you submit
- [Move an earlier submission to the developer portal](https://claude.com/docs/directory/publish#move-an-earlier-submission-to-the-developer-portal): what to do if you submitted a plugin through one of the earlier submission forms, before the portal existed

Before you open the portal, validate locally and check which of your components load outside Claude Code:

- **Run `claude plugin validate ./your-plugin --strict` in your shell**: replace `./your-plugin` with the path to your plugin directory. The command catches manifest errors locally; [plugin validate](plugins-cli-reference.md#plugin-validate) lists which files each run reads. The portal applies additional directory rules that the CLI doesn’t check, so a clean local run doesn’t guarantee a clean portal validation.
- **Check what loads where**: some plugin components are Claude Code-only and don’t load on claude.ai or in Cowork. The [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app) lists each component by app, so you know what users outside Claude Code will get.

Anthropic’s official marketplace, `claude-plugins-official`, doesn’t take submissions through the directory portal. If you work with an Anthropic partner contact, ask them about an official-marketplace listing.


[​](#how-a-listed-plugin-reaches-claude-code-users)

How a listed plugin reaches Claude Code users

A person who installs your plugin from the directory on claude.ai has it on their account, and Claude Code loads it as `<name>@synced`. [Plugins synced from claude.ai](plugins-loading.md#synced-plugins) covers what they see and how they turn it off.


[​](#ship-updates-renames-and-removals)

Ship updates, renames, and removals


[​](#release-a-new-version)

Release a new version

If you publish through your own marketplace and your `plugin.json` sets `version`, increment it and push. Users who run `claude plugin update` or have auto-update on then receive the new version, as described under [Ship updates to users](#ship-updates-to-users). For a directory listing, see [Update a published plugin](https://claude.com/docs/plugins/submit#update-a-published-plugin).


[​](#tag-a-release)

Tag a release

Tag the release in git when other plugins declare a version range on yours, because those ranges resolve against tags. Otherwise you don’t need a tag. To tag, run `claude plugin tag` in your shell from the plugin directory. It creates a `{name}--v{version}` tag. Add `--push` to send the tag to `origin`. The [`plugin tag` reference](plugins-cli-reference.md#plugin-tag) lists its flags.


[​](#rename-or-remove-a-plugin)

Rename or remove a plugin

Never change a published plugin’s `name`. After a rename, users who already installed it lose the plugin, because their install is recorded under the old name. A `renames` entry in your marketplace file migrates them instead. Change `displayName` when you want a different label. If a rename is unavoidable, use the marketplace file’s `renames` map so that existing installs migrate instead of failing with [`Plugin "<name>" not found in marketplace`](plugins-troubleshooting.md#plugin-not-found-in-marketplace). To remove a plugin from the marketplace, or for the full `renames` details, see [Rename or remove a plugin](plugins-host-marketplace.md#rename-or-remove-a-plugin) on the hosting page. The [marketplace reference](plugins-marketplace-reference.md#top-level-fields) has the field.


[​](#declare-dependencies)

Declare dependencies

If your plugin needs another plugin from the same marketplace to be enabled, list it in the `dependencies` array of `plugin.json`. Each entry is a bare name or an object with a semver `version` range. When a user installs your plugin, Claude Code installs and enables the dependency too. [Plugin dependencies](plugins-dependencies.md) covers the range syntax, cross-marketplace dependencies, and how users prune dependencies they no longer need.


[​](#next-steps)

Next steps

- [Host and maintain a marketplace](plugins-host-marketplace.md): release new versions and keep users up to date
- [Plugin dependencies](plugins-dependencies.md): declare and version the plugins yours relies on
- [Recommend your plugin from your CLI](plugins-cli-hints.md): prompt Claude Code users of your CLI to install the plugin
- [Measure plugin cost and usage](plugins-measure.md): see what your plugin costs in context and whether people use it

---

## Ralph Loop | Claude by Anthropic

Source: https://www.claude.com/plugins/ralph-loop
Path: 08-Plugins-Skills/plugins-ralph-loop.md

# Ralph Loop

Anthropic verified

Interactive AI loops for iterative development using the Ralph Wiggum technique: Claude works on tasks repeatedly, seeing prior work until completion.

- 

  Install in
  Claude Code
- 

  Made by[Anthropic](https://anthropic.com)
- 

  Plugin source[View source](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/ralph-loop)
- 

  Installs196,527

Ralph Loop enables iterative, self-referential AI development loops where Claude works on the same task repeatedly until completion. The plugin intercepts session exits via a stop hook and automatically re-feeds your prompt while preserving all file modifications and git history between iterations. This creates autonomous improvement cycles where Claude can refine its work based on test failures and previous attempts.

The technique is ideal for well-defined projects with clear success criteria, greenfield development with automated verification, and any task amenable to iterative refinement. Claude reads its own past work to inform improvements, creating a powerful feedback loop for autonomous problem-solving.

**How to use:** Start an iterative session with `/ralph-loop "your prompt here" --max-iterations 10 --completion-promise "DONE"`. The loop continues until Claude outputs the completion promise or reaches the iteration limit. Cancel anytime with `/cancel-ralph`. Write prompts with explicit completion criteria and success metrics for best results.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Superpowers](https://www.claude.com/marketplace/plugins/superpowers)

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Plugin manifest reference - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins-reference
Path: 08-Plugins-Skills/plugins-reference.md

## On this page

- [Manifest file](#manifest-file)
  - [Unrecognized fields](#unrecognized-fields)
  - [Validate the manifest](#validate-the-manifest)
- [Fields](#fields)
  - [name](#name)
  - [displayName](#displayname)
  - [version](#version)
  - [metadata](#metadata)
  - [defaultEnabled](#defaultenabled)
  - [dependencies](#dependencies)
  - [settings](#settings)
- [Component path forms](#component-path-forms)
  - [Path-only fields](#path-only-fields)
  - [commands](#commands)
  - [hooks](#hooks)
  - [mcpServers](#mcpservers)
  - [lspServers](#lspservers)
  - [monitors](#monitors)
- [Path rules](#path-rules)
  - [Containment and existence](#containment-and-existence)
  - [How each key combines with its default location](#how-each-key-combines-with-its-default-location)
- [User configuration](#user-configuration)
  - [Limit a field to fixed options](#limit-a-field-to-fixed-options)
  - [Where values are stored](#where-values-are-stored)
  - [Reference a saved value](#reference-a-saved-value)
  - [Fields that run through a shell](#fields-that-run-through-a-shell)
- [Channels](#channels)
- [Environment variables](#environment-variables)
  - [Where each variable resolves](#where-each-variable-resolves)
  - [Quoting and path separators](#quoting-and-path-separators)
- [Standard layout](#standard-layout)
- [Marketplace entries and the manifest](#marketplace-entries-and-the-manifest)
  - [How entry fields combine with plugin.json](#how-entry-fields-combine-with-plugin-json)
  - [Metadata precedence](#metadata-precedence)
- [Next steps](#next-steps)

Reference

# Plugin manifest reference

Copy pageCopy page

Complete reference for plugin.json: every field with its type and default, accepted path forms, and the userConfig and environment variable schemas.

Copy pageCopy page

A plugin manifest is the `plugin.json` file in a plugin’s `.claude-plugin/` directory. It carries the plugin’s metadata and the [`userConfig`](#user-configuration) values that Claude Code prompts the user for. It also declares any component that you define inline or keep outside its [default location](#standard-layout). This reference is for plugin creators, and for marketplace owners who put component fields in a marketplace entry.

These cases are covered on other pages:

- **Learning to build a plugin**: start with [Create a plugin](plugins-create.md)
- **What each component does at runtime**: see [Plugin components](plugins-components.md)

Start at the section that matches what you’re looking up:

- A field: the [Fields table](#fields) gives each field’s type, whether it’s required, its default, and what it accepts. [Path rules](#path-rules) covers the `./` prefix and containment for every component path
- A `userConfig` option or a `channels` entry: the [User configuration](#user-configuration) and [Channels](#channels) schemas
- `${CLAUDE_PLUGIN_ROOT}` or another variable a plugin can reference: [Environment variables](#environment-variables)
- Where each component’s files go: [Standard layout](#standard-layout)
- A message from `claude plugin validate`: the [troubleshooting page](plugins-troubleshooting.md) lists each message with its fix and links to the relevant sections on this page


[​](#manifest-file)

Manifest file

The manifest is optional. Without it, Claude Code loads the components it finds in the [standard layout](#standard-layout). The plugin name then comes from the marketplace entry, or from the directory name when you load the plugin with `--plugin-dir`. Write a manifest when you want metadata, a component outside its default directory, `userConfig`, or an inline component definition. Save the manifest at `.claude-plugin/plugin.json` under the plugin root. Put every other plugin file at the plugin root, not inside `.claude-plugin/`. That includes `skills/`, `commands/`, and `hooks/`. The following example sets most of the keys in the [Fields table](#fields). It passes validation in a plugin directory that contains each referenced path.

```python
{
  "name": "deploy-tools",
  "displayName": "Deploy Tools",
  "version": "1.2.0",
  "description": "Deployment commands, a review agent, and a status monitor",
  "author": {
    "name": "Example Team",
    "email": "dev@example.com",
    "url": "https://example.com"
  },
  "homepage": "https://example.com/docs/deploy-tools",
  "repository": "https://github.com/example/deploy-tools",
  "license": "MIT",
  "keywords": ["deployment", "ci"],
  "defaultEnabled": true,
  "dependencies": ["secrets-vault"],
  "metadata": { "catalogId": "cat-123" },
  "skills": ["./extra-skills/"],
  "commands": {
    "status": {
      "source": "./commands/status.md",
      "description": "Show the current deployment status"
    },
    "about": {
      "content": "Explain what the deploy-tools plugin provides.",
      "description": "Describe this plugin"
    }
  },
  "agents": ["./agents/reviewer.md"],
  "hooks": "./config/extra-hooks.json",
  "mcpServers": {
    "deploy-api": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  },
  "lspServers": "./.lsp.json",
  "outputStyles": "./styles/",
  "experimental": {
    "themes": "./themes/",
    "monitors": "./config/monitors.json"
  },
  "userConfig": {
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for the deployment API",
      "sensitive": true
    }
  }
}
```


[​](#unrecognized-fields)

Unrecognized fields

An unrecognized top-level key is stripped, and an unrecognized key inside a `userConfig` option, `channels` entry, `lspServers` config, or `monitors` entry is rejected:

- **Top-level fields**: the field is stripped and the plugin loads. `claude plugin validate` reports each unrecognized top-level field as a warning
- **Strict objects**: `userConfig` options, `channels` entries, `lspServers` configs, and `monitors` entries are strict. An unknown key inside one is an error, and the plugin doesn’t load


[​](#validate-the-manifest)

Validate the manifest

`claude plugin validate` is the authoritative check for a manifest. Run it from your shell against the plugin directory:

```python
claude plugin validate ./my-plugin
```

The command reports one of these results:

- **`Validation passed`**: the manifest loads
- **`Validation passed with warnings`**: the manifest loads, but the validator found something to fix, such as an unknown top-level field that Claude Code strips, a `name` that isn’t kebab-case, or a missing `version`, `description`, or `author`. Pass `--strict` to turn warnings into failures in CI
- **`Validation failed`**: the manifest has a type mismatch, a path that is missing or escapes the plugin root, or an unknown key inside a `userConfig` option, `channels` entry, `lspServers` config, or `monitors` entry. Claude Code reports the same problem when it loads the plugin

The command also checks each MCP server entry the plugin declares in `.mcp.json`, in a `.json` file that [`mcpServers`](#mcpservers) names, or inline in `plugin.json`. These MCP checks require Claude Code v2.1.281 or later and include:

- **Errors**: an entry Claude Code would drop when it loads the plugin, a `${user_config.KEY}` reference to an option the manifest doesn’t declare, and a remote `url` that isn’t a valid absolute URL
- **Warnings**: an `http://` or `ws://` URL to a non-loopback host, and a header value that looks like a literal credential


[​](#fields)

Fields

The table lists the top-level keys in `plugin.json`. `name` is the only required key. Where a field name is a link, the linked section has its full rules. For component keys such as `commands` and `hooks`, [Component path forms](#component-path-forms) shows each accepted shape with an example, and every path follows the [path rules](#path-rules) for the `./` prefix, extensions, and containment.

| Field                                | Type                             | Description                                                                                                                                                                                                                                                                                                      |
|:-------------------------------------|:---------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `$schema`                            | String                           | JSON Schema URL for editor autocomplete. Claude Code ignores it at load time                                                                                                                                                                                                                                     |
| [`name`](#name)                      | String                           | Plugin identifier, required. Use kebab-case. Every component is namespaced under it                                                                                                                                                                                                                              |
| [`displayName`](#displayname)        | String                           | Name shown in UI in place of `name`                                                                                                                                                                                                                                                                              |
| [`version`](#version)                | String                           | Version string. Setting it keeps users on that version until you change it                                                                                                                                                                                                                                       |
| `description`                        | String                           | Short explanation of what the plugin provides                                                                                                                                                                                                                                                                    |
| `author`                             | Object                           | `name`, which is required, plus optional `email` and `url`                                                                                                                                                                                                                                                       |
| `homepage`                           | String                           | Documentation URL. Must parse as a URL, or the plugin fails to load                                                                                                                                                                                                                                              |
| `repository`                         | String                           | Source repository URL. Not validated                                                                                                                                                                                                                                                                             |
| `license`                            | String                           | SPDX identifier such as `MIT` or `Apache-2.0`                                                                                                                                                                                                                                                                    |
| `keywords`                           | Array of strings                 | Discovery tags                                                                                                                                                                                                                                                                                                   |
| [`metadata`](#metadata)              | Object                           | Free-form object for your own data. Claude Code doesn’t read it                                                                                                                                                                                                                                                  |
| [`defaultEnabled`](#defaultenabled)  | Boolean                          | Whether the plugin starts enabled when the user hasn’t set it. Defaults to `true`                                                                                                                                                                                                                                |
| [`dependencies`](#dependencies)      | Array of strings or objects      | Plugins that must be enabled for this one to work                                                                                                                                                                                                                                                                |
| [`settings`](#settings)              | Object                           | Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect                                                                                                                                                                                                      |
| [`userConfig`](#user-configuration)  | Object                           | Values Claude Code prompts the user for when the plugin is enabled                                                                                                                                                                                                                                               |
| [`channels`](#channels)              | Array of objects                 | Message channels the plugin provides, each bound to one of its MCP servers                                                                                                                                                                                                                                       |
| `skills`                             | Path, or array of paths          | Directories to scan for skills, each a directory of `<name>/SKILL.md` folders or one folder holding `SKILL.md` directly. `"."` names the plugin root. Adds to the default `skills/` scan                                                                                                                         |
| [`commands`](#commands)              | Path, array of paths, or object  | Flat `.md` command files, directories of them, or an object map of command name to `source` or `content`. Replaces the default `commands/` scan                                                                                                                                                                  |
| `agents`                             | Path, or array of paths          | Agent `.md` files. Directories aren’t accepted. Replaces the default `agents/` scan                                                                                                                                                                                                                              |
| [`hooks`](#hooks)                    | Path, object, or array of either | `.json` hook files or inline hook config. Loaded together with `hooks/hooks.json`                                                                                                                                                                                                                                |
| [`mcpServers`](#mcpservers)          | Path, object, or array of either | `.json` MCP config files, `.mcpb` or `.dxt` bundles, or inline server configs keyed by name. Loaded together with `.mcp.json`; a server name declared later replaces an earlier one                                                                                                                              |
| [`lspServers`](#lspservers)          | Path, object, or array of either | `.json` LSP config files or inline server configs keyed by name. Loaded together with `.lsp.json`                                                                                                                                                                                                                |
| `outputStyles`                       | Path, or array of paths          | Output style files or directories. Replaces the default `output-styles/` scan                                                                                                                                                                                                                                    |
| `workflows`                          | Path, or array of paths          | [Workflow](../02-Claude-Code-CLI/workflows.md#distribute-a-workflow-in-a-plugin) `.js` files or directories. Replaces the default `workflows/` scan                                                                                                                                                                              |
| `experimental`                       | Object                           | Container for `themes`, `monitors`, and `evals`, whose manifest shape may still change                                                                                                                                                                                                                           |
| `experimental.themes`                | Path, or array of paths          | Theme files or directories. Replaces the default `themes/` scan. A top-level `themes` key still loads, with a `claude plugin validate` warning                                                                                                                                                                   |
| [`experimental.monitors`](#monitors) | Path, or inline array            | A `.json` file holding the monitors array, or the array itself. Defaults to `monitors/monitors.json`. A top-level `monitors` key still loads, with a `claude plugin validate` warning. Monitors run only in interactive sessions, and not on Amazon Bedrock, Google Cloud’s Agent Platform, or Microsoft Foundry |
| `experimental.evals`                 | Path, or array of paths          | Directory that holds the plugin’s [eval cases](plugin-evals.md#use-a-different-eval-directory) when it isn’t the default `evals/`. `claude plugin eval --eval-dir` overrides it                                                                                                                            |

In the Type column, a path is a string relative to the plugin root, such as `"./custom/commands"`.


[​](#name)

`name`

The plugin identifier. It must be non-empty, with no spaces, `@`, `:`, path separators, control characters, or bidirectional-formatting characters; use kebab-case. Claude Code namespaces every component under it, so an agent `reviewer` in plugin `deploy-tools` appears as `deploy-tools:reviewer`.


[​](#displayname)

`displayName`

The name shown in UI in place of `name`. It may contain spaces and any casing, and it isn’t used for namespacing or lookup. For a marketplace-installed plugin, a `displayName` on the [marketplace entry](plugins-marketplace-reference.md#plugin-entries) takes precedence over this value.


[​](#version)

`version`

A version string, not checked against semver. Setting it pins the plugin to that version until you change it; see [Versions and updates](plugins-loading.md#versions-and-updates). A plugin with a [`command` source](plugins-marketplace-reference.md), a plugin from a [marketplace hosted on claude.ai](discover-plugins.md#add-from-claude-ai), and a plugin [loaded in place](plugins-loading.md#find-plugins-on-disk) from a marketplace added as a local directory aren’t pinned by this field.


[​](#metadata)

`metadata`

A free-form object for your own data, such as catalog or entitlement fields. Claude Code doesn’t read it. Requires Claude Code v2.1.222 or later.


[​](#defaultenabled)

`defaultEnabled`

Whether the plugin starts enabled when the user hasn’t set it in [`enabledPlugins`](../02-Claude-Code-CLI/settings-reference.md#enabledplugins). Defaults to `true`. A plugin that an enabled plugin depends on starts enabled regardless. The same field in the marketplace entry overrides this one. Once a user’s `enabledPlugins` entry is written, it persists across plugin updates, so changing `defaultEnabled` in a later release doesn’t change the setting for an existing user.


[​](#dependencies)

`dependencies`

Plugins that must be enabled for this one to work. Each entry is `"name"`, `"name@marketplace"`, or `{ "name": "...", "marketplace": "...", "version": "..." }`. Bare names resolve against this plugin’s own marketplace. See [dependency constraints](plugins-dependencies.md).


[​](#settings)

`settings`

Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect; other keys are dropped at load. A `settings.json` at the plugin root takes precedence over this key. See [Default settings](plugins-components.md#default-settings).


[​](#component-path-forms)

Component path forms

Every component key accepts a path relative to the plugin root. `hooks`, `mcpServers`, `lspServers`, and `experimental.monitors` also accept inline configuration, `commands` also accepts an object map, and `mcpServers` also accepts MCP bundle paths and URLs. The examples that follow show each accepted shape once. For what each component does at runtime, see [Plugin components](plugins-components.md).


[​](#path-only-fields)

Path-only fields

`agents`, `skills`, `outputStyles`, `workflows`, and `experimental.themes` take one path or an array of paths. `agents` entries must be `.md` files, and `skills` entries must be directories. The other three accept a directory or a file.

```python
{
  "agents": ["./custom-agents/reviewer.md", "./custom-agents/tester.md"],
  "skills": ["./extra-skills/", "."],
  "outputStyles": "./styles/"
}
```


[​](#commands)

`commands`

`commands` takes a path, an array of paths, or an object map. A path names a flat `.md` command file or a directory. In the object map, each key becomes the command name after the plugin prefix. For example, `"about"` in plugin `deploy-tools` runs as `/deploy-tools:about`. Each value sets exactly one of `source` or `content`, and an entry that sets both or neither fails validation. The other fields in this table are optional:

| Field          | Type             | Description                                                      |
|:---------------|:-----------------|:-----------------------------------------------------------------|
| `source`       | string           | Path to the command’s Markdown file, relative to the plugin root |
| `content`      | string           | Inline Markdown for the command body, instead of `source`        |
| `description`  | string           | Description shown for the command                                |
| `argumentHint` | string           | Argument hint shown after the command name, such as `[file]`     |
| `model`        | string           | Default model for the command                                    |
| `allowedTools` | array of strings | Tools the command may use without prompting                      |

This map declares one command from a file and one from inline content:

```python
{
  "commands": {
    "status": { "source": "./commands/status.md", "argumentHint": "[env]" },
    "about": { "content": "Explain what this plugin provides." }
  }
}
```


[​](#hooks)

`hooks`

`hooks` takes a `.json` file path, an inline hooks object in the same shape as [`hooks` in `settings.json`](../07-Hooks/hooks.md#configuration), or an array mixing both. For hook events and handler fields, see the [hooks reference](../07-Hooks/hooks.md#hook-events). Claude Code merges whatever you declare with `hooks/hooks.json` when that file exists.

```python
{
  "hooks": [
    "./config/extra-hooks.json",
    {
      "PostToolUse": [
        {
          "matcher": "Write|Edit",
          "hooks": [
            { "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/format.sh" }
          ]
        }
      ]
    }
  ]
}
```


[​](#mcpservers)

`mcpServers`

`mcpServers` takes a `.json` file path, an MCP bundle path or URL, an inline map, or an array mixing them. For server config fields, see [plugin-provided MCP servers](../06-MCP-Tools/General/mcp.md#plugin-provided-mcp-servers). Claude Code loads `.mcp.json` at the plugin root first, then each declared shape in order. A server name declared later replaces an earlier one. An `mcpServers` value takes one of these shapes:

| Shape             | Example value                                                                          | What Claude Code does                                                                                       |
|:------------------|:---------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------|
| `.json` file path | `"./mcp/servers.json"`                                                                 | Reads the file as an `mcpServers` map                                                                       |
| MCP bundle path   | `"./bundle.mcpb"`                                                                      | Extracts the `.mcpb` or `.dxt` bundle into `.mcpb-cache/` under the plugin root and reads its server config |
| MCP bundle URL    | `"https://example.com/server.mcpb"`                                                    | Downloads the bundle into `.mcpb-cache/`, then reads it                                                     |
| Inline map        | `{ "deploy-api": { "command": "node", "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"] } }` | Uses the map as server configs keyed by name                                                                |

A bundle path or URL must end in `.mcpb` or `.dxt`. Any other extension fails validation.


[​](#lspservers)

`lspServers`

`lspServers` takes a `.json` file path, an inline map of server name to config, or an array of either. Claude Code loads `.lsp.json` at the plugin root first, then each declared config in order. A server name declared later replaces an earlier one. Each server config is a strict object with these fields. An unknown key fails validation.

| Field                   | Required | Description                                                                                                                                                              |
|:------------------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `command`               | Yes      | Language server binary. No spaces unless the value starts with `/`; put arguments in `args`                                                                              |
| `extensionToLanguage`   | Yes      | Map of file extension to LSP language ID, at least one entry. Keys start with a dot, such as `".go"`                                                                     |
| `args`                  | No       | Arguments passed to the server                                                                                                                                           |
| `transport`             | No       | Communication transport: `stdio` (default) or `socket`. Claude Code accepts `socket` but runs every server over stdio, so the stdout protocol rules apply to all servers |
| `env`                   | No       | Environment variables for the server process                                                                                                                             |
| `initializationOptions` | No       | Options sent in the initialize request                                                                                                                                   |
| `settings`              | No       | Settings sent by `workspace/didChangeConfiguration`                                                                                                                      |
| `workspaceFolder`       | No       | Workspace folder path for the server                                                                                                                                     |
| `startupTimeout`        | No       | Milliseconds to wait for startup, a positive integer                                                                                                                     |
| `shutdownTimeout`       | No       | Milliseconds to wait for a graceful shutdown, a positive integer. When the timeout elapses, Claude Code terminates the server process. When unset, no timeout applies    |
| `restartOnCrash`        | No       | Whether to restart the server after it crashes. Defaults to `true`. Set to `false` to leave a crashed server stopped instead of restarting it                            |
| `maxRestarts`           | No       | Restart attempts before giving up, zero or more                                                                                                                          |
| `diagnostics`           | No       | Whether to push diagnostics into context after edits. Defaults to `true`                                                                                                 |

This inline config runs `gopls` for `.go` files:

```python
{
  "lspServers": {
    "go": {
      "command": "gopls",
      "args": ["serve"],
      "extensionToLanguage": { ".go": "go" }
    }
  }
}
```

For the language servers Anthropic publishes as plugins and how the servers behave at runtime, see [Code intelligence](plugins-code-intelligence.md).


[​](#monitors)

`monitors`

`experimental.monitors` takes a `.json` file path or the inline array. When you omit the key, Claude Code loads `monitors/monitors.json` if it exists. Each entry is a strict object with these fields.

| Field         | Required | Description                                                                                                                                                        |
|:--------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`        | Yes      | Identifier unique within the plugin                                                                                                                                |
| `command`     | Yes      | Shell command Claude Code runs as a persistent background process in the session working directory                                                                 |
| `description` | Yes      | Short summary shown in the task panel and notification summaries                                                                                                   |
| `when`        | No       | With `"always"`, the default, the monitor starts at session start and on plugin reload. With `"on-skill-invoke:<skill>"`, it starts the first time that skill runs |

This inline array declares one monitor that starts the first time the `deploy` skill runs:

```python
{
  "experimental": {
    "monitors": [
      {
        "name": "deploy-status",
        "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/poll-deploy.sh",
        "description": "Deployment status changes",
        "when": "on-skill-invoke:deploy"
      }
    ]
  }
}
```

A monitor `command` can’t reference `${user_config.*}`. See [Fields that run through a shell](#fields-that-run-through-a-shell).


[​](#path-rules)

Path rules

Every component path in a manifest is relative to the plugin root and must start with `./`. A path such as `commands/foo.md` fails validation. `skills` and `mcpServers` each accept one form outside that rule:

- **`skills`**: also accepts `"."`. Both `"."` and `"./"` denote the plugin root. Before v2.1.221, `"."` failed manifest validation, so use `"./"` when the plugin must load on earlier versions
- **`mcpServers`**: also accepts an `https://` bundle URL


[​](#containment-and-existence)

Containment and existence

Every component path must resolve inside the plugin root and must exist. `claude plugin validate` checks the paths under every component key:

- **Containment**: a path that resolves outside the plugin root doesn’t load, and the `/plugin` **Errors** tab shows `<component> path escapes plugin directory: <path>`. A path containing `..` is the usual case, and `claude plugin validate` reports the error `Path contains ".." which could be a path traversal attempt`
- **Existence**: a path that doesn’t exist doesn’t load, and the `/plugin` **Errors** tab shows `<component> path not found: <path>`. `claude plugin validate` reports the error `Path not found`

For `outputStyles`, `lspServers`, `monitors`, and `themes` paths, the `claude plugin validate` check requires Claude Code v2.1.283 or later.


[​](#how-each-key-combines-with-its-default-location)

How each key combines with its default location

Each component key either replaces its default location, adds to it, or merges with it:

- **Replaces the default**: `commands`, `agents`, `outputStyles`, `workflows`, `experimental.themes`, `experimental.monitors`. When you set `commands`, the default `commands/` directory isn’t scanned. To keep the default and add more, list it explicitly: `"commands": ["./commands/", "./extras/"]`
- **Adds to the default**: `skills`. The `skills/` directory is still scanned, and the listed directories load alongside it
- **Merges**: `hooks`, `mcpServers`, `lspServers`. The default file loads first, and what the manifest declares merges into it, as described under [Component path forms](#component-path-forms)

If a plugin has a default folder such as `commands/` and also sets the manifest key that replaces it, Claude Code loads the manifest paths and not the folder. `claude plugin list` and the `/plugin` interface then show the warning `Default <folder>/ folder is ignored because the manifest sets "<key>"`. To avoid the warning, set the key to a path inside that folder: `"commands": ["./commands/deploy.md"]` names a file in the default folder and produces no warning.


[​](#user-configuration)

User configuration

`userConfig` declares values Claude Code prompts the user for when the plugin is enabled, so users don’t edit `settings.json` themselves. Keys are identifiers made of letters, digits, and underscores, and can’t start with a digit. Each value is a strict object with these fields. An unknown key fails validation.

| Field         | Required | Description                                                                                                                                                                               |
|:--------------|:---------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`        | Yes      | One of `string`, `number`, `boolean`, `directory`, or `file`                                                                                                                              |
| `title`       | Yes      | Label shown in the configuration dialog                                                                                                                                                   |
| `description` | Yes      | Help text shown beneath the field                                                                                                                                                         |
| `required`    | No       | If `true`, the configuration dialog doesn’t accept an empty value                                                                                                                         |
| `default`     | No       | Value used when the user provides nothing: a string, number, boolean, or array of strings                                                                                                 |
| `options`     | No       | For `string`, the values the field accepts, shown as a picker in `/config`. See [Limit a field to fixed options](#limit-a-field-to-fixed-options). Requires Claude Code v2.1.271 or later |
| `multiple`    | No       | For `string`, allows an array of strings                                                                                                                                                  |
| `sensitive`   | No       | If `true`, masks input and stores the value in secure storage instead of `settings.json`                                                                                                  |
| `min` / `max` | No       | Bounds for `number`                                                                                                                                                                       |

Each option of each enabled plugin also appears as a row in the `/config` panel, except `sensitive` options and `multiple` lists. The `/config` rows require Claude Code v2.1.269 or later. This `userConfig` declares an endpoint and a masked token:

```python
{
  "userConfig": {
    "api_endpoint": {
      "type": "string",
      "title": "API endpoint",
      "description": "Your team's API endpoint"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "API authentication token",
      "sensitive": true
    }
  }
}
```


[​](#limit-a-field-to-fixed-options)

Limit a field to fixed options

Set `options` on a `userConfig` field to make users pick its value from a fixed list. To limit a `tone` field to three options, list them in `options` and set `default` to one of them:

```python
{
  "userConfig": {
    "tone": {
      "type": "string",
      "title": "Tone",
      "description": "Voice for generated replies",
      "options": ["neutral", "warm", "formal"],
      "default": "neutral"
    }
  }
}
```

If you declare `options` on any field, users on Claude Code versions before v2.1.271 can’t load the plugin. `options` applies to a `string` field that isn’t `multiple` or `sensitive`. Set `default` to one of the listed values, or set `required: true` so the user must pick one. Each option is a plain label of 1 to 64 characters, and `claude plugin validate`, which you run in your shell, reports anything else it rejects. A plugin whose `options` break these rules fails to load.


[​](#where-values-are-stored)

Where values are stored

Non-sensitive values are saved under [`pluginConfigs`](../02-Claude-Code-CLI/settings-reference.md#pluginconfigs) in the user’s `settings.json`. Sensitive values go to the platform’s secure credential store instead. The [settings page](../02-Claude-Code-CLI/settings-reference.md#pluginconfigs) lists which settings files `pluginConfigs` is read from.


[​](#reference-a-saved-value)

Reference a saved value

Reference a saved value where the plugin needs it, in one of two forms:

- **`${user_config.KEY}`**: substituted in MCP server config, LSP server config, [exec-form](../07-Hooks/hooks.md#exec-form-and-shell-form) hook `args`, and skill and agent content. In skill and agent content, only non-sensitive values are substituted, and a sensitive value there becomes a placeholder
- **`CLAUDE_PLUGIN_OPTION_<KEY>`**: exported to hook processes for every option, with `<KEY>` uppercased. A shell-form hook reads `$CLAUDE_PLUGIN_OPTION_API_TOKEN` for `api_token`


[​](#fields-that-run-through-a-shell)

Fields that run through a shell

Shell-form hook commands, monitor commands, and MCP [`headersHelper`](../06-MCP-Tools/General/mcp.md#use-dynamic-headers-for-custom-authentication) reject `${user_config.*}`. A component that references it in one of these fields fails with an [error](../02-Claude-Code-CLI/errors.md#plugin-command-references-user-config) instead of running, because the field’s value is passed to a shell that would re-parse the substituted value. The table shows how the value can reach each of these fields instead.

| Field                    | How the value can reach it                                                                                                                                                                                                    |
|:-------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Shell-form hook commands | Use [exec form](../07-Hooks/hooks.md#exec-form-and-shell-form) with `args`, or read `CLAUDE_PLUGIN_OPTION_<KEY>` from the hook’s environment                                                                                        |
| Monitor commands         | Not through Claude Code. Monitor processes don’t receive `CLAUDE_PLUGIN_OPTION_<KEY>`, so the monitor script has to obtain the value on its own                                                                               |
| MCP `headersHelper`      | Not through Claude Code. The helper’s environment carries `CLAUDE_PLUGIN_ROOT`, `CLAUDE_CODE_MCP_SERVER_NAME`, and `CLAUDE_CODE_MCP_SERVER_URL` but no option values, so the helper script has to obtain the value on its own |


[​](#channels)

Channels

`channels` declares the message channels a plugin provides, such as a bridge to a chat app. When you declare one, Claude Code can prompt for the channel’s configuration when the plugin is enabled. For how the server injects messages, see the [channels reference](../02-Claude-Code-CLI/channels-reference.md#package-as-a-plugin). Each entry is a strict object bound to one of the plugin’s MCP servers, with these fields:

| Field         | Required | Description                                                                                                                                                                   |
|:--------------|:---------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `server`      | Yes      | Key of the MCP server in this plugin’s `mcpServers` that the channel binds to                                                                                                 |
| `displayName` | No       | Name shown in the configuration dialog title. Defaults to the server name                                                                                                     |
| `userConfig`  | No       | Options to prompt for, in the same shape as [top-level `userConfig`](#user-configuration). Saved values substitute into `${user_config.KEY}` references in the server’s `env` |

This manifest binds a channel to the plugin’s `telegram` MCP server and prompts for a bot token that substitutes into the server’s `env`:

```python
{
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "displayName": "Telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}
```


[​](#environment-variables)

Environment variables

Claude Code provides three path variables to plugin components. Reference them as `${NAME}` in the fields listed under [Where each variable resolves](#where-each-variable-resolves), and read them as environment variables in the processes that receive them.

| Variable                | Resolves to                                                                                                                                                                                             | Use it for                                                                |
|:------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------|
| `${CLAUDE_PLUGIN_ROOT}` | Absolute path of the plugin’s installed version                                                                                                                                                         | Scripts, binaries, and config files bundled with the plugin               |
| `${CLAUDE_PLUGIN_DATA}` | `~/.claude/plugins/data/<id>/`, created on first reference and kept across plugin updates. `<id>` is the plugin identifier with every character other than a letter, digit, `_`, or `-` replaced by `-` | Installed dependencies such as `node_modules`, generated code, and caches |
| `${CLAUDE_PROJECT_DIR}` | The project root                                                                                                                                                                                        | Project-local scripts and config files                                    |

`${CLAUDE_PLUGIN_ROOT}` changes when the plugin updates, so don’t write state there. For where the root moves and when the old directory is cleaned up, see the [loading page](plugins-loading.md). By default, Claude Code deletes the `${CLAUDE_PLUGIN_DATA}` directory when you uninstall the plugin from the last place it’s installed. For `--keep-data` and the other cases where it stays, see [plugin uninstall](plugins-cli-reference.md#plugin-uninstall).


[​](#where-each-variable-resolves)

Where each variable resolves

In each plugin component, `${...}` references resolve inline in specific fields, and some components also receive the variables in their process environment:

| Plugin component                  | Fields where `${...}` resolves              | Exported to the process                                                                            |
|:----------------------------------|:--------------------------------------------|:---------------------------------------------------------------------------------------------------|
| Hook commands                     | Anywhere in `command` and `args`            | `CLAUDE_PLUGIN_ROOT`, `CLAUDE_PLUGIN_DATA`, `CLAUDE_PROJECT_DIR`, and `CLAUDE_PLUGIN_OPTION_<KEY>` |
| Monitor commands                  | Anywhere in `command`                       | Not exported                                                                                       |
| MCP `stdio` servers               | `command`, `args`, `env`                    | `CLAUDE_PLUGIN_ROOT`, `CLAUDE_PLUGIN_DATA`                                                         |
| MCP `http`, `sse`, `ws` servers   | `url`, `headers`, `headersHelper`           | Not applicable                                                                                     |
| LSP servers                       | `command`, `args`, `env`, `workspaceFolder` | `CLAUDE_PLUGIN_ROOT`, `CLAUDE_PLUGIN_DATA`, `CLAUDE_PROJECT_DIR`                                   |
| Skill, command, and agent content | Anywhere in the Markdown body               | Not applicable                                                                                     |

The variables aren’t present in the environment of commands Claude runs through the Bash tool, in the main session or in a subagent. In skill, command, and agent content, write the `${...}` reference in the Markdown body instead, and Claude Code substitutes the path inline when it loads the content.


[​](#quoting-and-path-separators)

Quoting and path separators

Keep each substituted path a single argument:

- **Hook commands**: use [exec form](../07-Hooks/hooks.md#exec-form-and-shell-form) with `args` so each path is one argument with no quoting
- **Shell-form hooks and monitor commands**: wrap the variable in double quotes so a path with spaces stays one word

If you leave one of these variables outside quotes in a shell-form command in a hooks file, `claude plugin validate` warns about it unless the hook sets [`shell`](../07-Hooks/hooks.md#command-hook-fields) to `"powershell"`. This shell-form hook runs a script bundled with the plugin:

```python
{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/process.sh"
          }
        ]
      }
    ]
  }
}
```

On Windows, the substituted paths use forward slashes so a shell doesn’t read backslashes as escapes.


[​](#standard-layout)

Standard layout

Each component type has a default location under the plugin root, used when the manifest doesn’t point elsewhere.

| Component     | Default location             | Contents                                                                                                                                                                                                                                                                                                                                              |
|:--------------|:-----------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Manifest      | `.claude-plugin/plugin.json` | Plugin metadata and configuration. Optional                                                                                                                                                                                                                                                                                                           |
| Skills        | `skills/`                    | One `<name>/SKILL.md` per skill. A plugin with `SKILL.md` at its root, no `skills/`, and no `skills` key loads as a single skill                                                                                                                                                                                                                      |
| Commands      | `commands/`                  | Flat Markdown command files. Prefer `skills/` for new plugins                                                                                                                                                                                                                                                                                         |
| Agents        | `agents/`                    | Agent Markdown files. Subfolders are part of the [agent name](plugins-components.md#agents)                                                                                                                                                                                                                                                     |
| Hooks         | `hooks/hooks.json`           | Hook configuration                                                                                                                                                                                                                                                                                                                                    |
| MCP servers   | `.mcp.json`                  | MCP server definitions                                                                                                                                                                                                                                                                                                                                |
| LSP servers   | `.lsp.json`                  | LSP server configurations                                                                                                                                                                                                                                                                                                                             |
| Output styles | `output-styles/`             | Output style Markdown files                                                                                                                                                                                                                                                                                                                           |
| Workflows     | `workflows/`                 | Workflow `.js` files                                                                                                                                                                                                                                                                                                                                  |
| Themes        | `themes/`                    | Theme JSON files                                                                                                                                                                                                                                                                                                                                      |
| Monitors      | `monitors/monitors.json`     | The monitors array                                                                                                                                                                                                                                                                                                                                    |
| Executables   | `bin/`                       | Files here are on the Bash tool’s `PATH` while the plugin is enabled, so Claude runs them as bare commands. claude.ai and Cowork don’t install a plugin that has this directory, including one you [distribute through claude.ai organization settings](https://claude.com/docs/plugins/org-sync#keep-executables-out-of-the-top-level-bin-directory) |
| Settings      | `settings.json`              | `agent` and `subagentStatusLine` defaults applied while the plugin is enabled                                                                                                                                                                                                                                                                         |

A plugin that uses every default location, plus a `scripts/` folder that its hooks call, is laid out like this:

```python
deploy-tools/
├── .claude-plugin/
│   └── plugin.json
├── skills/
│   └── deploy/
│       └── SKILL.md
├── commands/
│   └── status.md
├── agents/
│   └── reviewer.md
├── hooks/
│   └── hooks.json
├── monitors/
│   └── monitors.json
├── output-styles/
│   └── terse.md
├── themes/
│   └── dracula.json
├── workflows/
│   └── release-audit.js
├── bin/
│   └── deploy-tool
├── scripts/
│   └── format.sh
├── settings.json
├── .mcp.json
└── .lsp.json
```

To click through this layout and read what each file does, open the [plugin explorer](plugins-components.md#explore-the-plugin-directory). A `CLAUDE.md` at the plugin root isn’t loaded as context, and `claude plugin validate` warns when it finds one. To include instructions that load into Claude’s context, put them in a skill.


[​](#marketplace-entries-and-the-manifest)

Marketplace entries and the manifest

A [marketplace entry](plugins-marketplace-reference.md) accepts every field on this page alongside [its own fields](plugins-marketplace-reference.md#plugin-entries), including `strict`. The `strict` field decides whether the entry may add components to a plugin that has its own `plugin.json`. It defaults to `true`.


[​](#how-entry-fields-combine-with-plugin-json)

How entry fields combine with `plugin.json`

The entry either serves as the manifest, adds components to it, or conflicts with it:

- **No `plugin.json`**: the entry is the manifest, regardless of `strict`. Entry `hooks` loads only in the inline object form. For a file path or array there, the `/plugin` **Errors** tab shows a `not yet supported in a marketplace entry` error
- **`plugin.json` present, `strict` unset or `true`**: Claude Code loads the manifest and appends the entry’s `commands`, `agents`, `skills`, `outputStyles`, and `themes` to it. For `hooks`, the entry’s matchers for an event replace the manifest’s matchers for that same event, and events only the manifest declares keep theirs
- **`plugin.json` present, `strict: false`**: an entry that declares any of `commands`, `agents`, `skills`, `hooks`, `outputStyles`, or `themes` is a conflict, and the plugin fails to load with `Plugin <name> has conflicting manifests`

When a [marketplace entry whose `source` is the marketplace root](plugins-marketplace-reference.md) lists specific `skills` subdirectories, only those subdirectories load, and the plugin’s default `skills/` directory isn’t scanned. A `skills` key in the manifest instead [adds to the default](#how-each-key-combines-with-its-default-location).


[​](#metadata-precedence)

Metadata precedence

Some metadata fields have a fixed precedence regardless of `strict`:

- **`defaultEnabled` and display fields**: the entry’s `defaultEnabled` and its [display fields](plugins-marketplace-reference.md#entry-and-plugin-json) such as `displayName` override the manifest’s
- **`version`**: the manifest’s `version` overrides the entry’s
- **`name`**: when the entry lists the plugin under a different `name` than the manifest, `enabledPlugins` uses the entry name, and components are namespaced under the manifest name

For the full precedence table, see [Strict mode](plugins-marketplace-reference.md).


[​](#next-steps)

Next steps

- [Add components to a plugin](plugins-components.md): what each component does at runtime, with an example that validates
- [Marketplace reference](plugins-marketplace-reference.md): the entry fields a marketplace can set for your plugin
- [Plugin commands reference](plugins-cli-reference.md#plugin-validate): `claude plugin validate` flags and output
- [Troubleshoot plugins](plugins-troubleshooting.md#claude-plugin-validate-reports-errors): each validation message with its fix

---

## Recommend plugins for your org - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/relevance
Path: 08-Plugins-Skills/plugins-relevance.md

## On this page

- [Understand how plugin relevance works](#understand-how-plugin-relevance-works)
- [Add relevance to a plugin entry](#add-relevance-to-a-plugin-entry)
- [Field reference](#field-reference)
  - [relevance](#relevance)
  - [relevance.signals](#relevance-signals)
  - [Working directory matching](#working-directory-matching)
  - [Command name matching](#command-name-matching)
  - [Manifest dependency matching](#manifest-dependency-matching)
- [Validate your marketplace](#validate-your-marketplace)
- [Enable suggestions in managed settings](#enable-suggestions-in-managed-settings)
- [Preview what the user sees](#preview-what-the-user-sees)
- [See also](#see-also)

Run a marketplace

# Recommend plugins for your org

Copy pageCopy page

Add a relevance block to marketplace plugin entries so Claude Code suggests them when a user’s work matches, and allowlist the marketplace in managed settings.

Copy pageCopy page

Claude Code can suggest installing a plugin from your organization’s marketplace when a user’s session matches signals you define for that plugin. Signals include the working directory, files Claude has read, and commands Claude has run. You define them by adding a `relevance` block to the plugin’s entry in `marketplace.json`. A marketplace operator writes the `relevance` entries. An administrator then allowlists the marketplace in managed settings. Users see no suggestions from a marketplace until it’s allowlisted.

These cases are covered on other pages:

- **You want to install plugins**: see [Install and manage plugins](discover-plugins.md)
- **You want to turn suggestions off**: see [Understand how plugin relevance works](#understand-how-plugin-relevance-works)

Start with the sections for your role:

- **Marketplace operators**: read [how suggestions work](#understand-how-plugin-relevance-works), then [add relevance to a plugin entry](#add-relevance-to-a-plugin-entry) and [validate your marketplace](#validate-your-marketplace)
- **Administrators**: [enable suggestions in managed settings](#enable-suggestions-in-managed-settings)


[​](#understand-how-plugin-relevance-works)

Understand how plugin relevance works

Each plugin entry in `marketplace.json` can include a `relevance` object. The object names a topic and one or more signals. A signal is a pattern that Claude Code tests against the current session, such as the working directory or files Claude has read. Signal matching happens locally on the user’s machine and adds no network traffic. Claude Code doesn’t report which signals matched or their values to Anthropic or to the marketplace operator. When a signal matches and the plugin isn’t already installed, Claude Code suggests the plugin in these places:

- **Spinner tip**: a message with the `/plugin install` command appears below the spinner while Claude is responding.
- **Session-start notification**: if a `cwd` signal matches the working directory, a one-line notification appears before the user sends a first message.
- **`/plugin` Discover tab**: the plugin is pinned to the top of the Discover list.

[Preview what the user sees](#preview-what-the-user-sees) shows the exact text of each and how often they repeat. Claude Code never installs the plugin automatically. The user always confirms. The spinner tip and the session-start notification both stop appearing when the user or project sets [`spinnerTipsEnabled`](../02-Claude-Code-CLI/settings-reference.md#spinnertipsenabled) to `false`, or when a [`spinnerTipsOverride`](../02-Claude-Code-CLI/settings-reference.md#spinnertipsoverride) with `excludeDefault` replaces the built-in tips. The Discover-tab pin isn’t affected by either setting.


[​](#add-relevance-to-a-plugin-entry)

Add relevance to a plugin entry

Add a `relevance` object to the plugin’s entry in your `marketplace.json`. The following example declares that the `terraform-helpers` plugin is relevant when Claude reads a `.tf` file or runs `terraform`:

```python
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "plugins": [
    {
      "name": "terraform-helpers",
      "source": "./plugins/terraform-helpers",
      "description": "Your organization's Terraform conventions and helpers",
      "relevance": {
        "topic": "Terraform",
        "signals": {
          "cli": ["terraform"],
          "filesRead": ["**/*.tf"]
        }
      }
    }
  ]
}
```

While none of its signals match, the plugin keeps its normal position in the Discover list and doesn’t appear as a spinner tip. To check the block before publishing, [validate your marketplace](#validate-your-marketplace).


[​](#field-reference)

Field reference

The `relevance` object and its nested `signals` object accept the fields in the following tables. Older clients still load a marketplace that uses `relevance` fields they don’t recognize, because unknown fields under `relevance` and `relevance.signals` are ignored at load time. A recognized field whose value exceeds its limit in the [field reference](#field-reference) invalidates the whole plugin entry, and users can’t install that plugin from the marketplace until you fix it; `claude plugin validate` reports the same limits.


[​](#relevance)

`relevance`

| Field     | Type   | Description                                                                                                                                                             |
|:----------|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `topic`   | string | Optional. The phrase that fills “Working with *topic*?” in the spinner tip. Defaults to the plugin name with each hyphen segment capitalized. Maximum 64 characters.    |
| `signals` | object | Matchers that determine when the plugin is relevant. Claude Code suggests the plugin only if at least one signal is set. See [`relevance.signals`](#relevance-signals). |

The `topic` is often the product name, for example `Terraform`. Use a domain such as `design` when the plugin name doesn’t sound natural as a topic.


[​](#relevance-signals)

`relevance.signals`

The `signals` object accepts the following fields.

| Field          | Type             | Description                                                                                                                                                                                                                                 | Limit                                                                                        |
|:---------------|:-----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|
| `cwd`          | array of strings | Glob patterns matched against the session’s working directory. See [working directory matching](#working-directory-matching).                                                                                                               | 10 patterns of 256 characters each                                                           |
| `cli`          | array of strings | Command names from shell commands Claude has run this session, for example `["terraform"]`. Exact match. See [command name matching](#command-name-matching).                                                                               | 10 entries of 64 characters each                                                             |
| `hosts`        | array of strings | Hostnames seen in `http://` or `https://` URLs in Bash commands this session, for example `["registry.terraform.io"]`. Bare lowercase hostname only: no scheme, port, or path. Exact case-insensitive match.                                | 20 entries of 128 characters each                                                            |
| `filesRead`    | array of strings | Glob patterns matched against the paths of files Claude has read this session, for example `["**/*.tf"]`. Forward-slash normalized and case-insensitive.                                                                                    | 10 patterns of 256 characters each                                                           |
| `manifestDeps` | array of objects | Dependencies declared in package manifests Claude has read this session. Each entry is `{ "file": "...", "pattern": "..." }`, where both values are regular expressions. See [manifest dependency matching](#manifest-dependency-matching). | 10 entries, each value at most 256 characters. Manifest files larger than 512 KB are skipped |

The `filesRead` and `manifestDeps` signals also match against files Claude has written or edited this session and against the project’s auto-loaded `CLAUDE.md` memory files.


[​](#working-directory-matching)

Working directory matching

`cwd` is the only signal that can match at session start, before the user sends a first message. Claude Code matches each `cwd` pattern as follows:

- The pattern is matched against the working directory as an absolute path. When the session is inside a git repository, it’s also matched against the working directory’s path relative to the repository root.
- Matching is forward-slash normalized and case-insensitive.
- Every pattern matches the directory itself and everything under it, so `infra`, `infra/`, and `infra/**` behave identically.


[​](#command-name-matching)

Command name matching

Claude Code records one command name for each shell command Claude runs: the first token after any leading environment variable assignments and `sudo`. Compound commands contribute only their leading command, so `cd infra && terraform plan` records `cd`, not `terraform`.


[​](#manifest-dependency-matching)

Manifest dependency matching

Each `manifestDeps` entry pairs two JavaScript `RegExp` source strings:

- `file`: matched case-insensitively against the manifest file’s path. The path is typically absolute, so anchor the pattern at the end rather than the start. Paths aren’t separator-normalized for this signal, so Windows paths use backslashes.
- `pattern`: matched case-sensitively against that file’s contents.

The following example uses `manifestDeps` to suggest your plugin once Claude has read a `package.json` that depends on your SDK’s npm package, named `your-sdk` here.

```python
{
  "name": "your-plugin",
  "source": "./plugins/your-plugin",
  "relevance": {
    "signals": {
      "manifestDeps": [
        {
          "file": "[/\\\\]package\\.json$",
          "pattern": "\"your-sdk\"\\s*:"
        }
      ]
    }
  }
}
```

In this example, the `file` pattern uses `[/\\\\]` so it matches both forward-slash and backslash path separators, and `\\.` so the dot is literal. In JSON, each backslash in the regular expression is written twice.


[​](#validate-your-marketplace)

Validate your marketplace

In your shell, run `claude plugin validate` against your marketplace directory to check the `relevance` block before publishing:

```python
claude plugin validate ./my-marketplace
```

The validator reports errors and warnings on the `relevance` block, including these:

- Reports unknown keys under `relevance` and `relevance.signals` as warnings
- Flags a `relevance` value that isn’t an object
- Rejects a `signals.hosts` entry that includes a scheme, port, or path

Each finding prints with the path of the field it concerns, and the output ends with `Validation passed`, `Validation passed with warnings`, or `Validation failed`.


[​](#enable-suggestions-in-managed-settings)

Enable suggestions in managed settings

Users see no suggestions from a marketplace until an administrator allowlists it in [managed settings](plugins-org.md), even when its `marketplace.json` declares `relevance`. To allowlist a marketplace, edit your managed settings as follows:

- Add the marketplace name to `pluginSuggestionMarketplaces`.
- For any marketplace other than the official Anthropic marketplace, also declare the marketplace source, either as that name’s entry in [`extraKnownMarketplaces`](plugins-org.md#require-a-marketplace-and-its-plugins) or as an entry in [`strictKnownMarketplaces`](plugins-org.md#allowlist-with-strictknownmarketplaces).

On a machine where the marketplace isn’t registered, or is registered under the allowlisted name from a different source, no suggestions from it appear. The source check stops an unrelated source from registering under an allowlisted name to get its plugins suggested across your org. The following `managed-settings.json` registers an org marketplace from a GitHub repository and enables its suggestions:

```python
{
  "extraKnownMarketplaces": {
    "your-marketplace": {
      "source": {
        "source": "github",
        "repo": "your-org/your-marketplace"
      }
    }
  },
  "pluginSuggestionMarketplaces": ["your-marketplace"]
}
```

The official marketplace’s name can only register from the official Anthropic source, so it needs no source declaration. For the official marketplace, allowlist the name alone:

```python
{
  "pluginSuggestionMarketplaces": ["claude-plugins-official"]
}
```


[​](#preview-what-the-user-sees)

Preview what the user sees

When a plugin’s `relevance` signal matches during a session, the tip below the spinner reads:

```python
Working with Terraform? Install the terraform-helpers plugin:
/plugin install terraform-helpers@your-marketplace
```

When a `cwd` signal matches at session start, the one-line notification reads:

```python
plugin suggestion: terraform-helpers@your-marketplace · /plugin
```

In the `/plugin` Discover tab, the plugin is pinned above the other results with an annotation that names the matching signal, such as `suggested for this directory` or `suggested for terraform commands`. Claude Code limits how often it suggests a given plugin:

- The suggestion appears at most once every three sessions across the spinner tip and the session-start notification combined.
- The session-start notification stops appearing once the spinner tip and the notification have shown the plugin a combined total of two times.
- Neither the spinner tip nor the session-start notification repeats once the plugin is installed.
- The Discover tab pins the plugin the first time the user opens the tab while the plugin’s signals match. Claude Code records that in `~/.claude.json`, so every later time the user opens `/plugin` on that machine, the plugin appears in normal order.


[​](#see-also)

See also

- [Host a marketplace](plugins-host-marketplace.md): run the marketplace that hosts your plugins
- [Marketplace reference](plugins-marketplace-reference.md#plugin-entries): every field a plugin entry accepts
- [Recommend your plugin from your CLI](plugins-cli-hints.md): prompt users from your own CLI instead of from Claude Code’s session signals
- [Manage plugins for your organization](plugins-org.md): `extraKnownMarketplaces`, `strictKnownMarketplaces`, and the rest of the plugin policy keys

---

## Plugin security and trust - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/security
Path: 08-Plugins-Skills/plugins-security.md

## On this page

- [Understand what a plugin can do](#understand-what-a-plugin-can-do)
- [Identify Anthropic’s marketplaces by name](#marketplace-tiers)
  - [Official marketplace names](#official-marketplace-names)
- [Review a plugin before you install](#review-a-plugin-before-you-install)
  - [Remove a plugin you no longer trust](#remove-a-plugin-you-no-longer-trust)
- [Recognize when Claude Code refuses or warns](#recognize-when-claude-code-refuses-or-warns)
  - [Trust warning before you install](#trust-warning-before-you-install)
  - [Untrusted marketplace sources and failed integrity checks](#untrusted-marketplace-sources-and-failed-integrity-checks)
- [Enforce plugin controls for your organization](#enforce-plugin-controls-for-your-organization)
- [Find plugins in telemetry](#find-plugins-in-telemetry)
- [Next steps](#next-steps)

Use plugins

# Plugin security and trust

Copy pageCopy page

Decide whether to trust a plugin before you install it, from what a plugin can do on your machine to how to review one and remove it.

Copy pageCopy page

A Claude Code plugin you install can execute arbitrary code on your machine with your user privileges. You install a plugin from a marketplace, which is the catalog Claude Code fetches it from. Some marketplace names are [reserved for Anthropic’s own marketplaces](#marketplace-tiers), and every other marketplace is third-party. A marketplace’s name tells you who publishes the catalog, not what each plugin in it does, so [review a plugin before you install it](#review-a-plugin-before-you-install) whichever marketplace it comes from. Read this page if you’re deciding whether to install a plugin, or if you review tools before your team can use them.

These cases are covered on other pages:

- **Claude Code’s own security model**: see [Security](../13-Enterprise-Admin/security.md)
- **Restricting or requiring plugins for an organization**: see [Manage plugins for your organization](plugins-org.md)
- **The `security-guidance` or `claude-security` plugins**: this page isn’t about them. See [`security-guidance`](../02-Claude-Code-CLI/security-guidance.md) and [`claude-security`](../02-Claude-Code-CLI/claude-security.md)

Start with [what a plugin can do](#understand-what-a-plugin-can-do) and [which marketplaces are Anthropic’s](#marketplace-tiers), then [review the plugin before you install it](#review-a-plugin-before-you-install).


[​](#understand-what-a-plugin-can-do)

Understand what a plugin can do

A plugin can carry content that runs code on your machine with your user privileges and content that enters Claude’s context as instructions, so [review a plugin before you install it](#review-a-plugin-before-you-install). Here’s what an installed plugin can do:

- **Hooks**: a plugin’s [hooks](../07-Hooks/hooks.md) run as shell commands at points in Claude Code’s lifecycle, such as before or after a tool call.
- **MCP and LSP servers**: Claude Code connects to the [MCP servers](../06-MCP-Tools/General/mcp.md) an enabled plugin declares and gives Claude their tools. A stdio MCP server runs as a process that Claude Code starts on your machine. Claude Code also starts the language servers the plugin declares.
- **`bin/` directory**: Claude Code adds each enabled plugin’s `bin/` directory to the `PATH` of the Bash tool’s shell, so Claude’s Bash commands can run any executable there.
- **Skills, commands, and agents**: these enter Claude’s context as instructions, so they influence what Claude does with the tools it already has.
- **Updates**: when auto-update is on for the marketplace you installed a plugin from, Claude Code updates that plugin in the background, so the files you reviewed can change on disk. [When auto-update runs](plugins-loading.md#when-auto-update-runs) has the timing. To turn auto-update on or off per marketplace, see [Keep plugins updated](discover-plugins.md#keep-plugins-updated).

Claude Code’s [permission rules](../02-Claude-Code-CLI/permissions.md) and [sandbox](../02-Claude-Code-CLI/sandboxing.md) cover the tool calls Claude makes, not the code a plugin runs by itself:

- **Hooks and server processes**: command hooks execute shell commands with your full user permissions. Claude Code runs hooks and MCP servers outside the sandbox.
- **Claude’s tool calls**: a call to one of the plugin’s MCP tools, and a Bash command that runs an executable from the plugin’s `bin/`, are tool calls, so your permission rules apply to them.

Installing a plugin also enables it, unless its manifest or marketplace entry sets [`defaultEnabled: false`](discover-plugins.md#choose-an-install-scope) and you haven’t enabled it yourself. To remove a plugin you no longer trust, see [Remove a plugin you no longer trust](#remove-a-plugin-you-no-longer-trust).


[​](#marketplace-tiers)

Identify Anthropic’s marketplaces by name

A marketplace’s name places it in one of three tiers: official, community, or third-party. Claude Code accepts the official and community names only for marketplaces sourced from `github.com/anthropics/` repositories, so a third-party marketplace can’t present itself as an Anthropic one. A marketplace that a coworker or your organization publishes is third-party. The table lists which names fall in each tier:

| Tier        | Which marketplaces                                                                               |
|:------------|:-------------------------------------------------------------------------------------------------|
| Official    | The [official marketplace names](#official-marketplace-names), such as `claude-plugins-official` |
| Community   | `claude-community`, `claude-plugins-community`, and `healthcare`                                 |
| Third-party | Every other marketplace                                                                          |

Where the `claude-community` catalog pins a plugin to a commit SHA, which it does for nearly every entry, Claude Code refuses to install a different commit.


[​](#official-marketplace-names)

Official marketplace names

These marketplace names make up the official tier:

- `claude-plugins-official`
- `claude-code-marketplace`
- `claude-code-plugins`
- `anthropic-marketplace`
- `anthropic-plugins`
- `agent-skills`
- `anthropic-agent-skills`
- `life-sciences`
- `knowledge-work-plugins`
- `claude-for-legal`
- `claude-for-financial-services`
- `financial-services-plugins`
- `first-party-plugins`
- `claude-tag-plugins`

For how the official, community, and demo marketplaces differ and where to browse what each one lists, see [Anthropic’s marketplaces](plugins-anthropic-marketplaces.md).


[​](#review-a-plugin-before-you-install)

Review a plugin before you install

Before you install a plugin, look at what it adds and where it comes from.

1

Check the marketplace's source

In your shell, run `claude plugin marketplace list` to print the source each marketplace was added from, such as a GitHub repository or a directory.

2

Read the details pane

In a Claude Code session, run `/plugin` and select the plugin. The details pane shows a **Will install** section listing the plugin’s commands, agents, skills, hooks, and MCP and LSP servers. For a plugin Anthropic has no published component data for, the section shows what the marketplace entry declares, or a note: `Components will be discovered at installation` for a plugin stored inside the marketplace, or `Component summary not available for remote plugin` for one fetched from elsewhere.

3

Read the plugin's source

In the details pane, select **Open homepage** or **View on GitHub** below the install options. If the pane offers neither, open the marketplace repository you found in the first step. Find the plugin’s directory there. The **Will install** section shows that a hook exists but not what it runs, so read these files in the plugin’s directory:

- **`hooks/hooks.json`**: the command each hook runs
- **`.mcp.json`**: each server’s command or URL
- **`bin/`**: every file in the directory

4

List what the plugin contains

Clone the repository that holds the plugin’s directory, then run `claude --plugin-dir <plugin directory> plugin details <plugin name>` in your shell to see what Claude Code finds in it. The command reads the plugin’s files without starting a session and prints a `Component inventory` listing the plugin’s skills and commands, agents, hooks with each hook’s event, and MCP and LSP servers.

After you install a plugin, run `claude plugin details <plugin name>` in your shell to print the same `Component inventory` for the installed copy under `~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/`.


[​](#remove-a-plugin-you-no-longer-trust)

Remove a plugin you no longer trust

In your shell, run [`claude plugin uninstall <plugin>`](plugins-cli-reference.md#plugin-uninstall) with the `--scope` you installed it at. Then check what the uninstall removed and what it left:

- **Persistent data**: by default, when that was the last scope the plugin was installed at, uninstalling also deletes the plugin’s persistent data directory. For `--keep-data` and the other cases where it stays, see [plugin uninstall](plugins-cli-reference.md#plugin-uninstall).
- **Cached files**: the plugin’s files stay on disk under `~/.claude/plugins/cache/` for 14 days before a [background sweep removes them](plugins-loading.md#cleanup-of-previous-versions). After you uninstall your last plugin, orphaned directories stay until you install another. To delete the files now, remove the plugin’s directory under `~/.claude/plugins/cache/<marketplace>/<plugin>/` yourself.
- **The marketplace**: if you don’t trust the marketplace’s owner either, [remove the marketplace](discover-plugins.md#manage-marketplaces) too, which uninstalls every plugin you installed from it.


[​](#recognize-when-claude-code-refuses-or-warns)

Recognize when Claude Code refuses or warns

The details pane you open from the **Discover** or **Marketplaces** tab in `/plugin` shows the same trust warning for each plugin. Claude Code refuses instead of warning in cases such as those under [Untrusted marketplace sources and failed integrity checks](#untrusted-marketplace-sources-and-failed-integrity-checks).


[​](#trust-warning-before-you-install)

Trust warning before you install

The warning reads the same whatever marketplace the plugin comes from:

```python
Make sure you trust a plugin before installing, updating, or using it. Anthropic does not control what MCP servers, files, or other software are included in plugins and cannot verify that they will work as intended or that they won't change. See each plugin's homepage for more information.
```

If your organization sets `pluginTrustMessage` in [managed settings](plugins-org.md), Claude Code appends that text to the warning.


[​](#untrusted-marketplace-sources-and-failed-integrity-checks)

Untrusted marketplace sources and failed integrity checks

Claude Code refuses to load a marketplace or to install a plugin in these cases, each with its own error message:

- **Untrusted marketplace source**: when a marketplace uses an official or community name but its source is outside `github.com/anthropics/`, Claude Code stops loading the marketplace and the plugins you installed from it. The error is [Marketplace is registered from an untrusted source](../02-Claude-Code-CLI/errors.md#marketplace-is-registered-from-an-untrusted-source).
- **Archive integrity**: when a marketplace entry pins an [`archive` source](plugins-marketplace-reference.md#archive-plugin-source) to a `sha256` digest and the downloaded file’s digest doesn’t match it, Claude Code refuses the install. The error is [Plugin archive integrity check failed](../02-Claude-Code-CLI/errors.md#plugin-archive-integrity-check-failed).

The `sha256` pin is separate from the community catalog’s commit SHA pin, which selects the git commit to check out.


[​](#enforce-plugin-controls-for-your-organization)

Enforce plugin controls for your organization

With [managed settings](plugins-org.md), an administrator can enforce these plugin controls:

- Allowlist or blocklist marketplace sources
- Force-enable plugins
- Turn off the `--plugin-dir` and `--plugin-url` flags and the `CLAUDE_CODE_PLUGIN_DIRS` variable
- Limit hooks to those from managed settings and force-enabled plugins
- Stop plugins from members’ claude.ai accounts from loading in Claude Code, with [`syncClaudeAiPlugins`](plugins-org.md#control-matrix)

The [control matrix](plugins-org.md#control-matrix) says what each key does and doesn’t cover.


[​](#find-plugins-in-telemetry)

Find plugins in telemetry

If your organization exports Claude Code’s [OpenTelemetry events](../13-Enterprise-Admin/monitoring-usage.md) to its own backend, the [marketplace tiers](#marketplace-tiers) decide which plugin names appear there:

- **[Plugin loaded event](../13-Enterprise-Admin/monitoring-usage.md#plugin-loaded-event)**: the event reports official-tier plugin and marketplace names as they are. For the community and third-party tiers, `plugin.name` and `marketplace.name` are the literal string `third-party` unless you set `OTEL_LOG_TOOL_DETAILS=1`.
- **Plugin scope**: the loaded event’s `plugin.scope` still reports where the plugin came from, such as `org` for a plugin your managed settings enable or `user-local` for any other third-party plugin. The [plugin loaded event](../13-Enterprise-Admin/monitoring-usage.md#plugin-loaded-event) lists every value.
- **[Plugin installed event](../13-Enterprise-Admin/monitoring-usage.md#plugin-installed-event)**: unless you set `OTEL_LOG_TOOL_DETAILS=1`, the event omits the name fields for non-official plugins instead of reporting `third-party`.
- **[Claude Code Analytics API](../04-API-Reference/Admin/http-beta-organization-analytics-plugins-list.md)**: Claude Code reports plugins from the official and community tiers by name and reports every other plugin as `third-party`.


[​](#next-steps)

Next steps

- [Manage plugins for your organization](plugins-org.md): restrict which marketplaces users can install from and require the ones you trust
- [Install and manage plugins](discover-plugins.md): review a plugin’s details pane before you choose a scope
- [Anthropic’s marketplaces](plugins-anthropic-marketplaces.md): which marketplace names are Anthropic’s
- [Security](../13-Enterprise-Admin/security.md): Claude Code’s own security model

---

## Superpowers | Claude by Anthropic

Source: https://www.claude.com/plugins/superpowers
Path: 08-Plugins-Skills/plugins-superpowers.md

# Superpowers

Claude learns brainstorming, subagent development with code review, debugging, TDD, and skill authoring through Superpowers.

- 

  Install in
  Claude Code
- 

  Made by[Jesse Vincent](https://github.com/obra/superpowers)
- 

  Plugin source[View source](https://github.com/obra/superpowers.git)
- 

  Installs1,009,371

Superpowers is a comprehensive skills framework that teaches Claude structured software development methodologies. It provides composable skills for test-driven development (TDD), systematic debugging, brainstorming, subagent-driven development with built-in code review, and the ability to author new skills.

The plugin enforces disciplined practices like "red-green-refactor" TDD cycles where tests must fail before implementation, a four-phase debugging methodology that requires root cause investigation before any fixes, and Socratic brainstorming sessions that refine requirements before coding begins.

**How to use:** Invoke skills with slash commands like `/brainstorming` to explore requirements and design before implementation, or `/execute-plan` to run batched implementation plans with review checkpoints. The framework includes a code-reviewer agent that evaluates implementations against plans, coding standards, and architectural principles.

For debugging, the systematic methodology guides you through root cause investigation, pattern analysis, hypothesis testing, and implementation—with safeguards that trigger architectural review after three failed fix attempts. The writing-skills module teaches you to author and test new skills using TDD principles applied to documentation.

## Other plugins

### [Frontend Design](https://www.claude.com/marketplace/plugins/frontend-design)

Anthropic verified

Craft production-grade frontends with distinctive design. Generates polished code that avoids generic AI aesthetics.

### [Code Review](https://www.claude.com/marketplace/plugins/code-review)

Anthropic verified

AI code review with specialized agents and confidence-based filtering for pull requests

### [Context7](https://www.claude.com/marketplace/plugins/context7)

Upstash Context7 MCP server for live docs lookup. Pull version-specific docs and code examples from source repos into LLM context.

### [Code Simplifier](https://www.claude.com/marketplace/plugins/code-simplifier)

Anthropic verified

Code clarity agent: simplifies and refines recently modified code while preserving functionality and consistency.

### [Playwright](https://www.claude.com/marketplace/plugins/playwright)

Browser automation and end-to-end testing MCP server by Microsoft. Enables Claude to interact with web pages, take screenshots, fill forms, and automate testing workflows.

### [GitHub](https://www.claude.com/marketplace/plugins/github)

Official GitHub MCP server for repo management. Create issues, manage PRs, review code, search repos, and access GitHub's API from Claude Code.

[](https://www.claude.com/)

© 2026 Anthropic PBC

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)
- [Security and compliance](https://trust.anthropic.com/)
- [Status](https://status.anthropic.com/)
- [Support center](https://support.claude.com/en/)

## Company

- [Anthropic](https://www.anthropic.com/)
- [Careers](https://www.anthropic.com/careers)
- [Policy](https://www.anthropic.com/policy)
- [Research](../19-Reference/anthropic-com-research.md)
- [Anthropic news](../19-Reference/news.md)
- [Policy on the AI Exponential](https://www.anthropic.com/policy-on-the-ai-exponential)
- [Responsible Scaling Policy](../19-Reference/announcing-our-updated-responsible-scaling-policy.md)
- [Transparency](https://anthropic.com/transparency)

## Terms and policies

- Privacy choices
- [Privacy policy](https://www.anthropic.com/legal/privacy)
- [Responsible disclosure policy](https://www.anthropic.com/responsible-disclosure-policy)
- [Terms of service: Commercial](https://www.anthropic.com/legal/commercial-terms)
- [Terms of service: Consumer](https://www.anthropic.com/legal/consumer-terms)
- [Terms of Service: US K-12](https://anthropic.com/legal/k12-terms)
- [Data Processing Agreement: US K-12](https://anthropic.com/legal/k12-dpa)
- [Usage Policy](https://www.anthropic.com/legal/aup)

## Products

- [Claude](../15-Claude-AI-Features/product-overview.md)
- [Claude Code](../15-Claude-AI-Features/claude-com-product-claude-code.md)
- [Claude Cowork](../15-Claude-AI-Features/product-cowork.md)
- [@Claude](../14-Connectors/claude-for-slack.md)
- [Claude Science](../15-Claude-AI-Features/product-claude-science.md)
- [Claude Security](../15-Claude-AI-Features/product-claude-security.md)
- [Download app](https://www.claude.com/download)
- [Pricing](../17-Billing-Plans/pricing.md)
- [Log in](https://claude.ai/login)

## Capabilities

- [Artifacts](https://www.claude.com/features/artifacts)
- [Design](../15-Claude-AI-Features/product-design.md)
- [Connectors](https://www.claude.com/marketplace/connectors-plugins)
- [Plugins](https://www.claude.com/marketplace/plugins)
- [Skills](https://www.claude.com/skills)

## Extensions

- [Claude in Chrome](https://www.claude.com/claude-in-chrome)
- [Claude for Microsoft 365](https://www.claude.com/claude-for-microsoft-365)

## Models

- [Mythos](../15-Claude-AI-Features/claude-mythos.md)
- [Fable](../15-Claude-AI-Features/claude-fable.md)
- [Opus](../15-Claude-AI-Features/claude-opus.md)
- [Sonnet](../15-Claude-AI-Features/claude-sonnet.md)
- [Haiku](../15-Claude-AI-Features/claude-haiku.md)

## Enterprise

- [Overview](../18-Industry-UseCases/enterprise.md)
- [Claude Code for Enterprise](../15-Claude-AI-Features/product-claude-code-enterprise.md)

## Departments

- [Customer support](../18-Industry-UseCases/customer-support.md)
- [Cybersecurity](../18-Industry-UseCases/cybersecurity.md)
- [Legal](../18-Industry-UseCases/legal.md)
- [Sales](../18-Industry-UseCases/sales.md)

## Industries

- [Financial services](../18-Industry-UseCases/finance.md)
- [Government](../18-Industry-UseCases/government.md)
- [Healthcare](../18-Industry-UseCases/healthcare.md)
- [Higher education](../18-Industry-UseCases/education.md)
- [K-12 teachers](../18-Industry-UseCases/teachers.md)
- [Life sciences](../18-Industry-UseCases/life-sciences.md)
- [Nonprofits](../18-Industry-UseCases/nonprofits.md)
- [Small business](../18-Industry-UseCases/small-business.md)

## Programs

- [Startups](../15-Claude-AI-Features/programs-startups.md)
- [Scientists](../15-Claude-AI-Features/programs-claude-team-plan-for-research-labs.md)

## Developers

- [Developer docs](../02-Claude-Code-CLI/code-home.md)
- [Developer blog](https://claude.dev)
- [Community](https://www.claude.com/community)
- [Console](../04-API-Reference/Other/home.md)
- [Engineering at Anthropic](https://www.anthropic.com/engineering)

## Platform

- [Overview](https://www.claude.com/platform/api)
- [Marketplace](https://www.claude.com/marketplace)
- [Claude on AWS](../04-API-Reference/Other/partners-claude-on-aws.md)
- [Google Cloud](../04-API-Reference/Other/partners-google-cloud.md)
- [Microsoft Foundry](../04-API-Reference/Other/partners-microsoft-foundry.md)

## Resources

- [Blog](https://www.claude.com/blog)
- [Claude partner network](../04-API-Reference/Other/partners.md)
- [Claude Academy](https://academy.claude.com/)
- [Customer stories](../18-Industry-UseCases/customers.md)
- [Events](https://www.anthropic.com/events)
- [Powered by Claude](../04-API-Reference/Other/partners-powered-by-claude.md)
- [Service partners](https://www.claude.com/marketplace/service-partners)

## Help and security

- [Availability](https://www.anthropic.com/supported-countries)
- [Check files](https://www.claude.com/check-files)
- [Regional compliance](https://www.claude.com/regional-compliance)
- [Report abuse](https://www.claude.com/form/anthropic-content-reporting)

---

## Troubleshoot plugins - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins/troubleshooting
Path: 08-Plugins-Skills/plugins-troubleshooting.md

## On this page

- [Find where /plugin runs](#find-where-%2Fplugin-runs)
  - [/plugin isn't available in this environment](#plugin-isnt-available-in-this-environment)
  - [zsh: no such file or directory: /plugin](#zsh-no-such-file-or-directory-plugin)
  - [The term '/plugin' is not recognized as the name of a cmdlet](#the-term-plugin-is-not-recognized-as-the-name-of-a-cmdlet)
  - [claude: command not found after claude plugin ...](#claude-command-not-found-after-claude-plugin)
  - [Unknown command and command spellings that don’t exist](#unknown-command-and-command-spellings-that-dont-exist)
- [Add a marketplace](#add-a-marketplace)
  - [Marketplace "claude-plugins-official" not found](#marketplace-claude-plugins-official-not-found)
  - [Marketplace "\<name\>" not found](#marketplace-not-found)
  - [Invalid marketplace source format](#invalid-marketplace-source-format)
  - ['\<source\>' is not a valid GitHub owner/repo shorthand](#is-not-a-valid-github-owner-repo-shorthand)
  - [Path does not exist: \<path\>](#path-does-not-exist)
  - [Marketplace file not found at \<path\>/.claude-plugin/marketplace.json](#marketplace-file-not-found-at-claude-plugin-marketplace-json)
  - [SSH authentication failed or HTTPS authentication failed](#ssh-authentication-failed-or-https-authentication-failed)
  - [SSH host key is not in your known_hosts file](#ssh-host-key-is-not-in-your-known-hosts-file)
  - [Command 'git' not found or is in an unsafe location](#command-git-not-found-or-is-in-an-unsafe-location)
  - [Git clone timed out after 120s](#git-clone-timed-out-after-120s)
  - [Marketplace updates keep failing offline](#marketplace-updates-keep-failing-offline)
  - [Marketplace add fails on a GitHub Enterprise Server host](#marketplace-add-fails-on-a-github-enterprise-server-host)
- [Install a plugin](#install-a-plugin)
  - [Plugin "\<name\>" not found in marketplace "\<marketplace\>"](#plugin-not-found-in-marketplace)
  - [not found in marketplace with a refresh hint](#the-message-ends-with-a-refresh-hint)
  - [not found in marketplace with no hint](#the-message-has-no-hint)
  - [Plugin "\<name\>" not found in any marketplace](#plugin-not-found-in-any-marketplace)
  - [Plugin '\<name\>@\<marketplace\>' is already installed globally](#plugin-is-already-installed-globally)
  - [This plugin uses a source type your Claude Code version does not support](#this-plugin-uses-a-source-type-your-claude-code-version-does-not-suppo)
  - [Plugin archive integrity check failed](#plugin-archive-integrity-check-failed)
  - [Marketplace "\<name\>" is registered from an untrusted source](#marketplace-is-registered-from-an-untrusted-source)
  - [Plugin \<name\> has a corrupt manifest file or has an invalid manifest file](#plugin-has-a-corrupt-manifest-file-or-has-an-invalid-manifest-file)
  - [Plugin directory not found at path: \<path\>](#plugin-directory-not-found-at-path)
  - [No plugins available or No marketplaces configured](#no-plugins-available-or-no-marketplaces-configured)
  - [Marketplace "\<name\>" is already added from a different source](#marketplace-is-already-added-from-a-different-source)
  - [Cannot add marketplace "\<name\>": its network source differs from the one declared for it in settings](#cannot-add-marketplace-its-network-source-differs)
  - [Failed to install: \<plugin\> (\<reason\>)](#failed-to-install-from-the-plugin-menu)
  - [Could not move the new copy of this plugin version into \<path\>](#could-not-move-the-new-copy-of-this-plugin-version)
  - [Dependency errors](#dependency-errors)
- [Plugin installed but not working](#plugin-installed-but-not-working)
  - [Plugin doesn’t appear or its skills don’t show up](#plugin-doesnt-appear-or-its-skills-dont-show-up)
  - [Run /reload-plugins to activate.](#run-reload-plugins-to-activate)
  - [Plugin "\<name\>" not cached at \<path\>](#plugin-not-cached-at)
  - [installed_plugins.json holds a record under "\<id\>" that this version of Claude Code cannot read](#installed-plugins-json-holds-a-record-this-version-cannot-read)
  - [installed_plugins.json could not be read and was rebuilt](#installed-plugins-json-could-not-be-read-and-was-rebuilt)
  - [install records under names that no version of Claude Code can use were removed from installed_plugins.json](#install-records-under-names-that-no-version-can-use)
  - [Disabled in ~/.claude/settings.json but still loads](#a-plugin-you-disabled-still-loads)
  - [Plugin "\<name\>" is enabled in project settings but isn't installed here](#plugin-is-enabled-in-project-settings-but-isnt-installed-here)
  - [Failed to load hooks from \<path\> and hooks that don’t fire](#failed-to-load-hooks-from-and-hooks-that-dont-fire)
  - [Hooks fail to load](#hooks-fail-to-load)
  - [hook error notices in the transcript](#hook-error-notices-in-the-transcript)
  - [A plugin hook blocks a tool call or prompt](#a-plugin-hook-blocks-a-tool-call-or-prompt)
  - [Hook loads but never fires](#hook-loads-but-never-fires)
  - [Invalid MCP server config for "\<server\>" and MCP servers that don’t start](#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start)
  - [Invalid MCP server config for "\<server\>": \<error\>](#invalid-mcp-server-config-for-%3Cserver%3E-%3Cerror%3E)
  - [Server is configured but never connects](#server-is-configured-but-never-connects)
  - [Server works with --plugin-dir but fails after install](#server-works-with-plugin-dir-but-fails-after-install)
  - [Language server doesn’t start, uses too much memory, or reports wrong diagnostics](#language-server-doesnt-start)
  - [Language server doesn’t start](#language-server-doesn%E2%80%99t-start)
  - [Language server uses too much memory](#language-server-uses-too-much-memory)
  - [False positive diagnostics in a monorepo](#false-positive-diagnostics-in-a-monorepo)
- [Build a plugin](#build-a-plugin)
  - [commands path not found: \<path\>](#commands-path-not-found)
  - [--plugin-dir at a marketplace root doesn’t load the plugins under plugins/](#plugin-dir-loads-a-plugin-with-no-components)
  - [Files the plugin references outside its directory aren’t found](#files-the-plugin-references-outside-its-directory-arent-found)
  - [\${CLAUDE_PLUGIN_ROOT} shows forward slashes on Windows](#claude-plugin-root-shows-forward-slashes-on-windows)
  - [Plugin loads but its skills are missing](#plugin-loads-but-its-skills-are-missing)
  - [Skill loads but Claude never invokes the skill](#skill-loads-but-claude-never-invokes-the-skill)
  - [\<directory\> is not a plugin or skill folder from claude plugin eval init](#is-not-a-plugin-or-skill-folder)
  - [The userConfig dialog never appears](#the-userconfig-dialog-never-appears)
  - [claude plugin validate reports errors](#claude-plugin-validate-reports-errors)
  - [Plugin \<name\> has conflicting manifests](#plugin-has-conflicting-manifests)
  - [Warning: No commands found in plugin \<name\> custom directory](#warning-no-commands-found-in-plugin-custom-directory)
- [Host a marketplace](#host-a-marketplace)
  - [Plugins with relative paths fail in URL-based marketplaces](#plugins-with-relative-paths-fail-in-url-based-marketplaces)
  - [Marketplace validation errors](#marketplace-validation-errors)
- [Blocked by your organization](#blocked-by-your-organization)
  - [Marketplace source '\<source\>' is blocked by enterprise policy](#marketplace-source-is-blocked-by-enterprise-policy)
  - [Marketplace "\<name\>" is not in the allowed marketplace list](#marketplace-is-not-in-the-allowed-marketplace-list)
  - [Plugin "\<name\>" is blocked by your organization's policy and cannot be installed](#plugin-is-blocked-by-your-organizations-policy-and-cannot-be-installed)
  - [--plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)](#plugin-dir-is-disabled-by-your-organizations-managed-settings-disables)
  - [Plugins from ~/.claude/skills/ are blocked by your organization's managed settings](#plugins-from-claude-skills-are-blocked-by-your-organizations-managed-s)
  - [Command-sourced plugins are disabled by your organization's managed settings](#command-sourced-plugins-are-disabled-by-your-organizations-managed-set)
  - [Marketplace '\<name\>' is seed-managed](#marketplace-is-seed-managed)
- [Next steps](#next-steps)

Troubleshooting

# Troubleshoot plugins

Copy pageCopy page

Fix plugin errors in Claude Code. Find the exact message you saw, grouped by stage from where /plugin runs through install and org policy.

Copy pageCopy page

This page lists error messages and symptoms for Claude Code plugins and for marketplaces, the catalogs Claude Code installs plugins from. Each entry gives the cause, one fix, and what you see once the fix works. Where a message names a plugin or marketplace, the entry shows a placeholder such as `<name>` instead. Use this page whether you install plugins, build them, host a marketplace, or administer plugins for an organization.

These cases are covered on other pages:

- **Why scopes, the cache, and precedence behave the way they do**: read [Plugin loading reference](plugins-loading.md)
- **Looking up a flag, field, or command**: use the [plugin commands reference](plugins-cli-reference.md), the [manifest reference](plugins-reference.md), or the [marketplace reference](plugins-marketplace-reference.md)

Search for the exact message you saw. Each message is listed under the stage that produces it, which isn’t always the command you ran. For example, an install can fail because a marketplace is missing, so that message is under [Add a marketplace](#add-a-marketplace).


[​](#find-where-/plugin-runs)

Find where `/plugin` runs

`/plugin` is a command you type inside a running Claude Code terminal session, and it opens an interactive panel. The entries in this section cover the places where you can type it but it can’t run, and the command spellings that don’t exist.


[​](#plugin-isnt-available-in-this-environment)

`/plugin isn't available in this environment`

You typed `/plugin` somewhere other than a Claude Code terminal session, and Claude replied with this line instead of opening anything. You get this reply in a session that has no terminal to draw the `/plugin` panel in: [non-interactive mode](../02-Claude-Code-CLI/headless.md) with `claude -p`, the Agent SDK, the Claude desktop app’s Code tab, the VS Code extension panel, and the browser at claude.ai/code. In the VS Code extension panel, only a `/plugin` line with something after it, such as `/plugin install <plugin>@<marketplace>`, gets this reply. `/plugin` or `/plugins` typed alone opens the **Manage plugins** dialog. Install the plugin from the surface you’re on instead:

- **Claude desktop app, local or SSH session**: click the **+** button next to the prompt, then **Plugins**, then **Add plugin** to open the [plugin browser](../16-Mobile-Desktop/desktop.md#install-plugins)
- **VS Code extension**: use the **VS Code** tab under [Install a plugin](discover-plugins.md#install-a-plugin)
- **Claude Code on the web, or a desktop cloud session**: a cloud session has no plugin browser. See the **Cloud session** tab under [Install a plugin](discover-plugins.md#install-a-plugin) for what a cloud session loads
- **A terminal you have access to**: run `claude` and type `/plugin` there, or run `claude plugin install <plugin>@<marketplace>` in your shell without starting a session

When a terminal install works, `/plugin` prints an install summary that starts with `✓ Installed <plugin>.` and `claude plugin install` prints `Successfully installed plugin: <plugin>@<marketplace>`.


[​](#zsh-no-such-file-or-directory-plugin)

`zsh: no such file or directory: /plugin`

You typed `/plugin ...` at a shell prompt, and the shell reported that no file named `/plugin` exists. Bash reports `bash: /plugin: No such file or directory`. `/plugin` is a command you type inside a Claude Code session, not at the shell prompt. Start a session and type the same command there:

```python
claude
```

Then, at the Claude Code prompt:

```python
/plugin install <plugin>@<marketplace>
```

A successful install prints a summary that starts with `✓ Installed <plugin>.` If the install itself then fails, its message is under [Add a marketplace](#add-a-marketplace) or [Install a plugin](#install-a-plugin). To install from the shell without starting a session, run `claude plugin install <plugin>@<marketplace>` instead.


[​](#the-term-plugin-is-not-recognized-as-the-name-of-a-cmdlet)

`The term '/plugin' is not recognized as the name of a cmdlet`

You typed `/plugin ...` at a PowerShell prompt, and `/plugin` is a Claude Code command, not a program. Bash and Zsh report [their own form of this error](#zsh-no-such-file-or-directory-plugin). Use either of these instead:

- Run `claude`, then type `/plugin` at the Claude Code prompt
- Run `claude plugin install <plugin>@<marketplace>` in PowerShell without starting a session


[​](#claude-command-not-found-after-claude-plugin)

`claude: command not found` after `claude plugin ...`

You ran `claude plugin install ...` in your shell, and the shell couldn’t find `claude` at all. On Windows the message is `'claude' is not recognized as the name of a cmdlet` or `'claude' is not recognized as an internal or external command`. The cause isn’t the plugin command. Either Claude Code isn’t installed, or its install directory isn’t on your `PATH` in this shell. Follow [`command not found: claude` after installation](../02-Claude-Code-CLI/troubleshoot-install.md#command-not-found-claude-after-installation), then retry the plugin command.


[​](#unknown-command-and-command-spellings-that-dont-exist)

`Unknown command` and command spellings that don’t exist

You typed a plugin command you saw somewhere and got `Unknown command: /<name>` in a session, or `error: unknown command '<name>'` or `error: unknown option '<flag>'` from the `claude` binary in your shell. Several command spellings are in use that Claude Code doesn’t have. The table below maps each one to the real command. The [plugin commands reference](plugins-cli-reference.md) lists every subcommand and flag.

| You typed                                  | What Claude Code says                                                        | Use instead                                                                                                                          |
|:-------------------------------------------|:-----------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------|
| `claude plugin add <source>`               | `error: unknown command 'add'`                                               | `claude plugin marketplace add <source>` to add a marketplace, or `claude plugin install <plugin>@<marketplace>` to install a plugin |
| `claude plugin install <plugin> --project` | `error: unknown option '--project'`                                          | `claude plugin install <plugin>@<marketplace> --scope project`                                                                       |
| `/install <plugin>`                        | `Unknown command: /install`                                                  | `/plugin install <plugin>@<marketplace>`                                                                                             |
| `/plugin add <source>`                     | The `/plugin` panel opens on the **Discover** tab                            | `/plugin marketplace add <source>`                                                                                                   |
| `marketplace.anthropic.com` as a source    | `Invalid marketplace source format. Try: owner/repo, https://..., or ./path` | `anthropics/claude-plugins-official` for the official marketplace                                                                    |

These spellings look wrong but work:

- `claude plugins` is an alias of `claude plugin`
- `claude plugin remove` is an alias of `claude plugin uninstall`
- `/plugins` and `/marketplace` in a session open the same panel as `/plugin`


[​](#add-a-marketplace)

Add a marketplace

A marketplace is a catalog you add to Claude Code from a git repository, a URL, or a local path. These entries cover the messages you get when adding one fails or a later refresh fails.


[​](#marketplace-claude-plugins-official-not-found)

`Marketplace "claude-plugins-official" not found`

You ran `/plugin install <plugin>@claude-plugins-official` in a session, and Claude Code reported that it has no marketplace by that name. The official marketplace isn’t registered on this machine yet. Claude Code normally registers it on its own the first time you start an interactive terminal session. It hasn’t run yet if you’ve only used Claude Code through the VS Code extension, and it skips or defers that step:

- When a policy blocks the source
- When `CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL` is set
- After a failed attempt that’s waiting to retry

The `claude plugin` shell commands never register it for you. Add it, then retry the install:

```python
/plugin marketplace add anthropics/claude-plugins-official
```

Claude Code prints `Successfully added marketplace: claude-plugins-official`, and `/plugin marketplace list` shows the marketplace with its source. For any other marketplace name in this message, see [`Marketplace "<name>" not found`](#marketplace-not-found). The same string also appears in the `/plugin` **Errors** tab, the panel’s list of load failures, when a plugin listed in your settings names a marketplace you haven’t added.


[​](#marketplace-not-found)

`Marketplace "<name>" not found`

You ran `/plugin install` in a session and Claude Code reported that it has no marketplace by that name. Two forms of the command reach this message:

- **`/plugin install <plugin>@<name>`**: the install line, often one someone sent you, names a marketplace you haven’t added. The rest of this entry covers finding and adding it.
- **`/plugin install <source>` with a path, URL, or `owner/repo`**: this form reports the message instead of installing, even for a source you’ve already added. To install from a source in one command, see [Add a marketplace and install in one command](discover-plugins.md#add-a-marketplace-and-install-in-one-command).

If the name starts with `claudeai-`, the marketplace is hosted on claude.ai, and you add it by name from your shell with `claude plugin marketplace add --claudeai <name>`. See [Add a marketplace from claude.ai](discover-plugins.md#add-from-claude-ai). For any other name, an install line names a marketplace but doesn’t say where the marketplace is hosted, and Claude Code has no index to look a marketplace name up in. Ask whoever sent the line for the marketplace’s source, which is a GitHub `owner/repo`, a git URL, or a path. Then [add the marketplace](discover-plugins.md#add-a-marketplace) and run the install line again. A marketplace someone sends you is third-party, so [review the plugin before you install it](plugins-security.md#review-a-plugin-before-you-install). If you already added the marketplace, check the spelling against `/plugin marketplace list`.


[​](#invalid-marketplace-source-format)

`Invalid marketplace source format`

You ran `/plugin marketplace add <source>` or `claude plugin marketplace add <source>`, and Claude Code replied `Invalid marketplace source format. Try: owner/repo, https://..., or ./path`. Claude Code accepts a source in one of these forms:

- A GitHub `owner/repo` shorthand
- An `https://` or `http://` URL
- A `user@host:path` SSH URL
- A local path starting with `./`, `../`, `/`, or `~`

A bare name such as `claude-plugins-official` matches none of them. Neither does a bare hostname such as `marketplace.anthropic.com`. Retype the source in one of the accepted forms:

```python
/plugin marketplace add anthropics/claude-plugins-official
```

Claude Code prints `Successfully added marketplace: <name>` when the add works.


[​](#is-not-a-valid-github-owner-repo-shorthand)

`'<source>' is not a valid GitHub owner/repo shorthand`

You passed a source with a slash that isn’t `owner/repo`, such as `github.com/owner/repo` or a `gitlab.example.com/group/project` path. Claude Code refused it with this message and a list of accepted forms. The `owner/repo` shorthand is GitHub-only and has to follow GitHub’s naming rules, so a hostname or an extra path segment fails. Pass the source in the form that matches where the marketplace is hosted:

- **A repository on any host**: the full clone URL
- **A hosted `marketplace.json`**: its `https://` URL
- **A local checkout**: `./path` or an absolute path

For example, to add the official marketplace by its clone URL, in a session:

```python
/plugin marketplace add https://github.com/anthropics/claude-plugins-official.git
```

A successful add prints `Successfully added marketplace: <name>`.


[​](#path-does-not-exist)

`Path does not exist: <path>`

You passed a local path to `marketplace add`, and nothing exists at that path. A relative path resolves against your current directory. Check the resolved path in the message. Then run the command from the directory the relative path starts from, or pass an absolute path to the marketplace directory. A successful add prints `Successfully added marketplace: <name>`. Claude Code accepts a directory that contains `.claude-plugin/marketplace.json`, or a path to a `.json` file. A path to any other file fails with `File path must point to a .json file (marketplace.json)`.


[​](#marketplace-file-not-found-at-claude-plugin-marketplace-json)

`Marketplace file not found at <path>/.claude-plugin/marketplace.json`

Claude Code cloned or downloaded the marketplace but found no `marketplace.json` at the expected path inside it. The add command reports it as `Failed to add marketplace: Marketplace file not found at ...`. The default location is `.claude-plugin/marketplace.json` at the repository root, and the [marketplace reference](plugins-marketplace-reference.md) lists the accepted locations. The fix differs for the owner and for everyone else:

- **You own the marketplace**: put the file at that location and re-add the marketplace
- **Someone else hosts it**: ask the owner for the exact source they publish


[​](#ssh-authentication-failed-or-https-authentication-failed)

`SSH authentication failed` or `HTTPS authentication failed`

You added or updated a marketplace from a git repository, and the clone failed with `Failed to clone marketplace repository:` followed by one of these lines. First check the repository itself: a misspelled `owner/repo`, a repository that doesn’t exist, or a private repository you can’t see also ends in this message. Open the repository URL in your browser, or run `git ls-remote <url>` in your terminal, to confirm it exists and you have access. If the repository is right, the cause is credentials. Claude Code runs git with interactive prompts disabled, so it can’t ask you for a password, a key passphrase, or a credential the way your terminal would. If git needs to prompt, you see `fatal: Cannot prompt because user interactivity has been disabled` or `terminal prompts disabled` in the original error. Only credentials that already work non-interactively succeed:

- **SSH**: `ssh -T git@<host>` must succeed without prompting for a passphrase, and the host must already be in `known_hosts`
- **HTTPS**: your credential helper must hold a token for the host. For GitHub, run `gh auth login` and `gh auth setup-git`. For another host, store a personal access token in your git credential helper. Test with `git ls-remote <url>`

Once `git ls-remote` succeeds in your terminal without a prompt, run the add or update again. A successful add prints `Successfully added marketplace: <name>`. A successful update prints `Successfully updated marketplace: <name>` from your shell, or `✔ Updated 1 marketplace` in a session. To make Claude Code skip SSH for GitHub `owner/repo` sources, set `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`. Without it, Claude Code clones those sources over SSH when an SSH key for `github.com` looks configured, and falls back to HTTPS when the SSH clone fails. For what background auto-updates can and can’t do with your credentials, see [What background auto-update does with credentials](plugins-host-marketplace.md#what-background-auto-update-does-with-credentials).


[​](#ssh-host-key-is-not-in-your-known-hosts-file)

`SSH host key is not in your known_hosts file`

You added a marketplace over SSH from a host you’ve never connected to, and the clone failed with this line and a `ssh -T git@<host>` hint. For a host whose key changed, the message is `SSH host key has changed` with a `ssh-keygen -R <host>` hint instead. Claude Code clones with `StrictHostKeyChecking=yes`, so it refuses a host whose key you haven’t accepted yet rather than accepting the key automatically. Connect once from your terminal to accept the fingerprint, then retry:

```python
ssh -T git@github.com
```

For a public repository, add the marketplace by its `https://` URL instead to avoid SSH entirely.


[​](#command-git-not-found-or-is-in-an-unsafe-location)

`Command 'git' not found or is in an unsafe location`

On Windows, you added a marketplace and Claude Code reported `Failed to clone marketplace repository: Command 'git' not found or is in an unsafe location (current directory)`. Claude Code looks for `git` on your `PATH` and refuses to run one found only in the current directory. To fix it, install Git and retry:

1

Install Git for Windows

Install Git for Windows so that `git` is on your `PATH`.

2

Open a new terminal

Open a new terminal so the updated `PATH` applies.

3

Confirm git runs

Confirm `git --version` prints a version.

4

Retry the add

Run the `marketplace add` command again.


[​](#git-clone-timed-out-after-120s)

`Git clone timed out after 120s`

You added or updated a marketplace, and it failed with `Git clone timed out after 120s`, followed by a hint to set `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS`. Cloning a marketplace, and re-cloning one to update it, gets 120 seconds by default. For a large repository or a slow connection, raise the limit. The value is in milliseconds:

- Bash or Zsh

- PowerShell

```python
export CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS=300000
```

```python
$env:CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS = "300000"
```

Then retry in the same shell. If the repository is a monorepo, limit the checkout to the directories you name with `claude plugin marketplace add <source> --sparse <paths>`.


[​](#marketplace-updates-keep-failing-offline)

Marketplace updates keep failing offline

You work in an environment where the marketplace’s git host is unreachable, and every session repeats a failed refresh in the background. Your existing checkout of the marketplace stays in place and startup isn’t delayed. Each session, for a marketplace with [auto-update on](plugins-loading.md#which-marketplaces-and-plugins-auto-update), Claude Code checks the marketplace’s git host for new commits in the background. When that check can’t reach the host, it tries to clone the marketplace again, and offline that clone fails too. Set this variable to skip the re-clone attempt and keep using the existing checkout when the check can’t reach the host:

- Bash or Zsh

- PowerShell

```python
export CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1
```

```python
$env:CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE = "1"
```

With the variable set, Claude Code skips the re-clone only for a checkout that already contains `.claude-plugin/marketplace.json`. A marketplace that was never cloned or whose clone stopped partway still gets the clone attempt, so add it once while online. For a fully offline deployment, pre-populate the plugins directory at image build time with `CLAUDE_CODE_PLUGIN_SEED_DIR` instead, following [Seed containers and CI](plugins-org.md#seed-containers-and-ci).


[​](#marketplace-add-fails-on-a-github-enterprise-server-host)

Marketplace add fails on a GitHub Enterprise Server host

You added a marketplace from a GitHub Enterprise Server (GHES) URL and got a policy error, or you added it from claude.ai and got a GitHub access error. Both cases are on the GHES page:

- [A policy error](../02-Claude-Code-CLI/github-enterprise-server.md#marketplace-add-fails-with-a-policy-error) means your organization restricted marketplace sources and an admin needs to add a `hostPattern` for the host
- [A GitHub access error on claude.ai](../02-Claude-Code-CLI/github-enterprise-server.md#marketplace-add-on-claude-ai-fails-with-a-github-access-error) means your own GitHub Enterprise account isn’t connected yet


[​](#install-a-plugin)

Install a plugin

You added a marketplace and ran an install, and the install stopped with a message instead of installing anything. These entries cover those messages. They also cover the related messages that appear later in the `/plugin` **Errors** tab, or as an empty **Discover** tab, when a plugin or its marketplace can’t be found, read, or trusted.


[​](#plugin-not-found-in-marketplace)

`Plugin "<name>" not found in marketplace "<marketplace>"`

You ran `/plugin install <name>@<marketplace>` or `claude plugin install <name>@<marketplace>`, and the plugin name isn’t in the copy of that marketplace’s catalog on your machine. `claude plugin install` in your shell prints the same message when you haven’t added the marketplace at all. If `claude plugin marketplace update <marketplace>` then answers `Marketplace '<marketplace>' not found`, [add the marketplace](#add-a-marketplace) first.


[​](#the-message-ends-with-a-refresh-hint)

`not found in marketplace` with a refresh hint

The hint reads `Your local copy may be out of date — try claude plugin marketplace update <marketplace>` or `The marketplace couldn't be refreshed (...)`. Claude Code didn’t refresh the marketplace before the lookup, such as when you’re offline, so your copy of the catalog may be stale. Refresh with the marketplace’s name, then install again:

```python
/plugin marketplace update <marketplace>
```

`claude plugin marketplace update` prints `Successfully updated marketplace: <name>`, and `/plugin marketplace update` shows `✔ Updated 1 marketplace`. If the retried install prints the same message, check the name as [`not found in marketplace` with no hint](#the-message-has-no-hint) describes. [When Claude Code refreshes a marketplace before an install](plugins-loading.md#when-claude-code-refreshes-a-marketplace-before-an-install) lists the other cases where the refresh doesn’t run.


[​](#the-message-has-no-hint)

`not found in marketplace` with no hint

The name is the likeliest problem. Open `/plugin`, go to **Discover**, and copy the name from the list. Before v2.1.232, Claude Code refreshed the named marketplace only after the lookup missed, and only when auto-update was on for it.


[​](#plugin-not-found-in-any-marketplace)

`Plugin "<name>" not found in any marketplace`

You ran `/plugin install <name>` with no `@marketplace`, and no registered marketplace has that plugin. `claude plugin install <name>` reports `Plugin "<name>" not found in any configured marketplace`. Without a marketplace name, `claude plugin install` searches the catalogs it already has and doesn’t refresh them first, and `/plugin install` refreshes only marketplaces that have auto-update on. Name the marketplace, and Claude Code refreshes it before looking the plugin up:

```python
/plugin install <name>@<marketplace>
```

When the install works, you see `✓ Installed <plugin>.` in a session, or `Successfully installed plugin: <plugin>@<marketplace>` from `claude plugin install`. If you don’t know which marketplace lists the plugin, run `/plugin marketplace list` for the marketplaces you have, and browse **Discover** in `/plugin` for the plugin name.


[​](#plugin-is-already-installed-globally)

`Plugin '<name>@<marketplace>' is already installed globally`

You ran `/plugin install` for a plugin that’s already installed at user scope or by managed settings, and Claude Code refused with `Use '/plugin' to manage existing plugins.` If you typed the plugin name without `@<marketplace>`, the message omits `globally`. The plugin is already available in every project, so there’s nothing to add. To change its [scope](discover-plugins.md), enable or disable it, or configure it, open `/plugin` and go to **Installed**. A plugin installed only at project or local scope doesn’t trigger this message. Claude Code lets you install it at user scope as well, so it’s available in other projects. `claude plugin install` in your shell prints a different message. For a plugin already installed at the target scope, it prints `Plugin "<name>@<marketplace>" is already installed (scope: user)` and exits 0. If its cache directory is missing, the same command re-downloads it.


[​](#this-plugin-uses-a-source-type-your-claude-code-version-does-not-suppo)

`This plugin uses a source type your Claude Code version does not support`

You installed a plugin whose marketplace entry uses a source type this version of Claude Code can’t fetch, and Claude Code stopped with this message and `Update Claude Code and try again.` Update Claude Code, then retry the install. Source types are on the [marketplace reference](plugins-marketplace-reference.md).


[​](#plugin-archive-integrity-check-failed)

`Plugin archive integrity check failed`

You installed a plugin that’s distributed as a zip archive, and Claude Code refused it with this line and `The archive was not installed.` The plugin’s marketplace entry uses an [`archive` source](plugins-marketplace-reference.md) with a `sha256` pin, and the downloaded file’s digest doesn’t match the pin. The full message looks like this:

```python
Plugin archive integrity check failed for https://artifacts.example.com/claude-plugins/my-plugin.zip: expected sha256 6bfa50e3d2e00c052b46abe51fff89346ac803e45771f76dcf6df1ab74cca5e1, got ac52220c0914ef8ca6a602e4a7362f88d30fb021110f72a6d15b68c3fe7df2b7. The archive was not installed. Verify the sha256 in the marketplace entry, or that the URL serves the intended file.
```

The fix differs for the publisher and the installer:

- **You publish the plugin**: recompute the digest of the exact file the URL serves and update the `sha256` in the marketplace entry. Use `shasum -a 256 my-plugin.zip`, or `Get-FileHash -Algorithm SHA256 my-plugin.zip` in PowerShell
- **You install the plugin**: run `/plugin marketplace update <name>` in a session to refresh the catalog in case the entry was corrected, then retry the install. If the digests still disagree after the refresh, ask the marketplace owner which file they pinned before installing


[​](#marketplace-is-registered-from-an-untrusted-source)

`Marketplace "<name>" is registered from an untrusted source`

A marketplace you added earlier stopped loading, and so did its plugins. This line appears in the `/plugin` **Errors** tab or on the next refresh. The marketplace is registered under a name that is [reserved for official Anthropic marketplaces](plugins-marketplace-reference.md), but its registered source isn’t an `anthropics` GitHub repository. Reserved names are re-checked every time a marketplace loads or refreshes, so the marketplace and the plugins installed from it stop loading. The full message names the reserved name and the fix:

```python
Marketplace "claude-community" is registered from an untrusted source: The name 'claude-community' is reserved for official Anthropic marketplaces. Only repositories from 'github.com/anthropics/' can use this name. To fix it, remove the marketplace and re-add it from the official source.
```

The fix differs for users and publishers:

- **You use the marketplace**: in your shell, run `claude plugin marketplace remove <name>`, then add the marketplace again from the official `github.com/anthropics` repository
- **You publish a third-party marketplace that used the name before it became reserved**: rename it and ask users to re-add it from your source

Before v2.1.205, Claude Code checked the name only when you added the marketplace, so an entry registered before its name became reserved kept loading.


[​](#plugin-has-a-corrupt-manifest-file-or-has-an-invalid-manifest-file)

`Plugin <name> has a corrupt manifest file` or `has an invalid manifest file`

Claude Code fetched the plugin, then failed to read its `.claude-plugin/plugin.json`. In the shell, the `<name>` in this line can be a temporary directory name; the `Failed to install plugin "<name>@<marketplace>"` prefix carries the plugin’s real name. The wording says which check failed:

- **`corrupt manifest file`, followed by `JSON parse error:`**: the file isn’t valid JSON
- **`invalid manifest file`, followed by `Validation errors:`**: the file parses but fails the schema, such as `name: Invalid input` for a missing required field

`claude plugin install` reports either as `Failed to install plugin "<name>@<marketplace>":` and exits with code 1. The plugin’s author has to fix the file, and the plugin can’t be installed until then:

- **If that’s you**: run `claude plugin validate <plugin-directory>` in your shell to see the same error with the offending path, then fix the file
- **If it isn’t you**: report the message to the marketplace owner


[​](#plugin-directory-not-found-at-path)

`Plugin directory not found at path: <path>`

The **Errors** tab in `/plugin` shows this for an enabled plugin that its marketplace lists by a relative path, such as `./plugins/my-plugin`, when no directory exists at that path inside the marketplace. If you maintain the marketplace, correct the entry’s `source` path or restore the folder. Otherwise, report the message to the marketplace owner. `Marketplace directory not found at path: <path>` means the marketplace’s own directory is missing instead. For a marketplace you added from a local path, that directory moved or was deleted. Restore it, or remove the marketplace and add it again from its new location.


[​](#no-plugins-available-or-no-marketplaces-configured)

`No plugins available` or `No marketplaces configured`

You opened `/plugin` and the **Discover** tab is empty, or `claude plugin marketplace list` printed `No marketplaces configured`. No marketplace is registered, so there’s no catalog to show. In a session, add the official marketplace, `anthropics/claude-plugins-official`:

```python
/plugin marketplace add anthropics/claude-plugins-official
```

Claude Code prints `Successfully added marketplace: claude-plugins-official`, and **Discover** lists its plugins. The [Anthropic marketplaces](plugins-anthropic-marketplaces.md) page lists the other marketplaces you can add.


[​](#marketplace-is-already-added-from-a-different-source)

`Marketplace "<name>" is already added from a different source`

You confirmed adding a marketplace through [`/plugin install <plugin> --marketplace <source>`](discover-plugins.md#add-a-marketplace-and-install-in-one-command), and the catalog Claude Code fetched from that source has the same name as a marketplace you already added from a different source. Claude Code keeps the existing marketplace instead of replacing it, and the plugin isn’t installed. The full message looks like this:

```python
Marketplace "acme-tools" is already added from a different source (github:acme/plugins). To use this source instead, remove that marketplace first with /plugin marketplace remove acme-tools.
```

Choose which source you want:

- **The marketplace you already added**: install from it by name with `/plugin install <plugin>@<name>`
- **The new source**: run `/plugin marketplace remove <name>`, then retry the install


[​](#cannot-add-marketplace-its-network-source-differs)

`Cannot add marketplace "<name>": its network source differs from the one declared for it in settings`

You ran `marketplace add`, and the catalog at that source has the same name as a marketplace that a settings file already declares under [`extraKnownMarketplaces`](../02-Claude-Code-CLI/settings-reference.md#extraknownmarketplaces) with a different source. Claude Code refuses the add and registers nothing. The message ends with the fix: the source must match the one declared for this name in settings, or you change the declaration. Compare the source you passed against the `extraKnownMarketplaces` entry for that name, including its `ref`, `path`, and `headers`, then do one of these:

- **Use the declared source**: add the marketplace from the source the settings entry names
- **Use the new source**: edit or remove the `extraKnownMarketplaces` entry, then add the marketplace again. If managed settings declare it, ask your administrator


[​](#failed-to-install-from-the-plugin-menu)

`Failed to install: <plugin> (<reason>)`

You selected plugins to install in the `/plugin` menu, none of them installed, and the menu closed with this summary of what failed. Some reasons, such as git’s output after a failed clone, show only their first line. When such a reason was shortened, the summary ends with `Installing a plugin from its details (Enter) in /plugin shows its full error.` What to do depends on whether the summary shortened the reason:

- Fix what the reason in parentheses names
- When the reason was shortened, run `/plugin`, select the plugin on the **Discover** tab, and press **Enter** to install it from its details. If the install fails there, the details view shows the whole error


[​](#could-not-move-the-new-copy-of-this-plugin-version)

`Could not move the new copy of this plugin version into <path>`

When you install a plugin, Claude Code downloads a fresh copy of its files and moves it into that version’s folder in the [plugin cache](plugins-loading.md#find-plugins-on-disk). This message means the move failed, usually because another program was using the folder while the install ran. The file-system code appears in parentheses:

```python
Could not move the new copy of this plugin version into /home/user/.claude/plugins/cache/acme-tools/formatter/1.2.0: the new copy or the version folder stayed busy while the install ran (ENOTEMPTY) — usually a scanner still reading the freshly downloaded files, another program using that folder, or another process re-creating it. The previously installed copy was moved back. Run the install again once other Claude Code sessions or programs using that folder have finished.
```

The message says what happened to the copy that was installed before, which tells you whether the plugin still works:

- `The previously installed copy was moved back`: the version you had is still installed
- `had to be removed first`, `was not moved back`, or `could not be moved back`: that plugin version isn’t installed until an install succeeds
- No such sentence: there was no earlier copy, so the version isn’t installed yet

On Windows, when another program holds the installed copy itself, the message instead says that copy `could not be replaced` and that `It was not replaced and the new copy was discarded`, so the version you had is still installed. A `Left on disk` list names set-aside folders inside the cache. A later install of that version or a plugin cache cleanup removes them, so you don’t need to delete them. To fix the install:

- Close other Claude Code sessions, editors, and terminals that are using the plugin’s folder under `~/.claude/plugins/cache`, then run the install again
- When the message says to check the plugin cache folder’s permissions, restore your write permission on the folder it names and free disk space, then run the install again


[​](#dependency-errors)

Dependency errors

A plugin that declares dependencies can fail to install, or install and stay disabled, when a dependency can’t be satisfied. The message reaches you at install time or at load time:

- **During install**: the refusal comes back as the install’s error message
- **When the plugin loads**: the problem appears in `claude plugin list` and the `/plugin` **Errors** tab, and Claude Code keeps the affected plugin disabled until you resolve it

The table lists each message and its fix. To declare dependencies as an author, see [Plugin dependencies](plugins-dependencies.md).

| Message                                                                                         | Meaning                                                                                           | How to resolve                                                                                                                                                                                                                                                      |
|:------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Dependency "<dep>" is not installed`                                                           | A declared dependency isn’t installed.                                                            | Install it in your shell with `claude plugin install <dep>@<marketplace>`, or uninstall the plugin. If the dependency’s marketplace isn’t registered yet, add it and run `/reload-plugins` in your session, which installs the missing dependencies it can resolve. |
| `Dependency "<dep>" is disabled`                                                                | The dependency is installed but turned off.                                                       | Enable the dependency, or uninstall the plugin that needs it.                                                                                                                                                                                                       |
| `Requires "<dep>" <range>, installed <version>`                                                 | The installed dependency’s version is outside the plugin’s declared range.                        | Update the dependency to a version in the range, or uninstall the plugin.                                                                                                                                                                                           |
| `<Plugin or Dependency> "<name>" has conflicting version requirements`                          | No version satisfies every range that pins it. The message lists the ranges.                      | Uninstall or update one of the conflicting plugins, or ask the upstream author to widen its constraint.                                                                                                                                                             |
| `... has version requirements too complex to intersect` or `has an invalid version requirement` | A range isn’t valid semver, or the combined ranges can’t be intersected.                          | Fix the invalid range or simplify long `||` chains.                                                                                                                                                                                                                 |
| `... has no git tag satisfying <range>`                                                         | The dependency’s repository has no `<name>--v*` tag in the range.                                 | Check that the upstream tags releases with that convention, or relax the range.                                                                                                                                                                                     |
| `Dependency "<dep>" (required by <plugin>) is in <marketplace>, which is not in the allowlist`  | The dependency is in a different marketplace, and cross-marketplace resolution is off by default. | Install the dependency yourself at the same scope, in your shell with `claude plugin install <dep>@<marketplace>` plus the `--scope` you’re installing the plugin at, then retry.                                                                                   |

To see these programmatically, run `claude plugin list --json` in your shell. Plugins with problems carry an `errors` field with the messages and an `errorDetails` field with a `type` for each: the first two rows are `dependency-unsatisfied` and the third is `dependency-version-unsatisfied`.


[​](#plugin-installed-but-not-working)

Plugin installed but not working

The install succeeded, but the plugin’s skills, hooks, or servers aren’t doing anything. Start with [Plugin doesn’t appear or its skills don’t show up](#plugin-doesnt-appear-or-its-skills-dont-show-up), which tells you where Claude Code reports what it loaded, then match the message.


[​](#plugin-doesnt-appear-or-its-skills-dont-show-up)

Plugin doesn’t appear or its skills don’t show up

You installed a plugin and typed `/` expecting its skills, or asked Claude to use it, and nothing happened. Check the plugin’s state before changing anything:

1

Confirm the plugin is installed and enabled

Run `/plugin` and open **Installed**. Confirm the plugin is listed and enabled. `claude plugin list` in your shell prints the same list with each plugin’s version, scope, and `Status: ✔ enabled`.

2

Read the Errors tab

Open the **Errors** tab in the same panel. Each entry pairs a message with a guidance line. Most messages in the rest of this section come from that tab.

3

Reload if you installed during this session

If the plugin is installed and error-free but you installed it during this session, run `/reload-plugins`. It prints `Reloaded:` with counts of plugins, skills, agents, hooks, and servers. When something failed it adds `N errors during load. Run /plugin for details.`

If the plugin loads with no error and its skills still don’t appear, the next step differs for your own plugin and for someone else’s:

- **A plugin you’re building**: see [Plugin loads but its skills are missing](#plugin-loads-but-its-skills-are-missing)
- **A plugin someone else published**: open **Installed** in `/plugin` and open the plugin’s details pane, which lists what the plugin contains. A plugin that lists no skills there has none to offer when you type `/`


[​](#run-reload-plugins-to-activate)

`Run /reload-plugins to activate.`

The install summary in `/plugin` ended with `Run /reload-plugins to activate.` instead of `Plugin is now active.` Claude Code didn’t activate the plugin during the install, either because activating it would [invalidate the prompt cache](../02-Claude-Code-CLI/prompt-caching.md#enabling-or-disabling-a-plugin) or because the activation attempt failed. You don’t need to type the command. The panel closes and Claude Code runs `/reload-plugins` for you, or queues it until the response that’s streaming finishes. Read what that reload prints:

- **`Reloaded:` with counts of plugins, skills, agents, hooks, and servers**: the plugin is now active. When something failed to load, the line adds `N errors during load. Run /plugin for details.`
- **`This reload changes MCP tools (...) — your next message will re-read the whole conversation instead of using the cache. Run /reload-plugins --force to apply.`**: the reload would add or remove a plugin MCP server, or the `LSP` tool, and invalidate your prompt cache. For the LSP case the line starts `This reload adds the LSP tool` or `This reload removes the LSP tool`. Run it with `--force` to activate the plugin anyway, or start a new session

Before v2.1.268, an install that didn’t activate during the install stayed pending until you ran `/reload-plugins` yourself. Before v2.1.246, the skills count in that summary included only a plugin’s `commands/` entries, so a reload could load a plugin’s `SKILL.md` skills and still report `0 skills`.


[​](#plugin-not-cached-at)

`Plugin "<name>" not cached at <path>`

The **Errors** tab shows this line with the guidance `Run /plugin to refresh the plugin cache`. Claude Code has an install record for the plugin, but the directory the record points at is missing, for example after you cleared the cache. Reinstall the plugin from your shell. `claude plugin install <name>@<marketplace>` re-downloads a plugin whose install directory is missing even though its record exists:

```python
claude plugin install <name>@<marketplace>
```

Then run `/reload-plugins` in your session. The **Errors** tab entry disappears and the plugin is back under **Installed**.


[​](#installed-plugins-json-holds-a-record-this-version-cannot-read)

`installed_plugins.json holds a record under "<id>" that this version of Claude Code cannot read`

The message surfaces in these forms:

- **`claude plugin list`**: prints it as a `Note:`
- **`claude plugin install`, `uninstall`, and `update`**: refuse with `Plugin "<name>" was not installed:`, `Plugin "<name>" was not uninstalled:`, or `Plugin "<name>" was not updated:`, followed by the same text
- **`--json` on any of those three commands**: the result line carries the same `message` and `failureCode: "install_records_unreadable"`
- **Several such records**: the message reads `holds records under`
- **The whole file declares a format this version doesn’t know**: the message reads `installed_plugins.json is in a format (version <N>) that this version of Claude Code does not know` instead

The named record in `installed_plugins.json` is valid JSON under a valid plugin id, but its fields don’t parse for this version. Most likely another version of Claude Code wrote it, perhaps a newer one. While the record is there, this version doesn’t rewrite the file, so the record isn’t lost. Take the message’s options in order:

1.  Update Claude Code with `claude update`.
2.  If you can’t update, uninstall the named plugin with the version of Claude Code that wrote the record.
3.  If neither helps, delete the record from `installed_plugins.json` by hand, then restart Claude Code or run `/reload-plugins`.


[​](#installed-plugins-json-could-not-be-read-and-was-rebuilt)

`installed_plugins.json could not be read and was rebuilt`

`claude plugin list` prints this note, with the path of a kept file named `installed_plugins.unreadable.<date>.<hash>.kept`, for as long as that file sits beside `installed_plugins.json`. An `installed_plugins.json` that isn’t valid JSON, or isn’t a list of plugins, can’t say what you installed. Open the `.kept` file to see what the old file recorded, and reinstall the plugins you’re missing. Claude Code never reads the file back, and the file ages out on the [`cleanupPeriodDays`](../02-Claude-Code-CLI/settings-reference.md#cleanupperioddays) schedule.


[​](#install-records-under-names-that-no-version-can-use)

`install records under names that no version of Claude Code can use were removed from installed_plugins.json`

`claude plugin list` prints this note, with the path of a copy named `installed_plugins.set-aside.<date>.<hash>.json`, for as long as that copy sits beside `installed_plugins.json`. The note ends `Nothing needs doing about these copies.` A record in `installed_plugins.json` sat under a key that isn’t a valid plugin id, so no version of Claude Code can use it. The rest of the file loads normally. Claude Code copies the unusable records into the `.set-aside` file and drops them from the list. Claude Code never reads the copies back, and the copies age out on the [`cleanupPeriodDays`](../02-Claude-Code-CLI/settings-reference.md#cleanupperioddays) schedule.


[​](#a-plugin-you-disabled-still-loads)

`Disabled in ~/.claude/settings.json but still loads`

You set a plugin to `false` in `~/.claude/settings.json`, and its row in `claude plugin list` or `/plugin` shows this message followed by the source that enables it, such as `— project settings enable it, which overrides your user setting`. A `true` in that higher-precedence source is overriding your user setting. To opt out of a project-enabled plugin on your machine, set the id to `false` in `.claude/settings.local.json`, which has higher precedence than the project file. For the other sources the message can name, see [Disabled in user settings but still loads](plugins-loading.md#disabled-in-user-settings-but-still-loads). If `claude plugin list` instead marks the plugin `required by your org`, no settings file is involved: your organization marks that synced plugin as required on claude.ai, and it loads even if you disabled it earlier. See [Plugins synced from claude.ai](plugins-loading.md#synced-plugins).


[​](#plugin-is-enabled-in-project-settings-but-isnt-installed-here)

`Plugin "<name>" is enabled in project settings but isn't installed here`

The **Errors** tab shows this line for a plugin your project’s `.claude/settings.json` enables, with the guidance `Run claude plugin install <name>@<marketplace> --scope project to install it for this project`. A repository’s settings can enable a plugin for everyone who opens it, but they don’t install it. When the plugin comes from an external source such as a GitHub repository or an npm package, Claude Code doesn’t download it until you install it yourself. Run the command from the guidance line in your shell, then reload:

```python
claude plugin install <name>@<marketplace> --scope project
```

After you run `/reload-plugins` in your session, the **Errors** tab entry is gone and the plugin is listed under **Installed**. If your organization pre-installs plugins for you, it does so through managed settings instead. See [Pre-install and require plugins](plugins-org.md#pre-install-and-require-plugins).


[​](#failed-to-load-hooks-from-and-hooks-that-dont-fire)

`Failed to load hooks from <path>` and hooks that don’t fire

A plugin’s hooks don’t run, or one blocks an action. Either the **Errors** tab shows a load failure for them, the hooks load and you see `<Event> hook error` notices or a blocking error in the transcript, or a hook loads without error and never fires.


[​](#hooks-fail-to-load)

Hooks fail to load

The **Errors** tab shows one of these messages:

- **`Failed to load hooks from <path>: <reason>`**: `hooks/hooks.json` isn’t valid JSON or fails the hooks schema. The reason names the parse or validation error. Fix the file. To catch a JSON syntax problem in `hooks/hooks.json` before you publish the plugin, run `claude plugin validate <plugin-directory>` in your shell
- **`hooks path not found: <path>`**: the manifest’s `hooks` field names a file that doesn’t exist at that path relative to the plugin root. Fix the path or add the file


[​](#hook-error-notices-in-the-transcript)

`hook error` notices in the transcript

A notice of the form `... hook error: Failed with non-blocking status code: <stderr>` means the hook ran and its command failed. For example, `Stop hook error: Failed with non-blocking status code: /bin/sh: node: command not found` means the shell Claude Code spawned couldn’t find `node`. Install it, or make sure it’s on the `PATH` of the terminal you start `claude` from. If the stderr shows the plugin’s path cut off at a space, the hook’s shell-form command uses `${CLAUDE_PLUGIN_ROOT}` outside quotes and the install path contains a space. Wrap the variable in double quotes or use [exec form](../07-Hooks/hooks.md#exec-form-and-shell-form). To find the unquoted variable, run `claude plugin validate` on the plugin’s directory and look for its [quoting warning](plugins-reference.md#quoting-and-path-separators). For any other error, run the hook’s command yourself from the plugin directory to see the full output, or capture the full stderr with [debug logging](../07-Hooks/hooks.md#debug-hooks).


[​](#a-plugin-hook-blocks-a-tool-call-or-prompt)

A plugin hook blocks a tool call or prompt

A hook that exits with code 2 [blocks the action it ran for](../07-Hooks/hooks.md#exit-code-2). When a plugin’s hook blocks this way and its stderr is the blocking message, the error ends with `This hook comes from the <plugin> plugin.` so that you know which plugin to disable or fix. Before v2.1.281, the error didn’t name the plugin. If that message shows the plugin’s path cut off at a space, apply the [unquoted `${CLAUDE_PLUGIN_ROOT}` fix](#hook-error-notices-in-the-transcript).


[​](#hook-loads-but-never-fires)

Hook loads but never fires

If a hook loads without error but never fires, check its definition and then watch it run:

1

Check the event name

Event names are case-sensitive, so confirm yours matches exactly, for example `PostToolUse`.

2

Check the matcher

Confirm the hook’s `matcher` matches the tool name.

3

Trigger the event on purpose

For a `PostToolUse` hook, ask Claude to edit a file.

4

Read the debug log

Open the [debug log](../07-Hooks/hooks.md#debug-hooks), which records which hooks matched. A hook that ran shows up there with its exit code.


[​](#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start)

`Invalid MCP server config for "<server>"` and MCP servers that don’t start

A plugin bundles an MCP server, and the **Errors** tab shows `Invalid MCP server config for "<server>": <error>`, or the server is listed but `/mcp` never shows it connected.


[​](#invalid-mcp-server-config-for-%3Cserver%3E-%3Cerror%3E)

`Invalid MCP server config for "<server>": <error>`

The server’s configuration passes the schema check, but Claude Code can’t resolve it for this session. The text after the colon names the cause and decides the fix:

- **`Missing environment variables: <names>`**: set those variables in the shell you start Claude Code from, then start a new session
- **`URL is unset or invalid`**: a `${user_config.*}` option that the URL uses isn’t set. Run `/plugin configure <plugin>` to set it
- **`has an invalid MCP url`** or **`headersHelper for MCP server '<server>' references ${user_config.*}`**: the plugin’s own configuration is at fault. Fix the `url` or `headersHelper` in your plugin’s MCP configuration, or report it to the plugin’s author if the plugin isn’t yours. The `headersHelper` case has its own entry under [plugin command references user_config](../02-Claude-Code-CLI/errors.md#plugin-command-references-user-config)


[​](#server-is-configured-but-never-connects)

Server is configured but never connects

Run `/mcp` to see the server’s status. When the server is healthy, `/mcp` lists it as connected. To read the error the server printed while starting, run `claude --debug` and open the log at `~/.claude/debug/<session-id>.txt`. The `--debug` flag doesn’t print to the terminal. A server entry in `.mcp.json` that fails the schema doesn’t appear in the **Errors** tab. Claude Code drops that server and records `Invalid MCP server config for <server> in <path>` only in that debug log. To find the entry without loading the plugin, run `claude plugin validate` in your shell on the plugin directory, which reports it as an error. Before v2.1.281, `claude plugin validate` didn’t check `.mcp.json`.


[​](#server-works-with-plugin-dir-but-fails-after-install)

Server works with `--plugin-dir` but fails after install

You’re the plugin’s author, and the server starts when you load the plugin from its source directory with `--plugin-dir` but fails once the plugin is installed. Claude Code copies an installed plugin into its cache, so a path that only works from the source directory breaks. Write paths inside the plugin with `${CLAUDE_PLUGIN_ROOT}`. For paths that reach outside the plugin directory, see [Files the plugin references outside its directory aren’t found](#files-the-plugin-references-outside-its-directory-arent-found).


[​](#language-server-doesnt-start)

Language server doesn’t start, uses too much memory, or reports wrong diagnostics

You installed a [code intelligence plugin](plugins-code-intelligence.md) and Claude isn’t seeing diagnostics, or the language server is using too much memory or reporting errors that aren’t real.


[​](#language-server-doesn’t-start)

Language server doesn’t start

The plugin connects to a language server binary you install separately, and Claude Code spawns it by command name from your `PATH`. The `/plugin` **Errors** tab shows the failure with its reason, such as `Executable not found in $PATH: "<binary>"`, and `claude --debug` logs it as `LSP server <name> failed to start: <reason>`. Install the binary and confirm it’s on the `PATH` of the terminal you start `claude` from, for example with `which typescript-language-server`. Then start a new session.


[​](#language-server-uses-too-much-memory)

Language server uses too much memory

Language servers such as `rust-analyzer` and `pyright` index the whole project. Disable the plugin with `/plugin disable <plugin>` in a session and rely on Claude’s built-in search tools instead.


[​](#false-positive-diagnostics-in-a-monorepo)

False positive diagnostics in a monorepo

A language server that isn’t configured for the workspace can report unresolved imports for internal packages. There’s nothing to fix on the Claude Code side, and the diagnostics don’t stop Claude from editing code.


[​](#build-a-plugin)

Build a plugin

You’re developing a plugin and loading it with `--plugin-dir` or installing it from a local marketplace. These entries cover the failures you hit while developing a plugin. For the checks to run after each change, see [Test and debug](plugins-create.md#test-and-debug). Two failures that also reach a plugin’s users have their entries under [Plugin installed but not working](#plugin-installed-but-not-working):

- **A hook that doesn’t fire**: see [hooks that don’t fire](#failed-to-load-hooks-from-and-hooks-that-dont-fire)
- **An MCP server that doesn’t start**: see [MCP servers that don’t start](#invalid-mcp-server-config-for-and-mcp-servers-that-dont-start)


[​](#commands-path-not-found)

`commands path not found: <path>`

The **Errors** tab shows `commands path not found: <absolute path>` with the guidance `Check that the path in your manifest or marketplace config is correct`. The same message appears for `skills`, `agents`, and `hooks`. Claude Code resolved a path from your `plugin.json` or marketplace entry against the plugin root and found nothing there. The path in the message is the absolute path it checked, so compare it with what’s on disk. Fix the path or create the directory, then run `/reload-plugins`. Paths in the manifest are relative to the plugin root and start with `./`. A path that resolves outside the plugin root is reported as `<component> path escapes plugin directory` instead and is dropped.


[​](#plugin-dir-loads-a-plugin-with-no-components)

`--plugin-dir` at a marketplace root doesn’t load the plugins under `plugins/`

You started `claude --plugin-dir <path>` and see no error, but the plugin’s skills, agents, and hooks aren’t there. `--plugin-dir` takes the plugin’s root directory, the one that contains `.claude-plugin/plugin.json` and the component directories such as `skills/`. If you point it at a marketplace root instead, Claude Code doesn’t read `marketplace.json`, so a plugin under `plugins/` doesn’t load, and you see no error. Before v2.1.281, Claude Code loaded a marketplace root as one empty plugin named after that directory. Point the flag at the plugin directory itself:

```python
claude --plugin-dir ./my-marketplace/plugins/my-plugin
```

Then open **Installed** in `/plugin`, where the plugin’s details pane lists its components.


[​](#files-the-plugin-references-outside-its-directory-arent-found)

Files the plugin references outside its directory aren’t found

A plugin works from its source directory with `--plugin-dir` but fails after install, with errors about a path such as `../shared-utils`. Claude Code copies an installed plugin into its cache and loads it from there, so a path that reaches outside the plugin’s own directory points at nothing in the cache. Move the shared files inside the plugin directory, or reference them through a symlink inside it. For where the cache is and how paths resolve, see [Find plugins on disk](plugins-loading.md#find-plugins-on-disk).


[​](#claude-plugin-root-shows-forward-slashes-on-windows)

`${CLAUDE_PLUGIN_ROOT}` shows forward slashes on Windows

On Windows, a plugin hook receives `${CLAUDE_PLUGIN_ROOT}` as `C:/Users/you/...` rather than `C:\Users\you\...`, and a script that expected backslashes breaks. Claude Code runs shell-form hooks through Git Bash on Windows and substitutes the plugin root in the forward-slash Win32 form on purpose. Bash builtins, MSYS tools, and native Windows binaries all accept that form. If your script needs backslashes, switch the hook to one of the forms that keep native paths, described under [exec form and shell form](../07-Hooks/hooks.md#exec-form-and-shell-form):

- An exec-form hook, which spawns the process directly with an `args` array
- A hook with `"shell": "powershell"`


[​](#plugin-loads-but-its-skills-are-missing)

Plugin loads but its skills are missing

Your plugin is listed under **Installed** with no errors, but its skills aren’t offered when you type `/`. Skills load from `skills/` at the plugin root and commands from `commands/` at the plugin root. Only `plugin.json` belongs inside `.claude-plugin/`, and a `skills/` directory inside `.claude-plugin/` isn’t scanned. Move the directories to the plugin root and run `/reload-plugins`. Afterward, the plugin’s details pane in `/plugin` lists the skills, and typing `/` offers them. Each skill is a directory containing `SKILL.md`. A `skills` entry in the manifest that points at a `SKILL.md` file rather than its directory is reported as `path is a file; skills entries must be directories containing SKILL.md`.


[​](#skill-loads-but-claude-never-invokes-the-skill)

Skill loads but Claude never invokes the skill

Your plugin’s skill runs when you type its `/<plugin>:<skill>` command, but Claude never invokes it in response to a plain request. Check these causes in order:

- **The skill sets `disable-model-invocation: true`**: with that field set, only you can invoke the skill. The template skill in [Create your first plugin](plugins-create.md#create-your-first-plugin) sets it. Remove the line from a skill you want Claude to invoke on its own. [Control who invokes a skill](skills.md#control-who-invokes-a-skill) covers the field
- **The description doesn’t match how people ask**: work through the checks in [Skill not triggering](skills.md#skill-not-triggering)
- **The description is truncated**: when many skills are installed, Claude Code shortens descriptions to fit the listing’s character budget, which can strip the keywords Claude needs to match a request. See [Skill descriptions are cut short](skills.md#skill-descriptions-are-cut-short)

To measure how often the skill triggers across realistic prompts rather than checking one at a time, write an eval case with a [`tool_used: Skill` grader](plugin-evals.md#create-your-first-eval-suite) and run it with `claude plugin eval` after each description change.


[​](#is-not-a-plugin-or-skill-folder)

`<directory> is not a plugin or skill folder` from `claude plugin eval init`

You ran `claude plugin eval init` from a directory that isn’t a plugin’s root, such as your home directory or the root of a repository that keeps the plugin in a subdirectory. `init` writes the suite under the working directory, so it stops instead of creating an `evals/` directory the plugin would never see. Change to the plugin’s root, the directory that holds `.claude-plugin/plugin.json` or the skill’s `SKILL.md`, and run the command again. To scaffold the suite somewhere else on purpose, pass `--eval-dir`. See [Test plugins with evals](plugin-evals.md).


[​](#the-userconfig-dialog-never-appears)

The `userConfig` dialog never appears

Your plugin declares `userConfig` options, but no configuration dialog appears when you install it. The interactive install shows the dialog, and the shell command takes the values as flags instead:

- **`/plugin install` in a session, or the Discover tab in `/plugin`**: the dialog is part of this interactive install
- **`claude plugin install` in your shell**: never prompts for `userConfig` values. It saves any `--config KEY=VALUE` values you pass, and when options remain unset it prints `N userConfig options not yet set — run /plugin configure <plugin>@<marketplace> in Claude Code, or pass --config KEY=VALUE.` When any of the unset options is required, `(M required)` follows `not yet set`.

If you installed from the shell, pass the values with `--config`, one flag per option:

```python
claude plugin install my-plugin@my-marketplace --config api_url=https://example.com
```

When every option is set, the install output carries no `not yet set` line. To open the dialog afterwards instead, run `/plugin configure my-plugin@my-marketplace` in a session. If you pass a `--config` key the manifest doesn’t declare, the plugin still installs, and the command prints `⚠ Installed, but --config not applied: --config key "<key>" isn't declared in this plugin's userConfig.` followed by the keys the plugin does declare.


[​](#claude-plugin-validate-reports-errors)

`claude plugin validate` reports errors

You ran `claude plugin validate <path>`, or `/plugin validate <path>` in a session, and it printed `Found N errors` and `Validation failed`, then exited with code 1. The validator reads the manifest at the path you give it: `.claude-plugin/plugin.json` for a plugin directory, or `.claude-plugin/marketplace.json` for a marketplace directory. For a marketplace, it prefixes problems in an entry’s own manifest with the entry index, as `plugins[1] plugin.json → json: ...`. The table covers the messages that stop validation and two warnings, `No frontmatter block found` and `Unknown field '<key>'`, which stop it only when you pass `--strict`. Other warnings, such as a missing description, aren’t listed.

| Message                                                                                                  | Cause                                                                    | Fix                                                                                                        |
|:---------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------|
| `File not found: <path>`                                                                                 | The path has no manifest, or doesn’t exist.                              | Run the command against the plugin or marketplace root, the directory that contains `.claude-plugin/`.     |
| `No manifest found in directory. Expected .claude-plugin/marketplace.json or .claude-plugin/plugin.json` | The directory has no `.claude-plugin/` manifest.                         | Create the manifest, or point at the right directory.                                                      |
| `Invalid JSON syntax: <parse error>`                                                                     | The manifest, or `hooks/hooks.json`, isn’t valid JSON.                   | Fix the JSON. Until you fix `hooks/hooks.json`, a session loads the plugin without the hooks in that file. |
| `Path not found: <path>. The runtime loader will report this as a load failure.`                         | A component path in the manifest doesn’t exist.                          | Fix the path or create the directory.                                                                      |
| `Path contains ".." which could be a path traversal attempt: <path>`                                     | A component path escapes the plugin directory.                           | Use paths inside the plugin root.                                                                          |
| `Path is a file; skills entries must be directories containing SKILL.md`                                 | A `skills` entry points at `SKILL.md` instead of its directory.          | Point at the parent directory, or `.` for a root-level `SKILL.md`.                                         |
| `No frontmatter block found` or `YAML frontmatter failed to parse: <error>`                              | A skill, agent, or command file has missing or invalid YAML frontmatter. | Add or fix the frontmatter between `---` delimiters. Reported when validating a plugin directory.          |
| `Unknown field '<key>'`                                                                                  | The manifest has a field the schema doesn’t define.                      | Remove it, or use the name the message suggests. Claude Code ignores unknown fields at load time.          |

Run the command again after each fix until it prints no errors. `plugin.json` fields are on the [manifest reference](plugins-reference.md), and marketplace-level messages are under [Marketplace validation errors](#marketplace-validation-errors).


[​](#plugin-has-conflicting-manifests)

`Plugin <name> has conflicting manifests`

The plugin fails to load with `Plugin <name> has conflicting manifests: both plugin.json and marketplace entry specify components.` The plugin has its own `plugin.json`, and its marketplace entry sets `strict: false` while also declaring any of `commands`, `agents`, `skills`, `hooks`, `outputStyles`, or `themes`. Remove those fields from the entry, or set `strict: true` in the entry so Claude Code appends them to `plugin.json`. See [Strict mode](plugins-marketplace-reference.md#strict-mode).


[​](#warning-no-commands-found-in-plugin-custom-directory)

`Warning: No commands found in plugin <name> custom directory`

When the plugin loads, the `claude --debug` log at `~/.claude/debug/<session-id>.txt` records `Warning: No commands found in plugin <name> custom directory: <path>. Expected .md files or SKILL.md in subdirectories.` Nothing appears in the session or the **Errors** tab. The `commands` path in the manifest exists but holds no `.md` files and no `SKILL.md` in a subdirectory. Add the command files, or remove the path from the manifest.


[​](#host-a-marketplace)

Host a marketplace

You publish a marketplace and a user reports an error, or your own validation fails. These entries are for the marketplace owner.


[​](#plugins-with-relative-paths-fail-in-url-based-marketplaces)

Plugins with relative paths fail in URL-based marketplaces

Users added your marketplace with an `https://example.com/marketplace.json` URL. Installs of plugins whose `source` is a relative path, such as `./plugins/my-plugin`, fail with `its marketplace entry path does not stay inside the marketplace directory`. Already-installed plugins fail to load with `Plugin source path refused`. Both messages have an [error reference entry](../02-Claude-Code-CLI/errors.md#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory). When a user adds a URL-based marketplace, Claude Code downloads only the `marketplace.json` file itself. It doesn’t fetch plugin files by relative path from that server, so a relative path in an entry points at a directory that was never fetched. Give each entry a source Claude Code can fetch on its own, such as a GitHub repository:

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

Alternatively, host the marketplace in a git repository and tell users to add it with the repository URL. For a git source, Claude Code clones the whole repository, so relative paths resolve. Source types are on the [marketplace reference](plugins-marketplace-reference.md).


[​](#marketplace-validation-errors)

Marketplace validation errors

You ran `claude plugin validate .` from your marketplace directory and it reported errors or warnings on the marketplace file itself. `claude plugin validate` also validates each entry whose `source` is a local path and warns when the entry’s `version` disagrees with the plugin’s own manifest. The table lists the marketplace-level messages. Entry-level messages are the plugin messages under [`claude plugin validate` reports errors](#claude-plugin-validate-reports-errors), prefixed with `plugins[N] plugin.json →`.

| Message                                                                                                                                                                                                                                               | Kind    | Fix                                                                                                                              |
|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------------------------------------------------------------------------------------------------------------------------------|
| `Duplicate plugin name "<name>" found in marketplace`                                                                                                                                                                                                 | Error   | Give each plugin a unique `name`.                                                                                                |
| `Path contains "..": <path>` under `plugins[N].source`                                                                                                                                                                                                | Error   | Use paths relative to the marketplace root without `..` segments.                                                                |
| `Marketplace name cannot contain control or bidirectional-formatting characters`                                                                                                                                                                      | Error   | Remove the character from the name, such as an escape or a newline.                                                              |
| `Plugin name cannot contain control or bidirectional-formatting characters`                                                                                                                                                                           | Error   | Remove the character from the plugin `name`.                                                                                     |
| `Claude Code cannot install plugins from marketplace "<name>". Each part of a plugin id (plugin@marketplace) may use only the letters a-z and A-Z, digits, ".", "_" and "-", and must start with a letter or digit. Change the marketplace's "name".` | Error   | Rename the marketplace to fit the rule the message states.                                                                       |
| `Claude Code cannot install plugin "<name>". Each part of a plugin id (plugin@marketplace) may use only the letters a-z and A-Z, digits, ".", "_" and "-", and must start with a letter or digit. Change this entry's "name".`                        | Error   | Rename the entry to fit the rule the message states.                                                                             |
| `Marketplace has no plugins defined`                                                                                                                                                                                                                  | Warning | Add at least one entry to `plugins`.                                                                                             |
| `No marketplace description provided`                                                                                                                                                                                                                 | Warning | Add a top-level `description`.                                                                                                   |
| `Plugin name "<name>" is not kebab-case` under `plugins[N] plugin.json → name`                                                                                                                                                                        | Warning | Rename to lowercase letters, digits, and hyphens; the claude.ai marketplace sync requires that form.                             |
| `Entry declares version "<a>" but <path>/plugin.json says "<b>"`                                                                                                                                                                                      | Warning | Update the entry to match `plugin.json`, which is authoritative at install time.                                                 |
| `Marketplace name "<name>" is reserved in Claude Desktop`                                                                                                                                                                                             | Warning | Rename the marketplace. Claude Desktop’s managed marketplace sync rejects `org`, `org-provisioned`, and `unknown` in any casing. |
| `Marketplace name "<name>" is not accepted by Claude Desktop` or `Plugin name "<name>" is not accepted by Claude Desktop`                                                                                                                             | Warning | Rename to at most 128 characters of letters, digits, `.`, `_`, and `-`, starting with a letter or digit.                         |

Before v2.1.247, a marketplace name containing control or bidirectional-formatting characters was reported only as `Marketplace name impersonates an official Anthropic/Claude marketplace`.


[​](#blocked-by-your-organization)

Blocked by your organization

Your organization deploys managed settings that restrict plugins, and a command was refused with a policy message. These entries name the setting behind each refusal so you know what to ask your administrator for. For the admin side, see [Manage plugins for your organization](plugins-org.md).


[​](#marketplace-source-is-blocked-by-enterprise-policy)

`Marketplace source '<source>' is blocked by enterprise policy`

You ran `/plugin marketplace add`, `update`, or an install, and Claude Code refused with this line. For a GitHub or git source, the host follows the source in parentheses, as in `'github:owner/repo' (github.com)`. Your administrator set `blockedMarketplaces` or `strictKnownMarketplaces` in managed settings, and this source isn’t permitted. Ask your administrator to allow the source, or add one of the allowed sources the message lists. Match the rest of the message to see what kind of policy blocked the source:

- **`Allowed sources: <list>`**: the block comes from the `strictKnownMarketplaces` allowlist rather than the `blockedMarketplaces` blocklist
- **`No external marketplaces are allowed.`**: the `strictKnownMarketplaces` allowlist is empty
- **A `Tip:` that the shorthand assumes github.com**: the allowlist permits a git host by hostname, and the `owner/repo` shorthand you passed points at github.com. If the repository lives on your internal host, add it again with its full URL, such as `git@your-git-host.com:owner/repo.git`

A marketplace you added before the policy became more restrictive stops refreshing too, because the policy applies on every refresh.


[​](#marketplace-is-not-in-the-allowed-marketplace-list)

`Marketplace "<name>" is not in the allowed marketplace list`

The **Errors** tab shows this line, or `Marketplace "<name>" is blocked by enterprise policy`, for a marketplace you already have registered. The same managed settings that block a [marketplace source](#marketplace-source-is-blocked-by-enterprise-policy) apply at load time. `strictKnownMarketplaces` doesn’t include this marketplace, or `blockedMarketplaces` names it, so Claude Code stops loading it and its plugins. For the allowlist variant, the guidance line shows the allowed sources, or `Contact your administrator to configure allowed marketplace sources`. For the blocklist variant it reads `This marketplace source is explicitly blocked by your administrator`.


[​](#plugin-is-blocked-by-your-organizations-policy-and-cannot-be-installed)

`Plugin "<name>" is blocked by your organization's policy and cannot be installed`

An install was refused with this line, an enable with the same line ending `cannot be enabled`, or an install or update with one naming the reason: `Plugin "<name>" is from marketplace "<marketplace>", which is blocked by your organization's policy`, or `Plugin "<name>" depends on "<dep>", which is blocked by your organization's policy`. Managed settings block this plugin, its marketplace, or a dependency it needs. Ask your administrator which entry applies. A blocked dependency means the plugin can’t install until the dependency’s marketplace is allowed.


[​](#plugin-dir-is-disabled-by-your-organizations-managed-settings-disables)

`--plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)`

You started `claude` with `--plugin-dir`, `--plugin-url`, `--agents`, or `--mcp-config`. Claude Code exited with this message and `Plugins, custom agents, and MCP servers can only be loaded from sources your administrator has approved.` Your administrator set `disableSideloadFlags` in managed settings, which turns off the flags that load plugins, agents, and servers from arbitrary paths. Load the plugin from an approved marketplace instead, or ask your administrator to remove the setting. A related message in the `/plugin` **Errors** tab is `--plugin-dir copy of "<name>" ignored: plugin is locked by managed settings`. Managed settings enable or disable that plugin by name, and Claude Code ignores your `--plugin-dir` copy of it so the flag can’t override the policy.


[​](#plugins-from-claude-skills-are-blocked-by-your-organizations-managed-s)

`Plugins from ~/.claude/skills/ are blocked by your organization's managed settings`

You ran `claude plugin init` or `claude plugin enable`, and it stopped with this line. The message names `strictKnownMarketplaces or blockedMarketplaces` and asks your administrator to add `{"source":"skills-dir"}` to `strictKnownMarketplaces` or remove it from `blockedMarketplaces`. The `skills-dir` source stands for plugins Claude Code loads from your `~/.claude/skills/` directory. Ask your administrator to make the change the message names.


[​](#command-sourced-plugins-are-disabled-by-your-organizations-managed-set)

`Command-sourced plugins are disabled by your organization's managed settings`

You installed or updated a plugin with a `command` source, and it stopped with this line and `The plugin was not installed or updated and its command was not run.` Your administrator set `disableCommandPluginSources`, so Claude Code refuses to run the marketplace-declared command that produces the plugin. Setting `allowManagedHooksOnly` alone has the same effect when `disableCommandPluginSources` is unset. Ask your administrator whether the plugin can be published from a source type the policy allows.


[​](#marketplace-is-seed-managed)

`Marketplace '<name>' is seed-managed`

You ran `claude plugin marketplace update <name>`, and it failed with `Marketplace '<name>' is seed-managed (<dir>)` and a hint to ask your admin. An operator pre-populated this marketplace through `CLAUDE_CODE_PLUGIN_SEED_DIR`, and Claude Code treats a seed-managed marketplace as read-only. A bulk `marketplace update` skips it and updates the others. To change the marketplace’s content, ask the person who maintains the seed image to update it. For the procedure, see [Seed containers and CI](plugins-org.md#seed-containers-and-ci).


[​](#next-steps)

Next steps

- [Plugin loading reference](plugins-loading.md): why scopes, the cache, and precedence behave the way they do
- [Plugin commands reference](plugins-cli-reference.md): flags, defaults, output, and exit codes for the `claude plugin` commands
- [Install and manage plugins](discover-plugins.md): the install steps from the start
- [Manage plugins for your organization](plugins-org.md#troubleshoot-policy): policy-side troubleshooting for administrators

---

## Plugins overview - Claude Code Docs

Source: https://code.claude.com/docs/en/plugins
Path: 08-Plugins-Skills/plugins.md

## On this page

- [Understand what a plugin is](#understand-what-a-plugin-is)
  - [Decide whether you need a plugin](#decide-whether-you-need-a-plugin)
  - [What an enabled plugin adds to your sessions](#what-an-enabled-plugin-adds-to-your-sessions)
- [Get plugins from a marketplace](#get-plugins-from-a-marketplace)
  - [Make an installed plugin available in your session](#make-an-installed-plugin-available-in-your-session)
- [Tell Anthropic’s marketplaces from third-party ones](#tell-anthropic%E2%80%99s-marketplaces-from-third-party-ones)
- [Understand install scopes](#understand-install-scopes)
- [Next steps](#next-steps)

Plugins

# Plugins overview

Copy pageCopy page

Understand what a Claude Code plugin is, when you need one instead of a standalone skill or MCP server, and which page to read to install or create one.

Copy pageCopy page

A Claude Code plugin is a directory of skills, agents, hooks, MCP servers, or other components that Claude Code installs and loads as one unit. Most plugins come from a marketplace, which is a catalog that lists plugins and where to fetch each one. You can also load a plugin from a folder someone gives you, or [build your own](plugins-create.md).

Start on claude.com instead if either of these describes you:

- **You use claude.ai chat or Cowork and not Claude Code**: see [Plugins on claude.ai and in Cowork](https://claude.com/docs/plugins/overview)
- **You built an MCP server and want it in Anthropic’s directory**: see [Publish to the directory](https://claude.com/docs/directory/publish)

To try a plugin now, run `/plugin` in a Claude Code terminal session and install one from the **Discover** tab, which lists the plugins from Anthropic’s official marketplace and any marketplace you’ve added. From there:

- [Install and manage plugins](discover-plugins.md): the full install steps, scopes, and other surfaces
- [Create a plugin](plugins-create.md): build your own
- [Decide whether you need a plugin](#decide-whether-you-need-a-plugin): whether a plugin is the right tool for what you want


[​](#understand-what-a-plugin-is)

Understand what a plugin is

A plugin is a directory of components, usually with a manifest. The manifest, a JSON file at `.claude-plugin/plugin.json`, gives the plugin its name and can add a version, a description, and other [metadata](plugins-reference.md). The components are what the plugin adds to Claude Code, such as:

- [**Skills**](plugins-components.md#skills): `SKILL.md` instructions Claude loads when relevant, and that you can also run as a command
- [**Agents**](plugins-components.md#agents): subagent definitions Claude can delegate to
- [**Hooks**](plugins-components.md#hooks): commands Claude Code runs at points in its lifecycle, such as after every edit
- [**MCP servers**](plugins-components.md#mcp-servers): tool servers Claude Code connects to while the plugin is enabled

This diagram shows a plugin named `my-plugin` that holds one of each of those components, and what you get from each file once the plugin loads.

For every component type a plugin can hold, with an example of each, see [Plugin components](plugins-components.md). To see where each piece is located in a plugin’s directory, use the [plugin explorer](plugins-components.md#explore-the-plugin-directory) on that page.


[​](#decide-whether-you-need-a-plugin)

Decide whether you need a plugin

Skills, subagents, hooks, and MCP servers all work on their own, without a plugin. A skill you save in `~/.claude/skills/`, for example, is available in every project on your machine. To set one up on its own, see [Skills](skills.md), [Subagents](../09-Agents-Patterns/sub-agents.md), [Hooks](../07-Hooks/hooks-guide.md), or [MCP](../06-MCP-Tools/General/mcp.md). Use a plugin when you want several skills, subagents, hooks, or MCP servers packaged as one unit. Install one to get a setup someone else built, with one command and updates from its marketplace. Make one to give your own setup to teammates, install it in many projects, or publish versioned releases.


[​](#what-an-enabled-plugin-adds-to-your-sessions)

What an enabled plugin adds to your sessions

An enabled plugin is part of every session, not only the sessions where you use it. That has a few consequences worth knowing before you install one:

- **Context and usage**: for each skill, agent, and command that [Claude can invoke on its own](skills.md#control-who-invokes-a-skill), the name and description are in Claude’s context on every turn so that Claude knows it exists. Those tokens count toward your usage and leave less room in the [context window](../02-Claude-Code-CLI/context-window.md) even in sessions where nothing from the plugin runs. The full text of a skill or agent loads only when it’s used. What the plugin’s MCP servers add per turn follows [MCP tool search](../06-MCP-Tools/General/mcp.md#scale-with-mcp-tool-search).
- **Processes**: MCP servers the plugin defines run alongside each session where it’s enabled, and its hooks fire at their events.
- **Permissions**: what the plugin runs, it runs as you. See [Plugin security and trust](plugins-security.md) for what to review first.

You can check a plugin’s footprint at each stage:

- **Before you install**: open the plugin from the **Marketplaces** tab in `/plugin`. Plugins in Anthropic’s official marketplace show a **Context cost** estimate there.
- **After you install**: [Measure what a plugin costs](plugins-measure.md#measure-what-a-plugin-costs) shows how to read a plugin’s footprint, and the **Installed** tab’s **Not used recently** group lists plugins you could turn off.
- **To stop it without uninstalling**: disable the plugin with `/plugin` or, in your shell, `claude plugin disable`. See [Manage installed plugins](discover-plugins.md#manage-installed-plugins).


[​](#get-plugins-from-a-marketplace)

Get plugins from a marketplace

A marketplace is a repository or directory with a `.claude-plugin/marketplace.json` file that lists plugins and where to fetch each one. It’s a catalog, not a hosted store. You add a marketplace once, then install plugins from it by name, such as `commit-commands@claude-plugins-official`.

A plugin marketplace isn’t [Claude Marketplace](https://claude.com/marketplace). Claude Marketplace is the website at claude.com/marketplace where you browse plugins, connectors, partner products, and service partners. It isn’t a marketplace you add with `/plugin marketplace add`.

Claude Code adds Anthropic’s official marketplace the first time you start an interactive terminal session, unless a [managed policy](plugins-org.md#allow-the-official-marketplace-and-your-own) blocks it. Claude Code adds no other marketplace on its own, including Anthropic’s community and demo marketplaces. To distinguish the three Anthropic marketplaces, read [Anthropic’s marketplaces](plugins-anthropic-marketplaces.md). To see what the official one lists, open the **Discover** tab of `/plugin` in a session or browse [Claude Marketplace](https://claude.com/marketplace/plugins). This diagram shows the path from a marketplace to your session. A marketplace lists a plugin, you install that plugin, and Claude Code loads its components.

[Install and manage plugins](discover-plugins.md#install-a-plugin) has the install steps for each place you run Claude Code. While you’re developing a plugin, you don’t need a marketplace: load it straight from its folder with `--plugin-dir`, as [Develop without a marketplace](plugins-create.md#develop-without-a-marketplace) shows.


[​](#make-an-installed-plugin-available-in-your-session)

Make an installed plugin available in your session

Before a plugin you installed gives you a skill you can run, it has to be present at each of these layers:

- **Settings**: your settings list the marketplaces you’ve added and the plugins that are enabled.
- **Disk**: `~/.claude/plugins/` holds what Claude Code has fetched and installed.
- **Session**: plugins load at startup, or when you [reload plugins](plugins-loading.md#check-which-stage-a-plugin-reached).

Read [Plugin loading reference](plugins-loading.md) for the rules at each layer, including which settings file takes precedence and where the files are on disk.


[​](#tell-anthropic’s-marketplaces-from-third-party-ones)

Tell Anthropic’s marketplaces from third-party ones

A marketplace’s name places it in one of three tiers. Claude Code accepts the official and community names only for marketplaces sourced from `github.com/anthropics/` repositories:

- **Official**: marketplaces with one of Anthropic’s [official marketplace names](plugins-security.md#official-marketplace-names), including `claude-plugins-official` and the demo marketplace `claude-code-plugins`.
- **Community**: marketplaces with one of Anthropic’s community names, such as `claude-community`. [Identify Anthropic’s marketplaces by name](plugins-security.md#marketplace-tiers) lists them.
- **Third-party**: every other marketplace. A marketplace your coworker or your organization publishes is third-party.

Whatever the tier, a plugin you install can run code with your user privileges. Read [Plugin security and trust](plugins-security.md) for how to review a plugin before you install it. Through [managed settings](../02-Claude-Code-CLI/settings.md#settings-files), an organization can allowlist or block marketplaces, force-install plugins, and turn off session-only loading. Read [Manage plugins for your organization](plugins-org.md) for those controls.


[​](#understand-install-scopes)

Understand install scopes

When you install a plugin, you pick a scope, and the scope decides who the plugin is enabled for:

- **User scope**: enabled for you in every project on this computer
- **Project scope**: enabled for everyone who works in this repository, through the committed `.claude/settings.json`. Each collaborator still [installs it on their own machine](plugins-loading.md#enabled-in-project-settings-but-not-installed)
- **Local scope**: enabled for you in this repository only

A plugin you install at user scope in the terminal, the desktop app’s local sessions, or the VS Code extension is available in the other two on that computer, because all three read the same settings files. See [Choose an install scope](discover-plugins.md#choose-an-install-scope) for how to pick one. A cloud session, including one in the browser at claude.ai/code, doesn’t load the plugins in your local settings. For install steps in the terminal, VS Code, and the desktop app, and for what a cloud session loads, see [Install a plugin](discover-plugins.md#install-a-plugin).

The same plugin format also installs on claude.ai and in Cowork, where a different set of components loads. For those surfaces, see [Plugins on claude.ai and in Cowork](https://claude.com/docs/plugins/overview) on claude.com and its [component support table](https://claude.com/docs/plugins/platform-support#compare-component-support-by-app).


[​](#next-steps)

Next steps

Most people start by installing a plugin from Anthropic’s official marketplace, which Claude Code adds the first time you start an interactive terminal session. Run `/plugin` in a terminal session to browse it, or follow [Install and manage plugins](discover-plugins.md), which also covers the desktop app and VS Code. To see what’s in that marketplace before you open Claude Code, browse [Claude Marketplace](https://claude.com/marketplace/plugins) on the web. To build your own, [Create a plugin](plugins-create.md) starts with an empty directory and ends with a working plugin. Once you’ve installed or built a plugin, these pages cover what comes next:

- **Share what you built**: [Publish and distribute a plugin](plugins-publish.md), through your own marketplace or [Anthropic’s directory](plugins-publish.md#submit-to-anthropics-directory)
- **Check whether it works and is used**: [Test plugins with evals](plugin-evals.md) and [Measure plugin cost and usage](plugins-measure.md)
- **Run a marketplace for your team**: [Create a marketplace](plugin-marketplaces.md), then [Host and maintain a marketplace](plugins-host-marketplace.md)
- **Set plugin policy for an organization**: [Manage plugins for your organization](plugins-org.md)
- **Fix a problem**: [Troubleshoot plugins](plugins-troubleshooting.md)

---

## Best practices for skill creators - Agent Skills

Source: https://agentskills.io/skill-creation/best-practices
Path: 08-Plugins-Skills/skill-creation-best-practices.md

## On this page

- [Start from real expertise](#start-from-real-expertise)
  - [Extract from a hands-on task](#extract-from-a-hands-on-task)
  - [Synthesize from existing project artifacts](#synthesize-from-existing-project-artifacts)
- [Refine with real execution](#refine-with-real-execution)
- [Spending context wisely](#spending-context-wisely)
  - [Add what the agent lacks, omit what it knows](#add-what-the-agent-lacks-omit-what-it-knows)
  - [Design coherent units](#design-coherent-units)
  - [Aim for moderate detail](#aim-for-moderate-detail)
  - [Structure large skills with progressive disclosure](#structure-large-skills-with-progressive-disclosure)
- [Calibrating control](#calibrating-control)
  - [Match specificity to fragility](#match-specificity-to-fragility)
  - [Provide defaults, not menus](#provide-defaults-not-menus)
  - [Favor procedures over declarations](#favor-procedures-over-declarations)
- [Patterns for effective instructions](#patterns-for-effective-instructions)
  - [Gotchas sections](#gotchas-sections)
  - [Templates for output format](#templates-for-output-format)
  - [Checklists for multi-step workflows](#checklists-for-multi-step-workflows)
  - [Validation loops](#validation-loops)
  - [Plan-validate-execute](#plan-validate-execute)
  - [Bundling reusable scripts](#bundling-reusable-scripts)
- [Next steps](#next-steps)

For skill creators

# Best practices for skill creators

Copy pageCopy page

How to write skills that are well-scoped and calibrated to the task.

Copy pageCopy page


[​](#start-from-real-expertise)

Start from real expertise

A common pitfall in skill creation is asking an LLM to generate a skill without providing domain-specific context — relying solely on the LLM’s general training knowledge. The result is vague, generic procedures (“handle errors appropriately,” “follow best practices for authentication”) rather than the specific API patterns, edge cases, and project conventions that make a skill valuable. Effective skills are grounded in real expertise. The key is feeding domain-specific context into the creation process.


[​](#extract-from-a-hands-on-task)

Extract from a hands-on task

Complete a real task in conversation with an agent, providing context, corrections, and preferences along the way. Then extract the reusable pattern into a skill. Pay attention to:

- **Steps that worked** — the sequence of actions that led to success
- **Corrections you made** — places where you steered the agent’s approach (e.g., “use library X instead of Y,” “check for edge case Z”)
- **Input/output formats** — what the data looked like going in and coming out
- **Context you provided** — project-specific facts, conventions, or constraints the agent didn’t already know


[​](#synthesize-from-existing-project-artifacts)

Synthesize from existing project artifacts

When you have a body of existing knowledge, you can feed it into an LLM and ask it to synthesize a skill. A data-pipeline skill synthesized from your team’s actual incident reports and runbooks will outperform one synthesized from a generic “data engineering best practices” article, because it captures *your* schemas, failure modes, and recovery procedures. The key is project-specific material, not generic references. Good source material includes:

- Internal documentation, runbooks, and style guides
- API specifications, schemas, and configuration files
- Code review comments and issue trackers (captures recurring concerns and reviewer expectations)
- Version control history, especially patches and fixes (reveals patterns through what actually changed)
- Real-world failure cases and their resolutions


[​](#refine-with-real-execution)

Refine with real execution

The first draft of a skill usually needs refinement. Run the skill against real tasks, then feed the results — all of them, not just failures — back into the creation process. Ask: what triggered false positives? What was missed? What could be cut? Even a single pass of execute-then-revise noticeably improves quality, and complex domains often benefit from several.

Read agent execution traces, not just final outputs. If the agent wastes time on unproductive steps, common causes include instructions that are too vague (the agent tries several approaches before finding one that works), instructions that don’t apply to the current task (the agent follows them anyway), or too many options presented without a clear default.

For a more structured approach to iteration, including test cases, assertions, and grading, see [Evaluating skill output quality](skill-creation-evaluating-skills.md).


[​](#spending-context-wisely)

Spending context wisely

Once a skill activates, its full `SKILL.md` body loads into the agent’s context window alongside conversation history, system context, and other active skills. Every token in your skill competes for the agent’s attention with everything else in that window.


[​](#add-what-the-agent-lacks-omit-what-it-knows)

Add what the agent lacks, omit what it knows

Focus on what the agent *wouldn’t* know without your skill: project-specific conventions, domain-specific procedures, non-obvious edge cases, and the particular tools or APIs to use. You don’t need to explain what a PDF is, how HTTP works, or what a database migration does.

```` shiki
<!-- Too verbose — the agent already knows what PDFs are -->
## Extract PDF text

PDF (Portable Document Format) files are a common file format that contains
text, images, and other content. To extract text from a PDF, you'll need to
use a library. pdfplumber is recommended because it handles most cases well.

<!-- Better — jumps straight to what the agent wouldn't know on its own -->
## Extract PDF text

Use pdfplumber for text extraction. For scanned documents, fall back to
pdf2image with pytesseract.

```python
import pdfplumber

with pdfplumber.open("file.pdf") as pdf:
    text = pdf.pages[0].extract_text()
```
````

Ask yourself about each piece of content: “Would the agent get this wrong without this instruction?” If the answer is no, cut it. If you’re unsure, test it. And if the agent already handles the entire task well without the skill, the skill may not be adding value. See [Evaluating skill output quality](skill-creation-evaluating-skills.md) for how to test this systematically.


[​](#design-coherent-units)

Design coherent units

Deciding what a skill should cover is like deciding what a function should do: you want it to encapsulate a coherent unit of work that composes well with other skills. Skills scoped too narrowly force multiple skills to load for a single task, risking overhead and conflicting instructions. Skills scoped too broadly become hard to activate precisely. A skill for querying a database and formatting the results may be one coherent unit, while a skill that also covers database administration is probably trying to do too much.


[​](#aim-for-moderate-detail)

Aim for moderate detail

Overly comprehensive skills can hurt more than they help — the agent struggles to extract what’s relevant and may pursue unproductive paths triggered by instructions that don’t apply to the current task. Concise, stepwise guidance with a working example tends to outperform exhaustive documentation. When you find yourself covering every edge case, consider whether most are better handled by the agent’s own judgment.


[​](#structure-large-skills-with-progressive-disclosure)

Structure large skills with progressive disclosure

The [specification](specification.md#progressive-disclosure) recommends keeping `SKILL.md` under 500 lines and 5,000 tokens — just the core instructions the agent needs on every run. When a skill legitimately needs more content, move detailed reference material to separate files in `references/` or similar directories. The key is telling the agent *when* to load each file. “Read `references/api-errors.md` if the API returns a non-200 status code” is more useful than a generic “see references/ for details.” This lets the agent load context on demand rather than up front, which is how [progressive disclosure](specification.md#progressive-disclosure) is designed to work.


[​](#calibrating-control)

Calibrating control

Not every part of a skill needs the same level of prescriptiveness. Match the specificity of your instructions to the fragility of the task.


[​](#match-specificity-to-fragility)

Match specificity to fragility

**Give the agent freedom** when multiple approaches are valid and the task tolerates variation. For flexible instructions, explaining *why* can be more effective than rigid directives — an agent that understands the purpose behind an instruction makes better context-dependent decisions. A code review skill can describe what to look for without prescribing exact steps:

```python
## Code review process

1. Check all database queries for SQL injection (use parameterized queries)
2. Verify authentication checks on every endpoint
3. Look for race conditions in concurrent code paths
4. Confirm error messages don't leak internal details
```

**Be prescriptive** when operations are fragile, consistency matters, or a specific sequence must be followed:

```` shiki
## Database migration

Run exactly this sequence:

```bash
python scripts/migrate.py --verify --backup
```

Do not modify the command or add additional flags.
````

Most skills have a mix. Calibrate each part independently.


[​](#provide-defaults-not-menus)

Provide defaults, not menus

When multiple tools or approaches could work, pick a default and mention alternatives briefly rather than presenting them as equal options.

```` shiki
<!-- Too many options -->
You can use pypdf, pdfplumber, PyMuPDF, or pdf2image...

<!-- Clear default with escape hatch -->
Use pdfplumber for text extraction:

```python
import pdfplumber
```

For scanned PDFs requiring OCR, use pdf2image with pytesseract instead.
````


[​](#favor-procedures-over-declarations)

Favor procedures over declarations

A skill should teach the agent *how to approach* a class of problems, not *what to produce* for a specific instance. Compare:

```python
<!-- Specific answer — only useful for this exact task -->
Join the `orders` table to `customers` on `customer_id`, filter where
`region = 'EMEA'`, and sum the `amount` column.

<!-- Reusable method — works for any analytical query -->
1. Read the schema from `references/schema.yaml` to find relevant tables
2. Join tables using the `_id` foreign key convention
3. Apply any filters from the user's request as WHERE clauses
4. Aggregate numeric columns as needed and format as a markdown table
```

This doesn’t mean skills can’t include specific details — output format templates (see [Templates for output format](#templates-for-output-format)), constraints like “never output PII,” and tool-specific instructions are all valuable. The point is that the *approach* should generalize even when individual details are specific.


[​](#patterns-for-effective-instructions)

Patterns for effective instructions

These are reusable techniques for structuring skill content. Not every skill needs all of them — use the ones that fit your task.


[​](#gotchas-sections)

Gotchas sections

The highest-value content in many skills is a list of gotchas — environment-specific facts that defy reasonable assumptions. These aren’t general advice (“handle errors appropriately”) but concrete corrections to mistakes the agent will make without being told otherwise:

```python
## Gotchas

- The `users` table uses soft deletes. Queries must include
  `WHERE deleted_at IS NULL` or results will include deactivated accounts.
- The user ID is `user_id` in the database, `uid` in the auth service,
  and `accountId` in the billing API. All three refer to the same value.
- The `/health` endpoint returns 200 as long as the web server is running,
  even if the database connection is down. Use `/ready` to check full
  service health.
```

Keep gotchas in `SKILL.md` where the agent reads them before encountering the situation. A separate reference file works if you tell the agent when to load it, but for non-obvious issues, the agent may not recognize the trigger.

When an agent makes a mistake you have to correct, add the correction to the gotchas section. This is one of the most direct ways to improve a skill iteratively (see [Refine with real execution](#refine-with-real-execution)).


[​](#templates-for-output-format)

Templates for output format

When you need the agent to produce output in a specific format, provide a template. This is more reliable than describing the format in prose, because agents pattern-match well against concrete structures. Short templates can live inline in `SKILL.md`; for longer templates, or templates only needed in certain cases, store them in `assets/` and reference them from `SKILL.md` so they only load when needed.

```` shiki
## Report structure

Use this template, adapting sections as needed for the specific analysis:

```markdown
# [Analysis Title]

## Executive summary
[One-paragraph overview of key findings]

## Key findings
- Finding 1 with supporting data
- Finding 2 with supporting data

## Recommendations
1. Specific actionable recommendation
2. Specific actionable recommendation
```
````


[​](#checklists-for-multi-step-workflows)

Checklists for multi-step workflows

An explicit checklist helps the agent track progress and avoid skipping steps, especially when steps have dependencies or validation gates.

```python
## Form processing workflow

Progress:
- [ ] Step 1: Analyze the form (run `scripts/analyze_form.py`)
- [ ] Step 2: Create field mapping (edit `fields.json`)
- [ ] Step 3: Validate mapping (run `scripts/validate_fields.py`)
- [ ] Step 4: Fill the form (run `scripts/fill_form.py`)
- [ ] Step 5: Verify output (run `scripts/verify_output.py`)
```


[​](#validation-loops)

Validation loops

Instruct the agent to validate its own work before moving on. The pattern is: do the work, run a validator (a script, a reference checklist, or a self-check), fix any issues, and repeat until validation passes.

```python
## Editing workflow

1. Make your edits
2. Run validation: `python scripts/validate.py output/`
3. If validation fails:
   - Review the error message
   - Fix the issues
   - Run validation again
4. Only proceed when validation passes
```

A reference document can also serve as the “validator” — instruct the agent to check its work against the reference before finalizing.


[​](#plan-validate-execute)

Plan-validate-execute

For batch or destructive operations, have the agent create an intermediate plan in a structured format, validate it against a source of truth, and only then execute.

```python
## PDF form filling

1. Extract form fields: `python scripts/analyze_form.py input.pdf` → `form_fields.json`
   (lists every field name, type, and whether it's required)
2. Create `field_values.json` mapping each field name to its intended value
3. Validate: `python scripts/validate_fields.py form_fields.json field_values.json`
   (checks that every field name exists in the form, types are compatible, and
   required fields aren't missing)
4. If validation fails, revise `field_values.json` and re-validate
5. Fill the form: `python scripts/fill_form.py input.pdf field_values.json output.pdf`
```

The key ingredient is step 3: a validation script that checks the plan (`field_values.json`) against the source of truth (`form_fields.json`). Errors like “Field ‘signature_date’ not found — available fields: customer_name, order_total, signature_date_signed” give the agent enough information to self-correct.


[​](#bundling-reusable-scripts)

Bundling reusable scripts

When [iterating on a skill](skill-creation-evaluating-skills.md), compare the agent’s execution traces across test cases. If you notice the agent independently reinventing the same logic each run — building charts, parsing a specific format, validating output — that’s a signal to write a tested script once and bundle it in `scripts/`. For more on designing and bundling scripts, see [Using scripts in skills](skill-creation-using-scripts.md).


[​](#next-steps)

Next steps

Once you have a working skill, two guides can help you refine it further:

- **[Evaluating skill output quality](skill-creation-evaluating-skills.md)** — Set up test cases, grade results, and iterate systematically.
- **[Optimizing skill descriptions](skill-creation-optimizing-descriptions.md)** — Test and improve your skill’s `description` field so it triggers on the right prompts.

[Quickstart](skill-creation-quickstart.md)[Optimizing descriptions](skill-creation-optimizing-descriptions.md)

---

## Evaluating skill output quality - Agent Skills

Source: https://agentskills.io/skill-creation/evaluating-skills
Path: 08-Plugins-Skills/skill-creation-evaluating-skills.md

## On this page

- [Designing test cases](#designing-test-cases)
- [Running evals](#running-evals)
  - [Workspace structure](#workspace-structure)
  - [Spawning runs](#spawning-runs)
  - [Capturing timing data](#capturing-timing-data)
- [Writing assertions](#writing-assertions)
- [Grading outputs](#grading-outputs)
  - [Grading principles](#grading-principles)
- [Aggregating results](#aggregating-results)
- [Analyzing patterns](#analyzing-patterns)
- [Reviewing results with a human](#reviewing-results-with-a-human)
- [Iterating on the skill](#iterating-on-the-skill)
  - [The loop](#the-loop)

For skill creators

# Evaluating skill output quality

Copy pageCopy page

How to test whether your skill produces good outputs using eval-driven iteration.

Copy pageCopy page

You wrote a skill, tried it on a prompt, and it seemed to work. But does it work reliably — across varied prompts, in edge cases, better than no skill at all? Running structured evaluations (evals) answers these questions and gives you a feedback loop for improving the skill systematically.


[​](#designing-test-cases)

Designing test cases

A test case has three parts:

- **Prompt**: a realistic user message — the kind of thing someone would actually type.
- **Expected output**: a human-readable description of what success looks like.
- **Input files** (optional): files the skill needs to work with.

Store test cases in `evals/evals.json` inside your skill directory:

evals/evals.json

```python
{
  "skill_name": "csv-analyzer",
  "evals": [
    {
      "id": 1,
      "prompt": "I have a CSV of monthly sales data in data/sales_2025.csv. Can you find the top 3 months by revenue and make a bar chart?",
      "expected_output": "A bar chart image showing the top 3 months by revenue, with labeled axes and values.",
      "files": ["evals/files/sales_2025.csv"]
    },
    {
      "id": 2,
      "prompt": "there's a csv in my downloads called customers.csv, some rows have missing emails — can you clean it up and tell me how many were missing?",
      "expected_output": "A cleaned CSV with missing emails handled, plus a count of how many were missing.",
      "files": ["evals/files/customers.csv"]
    }
  ]
}
```

**Tips for writing good test prompts:**

- **Start with 2-3 test cases.** Don’t over-invest before you’ve seen your first round of results. You can expand the set later.
- **Vary the prompts.** Use different phrasings, levels of detail, and formality. Some prompts should be casual (“hey can you clean up this csv”), others precise (“Parse the CSV at data/input.csv, drop rows where column B is null, and write the result to data/output.csv”).
- **Cover edge cases.** Include at least one prompt that tests a boundary condition — a malformed input, an unusual request, or a case where the skill’s instructions might be ambiguous.
- **Use realistic context.** Real users mention file paths, column names, and personal context. Prompts like “process this data” are too vague to test anything useful.

Don’t worry about defining specific pass/fail checks yet — just the prompts and expected outputs. You’ll add detailed checks (called assertions) after you see what the first run produces.


[​](#running-evals)

Running evals

The core pattern is to run each test case twice: once **with the skill** and once **without it** (or with a previous version). This gives you a baseline to compare against.


[​](#workspace-structure)

Workspace structure

Organize eval results in a workspace directory alongside your skill directory. Each pass through the full eval loop gets its own `iteration-N/` directory. Within that, each test case gets an eval directory with `with_skill/` and `without_skill/` subdirectories:

```python
csv-analyzer/
├── SKILL.md
└── evals/
    └── evals.json
csv-analyzer-workspace/
└── iteration-1/
    ├── eval-top-months-chart/
    │   ├── with_skill/
    │   │   ├── outputs/       # Files produced by the run
    │   │   ├── timing.json    # Tokens and duration
    │   │   └── grading.json   # Assertion results
    │   └── without_skill/
    │       ├── outputs/
    │       ├── timing.json
    │       └── grading.json
    ├── eval-clean-missing-emails/
    │   ├── with_skill/
    │   │   ├── outputs/
    │   │   ├── timing.json
    │   │   └── grading.json
    │   └── without_skill/
    │       ├── outputs/
    │       ├── timing.json
    │       └── grading.json
    └── benchmark.json         # Aggregated statistics
```

The main file you author by hand is `evals/evals.json`. The other JSON files (`grading.json`, `timing.json`, `benchmark.json`) are produced during the eval process — by the agent, by scripts, or by you.


[​](#spawning-runs)

Spawning runs

Each eval run should start with a clean context — no leftover state from previous runs or from the skill development process. This ensures the agent follows only what the `SKILL.md` tells it. In environments that support subagents (Claude Code, for example), this isolation comes naturally: each child task starts fresh. Without subagents, use a separate session for each run. For each run, provide:

- The skill path (or no skill for the baseline)
- The test prompt
- Any input files
- The output directory

Here’s an example of the instructions you’d give the agent for a single with-skill run:

```python
Execute this task:
- Skill path: /path/to/csv-analyzer
- Task: I have a CSV of monthly sales data in data/sales_2025.csv.
  Can you find the top 3 months by revenue and make a bar chart?
- Input files: evals/files/sales_2025.csv
- Save outputs to: csv-analyzer-workspace/iteration-1/eval-top-months-chart/with_skill/outputs/
```

For the baseline, use the same prompt but without the skill path, saving to `without_skill/outputs/`. When improving an existing skill, use the previous version as your baseline. Snapshot it before editing (`cp -r <skill-path> <workspace>/skill-snapshot/`), point the baseline run at the snapshot, and save to `old_skill/outputs/` instead of `without_skill/`.


[​](#capturing-timing-data)

Capturing timing data

Timing data lets you compare how much time and tokens the skill costs relative to the baseline — a skill that dramatically improves output quality but triples token usage is a different trade-off than one that’s both better and cheaper. When each run completes, record the token count and duration:

timing.json

```python
{
  "total_tokens": 84852,
  "duration_ms": 23332
}
```

In Claude Code, when a subagent task finishes, the [task completion notification](https://agentskills.io/05-Agent-SDK/agent-sdk-typescript.md#sdk-task-notification-message) includes `total_tokens` and `duration_ms`. Save these values immediately — they aren’t persisted anywhere else.


[​](#writing-assertions)

Writing assertions

Assertions are verifiable statements about what the output should contain or achieve. Add them after you see your first round of outputs — you often don’t know what “good” looks like until the skill has run. Good assertions:

- `"The output file is valid JSON"` — programmatically verifiable.
- `"The bar chart has labeled axes"` — specific and observable.
- `"The report includes at least 3 recommendations"` — countable.

Weak assertions:

- `"The output is good"` — too vague to grade.
- `"The output uses exactly the phrase 'Total Revenue: $X'"` — too brittle; correct output with different wording would fail.

Not everything needs an assertion. Some qualities — writing style, visual design, whether the output “feels right” — are hard to decompose into pass/fail checks. These are better caught during [human review](#reviewing-results-with-a-human). Reserve assertions for things that can be checked objectively. Add assertions to each test case in `evals/evals.json`:

evals/evals.json

```python
{
  "skill_name": "csv-analyzer",
  "evals": [
    {
      "id": 1,
      "prompt": "I have a CSV of monthly sales data in data/sales_2025.csv. Can you find the top 3 months by revenue and make a bar chart?",
      "expected_output": "A bar chart image showing the top 3 months by revenue, with labeled axes and values.",
      "files": ["evals/files/sales_2025.csv"],
      "assertions": [
        "The output includes a bar chart image file",
        "The chart shows exactly 3 months",
        "Both axes are labeled",
        "The chart title or caption mentions revenue"
      ]
    }
  ]
}
```


[​](#grading-outputs)

Grading outputs

Grading means evaluating each assertion against the actual outputs and recording **PASS** or **FAIL** with specific evidence. The evidence should quote or reference the output, not just state an opinion. The simplest approach is to give the outputs and assertions to an LLM and ask it to evaluate each one. For assertions that can be checked by code (valid JSON, correct row count, file exists with expected dimensions), use a verification script — scripts are more reliable than LLM judgment for mechanical checks and reusable across iterations.

grading.json

```python
{
  "assertion_results": [
    {
      "text": "The output includes a bar chart image file",
      "passed": true,
      "evidence": "Found chart.png (45KB) in outputs directory"
    },
    {
      "text": "The chart shows exactly 3 months",
      "passed": true,
      "evidence": "Chart displays bars for March, July, and November"
    },
    {
      "text": "Both axes are labeled",
      "passed": false,
      "evidence": "Y-axis is labeled 'Revenue ($)' but X-axis has no label"
    },
    {
      "text": "The chart title or caption mentions revenue",
      "passed": true,
      "evidence": "Chart title reads 'Top 3 Months by Revenue'"
    }
  ],
  "summary": {
    "passed": 3,
    "failed": 1,
    "total": 4,
    "pass_rate": 0.75
  }
}
```


[​](#grading-principles)

Grading principles

- **Require concrete evidence for a PASS.** Don’t give the benefit of the doubt. If an assertion says “includes a summary” and the output has a section titled “Summary” with one vague sentence, that’s a FAIL — the label is there but the substance isn’t.
- **Review the assertions themselves, not just the results.** While grading, notice when assertions are too easy (always pass regardless of skill quality), too hard (always fail even when the output is good), or unverifiable (can’t be checked from the output alone). Fix these for the next iteration.

For comparing two skill versions, try **blind comparison**: present both outputs to an LLM judge without revealing which came from which version. The judge scores holistic qualities — organization, formatting, usability, polish — on its own rubric, free from bias about which version “should” be better. This complements assertion grading: two outputs might both pass all assertions but differ significantly in overall quality.


[​](#aggregating-results)

Aggregating results

Once every run in the iteration is graded, compute summary statistics per configuration and save them to `benchmark.json` alongside the eval directories (e.g., `csv-analyzer-workspace/iteration-1/benchmark.json`):

benchmark.json

```python
{
  "run_summary": {
    "with_skill": {
      "pass_rate": { "mean": 0.83, "stddev": 0.06 },
      "time_seconds": { "mean": 45.0, "stddev": 12.0 },
      "tokens": { "mean": 3800, "stddev": 400 }
    },
    "without_skill": {
      "pass_rate": { "mean": 0.33, "stddev": 0.10 },
      "time_seconds": { "mean": 32.0, "stddev": 8.0 },
      "tokens": { "mean": 2100, "stddev": 300 }
    },
    "delta": {
      "pass_rate": 0.50,
      "time_seconds": 13.0,
      "tokens": 1700
    }
  }
}
```

The `delta` tells you what the skill costs (more time, more tokens) and what it buys (higher pass rate). A skill that adds 13 seconds but improves pass rate by 50 percentage points is probably worth it. A skill that doubles token usage for a 2-point improvement might not be.

Standard deviation (`stddev`) is only meaningful with multiple runs per eval. In early iterations with just 2-3 test cases and single runs, focus on the raw pass counts and the delta — the statistical measures become useful as you expand the test set and run each eval multiple times.


[​](#analyzing-patterns)

Analyzing patterns

Aggregate statistics can hide important patterns. After computing the benchmarks:

- **Remove or replace assertions that always pass in both configurations.** These don’t tell you anything useful — the model handles them fine without the skill. They inflate the with-skill pass rate without reflecting actual skill value.
- **Investigate assertions that always fail in both configurations.** Either the assertion is broken (asking for something the model can’t do), the test case is too hard, or the assertion is checking for the wrong thing. Fix these before the next iteration.
- **Study assertions that pass with the skill but fail without.** This is where the skill is clearly adding value. Understand *why* — which instructions or scripts made the difference?
- **Tighten instructions when results are inconsistent across runs.** If the same eval passes sometimes and fails others (reflected as high `stddev` in the benchmark), the eval may be flaky (sensitive to model randomness), or the skill’s instructions may be ambiguous enough that the model interprets them differently each time. Add examples or more specific guidance to reduce ambiguity.
- **Check time and token outliers.** If one eval takes 3x longer than the others, read its execution transcript (the full log of what the model did during the run) to find the bottleneck.


[​](#reviewing-results-with-a-human)

Reviewing results with a human

Assertion grading and pattern analysis catch a lot, but they only check what you thought to write assertions for. A human reviewer brings a fresh perspective — catching issues you didn’t anticipate, noticing when the output is technically correct but misses the point, or spotting problems that are hard to express as pass/fail checks. For each test case, review the actual outputs alongside the grades. Record specific feedback for each test case and save it in the workspace (e.g., as a `feedback.json` alongside the eval directories):

feedback.json

```python
{
  "eval-top-months-chart": "The chart is missing axis labels and the months are in alphabetical order instead of chronological.",
  "eval-clean-missing-emails": ""
}
```

“The chart is missing axis labels” is actionable; “looks bad” is not. Empty feedback means the output looked fine — that test case passed your review. During the [iteration step](#iterating-on-the-skill), focus your improvements on the test cases where you had specific complaints.


[​](#iterating-on-the-skill)

Iterating on the skill

After grading and reviewing, you have three sources of signal:

- **Failed assertions** point to specific gaps — a missing step, an unclear instruction, or a case the skill doesn’t handle.
- **Human feedback** points to broader quality issues — the approach was wrong, the output was poorly structured, or the skill produced a technically correct but unhelpful result.
- **Execution transcripts** reveal *why* things went wrong. If the agent ignored an instruction, the instruction may be ambiguous. If the agent spent time on unproductive steps, those instructions may need to be simplified or removed.

The most effective way to turn these signals into skill improvements is to give all three — along with the current `SKILL.md` — to an LLM and ask it to propose changes. The LLM can synthesize patterns across failed assertions, reviewer complaints, and transcript behavior that would be tedious to connect manually. When prompting the LLM, include these guidelines:

- **Generalize from feedback.** The skill will be used across many different prompts, not just the test cases. Fixes should address underlying issues broadly rather than adding narrow patches for specific examples.
- **Keep the skill lean.** Fewer, better instructions often outperform exhaustive rules. If transcripts show wasted work (unnecessary validation, unneeded intermediate outputs), remove those instructions. If pass rates plateau despite adding more rules, the skill may be over-constrained — try removing instructions and see if results hold or improve.
- **Explain the why.** Reasoning-based instructions (“Do X because Y tends to cause Z”) work better than rigid directives (“ALWAYS do X, NEVER do Y”). Models follow instructions more reliably when they understand the purpose.
- **Bundle repeated work.** If every test run independently wrote a similar helper script (a chart builder, a data parser), that’s a signal to bundle the script into the skill’s `scripts/` directory. See [Using scripts](skill-creation-using-scripts.md) for how to do this.


[​](#the-loop)

The loop

1.  Give the eval signals and current `SKILL.md` to an LLM and ask it to propose improvements.
2.  Review and apply the changes.
3.  Rerun all test cases in a new `iteration-<N+1>/` directory.
4.  Grade and aggregate the new results.
5.  Review with a human. Repeat.

Stop when you’re satisfied with the results, feedback is consistently empty, or you’re no longer seeing meaningful improvement between iterations.

The [`skill-creator`](https://github.com/anthropics/skills/tree/main/skills/skill-creator) Skill automates much of this workflow — running evals, grading assertions, aggregating benchmarks, and presenting results for human review.

[Optimizing descriptions](skill-creation-optimizing-descriptions.md)[Using scripts](skill-creation-using-scripts.md)

---

## Optimizing skill descriptions - Agent Skills

Source: https://agentskills.io/skill-creation/optimizing-descriptions
Path: 08-Plugins-Skills/skill-creation-optimizing-descriptions.md

## On this page

- [How skill triggering works](#how-skill-triggering-works)
- [Writing effective descriptions](#writing-effective-descriptions)
- [Designing trigger eval queries](#designing-trigger-eval-queries)
  - [Should-trigger queries](#should-trigger-queries)
  - [Should-not-trigger queries](#should-not-trigger-queries)
  - [Tips for realism](#tips-for-realism)
- [Testing whether a description triggers](#testing-whether-a-description-triggers)
  - [Running multiple times](#running-multiple-times)
- [Avoiding overfitting with train/validation splits](#avoiding-overfitting-with-train%2Fvalidation-splits)
- [The optimization loop](#the-optimization-loop)
- [Applying the result](#applying-the-result)
- [Next steps](#next-steps)

For skill creators

# Optimizing skill descriptions

Copy pageCopy page

How to improve your skill’s description so it triggers reliably on relevant prompts.

Copy pageCopy page

A skill only helps if it gets activated. The `description` field in your `SKILL.md` frontmatter is the primary mechanism agents use to decide whether to load a skill for a given task. An under-specified description means the skill won’t trigger when it should; an over-broad description means it triggers when it shouldn’t. This guide covers how to systematically test and improve your skill’s description for triggering accuracy.


[​](#how-skill-triggering-works)

How skill triggering works

Agents use [progressive disclosure](specification.md#progressive-disclosure) to manage context. At startup, they load only the `name` and `description` of each available skill — just enough to decide when a skill might be relevant. When a user’s task matches a description, the agent reads the full `SKILL.md` into context and follows its instructions. This means the description carries the entire burden of triggering. If the description doesn’t convey when the skill is useful, the agent won’t know to reach for it. One important nuance: agents typically only consult skills for tasks that require knowledge or capabilities beyond what they can handle alone. A simple, one-step request like “read this PDF” may not trigger a PDF skill even if the description matches perfectly, because the agent can handle it with basic tools. Tasks that involve specialized knowledge — an unfamiliar API, a domain-specific workflow, or an uncommon format — are where a well-written description can make the difference.


[​](#writing-effective-descriptions)

Writing effective descriptions

Before testing, it helps to know what a good description looks like. A few principles:

- **Use imperative phrasing.** Frame the description as an instruction to the agent: “Use this skill when…” rather than “This skill does…” The agent is deciding whether to act, so tell it when to act.
- **Focus on user intent, not implementation.** Describe what the user is trying to achieve, not the skill’s internal mechanics. The agent matches against what the user asked for.
- **Err on the side of being pushy.** Explicitly list contexts where the skill applies, including cases where the user doesn’t name the domain directly: “even if they don’t explicitly mention ‘CSV’ or ‘analysis.’”
- **Keep it concise.** A few sentences to a short paragraph is usually right — long enough to cover the skill’s scope, short enough that it doesn’t bloat the agent’s context across many skills. The [specification](specification.md#description-field) enforces a hard limit of 1024 characters.


[​](#designing-trigger-eval-queries)

Designing trigger eval queries

To test triggering, you need a set of eval queries — realistic user prompts labeled with whether they should or shouldn’t trigger your skill.

eval_queries.json

```python
[
  { "query": "I've got a spreadsheet in ~/data/q4_results.xlsx with revenue in col C and expenses in col D — can you add a profit margin column and highlight anything under 10%?", "should_trigger": true },
  { "query": "whats the quickest way to convert this json file to yaml", "should_trigger": false }
]
```

Aim for about 20 queries: 8-10 that should trigger and 8-10 that shouldn’t.


[​](#should-trigger-queries)

Should-trigger queries

These test whether the description captures the skill’s scope. Vary them along several axes:

- **Phrasing**: some formal, some casual, some with typos or abbreviations.
- **Explicitness**: some name the skill’s domain directly (“analyze this CSV”), others describe the need without naming it (“my boss wants a chart from this data file”).
- **Detail**: mix terse prompts with context-heavy ones — a short “analyze my sales CSV and make a chart” alongside a longer message with file paths, column names, and backstory.
- **Complexity**: vary the number of steps and decision points. Include single-step tasks alongside multi-step workflows to test whether the agent can discern the skill is relevant when the task it addresses is buried in a larger chain.

The most useful should-trigger queries are ones where the skill would help but the connection isn’t obvious from the query alone. These are the cases where description wording makes the difference — if the query already asks for exactly what the skill does, any reasonable description would trigger.


[​](#should-not-trigger-queries)

Should-not-trigger queries

The most valuable negative test cases are **near-misses** — queries that share keywords or concepts with your skill but actually need something different. These test whether the description is precise, not just broad. For a CSV analysis skill, weak negative examples would be:

- `"Write a fibonacci function"` — obviously irrelevant, tests nothing.
- `"What's the weather today?"` — no keyword overlap, too easy.

Strong negative examples:

- `"I need to update the formulas in my Excel budget spreadsheet"` — shares “spreadsheet” and “data” concepts, but needs Excel editing, not CSV analysis.
- `"can you write a python script that reads a csv and uploads each row to our postgres database"` — involves CSV, but the task is database ETL, not analysis.


[​](#tips-for-realism)

Tips for realism

Real user prompts contain context that generic test queries lack. Include:

- File paths (`~/Downloads/report_final_v2.xlsx`)
- Personal context (`"my manager asked me to..."`)
- Specific details (column names, company names, data values)
- Casual language, abbreviations, and occasional typos


[​](#testing-whether-a-description-triggers)

Testing whether a description triggers

The basic approach: run each query through your agent with the skill installed and observe whether the agent invokes it. Make sure the skill is registered and discoverable by your agent — how this works varies by client (e.g., a skills directory, a configuration file, or a CLI flag). Most agent clients provide some form of observability — execution logs, tool call histories, or verbose output — that lets you see which skills were consulted during a run. Check your client’s documentation for details. The skill triggered if the agent loaded your skill’s `SKILL.md`; it didn’t trigger if the agent proceeded without consulting it. A query “passes” if:

- `should_trigger` is `true` and the skill was invoked, or
- `should_trigger` is `false` and the skill was not invoked.


[​](#running-multiple-times)

Running multiple times

Model behavior is nondeterministic — the same query might trigger the skill on one run but not the next. Run each query multiple times (3 is a reasonable starting point) and compute a **trigger rate**: the fraction of runs where the skill was invoked. A should-trigger query passes if its trigger rate is above a threshold (0.5 is a reasonable default). A should-not-trigger query passes if its trigger rate is below that threshold. With 20 queries at 3 runs each, that’s 60 invocations. You’ll want to script this. Here’s the general structure — replace the `claude` invocation and detection logic in `check_triggered` with whatever your agent client provides:

```python
#!/bin/bash
QUERIES_FILE="${1:?Usage: $0 <queries.json>}"
SKILL_NAME="my-skill"
RUNS=3

# This example uses Claude Code's JSON output to check for Skill tool calls.
# Replace this function with detection logic for your agent client.
# Should return 0 (success) if the skill was invoked, 1 otherwise.
check_triggered() {
  local query="$1"
  claude -p "$query" --output-format json 2>/dev/null \
    | jq -e --arg skill "$SKILL_NAME" \
      'any(.messages[].content[]; .type == "tool_use" and .name == "Skill" and .input.skill == $skill)' \
      > /dev/null 2>&1
}

count=$(jq length "$QUERIES_FILE")
for i in $(seq 0 $((count - 1))); do
  query=$(jq -r ".[$i].query" "$QUERIES_FILE")
  should_trigger=$(jq -r ".[$i].should_trigger" "$QUERIES_FILE")
  triggers=0

  for run in $(seq 1 $RUNS); do
    check_triggered "$query" && triggers=$((triggers + 1))
  done

  jq -n \
    --arg query "$query" \
    --argjson should_trigger "$should_trigger" \
    --argjson triggers "$triggers" \
    --argjson runs "$RUNS" \
    '{query: $query, should_trigger: $should_trigger, triggers: $triggers, runs: $runs, trigger_rate: ($triggers / $runs)}'
done | jq -s '.'
```

If your agent client supports it, you can stop a run early once the outcome is clear — the agent either consulted the skill or started working without it. This can significantly reduce the time and cost of running the full eval set.


[​](#avoiding-overfitting-with-train/validation-splits)

Avoiding overfitting with train/validation splits

If you optimize the description against all your queries, you risk overfitting — crafting a description that works for these specific phrasings but fails on new ones. The solution is to split your query set:

- **Train set (~60%)**: the queries you use to identify failures and guide improvements.
- **Validation set (~40%)**: queries you set aside and only use to check whether improvements generalize.

Make sure both sets contain a proportional mix of should-trigger and should-not-trigger queries — don’t accidentally put all the positives in one set. Shuffle randomly and keep the split fixed across iterations so you’re comparing apples to apples. If you’re using a script like the one [above](#running-multiple-times), you can split your queries into two files — `train_queries.json` and `validation_queries.json` — and run the script against each one separately.


[​](#the-optimization-loop)

The optimization loop

1.  **Evaluate** the current description on both *train and validation sets*. The train results guide your changes; the validation results tell you whether those changes are generalizing.
2.  **Identify failures** in the *train set*: which should-trigger queries didn’t trigger? Which should-not-trigger queries did?
    - Only use train set failures to guide your changes — whether you’re revising the description yourself or prompting an LLM, keep validation set results out of the process.
3.  **Revise the description.** Focus on generalizing:
    - If should-trigger queries are failing, the description may be too narrow. Broaden the scope or add context about when the skill is useful.
    - If should-not-trigger queries are false-triggering, the description may be too broad. Add specificity about what the skill does *not* do, or clarify the boundary between this skill and adjacent capabilities.
    - Avoid adding specific keywords from failed queries — that’s overfitting. Instead, find the general category or concept those queries represent and address that.
    - If you’re stuck after several iterations, try a structurally different approach to the description rather than incremental tweaks. A different framing or sentence structure may break through where refinement can’t.
    - Check that the description stays under the 1024-character limit — descriptions tend to grow during optimization.
4.  **Repeat** steps 1-3 until all *train set* queries pass or you stop seeing meaningful improvement.
5.  **Select the best iteration** by its validation pass rate — the fraction of queries in the *validation set* that passed. Note that the best description may not be the last one you produced; an earlier iteration might have a higher validation pass rate than later ones that overfit to the train set.

Five iterations is usually enough. If performance isn’t improving, the issue may be with the queries (too easy, too hard, or poorly labeled) rather than the description.

The [`skill-creator`](https://github.com/anthropics/skills/tree/main/skills/skill-creator) Skill automates this loop end-to-end: it splits the eval set, evaluates trigger rates in parallel, proposes description improvements using Claude, and generates a live HTML report you can watch as it runs.


[​](#applying-the-result)

Applying the result

Once you’ve selected the best description:

1.  Update the `description` field in your `SKILL.md` frontmatter.
2.  Verify the description is under the [1024-character limit](specification.md#description-field).
3.  Verify the description triggers as expected. Try a few prompts manually as a quick sanity check. For a more rigorous test, write 5-10 fresh queries (a mix of should-trigger and should-not-trigger) and run them through the eval script — since these queries were never part of the optimization process, they give you an honest check on whether the description generalizes.

Before and after:

```python
# Before
description: Process CSV files.

# After
description: >
  Analyze CSV and tabular data files — compute summary statistics,
  add derived columns, generate charts, and clean messy data. Use this
  skill when the user has a CSV, TSV, or Excel file and wants to
  explore, transform, or visualize the data, even if they don't
  explicitly mention "CSV" or "analysis."
```

The improved description is more specific about what the skill does (summary stats, derived columns, charts, cleaning) and broader about when it applies (CSV, TSV, Excel; even without explicit keywords).


[​](#next-steps)

Next steps

Once your skill triggers reliably, you’ll want to evaluate whether it produces good outputs. See [Evaluating skill output quality](skill-creation-evaluating-skills.md) for how to set up test cases, grade results, and iterate.

[Best practices](skill-creation-best-practices.md)[Evaluating skills](skill-creation-evaluating-skills.md)

---

## Quickstart - Agent Skills

Source: https://agentskills.io/skill-creation/quickstart
Path: 08-Plugins-Skills/skill-creation-quickstart.md

## On this page

- [Prerequisites](#prerequisites)
- [Create the skill](#create-the-skill)
- [Try it out](#try-it-out)
- [How it works](#how-it-works)
- [Next steps](#next-steps)

For skill creators

# Quickstart

Copy pageCopy page

Create your first Agent Skill and see it work in VS Code.

Copy pageCopy page

In this tutorial, you’ll create a skill that gives an agent the capability to roll dice using a random number generator.


[​](#prerequisites)

Prerequisites

- [VS Code](https://code.visualstudio.com/) with [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot)

This tutorial uses VS Code, but Agent Skills are an open format. The same skill works in any compatible agent, including Claude Code and OpenAI Codex.


[​](#create-the-skill)

Create the skill

A skill is a folder containing a `SKILL.md` file. VS Code looks for skills in `.agents/skills/` by default. Create `.agents/skills/roll-dice/SKILL.md` in your project:

.agents/skills/roll-dice/SKILL.md

```` shiki
---
name: roll-dice
description: Roll dice using a random number generator. Use when asked to roll a die (d6, d20, etc.), roll dice, or generate a random dice roll.
---

To roll a die, use the following command that generates a random number from 1
to the given number of sides:

```bash
echo $((RANDOM % <sides> + 1))
```

```powershell
Get-Random -Minimum 1 -Maximum (<sides> + 1)
```

Replace `<sides>` with the number of sides on the die (e.g., 6 for a standard
die, 20 for a d20).
````

That’s it — one file, under 20 lines. Here’s what each part does:

- **`name`** — A short identifier for the skill. Must match the folder name.
- **`description`** — Tells the agent when to use this skill. This is how the agent decides whether to activate it.
- **The body** — Instructions the agent follows when the skill activates. Here, the agent is instructed to generate a random number using a terminal command, substituting the number of sides from the user’s request.


[​](#try-it-out)

Try it out

1.  Open your project in VS Code.
2.  Open the Copilot Chat panel.
3.  Select **Agent** mode from the mode dropdown at the bottom of the chat panel.
4.  Type `/skills` to confirm that `roll-dice` appears in the list. If it doesn’t, check that the file is at `.agents/skills/roll-dice/SKILL.md` relative to your project root.
5.  Ask: **“Roll a d20”**

The agent should activate the `roll-dice` skill. It may ask for permission to run a terminal command — allow it. It will run the command and return a random number between 1 and 20.

Tool-use reliability varies across models — some follow skill instructions and run commands consistently, while others may attempt to answer on their own. If the agent responds without running a terminal command, try selecting a different model from the model dropdown.


[​](#how-it-works)

How it works

Here’s what happened behind the scenes:

1.  **Discovery** — When the chat session started, the agent scanned default skill directories and found your skill. It read only the `name` and `description`, just enough to know when the skill might be relevant.
2.  **Activation** — When you asked about rolling dice, the agent matched your question to the skill’s description and loaded the full `SKILL.md` body into context.
3.  **Execution** — The agent followed the instructions in the body, adapting the terminal command to the number of sides in your request.

This process uses **progressive disclosure** to let the agent access many skills without loading all their instructions up front.


[​](#next-steps)

Next steps

You’ve created a working Agent Skill. From here:

- **[Best practices](skill-creation-best-practices.md)** — How to write skills that are well-scoped and effective.
- **[Optimizing skill descriptions](skill-creation-optimizing-descriptions.md)** — Test and improve your skill’s description so it activates on the right prompts.
- **[Specification](specification.md)** — The complete format reference for `SKILL.md` files.
- **[Example skills](https://github.com/anthropics/skills)** — Browse real-world skills on GitHub.

[Client Showcase](clients.md)[Best practices](skill-creation-best-practices.md)

---

## Using scripts in skills - Agent Skills

Source: https://agentskills.io/skill-creation/using-scripts
Path: 08-Plugins-Skills/skill-creation-using-scripts.md

## On this page

- [One-off commands](#one-off-commands)
- [Referencing scripts from SKILL.md](#referencing-scripts-from-skill-md)
- [Self-contained scripts](#self-contained-scripts)
- [Designing scripts for agentic use](#designing-scripts-for-agentic-use)
  - [Avoid interactive prompts](#avoid-interactive-prompts)
  - [Document usage with --help](#document-usage-with-help)
  - [Write helpful error messages](#write-helpful-error-messages)
  - [Use structured output](#use-structured-output)
  - [Further considerations](#further-considerations)

For skill creators

# Using scripts in skills

Copy pageCopy page

How to run commands and bundle executable scripts in your skills.

Copy pageCopy page

Skills can instruct agents to run shell commands and bundle reusable scripts in a `scripts/` directory. This guide covers one-off commands, self-contained scripts with their own dependencies, and how to design script interfaces for agentic use.


[​](#one-off-commands)

One-off commands

When an existing package already does what you need, you can reference it directly in your `SKILL.md` instructions without a `scripts/` directory. Many ecosystems provide tools that auto-resolve dependencies at runtime.

- uvx

- pipx

- npx

- bunx

- deno run

- go run

[uvx](https://docs.astral.sh/uv/guides/tools/) runs Python packages in isolated environments with aggressive caching. It ships with [uv](https://docs.astral.sh/uv/).

```python
uvx ruff@0.8.0 check .
uvx black@24.10.0 .
```

- Not bundled with Python — requires a separate install.
- Fast. Caches aggressively so repeat runs are near-instant.

[pipx](https://pipx.pypa.io/) runs Python packages in isolated environments. Available via OS package managers (`apt install pipx`, `brew install pipx`).

```python
pipx run 'black==24.10.0' .
pipx run 'ruff==0.8.0' check .
```

- Not bundled with Python — requires a separate install.
- A mature alternative to `uvx`. While `uvx` has become the standard recommendation, `pipx` remains a reliable option with broader OS package manager availability.

[npx](https://docs.npmjs.com/cli/commands/npx) runs npm packages, downloading them on demand. It ships with npm (which ships with Node.js).

```python
npx eslint@9 --fix .
npx create-vite@6 my-app
```

- Bundled with Node.js — no extra install needed.
- Downloads the package, runs it, and caches it for future use.
- Pin versions with `npx package@version` for reproducibility.

[bunx](https://bun.sh/docs/cli/bunx) is Bun’s equivalent of `npx`. It ships with [Bun](https://bun.sh/).

```python
bunx eslint@9 --fix .
bunx create-vite@6 my-app
```

- Drop-in replacement for `npx` in Bun-based environments.
- Only appropriate when the user’s environment has Bun rather than Node.js.

[deno run](https://docs.deno.com/runtime/reference/cli/run/) runs scripts directly from URLs or specifiers. It ships with [Deno](https://deno.com/).

```python
deno run npm:create-vite@6 my-app
deno run --allow-read npm:eslint@9 -- --fix .
```

- Permission flags (`--allow-read`, etc.) are required for filesystem/network access.
- Use `--` to separate Deno flags from the tool’s own flags.

[go run](https://pkg.go.dev/cmd/go#hdr-Compile_and_run_Go_program) compiles and runs Go packages directly. It is built into the `go` command.

```python
go run golang.org/x/tools/cmd/goimports@v0.28.0 .
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run
```

- Built into Go — no extra tooling needed.
- Pin versions or use `@latest` to make the command explicit.

**Tips for one-off commands in skills:**

- **Pin versions** (e.g., `npx eslint@9.0.0`) so the command behaves the same over time.
- **State prerequisites** in your `SKILL.md` (e.g., “Requires Node.js 18+”) rather than assuming the agent’s environment has them. For runtime-level requirements, use the [`compatibility` frontmatter field](specification.md#compatibility-field).
- **Move complex commands into scripts.** A one-off command works well when you’re invoking a tool with a few flags. When a command grows complex enough that it’s hard to get right on the first try, a tested script in `scripts/` is more reliable.


[​](#referencing-scripts-from-skill-md)

Referencing scripts from `SKILL.md`

Use **relative paths from the skill directory root** to reference bundled files. The agent resolves these paths automatically — no absolute paths needed. List available scripts in your `SKILL.md` so the agent knows they exist:

SKILL.md

```python
## Available scripts

- **`scripts/validate.sh`** — Validates configuration files
- **`scripts/process.py`** — Processes input data
```

Then instruct the agent to run them:

SKILL.md

```` shiki
## Workflow

1. Run the validation script:
   ```bash
   bash scripts/validate.sh "$INPUT_FILE"
   ```

2. Process the results:
   ```bash
   python3 scripts/process.py --input results.json
   ```
````

The same relative-path convention works in support files like `references/*.md` — script execution paths (in code blocks) are relative to the **skill directory root**, because the agent runs commands from there.


[​](#self-contained-scripts)

Self-contained scripts

When you need reusable logic, bundle a script in `scripts/` that declares its own dependencies inline. The agent can run the script with a single command — no separate manifest file or install step required. Several languages support inline dependency declarations:

- Python

- Deno

- Bun

- Ruby

[PEP 723](https://peps.python.org/pep-0723/) defines a standard format for inline script metadata. Declare dependencies in a TOML block inside `# ///` markers:

scripts/extract.py

```python
# /// script
# dependencies = [
#   "beautifulsoup4",
# ]
# ///

from bs4 import BeautifulSoup

html = '<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>'
print(BeautifulSoup(html, "html.parser").select_one("p.info").get_text())
```

Run with [uv](https://docs.astral.sh/uv/) (recommended):

```python
uv run scripts/extract.py
```

`uv run` creates an isolated environment, installs the declared dependencies, and runs the script. [pipx](https://pipx.pypa.io/) (`pipx run scripts/extract.py`) also supports PEP 723.

- Pin versions with [PEP 508](https://peps.python.org/pep-0508/) specifiers: `"beautifulsoup4>=4.12,<5"`.
- Use `requires-python` to constrain the Python version.
- Use `uv lock --script` to create a lockfile for full reproducibility.

Deno’s `npm:` and `jsr:` import specifiers make every script self-contained by default:

scripts/extract.ts

```python
#!/usr/bin/env -S deno run

import * as cheerio from "npm:cheerio@1.0.0";

const html = `<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
```

```python
deno run scripts/extract.ts
```

- Use `npm:` for npm packages, `jsr:` for Deno-native packages.
- Version specifiers follow semver: `@1.0.0` (exact), `@^1.0.0` (compatible).
- Dependencies are cached globally. Use `--reload` to force re-fetch.
- Packages with native addons (node-gyp) may not work — packages that ship pre-built binaries work best.

Bun auto-installs missing packages at runtime when no `node_modules` directory is found. Pin versions directly in the import path:

scripts/extract.ts

```python
#!/usr/bin/env bun

import * as cheerio from "cheerio@1.0.0";

const html = `<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>`;
const $ = cheerio.load(html);
console.log($("p.info").text());
```

```python
bun run scripts/extract.ts
```

- No `package.json` or `node_modules` needed. TypeScript works natively.
- Packages are cached globally. First run downloads; subsequent runs are near-instant.
- If a `node_modules` directory exists anywhere up the directory tree, auto-install is disabled and Bun falls back to standard Node.js resolution.

Bundler ships with Ruby since 2.6. Use `bundler/inline` to declare gems directly in the script:

scripts/extract.rb

```python
require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'nokogiri'
end

html = '<html><body><h1>Welcome</h1><p class="info">This is a test.</p></body></html>'
doc = Nokogiri::HTML(html)
puts doc.at_css('p.info').text
```

```python
ruby scripts/extract.rb
```

- Pin versions explicitly (`gem 'nokogiri', '~> 1.16'`) — there is no lockfile.
- An existing `Gemfile` or `BUNDLE_GEMFILE` env var in the working directory can interfere.


[​](#designing-scripts-for-agentic-use)

Designing scripts for agentic use

When an agent runs your script, it reads stdout and stderr to decide what to do next. A few design choices make scripts dramatically easier for agents to use.


[​](#avoid-interactive-prompts)

Avoid interactive prompts

This is a hard requirement of the agent execution environment. Agents operate in non-interactive shells — they cannot respond to TTY prompts, password dialogs, or confirmation menus. A script that blocks on interactive input will hang indefinitely. Accept all input via command-line flags, environment variables, or stdin:

```python
# Bad: hangs waiting for input
$ python scripts/deploy.py
Target environment: _

# Good: clear error with guidance
$ python scripts/deploy.py
Error: --env is required. Options: development, staging, production.
Usage: python scripts/deploy.py --env staging --tag v1.2.3
```


[​](#document-usage-with-help)

Document usage with `--help`

`--help` output is the primary way an agent learns your script’s interface. Include a brief description, available flags, and usage examples:

```python
Usage: scripts/process.py [OPTIONS] INPUT_FILE

Process input data and produce a summary report.

Options:
  --format FORMAT    Output format: json, csv, table (default: json)
  --output FILE      Write output to FILE instead of stdout
  --verbose          Print progress to stderr

Examples:
  scripts/process.py data.csv
  scripts/process.py --format csv --output report.csv data.csv
```

Keep it concise — the output enters the agent’s context window alongside everything else it’s working with.


[​](#write-helpful-error-messages)

Write helpful error messages

When an agent gets an error, the message directly shapes its next attempt. An opaque “Error: invalid input” wastes a turn. Instead, say what went wrong, what was expected, and what to try:

```python
Error: --format must be one of: json, csv, table.
       Received: "xml"
```


[​](#use-structured-output)

Use structured output

Prefer structured formats — JSON, CSV, TSV — over free-form text. Structured formats can be consumed by both the agent and standard tools (`jq`, `cut`, `awk`), making your script composable in pipelines.

```python
# Whitespace-aligned — hard to parse programmatically
NAME          STATUS    CREATED
my-service    running   2025-01-15

# Delimited — unambiguous field boundaries
{"name": "my-service", "status": "running", "created": "2025-01-15"}
```

**Separate data from diagnostics:** send structured data to stdout and progress messages, warnings, and other diagnostics to stderr. This lets the agent capture clean, parseable output while still having access to diagnostic information when needed.


[​](#further-considerations)

Further considerations

- **Idempotency.** Agents may retry commands. “Create if not exists” is safer than “create and fail on duplicate.”
- **Input constraints.** Reject ambiguous input with a clear error rather than guessing. Use enums and closed sets where possible.
- **Dry-run support.** For destructive or stateful operations, a `--dry-run` flag lets the agent preview what will happen.
- **Meaningful exit codes.** Use distinct exit codes for different failure types (not found, invalid arguments, auth failure) and document them in your `--help` output so the agent knows what each code means.
- **Safe defaults.** Consider whether destructive operations should require explicit confirmation flags (`--confirm`, `--force`) or other safeguards appropriate to the risk level.
- **Predictable output size.** Many agent harnesses automatically truncate tool output beyond a threshold (e.g., 10-30K characters), potentially losing critical information. If your script might produce large output, default to a summary or a reasonable limit, and support flags like `--offset` so the agent can request more information when needed. Alternatively, if output is large and not amenable to pagination, require agents to pass an `--output` flag that specifies either an output file or `-` to explicitly opt in to stdout.

[Evaluating skills](skill-creation-evaluating-skills.md)[Adding skills support](client-implementation-adding-skills-support.md)

---

## Extend Claude with skills - Claude Code Docs

Source: https://code.claude.com/docs/en/skills
Path: 08-Plugins-Skills/skills.md

## On this page

- [Bundled skills](#bundled-skills)
  - [Run and verify your app](#run-and-verify-your-app)
  - [Work on Claude API projects](#work-on-claude-api-projects)
- [Getting started](#getting-started)
  - [Create your first skill](#create-your-first-skill)
- [Choose where skills load](#where-skills-live)
  - [Load skills in monorepos and subdirectories](#discovery-from-parent-and-nested-directories)
  - [Load skills from a directory outside the project](#skills-from-additional-directories)
  - [Resolve skills that share a name](#resolve-skills-that-share-a-name)
  - [Use skills in Cowork and cloud sessions](#skills-in-cowork-and-cloud-sessions)
  - [Skills synced from claude.ai](#how-synced-skills-behave)
  - [Where synced skills load](#where-synced-skills-load)
  - [When a synced skill name matches another command](#when-a-synced-skill-name-matches-another-command)
  - [Names reserved for synced skills](#names-reserved-for-synced-skills)
  - [How Claude Code handles the frontmatter of a synced skill](#how-claude-code-handles-the-frontmatter-of-a-synced-skill)
  - [How Claude Code handles the body of a synced skill](#how-claude-code-handles-the-body-of-a-synced-skill)
  - [Edit a skill during a session](#live-change-detection)
  - [Remove a skill](#remove-a-skill)
- [Configure skills](#configure-skills)
  - [Types of skill content](#types-of-skill-content)
  - [Frontmatter reference](#frontmatter-reference)
  - [Using skill frontmatter outside Claude Code](#using-skill-frontmatter-outside-claude-code)
  - [How a skill gets its command name](#how-a-skill-gets-its-command-name)
  - [Available string substitutions](#available-string-substitutions)
  - [Add supporting files](#add-supporting-files)
  - [Control who invokes a skill](#control-who-invokes-a-skill)
  - [Skill content lifecycle](#skill-content-lifecycle)
  - [Pre-approve tools for a skill](#pre-approve-tools-for-a-skill)
  - [Pass arguments to skills](#pass-arguments-to-skills)
- [Advanced patterns](#advanced-patterns)
  - [Inject dynamic context](#inject-dynamic-context)
  - [How injected commands run](#how-injected-commands-run)
  - [When an injected command fails](#when-an-injected-command-fails)
  - [Permission checks on injected commands](#permission-checks-on-injected-commands)
  - [Run skills in a subagent](#run-skills-in-a-subagent)
  - [Example: Research skill using Explore agent](#example-research-skill-using-explore-agent)
  - [Restrict Claude’s skill access](#restrict-claude%E2%80%99s-skill-access)
  - [Override skill visibility from settings](#override-skill-visibility-from-settings)
  - [Find unused skills](#find-unused-skills)
- [Evaluate and iterate on a skill](#evaluate-and-iterate-on-a-skill)
  - [Run evals with skill-creator](#run-evals-with-skill-creator)
- [Share skills](#share-skills)
  - [Generate visual output](#generate-visual-output)
- [Troubleshooting](#troubleshooting)
  - [Skill not triggering](#skill-not-triggering)
  - [Skill triggers too often](#skill-triggers-too-often)
  - [Skill descriptions are cut short](#skill-descriptions-are-cut-short)
  - [Personal skills disappeared](#personal-skills-disappeared)
- [Related resources](#related-resources)

Skills

# Extend Claude with skills

Copy pageCopy page

Create, manage, and share skills to extend Claude’s capabilities in Claude Code. Includes custom commands and bundled skills.

Copy pageCopy page

Skills extend what Claude can do. Create a `SKILL.md` file with instructions, and Claude adds it to its toolkit. Claude uses skills when relevant, or you can invoke one directly with `/skill-name`. Create a skill when you keep pasting the same instructions, checklist, or multi-step procedure into chat, or when a section of CLAUDE.md has grown into a procedure rather than a fact. Unlike CLAUDE.md content, a skill’s body loads only when it’s used, so long reference material costs almost nothing until you need it.

For built-in commands like `/help` and `/compact`, and bundled skills like `/debug` and `/code-review`, see the [commands reference](../02-Claude-Code-CLI/commands.md).**Custom commands have been merged into skills.** A file at `.claude/commands/deploy.md` and a skill at `.claude/skills/deploy/SKILL.md` both create `/deploy` and work the same way. Your existing `.claude/commands/` files keep working. Skills add optional features: a directory for supporting files, frontmatter to [control whether you or Claude invokes them](#control-who-invokes-a-skill), and the ability for Claude to load them automatically when relevant.

Claude Code skills follow the [Agent Skills](https://agentskills.io) open standard, which works across multiple AI tools. Claude Code extends the standard with additional features like [invocation control](#control-who-invokes-a-skill), [subagent execution](#run-skills-in-a-subagent), and [dynamic context injection](#inject-dynamic-context). See [Using skill frontmatter outside Claude Code](#using-skill-frontmatter-outside-claude-code) for which frontmatter fields are part of the standard and which are Claude Code extensions.


[​](#bundled-skills)

Bundled skills

Claude Code includes a set of bundled skills, such as `/doctor`, `/code-review`, `/batch`, `/debug`, `/loop`, and `/claude-api`. Bundled skills are prompt-based: they give Claude detailed instructions and let it orchestrate the work using its tools. Most built-in commands instead execute fixed logic directly. You invoke a bundled skill the same way as any other skill, by typing `/` followed by the skill name. Claude invokes some bundled skills automatically when relevant; others, including `/verify`, run only when you invoke them, which keeps you in control of when these longer-running checks spend time and tokens. Most bundled skills are available in every session. A few depend on a specific feature: `/workflow-authoring`, for example, is available only when [dynamic workflows](../02-Claude-Code-CLI/workflows.md) are enabled. To turn bundled skills off, use the [`disableBundledSkills`](../02-Claude-Code-CLI/settings-reference.md#disablebundledskills) setting.

The [`/doctor`](../02-Claude-Code-CLI/commands.md#all-commands) setup checkup stays typable when `disableBundledSkills` is on, in Claude Code v2.1.205 and later. To hide it, set the `DISABLE_DOCTOR_COMMAND` environment variable or a [`skillOverrides`](#override-skill-visibility-from-settings) entry of `"doctor": "off"`. Before v2.1.205, `/doctor` was a built-in command rather than a bundled skill.

Bundled skills are listed alongside built-in commands in the [commands reference](../02-Claude-Code-CLI/commands.md), marked **Skill** in the Purpose column.


[​](#run-and-verify-your-app)

Run and verify your app

Three bundled skills work together to launch your app and confirm changes against the running app instead of just tests:

| Skill                  | Purpose                                                                                                           |
|:-----------------------|:------------------------------------------------------------------------------------------------------------------|
| `/run`                 | Launch and drive your app to see a change working                                                                 |
| `/verify`              | Build and run your app to confirm a code change does what it should, without falling back to tests or type checks |
| `/run-skill-generator` | Teach `/run` and `/verify` how to build and launch your project                                                   |

`/run` and `/verify` work without setup. They infer the launch from your project type (CLI, server, TUI, browser-driven) and from what’s in your README, `package.json`, or `Makefile`. That inference gets unreliable for projects that need anything beyond a standard launch: a database, an env file, a graphical session, a multi-step build. `/run-skill-generator` records the recipe instead. It gets your app running from a clean environment, captures what worked (the install commands, the env vars, the launch script), and commits it as a per-project skill at `.claude/skills/run-<name>/`. After that, `/run`, `/verify`, and any other agent in the repo follow the recorded recipe instead of rediscovering it. Run `/run-skill-generator` once per project, and again if the build or launch process changes. `/verify` can also record its own recipe. When it has to build and drive your app without a recorded recipe, it writes what worked to `.claude/skills/verify/SKILL.md` at the repo root, or in the touched package directory in a monorepo, so later runs and other agents follow the same steps. At the repo root, the recorded skill replaces the bundled `/verify`. This requires Claude Code v2.1.200 or later. Claude edits the recorded file only when it steered a run wrong, such as a command that failed or a missing step, so you can commit the file without per-session diffs. Before v2.1.205, the bundled skill told Claude to fold in anything a run learned, which caused frequent merge conflicts.


[​](#work-on-claude-api-projects)

Work on Claude API projects

The bundled `/claude-api` skill loads [Claude API](../04-API-Reference/Endpoints/overview.md) and [Managed Agents](../04-API-Reference/Other/managed-agents-overview.md) reference material for your project’s language. Claude also activates it automatically when your code imports `anthropic` or `@anthropic-ai/sdk`. To start one of the skill’s workflows, type a subcommand after the skill name at the Claude Code prompt, for example `/claude-api migrate`. The table lists what each subcommand does and the earliest Claude Code version that includes it. `migrate` and `managed-agents-onboard` predate v2.1.221, the oldest version the table tracks.

| Subcommand                     | What it does                                                                                                                                                                                                                                                                                                                  | Minimum version       |
|:-------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------|
| `migrate`                      | Update your existing Claude API code to a newer model                                                                                                                                                                                                                                                                         | Earlier than v2.1.221 |
| `upgrade`                      | Move your project’s Anthropic SDK dependency across a major version, currently the Python `anthropic` package from 0.x to 1.x                                                                                                                                                                                                 | v2.1.236 or later     |
| `managed-agents-onboard`       | Walk through creating a new Managed Agent                                                                                                                                                                                                                                                                                     | Earlier than v2.1.221 |
| `prompt-audit`                 | Flag instructions written for older models in your prompts, skills, and tool descriptions and propose fixes as a diff                                                                                                                                                                                                         | v2.1.221 or later     |
| `cost-optimize`                | Profile where your project’s Claude API spend goes and propose savings from options such as prompt caching, trimming unneeded input and output tokens, batch processing, effort, and model choice, one change at a time                                                                                                       | v2.1.247 or later     |
| `build-eval`                   | Build an eval set for your Claude-powered app                                                                                                                                                                                                                                                                                 | v2.1.259 or later     |
| `hillclimb`                    | Iteratively improve your app against an existing eval                                                                                                                                                                                                                                                                         | v2.1.259 or later     |
| `preserved-thinking-migration` | Find the edits your integration makes to earlier turns, its system prompt, or its tool list that invalidate [preserved thinking](../04-API-Reference/Guides/build-with-claude-preserved-thinking.md) blocks, measure how much reasoning each one drops, and propose fixes one at a time, re-measuring after each change | v2.1.282 or later     |


[​](#getting-started)

Getting started


[​](#create-your-first-skill)

Create your first skill

This example creates a skill that summarizes the uncommitted changes in your git repository and flags anything risky. It pulls the live diff into the prompt before Claude reads it, so the response is grounded in your actual working tree rather than what Claude can guess from open files. Claude loads the skill automatically when you ask about your changes, or you can invoke it directly with `/summarize-changes`.

1

Create the skill directory

Create a directory for the skill in your personal skills folder. Personal skills are available across all your projects.

```python
mkdir -p ~/.claude/skills/summarize-changes
```

2

Write SKILL.md

Every skill needs a `SKILL.md` file with two parts: YAML frontmatter between `---` markers that tells Claude when to use the skill, and markdown content with the instructions Claude follows when the skill runs. The directory name, or the frontmatter `name` when you set one, becomes the command you type, and the `description` helps Claude decide when to load the skill automatically.Save this to `~/.claude/skills/summarize-changes/SKILL.md`:

```python
---
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
---

## Current changes

!`git diff HEAD`

## Instructions

Summarize the changes above in two or three bullet points, then list any risks you notice such as missing error handling, hardcoded values, or tests that need updating. If the diff is empty, say there are no uncommitted changes.
```

The `` !`git diff HEAD` `` line uses [dynamic context injection](#inject-dynamic-context): Claude Code runs the command and replaces the line with its output before Claude sees the skill content, so the instructions arrive with the current diff already inlined.

3

Test the skill

Open a git project, make a small edit to any file, and start Claude Code by running `claude`. You can test the skill two ways.**Let Claude invoke it automatically** by asking something that matches the description:

```python
What did I change?
```

**Or invoke it directly** with the skill name:

```python
/summarize-changes
```

Either way, Claude should respond with a short summary of your edit and a list of risks.


[​](#where-skills-live)

Choose where skills load

Where you save a skill decides which sessions load it. Save it under your home directory to get it in every project, commit it to a repository to share it with everyone who works there, or distribute it through a plugin or managed settings to reach a whole team.

| Location             | Path                                                                                                                      | Loads in                                                                                                                                                                                                |
|:---------------------|:--------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Enterprise           | `.claude/skills/<skill-name>/SKILL.md` in the [managed settings directory](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms) | All users on machines where your organization deploys it                                                                                                                                                |
| Personal             | `~/.claude/skills/<skill-name>/SKILL.md`                                                                                  | All your projects on this machine, but not [Cowork or cloud sessions](#skills-in-cowork-and-cloud-sessions)                                                                                             |
| Project              | `.claude/skills/<skill-name>/SKILL.md`                                                                                    | Sessions in this repository. Commit it so your team gets it too                                                                                                                                         |
| Nested               | `<subdir>/.claude/skills/<skill-name>/SKILL.md`                                                                           | Sessions started in or below `<subdir>`. A session started above it loads the skill once Claude works on files there. See [monorepos and subdirectories](#discovery-from-parent-and-nested-directories) |
| Additional directory | `.claude/skills/<skill-name>/SKILL.md` in a directory you pass with `--add-dir`                                           | That session. See [directories outside the project](#skills-from-additional-directories)                                                                                                                |
| Plugin               | `<plugin>/skills/<skill-name>/SKILL.md`                                                                                   | Wherever the [plugin](plugins.md) is enabled, as `/plugin-name:skill-name`                                                                                                               |
| claude.ai account    | Skills enabled for your claude.ai account                                                                                 | Cowork sessions, cloud sessions, and terminal sessions where you sign in with that account. See [Skills synced from claude.ai](#how-synced-skills-behave)                                               |

Skill folders also follow these rules:

- **Symlinked folders**: a `<skill-name>` entry in the enterprise, personal, or project location can be a symlink to a directory elsewhere on disk. Claude Code reads `SKILL.md` from the target and loads the skill once even if several locations point at the same target. Plugin skills [handle symlinks differently](plugins-host-marketplace.md#share-files-within-a-marketplace-with-symlinks).
- **Reserved name `synced`**: don’t name a skill folder `synced`, in any capitalization. Claude Code uses `~/.claude/skills/synced/` for [skills downloaded from claude.ai](#where-synced-skills-load) and skips a skill you author at that name in the enterprise, personal, and project locations.
- **Reserved name `anthropic-skills`**: outside a plugin, a skill folder or command file whose name is `anthropic-skills` or starts with `anthropic-skills:` doesn’t load. See [Names reserved for synced skills](#names-reserved-for-synced-skills).
- **Command files**: a Markdown file in `.claude/commands/` is the older format and still works. It supports the same [frontmatter](#frontmatter-reference) except `name` and `paths`. To find the name you type to invoke it, see [How a skill gets its command name](#how-a-skill-gets-its-command-name). Prefer a skill for new work, since skills also support [supporting files](#add-supporting-files).
- **Skill folder as a plugin**: add a `.claude-plugin/plugin.json` to a skill folder and it loads as a [plugin](plugins-loading.md#plugins-shared-through-a-repository) named `<name>@skills-dir`, so it can bundle agents, hooks, and MCP servers. In a project’s `.claude/skills/`, this requires accepting the workspace trust dialog first.


[​](#discovery-from-parent-and-nested-directories)

Load skills in monorepos and subdirectories

Claude Code loads project skills from `.claude/skills/` in the directory where you start it and in every parent directory up to the repository root, so starting in `packages/frontend/` still picks up skills defined at the root. When you [move the session with `/cd`](../02-Claude-Code-CLI/permissions.md#move-the-session-to-another-directory) on v2.1.246 or later, Claude Code adds the new directory’s project skills. In a session running in a linked [git worktree](../02-Claude-Code-CLI/worktrees.md), Claude Code searches parent directories only up to the worktree root. On Claude Code v2.1.277 or later, when the worktree checkout has no `.claude/skills` directory at its root, Claude Code loads the main checkout’s project skills instead. See [What worktrees share with the main checkout](../02-Claude-Code-CLI/worktrees.md#what-worktrees-share-with-the-main-checkout). Skills in a `.claude/skills/` directory below where you started don’t load at startup. They load the first time Claude reads or edits a file in that subdirectory and stay available for the rest of the session. Until then they don’t appear in the `/` menu and you can’t invoke them by name. To load them sooner, run `/add-dir` with the subdirectory’s path, which requires Claude Code v2.1.257 or later. When a nested skill’s directory name matches another skill’s name, both stay available. With a `deploy` skill at the repository root and another in `apps/web/.claude/skills/`:

- `/deploy` runs the root skill. Claude Code also lists the directory-qualified variants for Claude, with an instruction to invoke the one whose directory holds the files it’s working on, so the nested skill still applies to work in `apps/web/`.
- `/apps/web:deploy` runs the nested skill on its own. Its description names the directory it applies to.


[​](#skills-from-additional-directories)

Load skills from a directory outside the project

When you add a directory with `--add-dir` or `/add-dir`, Claude Code loads the skills in that directory’s `.claude/skills/`, along with its `.claude/commands/` and `.claude/agents/`. Directories the Agent SDK adds through [`additionalDirectories`](../05-Agent-SDK/agent-sdk-typescript.md#options) in TypeScript or [`add_dirs`](../05-Agent-SDK/agent-sdk-python.md#claudeagentoptions) in Python load the same way, because the SDK passes them as `--add-dir`. The `permissions.additionalDirectories` setting in `settings.json` grants file access only and loads none of these. Claude Code watches `.claude/skills/` in a directory you pass with `--add-dir` at launch, as [Edit a skill during a session](#live-change-detection) describes. It doesn’t watch the added directory’s `.claude/commands/` or `.claude/agents/`, so restart the session after changing a file there. These loads depend on the `project` [setting source](../05-Agent-SDK/agent-sdk-claude-code-features.md#control-filesystem-settings-with-settingsources), which is on by default. A [`strictPluginOnlyCustomization`](../02-Claude-Code-CLI/settings-reference.md#strictpluginonlycustomization) policy, [bare mode](../02-Claude-Code-CLI/headless.md#start-faster-with-bare-mode), and [`--safe-mode`](../02-Claude-Code-CLI/cli-reference.md#cli-flags) each restrict them further, as those pages describe. See [Additional directories grant file access, not configuration](../02-Claude-Code-CLI/permissions.md#additional-directories-grant-file-access-not-configuration) for the full table of what an added directory loads, including `CLAUDE.md` and plugin settings.


[​](#resolve-skills-that-share-a-name)

Resolve skills that share a name

When two skills share a directory or file name, where each one came from decides which one `/name` runs. For a name set by the frontmatter `name` field, see [How a skill gets its command name](#how-a-skill-gets-its-command-name). The table covers the enterprise, personal, project, nested, plugin, and claude.ai locations, bundled skills, and command files:

| Same name in                                                                                                   | Which one runs                                                                                                                                                                                           |
|:---------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Two of enterprise, personal, and project                                                                       | Enterprise over personal, and personal over project. With `deploy` in both `~/.claude/skills/` and the project’s `.claude/skills/`, `/deploy` runs the personal one                                      |
| Any of those locations and a [bundled skill](#bundled-skills)                                                  | Your skill replaces the bundled command, but not its aliases. A project `code-review` skill replaces `/code-review`, and the bundled alias `/review` never runs your skill                               |
| A skill and a file in `.claude/commands/`                                                                      | The skill                                                                                                                                                                                                |
| A project-root skill and a nested skill                                                                        | Both load. See [monorepos and subdirectories](#discovery-from-parent-and-nested-directories)                                                                                                             |
| A plugin skill and a skill at any of the locations above                                                       | Both load, because plugin skills are namespaced as `/plugin-name:skill-name`                                                                                                                             |
| Any of the above and the short name of a skill [synced from your claude.ai account](#how-synced-skills-behave) | The other skill or command. The synced skill is then listed and runs only under its full name. See [When a synced skill name matches another command](#when-a-synced-skill-name-matches-another-command) |


[​](#skills-in-cowork-and-cloud-sessions)

Use skills in Cowork and cloud sessions

[Cowork](../15-Claude-AI-Features/product-cowork.md) sessions and [cloud sessions](../02-Claude-Code-CLI/cloud-environments.md#what-carries-over-from-your-setup), including [routines](../02-Claude-Code-CLI/web-scheduled-tasks.md), don’t read `~/.claude/skills/` on your machine. Both interactive and scheduled Cowork sessions load the skills enabled for your claude.ai account, synced at session start; manage them from **Customize** in the Desktop app sidebar or from the skills settings on claude.ai. Cloud sessions additionally load project skills committed to the cloned repository’s `.claude/skills/`. If a skill exists only in `~/.claude/skills/` on your machine, Claude Code reports that the skill was not found when a [routine](../02-Claude-Code-CLI/web-scheduled-tasks.md) invokes it, because each routine run starts as a fresh cloud session. To make a personal skill available in these sessions:

- For Cowork and cloud sessions, enable the skill for your claude.ai account.
- For cloud sessions, you can instead commit the skill to the repository’s `.claude/skills/`. Plugins declared in the repository’s `.claude/settings.json` and plugins enabled only in your user settings [don’t load in cloud sessions](../02-Claude-Code-CLI/cloud-environments.md#what-carries-over-from-your-setup).

[Desktop scheduled tasks](../16-Mobile-Desktop/desktop-scheduled-tasks.md) run locally on your machine, so they do load `~/.claude/skills/`.


[​](#how-synced-skills-behave)

Skills synced from claude.ai

This section applies to you if you use Cowork or cloud sessions, or sign in to Claude Code in your terminal with a claude.ai account. In those sessions, Claude Code loads the skills enabled for your claude.ai account, with no setup on your part, as [Where synced skills load](#where-synced-skills-load) describes. Those skills include the ones you create or turn on in your claude.ai settings, skills your organization provides there, and Anthropic’s built-in skills such as `pdf` and `xlsx`. Claude Code downloads a synced skill from your account rather than reading a file you wrote on the machine where the session runs, so it applies rules to synced skills that don’t apply to the skills you store in the [skills locations](#where-skills-live).


[​](#where-synced-skills-load)

Where synced skills load

In a Cowork or cloud session, Claude Code loads the skills enabled for your claude.ai account, and [Skills in Cowork and cloud sessions](#skills-in-cowork-and-cloud-sessions) says how to choose which skills those sessions get. In your terminal, Claude Code syncs those skills in sessions where you sign in with your claude.ai account. When the session starts, Claude Code downloads your account’s skills into `~/.claude/skills/synced/` in the background, then checks claude.ai for changes about every 10 minutes while the session runs. When a check finds that a skill was added, edited, or turned off on claude.ai, Claude Code adds, updates, or removes it in the running session without a restart. Syncing in terminal sessions requires Claude Code v2.1.273 or later. The sync never delays startup, because Claude waits for a skill’s download only when it invokes that skill. A short [non-interactive](../02-Claude-Code-CLI/headless.md) run can therefore finish before a newly added skill downloads, in which case a later session downloads it. To make a non-interactive run download your skills and wait for the list before it answers the prompt, set [`CLAUDE_CODE_SYNC_SKILLS`](../02-Claude-Code-CLI/env-vars.md#variables) to `1`. Claude Code syncs only in a session that signs in with your claude.ai account and [fetches feature flags from Anthropic](../02-Claude-Code-CLI/env-vars.md#features-that-need-feature-flag-fetching). It doesn’t sync in these sessions:

- A session that doesn’t use a sign-in stored by `/login`, such as one that authenticates with an API key, or one where `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, or an `apiKeyHelper` script supplies the credential
- A session that doesn’t fetch feature flags, such as one on Amazon Bedrock or one where you set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`
- A session in [bare mode](../02-Claude-Code-CLI/headless.md#start-faster-with-bare-mode) or one you start with `--safe-mode`
- A session where your organization’s managed settings [lock skills to plugin sources](../02-Claude-Code-CLI/settings-reference.md#strictpluginonlycustomization-skills), or one you start with a [`--setting-sources`](../02-Claude-Code-CLI/cli-reference.md#cli-flags) list that leaves out `user`

If you sign in with `/login` during a session, restart Claude Code to start syncing. Skills that an earlier session synced stay on disk. Claude Code loads them in later sessions signed in to the same account, even when it can’t reach claude.ai. Claude Code downloads synced skills and never uploads them. If you or Claude edit a file under `~/.claude/skills/synced/`, the change isn’t saved to your claude.ai account, and a later sync can overwrite or remove it. To change a synced skill, update it on claude.ai; the next sync downloads the new version. To see which skills synced, run `/skills`. The menu lists them under `claude.ai sync`. Some of Anthropic’s skills, such as `pdf` and `xlsx`, always sync. For the rest, turn a skill on or off in your skills settings on claude.ai to change whether it syncs. To stop syncing on a machine, set [`syncClaudeAiSkills`](../02-Claude-Code-CLI/settings-reference.md#syncclaudeaiskills) to `false` in your user settings. Claude Code stops downloading, and the next time it starts it moves the skills it already synced to `~/.claude/skills/.trash/` and no longer loads them. Your organization can turn syncing off for everyone by turning off Skills on claude.ai. To stop syncing while leaving Skills on, it can set the same key in [managed settings](../13-Enterprise-Admin/managed-settings.md). If your organization turns Skills off on claude.ai, Claude Code removes the downloaded skills and they stop loading. The removed skills move to `~/.claude/skills/.trash/`, where you can recover the files until the [retention sweep](../02-Claude-Code-CLI/claude-directory.md#cleaned-up-automatically) deletes them. Once your organization turns Skills back on, Claude Code downloads the skills you enabled at the next sync.


[​](#when-a-synced-skill-name-matches-another-command)

When a synced skill name matches another command

You can invoke a synced skill by its short name, `/<name>`, or by its full name, `/anthropic-skills:<name>`. When another command uses the short name, `/<name>` runs the other command, and the synced skill runs only as `/anthropic-skills:<name>`. With a local `deploy` skill and a synced `deploy`, `/deploy` runs the local skill and `/anthropic-skills:deploy` runs the synced one. Before v2.1.269, a synced skill had only its short name. In the `/` menu, `/skills`, and `/context`, a synced skill appears under its short name, or under its full name while another command uses the short name. Run `/skills` in your session. A note under the list explains each synced skill that lost its short name. If one of your personal skills or command files in `~/.claude/` uses the name, the note also says what to rename or delete to free it. From v2.1.269 through v2.1.280, these lists showed every synced skill under its full name, and `/skills` had no such note; both changed in v2.1.281. The command that uses the short name can be any of these:

- A built-in command or a [bundled skill](#bundled-skills), including one that’s unavailable in your session, for example after you turn bundled skills off
- A skill at any [local level](#where-skills-live) or a file in `.claude/commands/`
- A plugin skill
- An [MCP prompt](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands)

Claude Code labels synced skills so you can tell where they came from. The `/skills` menu and `/context` group synced skills under `claude.ai sync`, and the `/` command menu marks them as coming from claude.ai. When it compares names, Claude Code ignores case, spacing, and invisible characters, and treats compatibility forms such as fullwidth letters and dash variants as their plain equivalents. For example, a synced skill named `Commit` and a local skill named `commit` count as the same name, so `/commit` keeps running your local skill. A name that differs only by a look-alike letter from another alphabet counts as a different name, and the `claude.ai sync` label is how you tell the two apart. These checks and labels require Claude Code v2.1.228 or later.


[​](#names-reserved-for-synced-skills)

Names reserved for synced skills

Claude Code reserves the name `anthropic-skills`, and every name inside that namespace such as `anthropic-skills:pdf`, for skills synced from claude.ai, so a synced skill’s full name never runs anything else. The name is reserved in every session, whether or not you sign in with a claude.ai account.

- **A skill folder, a frontmatter `name`, a file or subfolder in `.claude/commands/`, or a [saved workflow](../02-Claude-Code-CLI/workflows.md#save-the-workflow-for-reuse)**: it doesn’t load. A [startup notice](../02-Claude-Code-CLI/errors.md#a-skill-command-or-workflow-wasnt-loaded-because-its-name-is-reserved) names the first item to rename or edit.
- **A plugin named `anthropic-skills`**: it loads. When one of its skills and a synced skill are both named `<name>`, `/anthropic-skills:<name>` runs the synced skill.
- **An MCP server named `anthropic-skills`**: it connects and its tools work, but [its prompts don’t appear as commands](../06-MCP-Tools/General/mcp.md#use-mcp-prompts-as-commands). Rename the server in your MCP configuration to list them.


[​](#how-claude-code-handles-the-frontmatter-of-a-synced-skill)

How Claude Code handles the frontmatter of a synced skill

Claude Code applies two rules to a synced skill’s frontmatter:

- Claude Code honors the frontmatter in every kind of session, so an `allowed-tools` grant goes through the normal [permission flow](../02-Claude-Code-CLI/permissions.md).
- Claude Code sanitizes the display text the skill supplies, such as its description. It removes control characters, and in text that reaches Claude, such as the description, it also escapes angle brackets so the text can’t imitate Claude Code’s internal formatting. This sanitization requires Claude Code v2.1.228 or later.


[​](#how-claude-code-handles-the-body-of-a-synced-skill)

How Claude Code handles the body of a synced skill

What Claude Code does with a synced skill’s body depends on where the session runs:

- In a cloud session, the body keeps the behavior a local skill has, because the session runs in an isolated container.
- In a Cowork session on your desktop, the body keeps the behavior a local skill has, except that Claude Code replaces every `!` command line with the [`disableSkillShellExecution` placeholder](#inject-dynamic-context), as it does for every skill you supply there.
- In any other session on your machine, Claude Code doesn’t run [`!` commands](#inject-dynamic-context), doesn’t attach the files that `@` references name the way it does for a local skill, and doesn’t substitute the `${CLAUDE_PROJECT_DIR}` and `${CLAUDE_SESSION_ID}` placeholders, so the `@` references and both placeholders reach Claude as literal text. A `!` command line reaches Claude as literal text too, or as that placeholder when `disableSkillShellExecution` is on. This handling requires Claude Code v2.1.228 or later.


[​](#live-change-detection)

Edit a skill during a session

Claude Code watches skill directories for file changes, except in [bare mode](../02-Claude-Code-CLI/headless.md#start-faster-with-bare-mode). When you add, edit, or remove a skill under `~/.claude/skills/`, the project `.claude/skills/`, or a `.claude/skills/` inside an `--add-dir` directory, Claude Code picks up the change within the current session, without a restart. If you create a top-level skills directory that didn’t exist when the session started, run [`/reload-skills`](../02-Claude-Code-CLI/commands.md#all-commands) to pick up the skills you put there. Claude Code isn’t watching that directory yet, so run `/reload-skills` again after each later change there. Live change detection covers `SKILL.md` text only. For a skill folder that is also a [plugin](plugins-loading.md#plugins-shared-through-a-repository), changes to `hooks/`, `.mcp.json`, `agents/`, and `output-styles/` need `/reload-plugins` to take effect.


[​](#remove-a-skill)

Remove a skill

How you remove a skill depends on where it came from:

- **Personal or project skill**: delete the skill’s directory, `~/.claude/skills/<skill-name>/` or `.claude/skills/<skill-name>/`. Claude Code [drops it from `/skills` in the current session](#live-change-detection); content Claude Code already loaded from it follows the [skill content lifecycle](#skill-content-lifecycle).
- **Enterprise skill**: an administrator deletes the skill’s directory from `.claude/skills/` inside the [managed settings directory](../13-Enterprise-Admin/managed-settings.md#delivery-mechanisms), for example `/etc/claude-code/.claude/skills/<skill-name>/` on Linux.
- **Plugin skill**: disable or uninstall the plugin that provides it, from the `/plugin` menu or with `/plugin uninstall <plugin-name>@<marketplace-name>`. Claude Code unloads the plugin’s skills when [the change applies](plugins-cli-reference.md#reload-plugins) or when you restart.
- **Skill synced from claude.ai**: turn the skill off for your claude.ai account, in the same place you [enabled it](#skills-in-cowork-and-cloud-sessions). Claude Code removes it from `~/.claude/skills/synced/` the next time it [syncs your skills](#where-synced-skills-load). If you delete the directory by hand instead, the next sync downloads it again while the skill stays enabled on claude.ai.
- **Bundled skill**: set [`disableBundledSkills`](#bundled-skills) to `true` to turn off bundled skills, or set one skill to `"off"` in [`skillOverrides`](#override-skill-visibility-from-settings) to hide it.

To keep a personal or project skill but stop Claude from invoking it on its own, set [`disable-model-invocation: true`](#control-who-invokes-a-skill) in its frontmatter, or `"user-invocable-only"` in [`skillOverrides`](#override-skill-visibility-from-settings) when you don’t want to edit the file.


[​](#configure-skills)

Configure skills

Skills are configured through YAML frontmatter at the top of `SKILL.md` and the markdown content that follows.


[​](#types-of-skill-content)

Types of skill content

Skill files can contain any instructions, but thinking about how you want to invoke them helps guide what to include: **Reference content** adds knowledge Claude applies to your current work. Conventions, patterns, style guides, domain knowledge. This content runs inline so Claude can use it alongside your conversation context.

```python
---
name: api-conventions
description: API design patterns for this codebase
---

When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats
- Include request validation
```

**Task content** gives Claude step-by-step instructions for a specific action, like deployments, commits, or code generation. These are often actions you want to invoke directly with `/skill-name` rather than letting Claude decide when to run them. Add `disable-model-invocation: true` to prevent Claude from triggering it automatically. The example below adds `context: fork`, which runs the skill in its own subagent context; see [Run skills in a subagent](#run-skills-in-a-subagent).

```python
---
name: deploy
description: Deploy the application to production
context: fork
disable-model-invocation: true
---

Deploy the application:
1. Run the test suite
2. Build the application
3. Push to the deployment target
```

Keep the body itself concise. Once a skill loads, its content [stays in context across turns](#skill-content-lifecycle), so every line is a recurring token cost. State what to do rather than narrating how or why, and apply the same conciseness test you would for [CLAUDE.md content](../02-Claude-Code-CLI/best-practices.md#write-an-effective-claude-md).


[​](#frontmatter-reference)

Frontmatter reference

Configure a skill with YAML [frontmatter](../02-Claude-Code-CLI/glossary.md#frontmatter) between `---` markers at the top of `SKILL.md`, and write the skill’s instructions as Markdown after the closing `---`. Field names use lowercase words separated by hyphens, except `when_to_use`. A [command file](#where-skills-live) in `.claude/commands/` accepts the same fields except `name` and `paths`. This example sets four fields:

```python
---
name: my-skill
description: What this skill does
disable-model-invocation: true
allowed-tools: Read Grep
---

Your skill instructions here...
```

All fields are optional. Only `description` is recommended so Claude knows when to use the skill. A field name must match the table exactly, hyphens included: Claude Code ignores a field it doesn’t recognize without reporting an error. Claude Code reads the frontmatter only when the opening `---` is the file’s first line. Otherwise it treats the whole file, `---` markers included, as skill content. If the YAML between the markers doesn’t parse, the skill still loads with no fields set; see [Skill not triggering](#skill-not-triggering) to find and fix the error. Boolean fields accept `yes`, `no`, `on`, `off`, `1`, and `0` in any letter case, in addition to `true` and `false`. Before v2.1.218, Claude Code recognized only `true` and `false`.

| Field                      | Required    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|:---------------------------|:------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`                     | No          | Command name shown in the `/` menu. Defaults to the directory name. See [How a skill gets its command name](#how-a-skill-gets-its-command-name) for how the field interacts with the name you type to invoke the skill.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `description`              | Recommended | What the skill does and when to use it. Claude uses this to decide when to apply the skill. If omitted, uses the first non-empty line of the markdown content. Put the key use case first: the combined `description` and `when_to_use` text is truncated at 1,536 characters in the skill listing to reduce context usage.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `when_to_use`              | No          | Additional context for when Claude should invoke the skill, such as trigger phrases or example requests. Appended to `description` in the skill listing and counts toward the 1,536-character cap.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `argument-hint`            | No          | Hint shown during autocomplete to indicate expected arguments. Example: `[issue-number]` or `[filename] [format]`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `arguments`                | No          | Named positional arguments for [`$name` substitution](#available-string-substitutions) in the skill content. Accepts a space-separated string or a YAML list. Names map to argument positions in order.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `disable-model-invocation` | No          | Set to `true` to prevent Claude from automatically loading this skill. Use for workflows you want to trigger manually with `/name`. Also prevents the skill from being [preloaded into subagents](../09-Agents-Patterns/sub-agents.md#preload-skills-into-subagents). As of v2.1.196, also prevents the skill from running when a [scheduled task](../02-Claude-Code-CLI/scheduled-tasks.md) fires with the skill as its prompt. Default: `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `user-invocable`           | No          | Set to `false` when only Claude should invoke the skill: Claude Code hides it from the `/` menu and doesn’t run it when you type `/name`. Use for background knowledge users shouldn’t invoke directly. Default: `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `allowed-tools`            | No          | Tools Claude can use without asking permission during the turn that invokes this skill. The grant clears when you send your next message. Accepts a space- or comma-separated string, or a YAML list. See [Pre-approve tools for a skill](#pre-approve-tools-for-a-skill).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `disallowed-tools`         | No          | Tools removed from Claude’s available pool while this skill is active. Use for autonomous skills that should never call certain tools, such as `AskUserQuestion` for a background loop. Accepts a space- or comma-separated string, or a YAML list. The restriction clears when you send your next message. Like deny rules, the field can’t remove [`EndConversation`](../02-Claude-Code-CLI/tools-reference.md#endconversation-tool-behavior) while any other tool remains.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `model`                    | No          | Model to use when this skill is active. The override applies for the rest of the current turn and isn’t saved to settings. The session model resumes when you send your next prompt. Accepts the same values as [`/model`](../02-Claude-Code-CLI/model-config.md), or `inherit` to keep the active model. A value excluded by your organization’s [`availableModels`](../02-Claude-Code-CLI/model-config.md#restrict-model-selection) allowlist isn’t used, and the session keeps its current model. In [auto mode](../02-Claude-Code-CLI/permission-modes.md#eliminate-prompts-with-auto-mode), and in [plan mode while the classifier reviews commands](../02-Claude-Code-CLI/permission-modes.md#analyze-before-you-edit-with-plan-mode), a model that auto mode doesn’t support also isn’t used, and the session keeps its current model. With `context: fork`, the value sets the [forked subagent’s model](#run-skills-in-a-subagent) instead, and an excluded value follows the [same rules as a subagent model override](../02-Claude-Code-CLI/model-config.md#restrict-model-selection). |
| `effort`                   | No          | [Effort level](../02-Claude-Code-CLI/model-config.md#adjust-effort-level) when this skill is active. Overrides the session effort level. Default: inherits from session. Options: `low`, `medium`, `high`, `xhigh`, `max`; available levels depend on the model.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `context`                  | No          | Set to `fork` to run in a forked subagent context. See [Run skills in a subagent](#run-skills-in-a-subagent).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `agent`                    | No          | Which subagent type to use when `context: fork` is set.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `background`               | No          | Only applies with `context: fork`. Set to `false` to wait for the forked subagent’s result in the turn that invoked the skill, instead of [running it in the background](#run-skills-in-a-subagent). Default: `true`. Requires Claude Code v2.1.218 or later.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `hooks`                    | No          | Hooks that Claude Code registers when the skill is invoked and keeps running for the rest of the session. See [Hooks in skills and agents](../07-Hooks/hooks.md#hooks-in-skills-and-agents) for the configuration format and the `once` option.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `paths`                    | No          | Glob patterns that limit when this skill is activated. Accepts a comma-separated string or a YAML list. When set, Claude loads the skill automatically only when working with files matching the patterns. Uses the same format as [path-specific rules](../02-Claude-Code-CLI/memory.md#path-specific-rules).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `shell`                    | No          | Shell to use for `` !`command` `` and ```` ```! ```` blocks in this skill. Accepts `bash` (default) or `powershell`. Setting `powershell` runs inline shell commands via PowerShell when the [PowerShell tool](../02-Claude-Code-CLI/tools-reference.md#powershell-tool) is enabled: it’s on by default on Windows without Git Bash, on by default with Git Bash for claude.ai and Console accounts, and needs `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` in Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry sessions and on macOS, Linux, and WSL. Set it to `0` to turn the tool off.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `metadata`                 | No          | Free-form YAML map for your own key-value data, such as entitlement or catalog fields, read by your own tooling from `SKILL.md`. Claude Code doesn’t act on its contents, and drops a value that isn’t a map. Don’t reuse frontmatter field names such as `paths` as keys.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `license`                  | No          | License covering the skill. Part of the [Agent Skills](https://agentskills.io) spec; see [Using skill frontmatter outside Claude Code](#using-skill-frontmatter-outside-claude-code). Claude Code accepts the field but doesn’t act on it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `compatibility`            | No          | Environment requirements for the skill, such as intended products or system prerequisites, as defined by the [Agent Skills](https://agentskills.io) spec; see [Using skill frontmatter outside Claude Code](#using-skill-frontmatter-outside-claude-code). Accepts a string of up to 500 characters. Claude Code accepts the field but doesn’t act on it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |


[​](#using-skill-frontmatter-outside-claude-code)

Using skill frontmatter outside Claude Code

Claude Code accepts every field in the table above. Outside Claude Code, you can use only the fields in the [Agent Skills](https://agentskills.io) spec:

| Distribution path                                                                                                                             | Frontmatter fields you can use                                                 |
|:----------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------|
| Claude Code skills at [any level](#where-skills-live), including [plugin](plugins.md) skills                                   | Every field in the table above                                                 |
| claude.ai skill uploads, the Skills API, and packaging with `package_skill.py` from [anthropics/skills](https://github.com/anthropics/skills) | `name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools` |

When you enable a personal skill for your claude.ai account, for example to use it in [Cowork and cloud sessions](#skills-in-cowork-and-cloud-sessions) and routines, you upload it to claude.ai, so the same rules apply. If you include any field the spec doesn’t allow, packaging or upload fails with a hard error instead of ignoring the field:

```python
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name
```

Restricting frontmatter to the spec’s six fields avoids the unexpected-key error above. The [Agent Skills spec](https://agentskills.io) and the [Skills API requirements](https://docs.claude.com/en/api/skills-guide) define everything else those paths validate. Claude Code-only body features, such as [dynamic context injection](#inject-dynamic-context), don’t function in claude.ai chat or through the API. Claude Code accepts all six fields, so frontmatter that follows the spec loads in Claude Code without changes.


[​](#how-a-skill-gets-its-command-name)

How a skill gets its command name

The command you type to invoke a skill comes from where the skill file lives and, for skill directories and plugin skills, from the frontmatter `name` field. In a personal or project skill directory, `name` sets the command that the `/` menu shows and that you type, unless another command already uses that name. The directory name also invokes the skill. In a plugin skill, `name` sets the last segment of the command and the plugin prefix stays in place. The table below shows where the command name comes from for each layout:

| Skill location                                                                                               | Command name source                                                                                           | Example                                                                                                                                     |
|:-------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------|
| Skill directory under `~/.claude/skills/` or `.claude/skills/`                                               | Frontmatter `name` or the directory name                                                                      | `.claude/skills/deploy-staging/SKILL.md` → `/deploy-staging`, or `/deploy` with `name: deploy`                                              |
| [Nested](#where-skills-live) `.claude/skills/` directory, when the directory name clashes with another skill | Subdirectory path relative to the working directory, then the skill directory name                            | `apps/web/.claude/skills/deploy/SKILL.md` → `/apps/web:deploy`                                                                              |
| File under `.claude/commands/`                                                                               | File name without extension                                                                                   | `.claude/commands/deploy.md` → `/deploy`                                                                                                    |
| File in a subdirectory of `.claude/commands/`                                                                | Subdirectory path relative to `commands/` with each `/` replaced by `:`, then the file name without extension | `.claude/commands/frontend/component.md` → `/frontend:component`                                                                            |
| Plugin `skills/` subdirectory                                                                                | Frontmatter `name` or the directory name, namespaced by plugin                                                | `my-plugin/skills/review/SKILL.md` → `/my-plugin:review`, or `/my-plugin:fancy` with `name: fancy`                                          |
| Plugin root `SKILL.md`                                                                                       | Frontmatter `name`, with the plugin directory name as a fallback                                              | `my-plugin/SKILL.md` with `name: review` → `/my-plugin:review`. See [a single skill at the plugin root](plugins-components.md#skills) |
| Skill [synced from claude.ai](#how-synced-skills-behave)                                                     | The skill’s name on your claude.ai account, prefixed with `anthropic-skills:`                                 | Account skill `deploy` → `/anthropic-skills:deploy`, or `/deploy` while no other command uses that name                                     |

In a plugin skill, the frontmatter `name` replaces the directory name in the last segment of the command, so `my-plugin/skills/review/SKILL.md` with `name: fancy` becomes `/my-plugin:fancy`. The bare `/fancy` also invokes the skill unless another command already uses that name. If the `name` you write already starts with the plugin’s own prefix, Claude Code doesn’t add the prefix again on v2.1.246 or later. For example, `name: my-plugin:fancy` still becomes `/my-plugin:fancy`. From v2.1.216 through v2.1.245, Claude Code doubled the prefix when the `name` already carried it. In [non-interactive sessions](../02-Claude-Code-CLI/headless.md), the names `help` and `feedback` aren’t reserved for their terminal-only built-in commands, so a plugin skill with one of those names keeps its bare command there. Every other terminal-only built-in’s name, such as `/login`, stays reserved even though the command can’t run in those sessions. For a plugin-root `SKILL.md`, there is no skill directory to take the name from, so `name` supplies the whole final segment. Without a `name` field, Claude Code falls back to the plugin’s directory name.


[​](#available-string-substitutions)

Available string substitutions

Skills support string substitution for dynamic values in the skill content:

| Variable                | Description                                                                                                                                                                                                                                                                                                      |
|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `$ARGUMENTS`            | All arguments passed when invoking the skill. When no placeholder receives an argument, Claude Code appends them as `ARGUMENTS: <value>`. See [Pass arguments to skills](#pass-arguments-to-skills).                                                                                                             |
| `$ARGUMENTS[N]`         | Access a specific argument by 0-based index, such as `$ARGUMENTS[0]` for the first argument.                                                                                                                                                                                                                     |
| `$N`                    | Shorthand for `$ARGUMENTS[N]`, such as `$0` for the first argument or `$1` for the second.                                                                                                                                                                                                                       |
| `$name`                 | Named argument declared in the [`arguments`](#frontmatter-reference) frontmatter list. Names map to positions in order, so with `arguments: [issue, branch]` the placeholder `$issue` expands to the first argument and `$branch` to the second.                                                                 |
| `${CLAUDE_SESSION_ID}`  | The current session ID. Useful for logging, creating session-specific files, or correlating skill output with sessions.                                                                                                                                                                                          |
| `${CLAUDE_EFFORT}`      | The current effort level: `low`, `medium`, `high`, `xhigh`, or `max`. Use this to adapt skill instructions to the active effort setting.                                                                                                                                                                         |
| `${CLAUDE_SKILL_DIR}`   | The directory containing the skill’s `SKILL.md` file. For plugin skills, this is the skill’s subdirectory within the plugin, not the plugin root. Use this in bash injection commands to reference scripts or files bundled with the skill, regardless of the current working directory.                         |
| `${CLAUDE_PROJECT_DIR}` | The project root directory. This is the same path [hooks](../07-Hooks/hooks.md#reference-scripts-by-path) and MCP servers receive as `CLAUDE_PROJECT_DIR`. Use this to reference project-local scripts or files, such as `${CLAUDE_PROJECT_DIR}/.claude/hooks/helper.sh`, independent of where the skill is installed. |
| `${CLAUDE_PLUGIN_ROOT}` | The plugin’s installation directory. Substituted only in plugin skills. Use this to reference scripts or files bundled anywhere in the plugin, including resources shared between the plugin’s skills. See [plugin environment variables](plugins-reference.md#environment-variables).            |
| `${CLAUDE_PLUGIN_DATA}` | The plugin’s [persistent data directory](plugins-components.md#path-variables-and-persistent-data), which survives plugin updates. Substituted only in plugin skills. Use this to reference installed dependencies, generated files, or caches that must outlive an update.                                |

Claude Code substitutes `${CLAUDE_SKILL_DIR}` and `${CLAUDE_PROJECT_DIR}` in two places: the skill’s markdown content, and Bash rules in the [`allowed-tools`](#frontmatter-reference) frontmatter. In a plugin skill, Claude Code substitutes `${CLAUDE_PLUGIN_ROOT}` and `${CLAUDE_PLUGIN_DATA}` in the same two places. Using the same variable in both places lets a skill run a bundled script without a permission prompt. The following skill shows the pattern:

```python
---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---

Run `${CLAUDE_SKILL_DIR}/scripts/render.sh <csv-file>` to render the chart.
```

If this skill is installed at `~/.claude/skills/render-chart/`, both occurrences of `${CLAUDE_SKILL_DIR}` expand to that directory. The `allowed-tools` rule then matches the exact command the skill body tells Claude to run, so the script runs without prompting. The `${CLAUDE_PROJECT_DIR}` substitution requires Claude Code v2.1.196 or later. Indexed arguments use shell-style quoting, so wrap multi-word values in quotes to pass them as a single argument. For example, `/my-skill "hello world" second` makes `$0` expand to `hello world` and `$1` to `second`. The `$ARGUMENTS` placeholder always expands to the full argument string as typed. An indexed placeholder with no corresponding argument, such as `$2` when only one argument was passed, stays in the content unchanged. A named placeholder from the [`arguments`](#frontmatter-reference) frontmatter with no matching argument expands to an empty string. If you pass an argument value that itself contains text such as `$1` or `$ARGUMENTS`, Claude Code inserts it as literal text and doesn’t expand it. For example, if a skill’s body contains `Summarize $0` and you run `/summarize "$ARGUMENTS from yesterday"`, Claude receives `Summarize $ARGUMENTS from yesterday`. Claude Code still replaces `${CLAUDE_*}` variables such as `${CLAUDE_SKILL_DIR}` after it inserts the arguments. To include a literal `$` before a digit, `ARGUMENTS`, or a declared argument name, such as `$1.00` in prose, escape it with a backslash: `\$1.00`. A backslash before any other `$` is left unchanged. Only a single backslash directly before the token escapes it. A doubled backslash such as `\\$1` leaves both backslashes in place, and `$1` still expands to the argument value. The backslash escape covers only these argument placeholders. A backslash doesn’t prevent substitution of a `${CLAUDE_*}` variable where the variable applies. **Example using substitutions:**

```python
---
name: session-logger
description: Log activity for this session
---

Log the following to logs/${CLAUDE_SESSION_ID}.log:

$ARGUMENTS
```


[​](#add-supporting-files)

Add supporting files

Skills can include multiple files in their directory. This keeps `SKILL.md` focused on the essentials while letting Claude access detailed reference material only when needed. Large reference docs, API specifications, or example collections don’t need to load into context every time the skill runs.

```python
my-skill/
├── SKILL.md (required - overview and navigation)
├── reference.md (detailed API docs - loaded when needed)
├── examples.md (usage examples - loaded when needed)
└── scripts/
    └── helper.py (utility script - executed, not loaded)
```

Reference supporting files from `SKILL.md` so Claude knows what each file contains and when to load it:

```python
## Additional resources

- For complete API details, see [reference.md](reference.md)
- For usage examples, see [examples.md](examples.md)
```

Keep `SKILL.md` under 500 lines. Move detailed reference material to separate files.


[​](#control-who-invokes-a-skill)

Control who invokes a skill

By default, both you and Claude can invoke any skill. You can type `/skill-name` to invoke it directly, and Claude can load it automatically when relevant to your conversation. Two frontmatter fields let you restrict this:

- **`disable-model-invocation: true`**: Only you can invoke the skill. Use this for workflows with side effects or that you want to control timing, like `/commit`, `/deploy`, or `/send-slack-message`. You don’t want Claude deciding to deploy because your code looks ready.
- **`user-invocable: false`**: Only Claude can invoke the skill. Use this for background knowledge that isn’t actionable as a command. A `legacy-system-context` skill explains how an old system works. Claude should know this when relevant, but `/legacy-system-context` isn’t a meaningful action for users to take.

This example creates a deploy skill that only you can trigger. If you set `disable-model-invocation: true`, Claude can’t run the skill automatically:

```python
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
---

Deploy $ARGUMENTS to production:

1. Run the test suite
2. Build the application
3. Push to the deployment target
4. Verify the deployment succeeded
```

If Claude tries anyway, Claude Code blocks the call and instructs it not to reproduce the deploy steps another way, so expect Claude to suggest running `/deploy` yourself. Here’s how the two fields affect invocation and context loading:

| Frontmatter                      | You can invoke | Claude can invoke | When loaded into context                                     |
|:---------------------------------|:---------------|:------------------|:-------------------------------------------------------------|
| (default)                        | Yes            | Yes               | Description always in context, full skill loads when invoked |
| `disable-model-invocation: true` | Yes            | No                | Description not in context, full skill loads when you invoke |
| `user-invocable: false`          | No             | Yes               | Description always in context, full skill loads when invoked |

In a regular session, skill descriptions are loaded into context so Claude knows what’s available, but full skill content only loads when invoked. [Subagents with preloaded skills](../09-Agents-Patterns/sub-agents.md#preload-skills-into-subagents) work differently: the full skill content is injected at startup.


[​](#skill-content-lifecycle)

Skill content lifecycle

When you or Claude invoke a skill, the rendered `SKILL.md` content enters the conversation as a single message and stays there across later turns. This persistence applies to the skill’s instructions, not its permissions: an [`allowed-tools`](#pre-approve-tools-for-a-skill) grant clears when you send your next message. Claude Code does not re-read the skill file on later turns, so write guidance that should apply throughout a task as standing instructions rather than one-time steps. When Claude re-invokes a skill whose rendered content is identical to the copy already in context, Claude Code adds a short note that the skill is already loaded rather than a second copy of the content. When the rendered content differs, because the arguments changed or a [dynamic context](#inject-dynamic-context) command produced new output, Claude Code appends the full content again. [Auto-compaction](../02-Claude-Code-CLI/how-claude-code-works.md#when-context-fills-up) carries invoked skills forward within a token budget. When the conversation is summarized to free context, Claude Code re-attaches the most recent invocation of each skill after the summary, keeping the first 5,000 tokens of each. Re-attached skills share a combined budget of 25,000 tokens. Claude Code fills this budget starting from the most recently invoked skill, so older skills can be dropped entirely after compaction if you have invoked many in one session. If a skill seems to stop influencing behavior after the first response, the content is usually still present and the model is choosing other tools or approaches. Strengthen the skill’s `description` and instructions so the model keeps preferring it, or use [hooks](../07-Hooks/hooks.md) to enforce behavior deterministically. If the skill is large or you invoked several others after it, re-invoke it after compaction to restore the full content.


[​](#pre-approve-tools-for-a-skill)

Pre-approve tools for a skill

The `allowed-tools` field grants permission for the listed tools during the turn that invokes the skill, so Claude can use them without prompting you for approval. The grant clears when you send your next message, even though the skill content [stays in context](#skill-content-lifecycle); invoking the skill again re-applies it for that turn. It does not restrict which tools are available: every tool remains callable, and your [permission settings](../02-Claude-Code-CLI/permissions.md) still govern tools that are not listed. To pre-approve tools for the whole session rather than a single turn, add allow rules to those permission settings instead. Workspace trust doesn’t gate this field. Claude Code applies a project skill’s `allowed-tools` whenever you or Claude invoke the skill, including in a `-p` run in a folder you’ve never trusted. A skill can grant itself broad tool access, so review the `allowed-tools` of skills checked into a repository before you run Claude Code there. This skill lets Claude run git commands without per-use approval whenever you invoke it:

```python
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---
```

To remove tools from Claude’s available pool while a skill is active, list them in `disallowed-tools` in the skill’s frontmatter. The restriction clears when you send your next message. Like deny rules, the field can’t remove [`EndConversation`](../02-Claude-Code-CLI/tools-reference.md#endconversation-tool-behavior) while any other tool remains. To block tools across all skills and prompts, add deny rules in your [permission settings](../02-Claude-Code-CLI/permissions.md).


[​](#pass-arguments-to-skills)

Pass arguments to skills

Both you and Claude can pass arguments when invoking a skill. Arguments are available via the `$ARGUMENTS` placeholder. This skill fixes a GitHub issue by number. The `$ARGUMENTS` placeholder gets replaced with whatever follows the skill name:

```python
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---

Fix GitHub issue $ARGUMENTS following our coding standards.

1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commit
```

When you run `/fix-issue 123`, Claude receives “Fix GitHub issue 123 following our coding standards…” If you invoke a skill with arguments but no placeholder in the skill’s content receives one, Claude Code appends `ARGUMENTS: <your input>` to the end of the skill content so Claude still sees what you typed. A placeholder is `$ARGUMENTS`, an indexed form such as `$1`, or a named argument. An indexed placeholder with no argument at its position stays as literal text and doesn’t count as receiving one. A named placeholder counts even when its position has no argument, because it expands to an empty string. You can also stack several skills at the start of one message. Typing `/write-tests /fix-issue 123` loads both skills and passes the trailing text `123` as `$ARGUMENTS` to each of them. Before v2.1.199, only the first skill loaded and received `/fix-issue 123` as literal argument text. Claude Code expands the first skill plus up to five more stacked after it. Expansion stops at the first token that isn’t an inline user-invocable skill, so a skill that runs as a [forked subagent](#run-skills-in-a-subagent), such as [`/code-review`](../02-Claude-Code-CLI/code-review.md#review-a-diff-locally), or one whose arguments may themselves start with a slash command, such as `/loop`, also ends the run there. That token and everything after it become the argument text for every expanded skill. `/code-review` runs as a forked subagent from v2.1.218; on earlier versions it ran inline and stacked. To access individual arguments by position, use `$ARGUMENTS[N]` or the shorter `$N`:

```python
---
name: migrate-component
description: Migrate a component from one language to another
---

Migrate the $ARGUMENTS[0] component from $ARGUMENTS[1] to $ARGUMENTS[2].
Preserve all existing behavior and tests.
```

Running `/migrate-component SearchBar JavaScript TypeScript` replaces `$ARGUMENTS[0]` with `SearchBar`, `$ARGUMENTS[1]` with `JavaScript`, and `$ARGUMENTS[2]` with `TypeScript`. The same skill using the `$N` shorthand:

```python
---
name: migrate-component
description: Migrate a component from one language to another
---

Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
```


[​](#advanced-patterns)

Advanced patterns


[​](#inject-dynamic-context)

Inject dynamic context

The `` !`<command>` `` syntax runs shell commands before the skill content is sent to Claude. The command output replaces the placeholder, so Claude receives actual data, not the command itself. Claude Code doesn’t run these commands on your machine when the skill is [synced from your claude.ai account](#how-claude-code-handles-the-body-of-a-synced-skill). This restriction requires Claude Code v2.1.228 or later. This skill summarizes a pull request by fetching live PR data with the GitHub CLI. The `` !`gh pr diff` `` and other commands run first, and their output gets inserted into the prompt:

```python
---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---

## Pull request context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`

## Your task
Summarize this pull request...
```

Substitution runs once over the original file. Command output is inserted as plain text and is not re-scanned for further `` !`<command>` `` placeholders, so a command cannot emit a placeholder for a later pass to expand. The inline form is only recognized when `!` appears at the start of a line or immediately after whitespace. If `!` follows another character, as in `` KEY=!`cmd` ``, the placeholder is left as literal text and the command does not run. For multi-line commands, use a fenced code block opened with ```` ```! ```` instead of the inline form:

```` shiki
## Environment
```!
node --version
git status --short
```
````

To disable this behavior for skills and custom commands from user, project, plugin, or [additional-directory](#skills-from-additional-directories) sources, set `"disableSkillShellExecution": true` in [settings](../02-Claude-Code-CLI/settings.md). Each command is replaced with `[shell command execution disabled by policy]` instead of being run. Bundled and managed skills are not affected. This setting is most useful in [managed settings](../13-Enterprise-Admin/managed-settings.md), where users cannot override it. Claude Code never runs these commands on your machine when they appear in skills [synced from your claude.ai account](#how-synced-skills-behave), regardless of this setting. This restriction requires Claude Code v2.1.228 or later. [How Claude Code handles the body of a synced skill](#how-claude-code-handles-the-body-of-a-synced-skill) says what Claude receives in place of the command in each kind of session.

To request deeper reasoning when a skill runs, include `ultrathink` anywhere in the skill content. See [Use ultrathink for one-off deep reasoning](../02-Claude-Code-CLI/model-config.md#use-ultrathink-for-one-off-deep-reasoning).


[​](#how-injected-commands-run)

How injected commands run

Claude Code picks the tool that runs a skill’s injected commands from the `shell` key in the skill’s frontmatter and your environment. Every combination runs the commands through the Bash tool or the PowerShell tool, except one that fails the invocation outright:

- `shell: powershell`, with the [PowerShell tool](../02-Claude-Code-CLI/tools-reference.md#powershell-tool) enabled: the commands run through the PowerShell tool.
- `shell: bash` when bash isn’t available: the invocation fails before any command runs. This happens on Windows without Git Bash. Claude Code shows `` Skill <name> requires bash (`shell: bash` in frontmatter) but Git Bash was not found ``.
- Any other combination: the commands run through the Bash tool when bash is available. When it isn’t, they run through the PowerShell tool.

Either tool runs the commands the same way it runs Claude’s own shell commands. They share the working directory, timeout, and output handling:

- **Working directory**: Claude Code runs each command in the session shell’s current working directory. That directory moves when Claude runs `cd`. Use [`${CLAUDE_SKILL_DIR}` or `${CLAUDE_PROJECT_DIR}`](#available-string-substitutions) in paths that must resolve the same way every time.
- **stderr**: with the default `bash` shell, Claude Code merges stderr into stdout. Anything the command writes to stderr appears in the injected text.
- **Timeout**: each command runs under the Bash tool’s default 2-minute [timeout](../02-Claude-Code-CLI/tools-reference.md#timeout-and-output-limits). When the Bash tool [moves a timed-out command to the background](../02-Claude-Code-CLI/tools-reference.md#background-commands), the skill still renders. The injected text reports the move and names the background task and the file collecting the command’s output. When the command is one the Bash tool never auto-backgrounds, Claude Code kills it at the timeout. That failure [aborts the invocation](#when-an-injected-command-fails).
- **Output size**: output past the Bash tool’s inline ceiling arrives as a file path plus a short preview, not truncated text. [Output limits](../02-Claude-Code-CLI/tools-reference.md#output-limits) covers the ceiling and how to adjust each boundary.

The PowerShell tool applies the same timeout, backgrounding, and output-ceiling behavior to the commands it runs. See the [PowerShell tool](../02-Claude-Code-CLI/tools-reference.md#powershell-tool) section for its specifics.


[​](#when-an-injected-command-fails)

When an injected command fails

A failed command aborts the entire skill invocation, not just its own placeholder. Claude never sees the skill content for that invocation. The abort shows `Shell command failed for pattern "..."`. The error message includes the command’s output under `[stderr]`. With the default `bash` shell, any non-zero exit code counts as a failure. One carveout applies: Claude Code treats exit code 1 from [search and comparison commands](../02-Claude-Code-CLI/tools-reference.md#output-limits) as a normal result and injects their output. Exit codes of 2 or higher fail even for those commands. Which commands get the carveout depends on the shell:

- Default `bash` shell: the commands listed under [Output limits](../02-Claude-Code-CLI/tools-reference.md#output-limits)
- `shell: powershell`, when the PowerShell tool is enabled: a [different set](../02-Claude-Code-CLI/tools-reference.md#shell-selection-in-settings-hooks-and-skills) that includes `grep` and `git diff` but not `find` or `diff`

With the default `bash` shell, append `|| true` to any other command you expect to exit non-zero. A check script that exits 1 when it finds problems is one example.


[​](#permission-checks-on-injected-commands)

Permission checks on injected commands

Injected commands never prompt for permission while the skill renders. Claude Code checks each one against your [permission rules](../02-Claude-Code-CLI/permissions.md) first. A command a deny rule matches aborts the invocation with `Shell command permission check failed for pattern "..."`. Outside [auto mode](../02-Claude-Code-CLI/permission-modes.md#eliminate-prompts-with-auto-mode), when a command’s permission check returns anything other than allow, Claude Code aborts the invocation with the same error. This includes a rule that would normally ask you. To keep an unmatched command from aborting here, pre-approve it with [`allowed-tools`](#pre-approve-tools-for-a-skill). Deny and ask rules still override `allowed-tools`. See [Manage permissions](../02-Claude-Code-CLI/permissions.md#manage-permissions). In auto mode, a command that would otherwise need your approval doesn’t abort the invocation. The skill loads with an instruction telling Claude to run the command first, and Claude’s own call then goes through [auto mode’s usual checks](../02-Claude-Code-CLI/permission-modes.md#how-the-classifier-evaluates-actions). The invocation still aborts in a [forked skill](#run-skills-in-a-subagent) that sets `agent`, and in a session where Claude doesn’t have the [shell tool that runs injected commands](#how-injected-commands-run).


[​](#run-skills-in-a-subagent)

Run skills in a subagent

Add `context: fork` to your frontmatter when you want a skill to run in isolation. Claude Code starts a new subagent of the type set in the `agent` field and gives it the skill content as its prompt. The subagent doesn’t see your conversation history, so the skill’s instructions have to stand on their own.

Despite the name, a skill with `context: fork` doesn’t run in a [fork of the current conversation](../09-Agents-Patterns/sub-agents.md#fork-the-current-conversation), which would hand the subagent everything you’ve discussed so far. When the task depends on that history, fork the conversation instead of using `context: fork`.

The forked subagent runs in the [background](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background): you keep working while it runs, and its result arrives in your conversation when it completes. Set `background: false` in the frontmatter to instead wait for the result in the turn that invoked the skill. Before v2.1.218, forked skills always blocked the turn until they finished. Claude Code also waits for the result, even when the skill doesn’t set `background: false`, in cases like these:

- In non-interactive mode, with the `-p` flag or the Agent SDK
- When you set [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](../02-Claude-Code-CLI/env-vars.md) to `1`, which also turns off all other background task features
- When you invoke a forked skill while an earlier invocation of the same skill is still running
- When a [scheduled task](../02-Claude-Code-CLI/scheduled-tasks.md) fires with the skill as its prompt

A backgrounded fork also runs with the [narrower tool set that applies to background subagents](../09-Agents-Patterns/sub-agents.md#run-subagents-in-foreground-or-background): the skill’s subagent is a regular agent type, so the exemption for subagents that fork the conversation doesn’t cover it. If your skill’s steps depend on a tool outside that set, set `background: false` to keep the full tool set. A forked skill that runs in the background applies its edits outside your session’s [checkpoints](../02-Claude-Code-CLI/checkpointing.md), so `/rewind` doesn’t undo them; use git to revert them.

`context: fork` only makes sense for skills with explicit instructions. If your skill contains guidelines like “use these API conventions” without a task, the subagent receives the guidelines but no actionable prompt, and returns without meaningful output.

Skills and [subagents](../09-Agents-Patterns/sub-agents.md) work together in two directions:

| Approach                     | System prompt            | Task                        | Also loads                                                                                                    |
|:-----------------------------|:-------------------------|:----------------------------|:--------------------------------------------------------------------------------------------------------------|
| Skill with `context: fork`   | From agent type          | SKILL.md content            | CLAUDE.md, per the agent’s [startup context](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup)                       |
| Subagent with `skills` field | Subagent’s markdown body | Claude’s delegation message | Preloaded skills + CLAUDE.md, per the subagent’s [startup context](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup) |

With `context: fork`, you write the task in your skill and pick an agent type to execute it. The built-in Explore and Plan agents [skip CLAUDE.md and git status](../09-Agents-Patterns/sub-agents.md#what-loads-at-startup) to keep their context small, so a forked skill using `agent: Explore` sees only the SKILL.md content and the agent’s own system prompt. For the inverse, where you define a custom subagent that uses skills as reference material, see [Subagents](../09-Agents-Patterns/sub-agents.md#preload-skills-into-subagents).


[​](#example-research-skill-using-explore-agent)

Example: Research skill using Explore agent

This skill runs research in a forked Explore agent. The skill content becomes the task, and the agent provides read-only tools optimized for codebase exploration:

```python
---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---

Research $ARGUMENTS thoroughly:

1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references
```

When this skill runs:

1.  A new isolated context is created
2.  The subagent receives the skill content as its prompt (the “Research \$ARGUMENTS thoroughly” instructions)
3.  The `agent` field determines the execution environment (model, tools, and permissions)
4.  The subagent summarizes its results and returns them to your main conversation when it finishes

The `agent` field specifies which subagent configuration to use. Options include built-in agents (`Explore`, `Plan`, `general-purpose`) or any custom subagent from `.claude/agents/`. If omitted, uses `general-purpose`.


[​](#restrict-claude’s-skill-access)

Restrict Claude’s skill access

By default, Claude can invoke any skill that doesn’t have `disable-model-invocation: true` set. Skills that define `allowed-tools` grant Claude access to those tools without per-use approval during the turn that invokes the skill; the grant clears when you send your next message. Your [permission settings](../02-Claude-Code-CLI/permissions.md) still govern baseline approval behavior for all other tools. A few built-in commands are also available through the Skill tool, including `/init` and `/security-review`. Other built-in commands such as `/compact` are not. Three ways to control which skills Claude can invoke: **Disable all skills** by denying the Skill tool in `/permissions`:

```python
# Add to deny rules:
Skill
```

**Allow or deny specific skills** using [permission rules](../02-Claude-Code-CLI/permissions.md):

```python
# Allow only specific skills
Skill(commit)
Skill(review-pr *)

# Deny specific skills
Skill(deploy *)
```

Permission syntax: `Skill(name)` for exact match, `Skill(name *)` for prefix match with any arguments. In an `allow` rule, a prefix outside the [namespace reserved for synced skills](#names-reserved-for-synced-skills) doesn’t match the names inside it: `Skill(anthropic *)` doesn’t cover `anthropic-skills:pdf`. If your `deny` rule names an alias or an unqualified name rather than the skill’s own name, Claude Code still blocks the skill: with `Skill(review)` it blocks the bundled `/code-review` through its `/review` alias, and with `Skill(deploy)` it blocks a [nested skill](#where-skills-live) listed as `apps/web:deploy` through its unqualified name. Before v2.1.260, Claude Code didn’t block a nested skill listed under its qualified name when the deny rule named only the unqualified name. Claude Code matches an `allow` rule only against the skill’s own name and the name in Claude’s invocation. To approve a [synced skill](#how-synced-skills-behave) without a prompt, name it inside its [reserved namespace](#names-reserved-for-synced-skills): `Skill(anthropic-skills:pdf)` approves the synced `pdf` skill, and `Skill(anthropic-skills *)` approves every synced skill. **Hide individual skills** by adding `disable-model-invocation: true` to their frontmatter. This removes the skill from Claude’s context entirely.

With `user-invocable: false`, you can’t invoke the skill, but Claude still can. To keep Claude from invoking it through the Skill tool, set `disable-model-invocation: true`.


[​](#override-skill-visibility-from-settings)

Override skill visibility from settings

The `skillOverrides` setting controls skill visibility from your [settings](../02-Claude-Code-CLI/settings.md) instead of the skill’s own frontmatter. Use it for skills whose SKILL.md you don’t want to edit, such as ones checked into a shared project repo. The `/skills` menu writes it for you: highlight a skill and press `Space` to cycle states, then `Esc` to save to `.claude/settings.local.json`. Each key is a skill name and each value is one of four states:

| Value                   | Listed to Claude     | In `/` menu |
|:------------------------|:---------------------|:------------|
| `"on"`                  | Name and description | Yes         |
| `"name-only"`           | Name only            | Yes         |
| `"user-invocable-only"` | Hidden               | Yes         |
| `"off"`                 | Hidden               | Hidden      |

The `/skills` menu labels the `"user-invocable-only"` state `user-only`. As of v2.1.199, `"off"` also hides the skill from the command lists advertised to [Remote Control](../02-Claude-Code-CLI/remote-control.md) clients and to [Agent SDK](../05-Agent-SDK/agent-sdk-skills.md#discover-available-commands) callers, in addition to the terminal `/` menu. Invoking a hidden skill by its full name still returns the `skillOverrides` error instead of running it. A skill that is absent from `skillOverrides` is treated as `"on"`. The example below collapses one skill to its name and turns another off entirely:

```python
{
  "skillOverrides": {
    "legacy-context": "name-only",
    "deploy": "off"
  }
}
```

Some bundled skills have aliases, such as `checkup` for `/doctor`. If you set a `skillOverrides` entry under an alias in [managed settings](../13-Enterprise-Admin/managed-settings.md) or in a file you pass with the `--settings` flag, Claude Code applies it to the skill behind the alias. You can only restrict a skill further through an alias, never make it more visible, and if you also set an entry under the skill’s own name in managed settings, that entry takes precedence. Before v2.1.260, Claude Code didn’t apply an entry under an alias to the skill in any settings source. In user, project, and local settings, Claude Code matches entries against skill names only. If you set an entry for `review` there, it applies to a skill named `review`, not to the bundled `/code-review` through its `/review` alias. Plugin skills are not affected by `skillOverrides`. Manage those through `/plugin` instead.


[​](#find-unused-skills)

Find unused skills

Every skill in the [skill listing](#skill-descriptions-are-cut-short) adds to your context on every turn, whether or not Claude ever uses it. Run `/skill-doctor` to see what each of your skills costs and how often it gets used, so you can decide which ones to turn off. In an interactive session, the report opens in the `/plugin` manager’s **Stats** tab. In [non-interactive mode](../02-Claude-Code-CLI/headless.md) with `-p`, Claude Code prints it as text. The report covers the skills in your session other than bundled skills and enterprise skills. It flags skills in the listing that have never been invoked and says where to turn them off. Of the skills it tells you where to turn off, start with the ones that have the highest context cost. The report also lists plugins you haven’t used recently. `/skill-doctor` requires Claude Code v2.1.252 or later and isn’t available in sessions that skip [feature-flag fetching](../02-Claude-Code-CLI/env-vars.md#features-that-need-feature-flag-fetching). If you run `/skill-doctor` over [Remote Control](../02-Claude-Code-CLI/remote-control.md) from your phone or browser, Claude Code replies [`Skill usage reports are not available on this connection.`](../02-Claude-Code-CLI/errors.md#skill-usage-reports-are-not-available-on-this-connection) instead. Run `/skill-doctor` in the terminal on the machine where the session is running.


[​](#evaluate-and-iterate-on-a-skill)

Evaluate and iterate on a skill

Seeing a skill trigger tells you Claude found it, not that it did what you intended. To know a skill is working, measure separately whether Claude invokes it on the prompts it should, and whether the output matches what you expect when it does. The check for both is a baseline comparison. Collect a few realistic prompts, run each one in a fresh session with the skill available and again with it [disabled](#override-skill-visibility-from-settings), and compare the results. A fresh session matters because leftover context from authoring the skill will mask gaps in the written instructions. Two tools automate that comparison. For a skill that ships in a [plugin](plugins.md), [`claude plugin eval`](plugin-evals.md) runs each prompt in an isolated session with and without the plugin, scores it with graders you define or that it writes for you, and exits non-zero below a threshold so you can gate CI on it. For iterating on a single skill inside a Claude Code conversation, the skill-creator plugin below runs a similar loop with its own `evals/evals.json` format. The two formats aren’t interchangeable.


[​](#run-evals-with-skill-creator)

Run evals with skill-creator

The [`skill-creator` plugin](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/skill-creator) automates the comparison loop inside Claude Code. Install it from the official marketplace:

```python
/plugin install skill-creator@claude-plugins-official
```

If the install fails, match the message Claude Code reports:

- `Marketplace "claude-plugins-official" not found`: add the marketplace with `/plugin marketplace add anthropics/claude-plugins-official`, then retry the install.
- The plugin is [not found in the marketplace](discover-plugins.md#install-a-plugin): check the plugin name.

If the install summary reports `Run /reload-plugins to activate.`, Claude Code then runs that reload for you. If the reload warns that your next message would re-read the conversation, run `/reload-plugins --force` to make the plugin’s skills available in the current session. Then ask Claude to evaluate an existing skill, for example `evaluate my summarize-changes skill with skill-creator`. The plugin walks you through writing test cases and runs the loop:

- **Test cases**: stores prompts, input files, and expected behavior in `evals/evals.json` inside the skill directory
- **Isolated runs**: spawns a [subagent](../09-Agents-Patterns/sub-agents.md) per test case so each run starts with a clean context, and records token count and duration
- **Grading**: checks each assertion against the output and writes pass or fail with evidence to `grading.json`
- **Benchmark**: aggregates pass rate, time, and tokens for with-skill versus without-skill into `benchmark.json` so you can compare the pass-rate improvement against the token and time overhead
- **Version comparison**: runs a blind A/B between two versions of the skill so you can confirm an edit is an improvement before committing it
- **Description tuning**: generates should-trigger and should-not-trigger prompts, measures the hit rate, and proposes description edits when the skill activates on the wrong requests
- **Review viewer**: opens an HTML report where you inspect each output and record qualitative feedback that the next iteration reads

For the eval file format and the full iteration workflow, see [Evaluating skill output quality](skill-creation-evaluating-skills.md) on agentskills.io. For background on the benchmark and comparison modes, see the [skill-creator announcement](https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills).


[​](#share-skills)

Share skills

Skills can be distributed at different scopes depending on your audience:

- **Project skills**: Commit `.claude/skills/` to version control
- **Plugins**: Create a `skills/` directory in your [plugin](plugins.md)
- **Managed**: Deploy organization-wide through [managed settings](../13-Enterprise-Admin/managed-settings.md)


[​](#generate-visual-output)

Generate visual output

Skills can bundle and run scripts in any language, giving Claude capabilities beyond what’s possible in a single prompt. One pattern is generating visual output: interactive HTML files that open in your browser for exploring data, debugging, or creating reports. This example creates a codebase explorer: an interactive tree view where you can expand and collapse directories, see file sizes at a glance, and identify file types by color. Create the Skill directory:

```python
mkdir -p ~/.claude/skills/codebase-visualizer/scripts
```

Save this to `~/.claude/skills/codebase-visualizer/SKILL.md`. The description tells Claude when to activate this Skill, and the instructions tell Claude to run the bundled script. The script path uses [`${CLAUDE_SKILL_DIR}`](#available-string-substitutions) so it resolves correctly whether the skill is installed at the personal, project, or plugin level:

```` shiki
---
name: codebase-visualizer
description: Generate an interactive collapsible tree visualization of your codebase. Use when exploring a new repo, understanding project structure, or identifying large files.
allowed-tools: Bash(python3 *)
---

# Codebase Visualizer

Generate an interactive HTML tree view that shows your project's file structure with collapsible directories.

## Usage

Run the visualization script from your project root:

```bash
python3 ${CLAUDE_SKILL_DIR}/scripts/visualize.py .
```

This creates `codebase-map.html` in the current directory and opens it in your default browser.

## What the visualization shows

- **Collapsible directories**: Click folders to expand/collapse
- **File sizes**: Displayed next to each file
- **Colors**: Different colors for different file types
- **Directory totals**: Shows aggregate size of each folder
````

Save this to `~/.claude/skills/codebase-visualizer/scripts/visualize.py`. This script scans a directory tree and generates a self-contained HTML file with:

- A **summary sidebar** showing file count, directory count, total size, and number of file types
- A **bar chart** breaking down the codebase by file type (top 8 by size)
- A **collapsible tree** where you can expand and collapse directories, with color-coded file type indicators

The script requires Python 3 but uses only built-in libraries, so there are no packages to install:

```python
#!/usr/bin/env python3
"""Generate an interactive collapsible tree visualization of a codebase."""

import json
import sys
import webbrowser
from html import escape
from pathlib import Path
from collections import Counter

IGNORE = {'.git', 'node_modules', '__pycache__', '.venv', 'venv', 'dist', 'build'}

def scan(path: Path, stats: dict) -> dict:
    result = {"name": path.name, "children": [], "size": 0}
    try:
        for item in sorted(path.iterdir()):
            if item.name in IGNORE or item.name.startswith('.'):
                continue
            if item.is_file():
                size = item.stat().st_size
                ext = item.suffix.lower() or '(no ext)'
                result["children"].append({"name": item.name, "size": size, "ext": ext})
                result["size"] += size
                stats["files"] += 1
                stats["extensions"][ext] += 1
                stats["ext_sizes"][ext] += size
            elif item.is_dir():
                stats["dirs"] += 1
                child = scan(item, stats)
                if child["children"]:
                    result["children"].append(child)
                    result["size"] += child["size"]
    except PermissionError:
        pass
    return result

def generate_html(data: dict, stats: dict, output: Path) -> None:
    ext_sizes = stats["ext_sizes"]
    total_size = sum(ext_sizes.values()) or 1
    sorted_exts = sorted(ext_sizes.items(), key=lambda x: -x[1])[:8]
    colors = {
        '.js': '#f7df1e', '.ts': '#3178c6', '.py': '#3776ab', '.go': '#00add8',
        '.rs': '#dea584', '.rb': '#cc342d', '.css': '#264de4', '.html': '#e34c26',
        '.json': '#6b7280', '.md': '#083fa1', '.yaml': '#cb171e', '.yml': '#cb171e',
        '.mdx': '#083fa1', '.tsx': '#3178c6', '.jsx': '#61dafb', '.sh': '#4eaa25',
    }
    lang_bars = "".join(
        f'<div class="bar-row"><span class="bar-label">{ext}</span>'
        f'<div class="bar" style="width:{(size/total_size)*100}%;background:{colors.get(ext,"#6b7280")}"></div>'
        f'<span class="bar-pct">{(size/total_size)*100:.1f}%</span></div>'
        for ext, size in sorted_exts
    )
    def fmt(b):
        if b < 1024: return f"{b} B"
        if b < 1048576: return f"{b/1024:.1f} KB"
        return f"{b/1048576:.1f} MB"

    html = f'''<!DOCTYPE html>
<html><head>
  <meta charset="utf-8"><title>Codebase Explorer</title>
  <style>
    body {{ font: 14px/1.5 system-ui, sans-serif; margin: 0; background: #1a1a2e; color: #eee; }}
    .container {{ display: flex; height: 100vh; }}
    .sidebar {{ width: 280px; background: #252542; padding: 20px; border-right: 1px solid #3d3d5c; overflow-y: auto; flex-shrink: 0; }}
    .main {{ flex: 1; padding: 20px; overflow-y: auto; }}
    h1 {{ margin: 0 0 10px 0; font-size: 18px; }}
    h2 {{ margin: 20px 0 10px 0; font-size: 14px; color: #888; text-transform: uppercase; }}
    .stat {{ display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #3d3d5c; }}
    .stat-value {{ font-weight: bold; }}
    .bar-row {{ display: flex; align-items: center; margin: 6px 0; }}
    .bar-label {{ width: 55px; font-size: 12px; color: #aaa; }}
    .bar {{ height: 18px; border-radius: 3px; }}
    .bar-pct {{ margin-left: 8px; font-size: 12px; color: #666; }}
    .tree {{ list-style: none; padding-left: 20px; }}
    details {{ cursor: pointer; }}
    summary {{ padding: 4px 8px; border-radius: 4px; }}
    summary:hover {{ background: #2d2d44; }}
    .folder {{ color: #ffd700; }}
    .file {{ display: flex; align-items: center; padding: 4px 8px; border-radius: 4px; }}
    .file:hover {{ background: #2d2d44; }}
    .size {{ color: #888; margin-left: auto; font-size: 12px; }}
    .dot {{ width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; }}
  </style>
</head><body>
  <div class="container">
    <div class="sidebar">
      <h1>📊 Summary</h1>
      <div class="stat"><span>Files</span><span class="stat-value">{stats["files"]:,}</span></div>
      <div class="stat"><span>Directories</span><span class="stat-value">{stats["dirs"]:,}</span></div>
      <div class="stat"><span>Total size</span><span class="stat-value">{fmt(data["size"])}</span></div>
      <div class="stat"><span>File types</span><span class="stat-value">{len(stats["extensions"])}</span></div>
      <h2>By file type</h2>
      {lang_bars}
    </div>
    <div class="main">
      <h1>📁 {escape(data["name"])}</h1>
      <ul class="tree" id="root"></ul>
    </div>
  </div>
  <script>
    const data = {json.dumps(data)};
    const colors = {json.dumps(colors)};
    function fmt(b) {{ if (b < 1024) return b + ' B'; if (b < 1048576) return (b/1024).toFixed(1) + ' KB'; return (b/1048576).toFixed(1) + ' MB'; }}
    function esc(s) {{ return s.replace(/[&<>"']/g, c => ({{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}}[c])); }}
    function render(node, parent) {{
      if (node.children) {{
        const det = document.createElement('details');
        det.open = parent === document.getElementById('root');
        det.innerHTML = `<summary><span class="folder">📁 ${{esc(node.name)}}</span><span class="size">${{fmt(node.size)}}</span></summary>`;
        const ul = document.createElement('ul'); ul.className = 'tree';
        node.children.sort((a,b) => (b.children?1:0)-(a.children?1:0) || a.name.localeCompare(b.name));
        node.children.forEach(c => render(c, ul));
        det.appendChild(ul);
        const li = document.createElement('li'); li.appendChild(det); parent.appendChild(li);
      }} else {{
        const li = document.createElement('li'); li.className = 'file';
        li.innerHTML = `<span class="dot" style="background:${{colors[node.ext]||'#6b7280'}}"></span>${{esc(node.name)}}<span class="size">${{fmt(node.size)}}</span>`;
        parent.appendChild(li);
      }}
    }}
    data.children.forEach(c => render(c, document.getElementById('root')));
  </script>
</body></html>'''
    output.write_text(html)

if __name__ == '__main__':
    target = Path(sys.argv[1] if len(sys.argv) > 1 else '.').resolve()
    stats = {"files": 0, "dirs": 0, "extensions": Counter(), "ext_sizes": Counter()}
    data = scan(target, stats)
    out = Path('codebase-map.html')
    generate_html(data, stats, out)
    print(f'Generated {out.absolute()}')
    webbrowser.open(f'file://{out.absolute()}')
```

See all 133 lines

To test, open Claude Code in any project and ask “Visualize this codebase.” Claude runs the script, which prints the generated file’s path, such as `Generated /path/to/codebase-map.html`, and opens it in your browser. If you work in a headless environment where no browser opens, the printed path confirms the script succeeded. This pattern works for any visual output: dependency graphs, test coverage reports, API documentation, or database schema visualizations. The bundled script does the work while Claude handles orchestration.


[​](#troubleshooting)

Troubleshooting


[​](#skill-not-triggering)

Skill not triggering

If Claude doesn’t use your skill when expected:

1.  Check the description includes keywords users would naturally say
2.  Verify the skill appears in `What skills are available?`
3.  Try rephrasing your request to match the description more closely
4.  Invoke it directly with `/skill-name` if the skill is user-invocable

If the frontmatter YAML is malformed, Claude Code loads the skill body with empty metadata, so `/skill-name` still works but Claude can’t match against your `description`. Run with `--debug` to see the parse error. If the skill ships in a plugin, you can measure how often it triggers across realistic prompts rather than checking one at a time: write an eval case with a [`tool_used: Skill` grader](plugin-evals.md#create-your-first-eval-suite) and run it with `claude plugin eval` after each description change. To find `SKILL.md` files whose frontmatter doesn’t parse, run [`claude plugin validate`](plugins-cli-reference.md#validate-a-directory) on the skills directory, for example `claude plugin validate .claude/skills` for project skills or `claude plugin validate ~/.claude/skills` for personal skills. Requires Claude Code v2.1.233 or later.


[​](#skill-triggers-too-often)

Skill triggers too often

If Claude uses your skill when you don’t want it:

1.  Make the description more specific
2.  Add `disable-model-invocation: true` if you only want manual invocation


[​](#skill-descriptions-are-cut-short)

Skill descriptions are cut short

Claude Code loads a listing of skill names and descriptions into context so Claude knows what’s available. The listing always contains every skill name, but if you have many skills, Claude Code drops some descriptions to fit the listing’s character budget, which removes the keywords Claude needs to match your request. The budget scales at 1% of the model’s context window. When the listing overflows, Claude Code drops descriptions starting with the skills you invoke least, so the skills you use most keep their full text. Run `/doctor` for an estimate of the listing’s context cost and its biggest contributors. To find skills worth turning off, run [`/skill-doctor`](#find-unused-skills). When the listing exceeds its budget, Claude Code also writes a warning to the debug log, visible with [`--debug`](../02-Claude-Code-CLI/cli-reference.md#cli-flags). The Skills row in `/context` reports the size of the listing after the budget is applied, so it matches what the model receives. Before v2.1.196, the row counted the full text of every description and could show a value several times larger than the configured budget. To raise the budget, set the [`skillListingBudgetFraction`](../02-Claude-Code-CLI/settings-reference.md#skilllistingbudgetfraction) setting (for example, `0.02` = 2%) or the `SLASH_COMMAND_TOOL_CHAR_BUDGET` environment variable to a fixed character count. To free budget for other skills, set low-priority entries to `"name-only"` in [`skillOverrides`](#override-skill-visibility-from-settings) so they list without a description. You can also trim the `description` and `when_to_use` text at the source: put the key use case first, since each entry’s combined text is capped at 1,536 characters regardless of budget. The cap is configurable with [`skillListingMaxDescChars`](../02-Claude-Code-CLI/settings-reference.md#skilllistingmaxdescchars).


[​](#personal-skills-disappeared)

Personal skills disappeared

If skill folders you created in `~/.claude/skills/` are gone, look in `~/.claude/skills/.trash/`. When Claude Code [syncs skills from claude.ai](#how-synced-skills-behave), it downloads them into the separate `synced` subfolder and doesn’t move or delete the folders you create. Before v2.1.280, a file named `manifest.json` in `~/.claude/skills/` caused Claude Code to move the skill folders that file listed into a timestamped folder under `~/.claude/skills/.trash/`, and those skills stopped loading. To restore a skill, move its folder from the timestamped folder back into `~/.claude/skills/`. Do this before the [retention sweep](../02-Claude-Code-CLI/claude-directory.md#cleaned-up-automatically) deletes trash entries, by default 30 days after they were moved to the trash.


[​](#related-resources)

Related resources

- **[Debug your configuration](../02-Claude-Code-CLI/debug-your-config.md)**: diagnose why a skill isn’t appearing or triggering
- **[Evaluating skill output quality](skill-creation-evaluating-skills.md)**: the eval file format and iteration workflow on agentskills.io
- **[Skill authoring best practices](../04-API-Reference/Agents-Tools/agents-and-tools-agent-skills-best-practices.md)**: writing guidance that applies across Claude products
- **[Subagents](../09-Agents-Patterns/sub-agents.md)**: delegate tasks to specialized agents
- **[Plugins](plugins.md)**: package and distribute skills with other extensions
- **[Hooks](../07-Hooks/hooks.md)**: automate workflows around tool events
- **[Memory](../02-Claude-Code-CLI/memory.md)**: manage CLAUDE.md files for persistent context
- **[Commands](../02-Claude-Code-CLI/commands.md)**: reference for built-in commands and bundled skills
- **[Permissions](../02-Claude-Code-CLI/permissions.md)**: control tool and skill access
- **[Claude Tag skills](https://claude.com/docs/claude-tag/admins/skills-repo)**: project skills committed to a repo also load when that repo is used in a Claude Tag channel

---

## Specification - Agent Skills

Source: https://agentskills.io/specification
Path: 08-Plugins-Skills/specification.md

## On this page

- [Directory structure](#directory-structure)
- [SKILL.md format](#skill-md-format)
  - [Frontmatter](#frontmatter)
  - [name field](#name-field)
  - [description field](#description-field)
  - [license field](#license-field)
  - [compatibility field](#compatibility-field)
  - [metadata field](#metadata-field)
  - [allowed-tools field](#allowed-tools-field)
  - [Body content](#body-content)
- [Optional directories](#optional-directories)
  - [scripts/](#scripts%2F)
  - [references/](#references%2F)
  - [assets/](#assets%2F)
- [Progressive disclosure](#progressive-disclosure)
- [File references](#file-references)
- [Validation](#validation)

# Specification

Copy pageCopy page

The complete format specification for Agent Skills.

Copy pageCopy page


[​](#directory-structure)

Directory structure

A skill is a directory containing, at minimum, a `SKILL.md` file:

```python
skill-name/
├── SKILL.md          # Required: metadata + instructions
├── scripts/          # Optional: executable code
├── references/       # Optional: documentation
├── assets/           # Optional: templates, resources
└── ...               # Any additional files or directories
```


[​](#skill-md-format)

`SKILL.md` format

The `SKILL.md` file must contain YAML frontmatter followed by Markdown content.


[​](#frontmatter)

Frontmatter

| Field           | Required | Constraints                                                                                                       |
|-----------------|----------|-------------------------------------------------------------------------------------------------------------------|
| `name`          | Yes      | Max 64 characters. Lowercase letters, numbers, and hyphens only. Must not start or end with a hyphen.             |
| `description`   | Yes      | Max 1024 characters. Non-empty. Describes what the skill does and when to use it.                                 |
| `license`       | No       | License name or reference to a bundled license file.                                                              |
| `compatibility` | No       | Max 500 characters. Indicates environment requirements (intended product, system packages, network access, etc.). |
| `metadata`      | No       | Arbitrary key-value mapping for additional metadata (a map from string keys to string values).                    |
| `allowed-tools` | No       | Space-separated string of pre-approved tools the skill may use. (Experimental)                                    |

**Minimal example:**

SKILL.md

```python
---
name: skill-name
description: A description of what this skill does and when to use it.
---
```

**Example with optional fields:**

SKILL.md

```python
---
name: pdf-processing
description: Extract PDF text, fill forms, merge files. Use when handling PDFs.
license: Apache-2.0
metadata:
  author: example-org
  version: "1.0"
---
```


[​](#name-field)

`name` field

The required `name` field:

- Must be 1-64 characters
- May only contain unicode lowercase alphanumeric characters (`a-z`, `0-9`) and hyphens (`-`)
- Must not start or end with a hyphen (`-`)
- Must not contain consecutive hyphens (`--`)
- Must match the parent directory name

**Valid examples:**

```python
name: pdf-processing
```

```python
name: data-analysis
```

```python
name: code-review
```

**Invalid examples:**

```python
name: PDF-Processing  # uppercase not allowed
```

```python
name: -pdf  # cannot start with hyphen
```

```python
name: pdf--processing  # consecutive hyphens not allowed
```


[​](#description-field)

`description` field

The required `description` field:

- Must be 1-1024 characters
- Should describe both what the skill does and when to use it
- Should include specific keywords that help agents identify relevant tasks

**Good example:**

```python
description: Extracts text and tables from PDF files, fills PDF forms, and merges multiple PDFs. Use when working with PDF documents or when the user mentions PDFs, forms, or document extraction.
```

**Poor example:**

```python
description: Helps with PDFs.
```


[​](#license-field)

`license` field

The optional `license` field:

- Specifies the license applied to the skill
- We recommend keeping it short (either the name of a license or the name of a bundled license file)

**Example:**

```python
license: Proprietary. LICENSE.txt has complete terms
```


[​](#compatibility-field)

`compatibility` field

The optional `compatibility` field:

- Must be 1-500 characters if provided
- Should only be included if your skill has specific environment requirements
- Can indicate intended product, required system packages, network access needs, etc.

**Examples:**

```python
compatibility: Designed for Claude Code (or similar products)
```

```python
compatibility: Requires git, docker, jq, and access to the internet
```

```python
compatibility: Requires Python 3.14+ and uv
```

Most skills do not need the `compatibility` field.


[​](#metadata-field)

`metadata` field

The optional `metadata` field:

- A map from string keys to string values
- Clients can use this to store additional properties not defined by the Agent Skills spec
- We recommend making your key names reasonably unique to avoid accidental conflicts

**Example:**

```python
metadata:
  author: example-org
  version: "1.0"
```


[​](#allowed-tools-field)

`allowed-tools` field

The optional `allowed-tools` field:

- A space-separated string of tools that are pre-approved to run
- Experimental. Support for this field may vary between agent implementations

**Example:**

```python
allowed-tools: Bash(git:*) Bash(jq:*) Read
```


[​](#body-content)

Body content

The Markdown body after the frontmatter contains the skill instructions. There are no format restrictions. Write whatever helps agents perform the task effectively. Recommended sections:

- Step-by-step instructions
- Examples of inputs and outputs
- Common edge cases

Note that the agent will load this entire file once it’s decided to activate a skill. Consider splitting longer `SKILL.md` content into referenced files.


[​](#optional-directories)

Optional directories

A skill directory may contain any files and directories beyond the required `SKILL.md`. The conventions below are recommendations for organizing common types of content.


[​](#scripts/)

`scripts/`

Contains executable code that agents can run. Scripts should:

- Be self-contained or clearly document dependencies
- Include helpful error messages
- Handle edge cases gracefully

Supported languages depend on the agent implementation. Common options include Python, Bash, and JavaScript.


[​](#references/)

`references/`

Contains additional documentation that agents can read when needed:

- `REFERENCE.md` - Detailed technical reference
- `FORMS.md` - Form templates or structured data formats
- Domain-specific files (`finance.md`, `legal.md`, etc.)

Keep individual [reference files](#file-references) focused. Agents load these on demand, so smaller files mean less use of context.


[​](#assets/)

`assets/`

Contains static resources:

- Templates (document templates, configuration templates)
- Images (diagrams, examples)
- Data files (lookup tables, schemas)


[​](#progressive-disclosure)

Progressive disclosure

Agents load skills *progressively*, pulling in more detail only as a task calls for it. Skills should be structured to take advantage of this:

1.  **Metadata** (~100 tokens): The `name` and `description` fields are loaded at startup for all skills
2.  **Instructions** (\< 5000 tokens recommended): The full `SKILL.md` body is loaded when the skill is activated
3.  **Resources** (as needed): Files (e.g. those in `scripts/`, `references/`, or `assets/`) are loaded only when required

Keep your main `SKILL.md` under 500 lines. Move detailed reference material to separate files.


[​](#file-references)

File references

When referencing other files in your skill, use relative paths from the skill root:

SKILL.md

```python
See [the reference guide](references/REFERENCE.md) for details.

Run the extraction script:
scripts/extract.py
```

Keep file references one level deep from `SKILL.md`. Avoid deeply nested reference chains.


[​](#validation)

Validation

Use the [skills-ref](https://github.com/agentskills/agentskills/tree/main/skills-ref) reference library to validate your skills:

```python
skills-ref validate ./my-skill
```

This checks that your `SKILL.md` frontmatter is valid and follows all naming conventions.