playbook/outfitter-agents/plugins/outfitter/skills/claude-plugins/references/marketplace.md

14 KiB

Marketplace Reference

Complete schema, hosting strategies, and team configuration for Claude Code plugin marketplaces.

What is a Marketplace?

A marketplace is a catalog of plugins defined in .claude-plugin/marketplace.json that enables:

  • Plugin discovery
  • One-command installation
  • Version management
  • Team distribution

Marketplace Schema

Required Fields

Field Type Description
name string Marketplace identifier (kebab-case, no spaces)
owner object Maintainer information
plugins array List of plugin entries

Owner Fields

Field Required Description
owner.name Yes Name of maintainer or team
owner.email No Contact email

Reserved Names

The following marketplace names are reserved and cannot be used:

  • claude-code-marketplace
  • claude-code-plugins
  • claude-plugins-official
  • anthropic-marketplace
  • anthropic-plugins
  • agent-skills
  • life-sciences

Names that impersonate official marketplaces (like official-claude-plugins or anthropic-tools-v2) are also blocked.

Optional Metadata

Field Type Description
metadata.description string Brief marketplace description
metadata.version string Marketplace version
metadata.pluginRoot string Documentation hint for where plugins live. Does NOT affect schema validation—always use explicit ./ prefix in source paths.

Complete Example

For local plugins (relative paths), use strict: false to consolidate metadata. Always use explicit ./ prefix for source paths:

{
  "name": "company-tools",
  "owner": {
    "name": "Engineering Team",
    "email": "eng@company.com"
  },
  "metadata": {
    "description": "Internal development tools",
    "version": "2.0.0"
  },
  "strict": false,
  "plugins": [
    {
      "name": "code-formatter",
      "source": "./code-formatter",
      "version": "1.0.0",
      "description": "Auto-format code on save",
      "license": "MIT"
    },
    {
      "name": "deployment-tools",
      "source": "./deployment",
      "version": "2.1.0",
      "description": "Deploy to staging and production",
      "license": "MIT"
    }
  ]
}

With strict: false, plugins don't need their own .claude-plugin/plugin.json—the marketplace is the single source of truth.

Plugin Entry Schema

Local Plugins (Consolidated)

For plugins in the same repo as the marketplace, define all metadata in the marketplace entry:

{
  "name": "code-formatter",
  "source": "./code-formatter",
  "version": "1.0.0",
  "description": "Auto-format code on save",
  "license": "MIT",
  "keywords": ["formatting", "linting"]
}

Set strict: false at the marketplace level. Plugins don't need their own .claude-plugin/plugin.json.

Benefits: Single source of truth, prevents version/metadata drift between marketplace and plugin manifests.

External Plugins (Distributed)

For plugins in external repos, use minimal entries—let the external repo own its manifest:

{
  "name": "enterprise-tools",
  "source": {
    "source": "github",
    "repo": "company/enterprise-plugin"
  }
}

The external repo should have its own .claude-plugin/plugin.json with metadata.

Why: External plugins may be used outside your marketplace. They should be self-contained.

Entry Fields

Required:

Field Type Description
name string Plugin identifier (kebab-case, no spaces)
source string|object Where to fetch plugin (relative path, GitHub, or git URL)

Standard metadata (optional):

Field Type Description
description string Brief plugin description
version string Plugin version
author object Author info (name required, email optional)
homepage string Documentation URL
repository string Source code URL
license string SPDX identifier (MIT, Apache-2.0)
keywords array Tags for discovery
category string Plugin category
tags array Additional searchability tags

Behavior control:

Field Type Default Description
strict boolean true When false, plugins don't need their own .claude-plugin/plugin.json—marketplace defines everything. Use for local plugins (relative paths). When true, plugins must have their own manifest.

When to use each mode:

Pattern strict Use when
Consolidated false All plugins are local (relative paths in same repo)
Distributed true Plugins are external repos that may be used elsewhere
Mixed false Local plugins consolidated, external plugins own their manifests

Component configuration (optional):

Field Type Description
commands string|array Custom paths to command files or directories
agents string|array Custom paths to agent files
hooks string|object Hook configuration or path to hooks file
mcpServers string|object MCP server configuration or path to MCP config
lspServers string|object LSP server configuration or path to LSP config

Plugin Source Types

Relative Path

For plugins in the same repository, always use explicit ./ prefix paths:

Plugins at repo root:

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

Plugins in a subdirectory:

{
  "plugins": [
    {"name": "my-plugin", "source": "./packages/my-plugin"},
    {"name": "another", "source": "./packages/another"}
  ]
}

The schema requires the ./ prefix for relative paths. Bare names like "source": "my-plugin" fail validation.

GitHub Repository

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

With specific version:

{
  "source": {
    "source": "github",
    "repo": "owner/plugin-repo",
    "ref": "v1.5.0"
  }
}

Pin to exact commit:

{
  "source": {
    "source": "github",
    "repo": "owner/plugin-repo",
    "ref": "v2.0.0",
    "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
  }
}

Monorepo pattern (plugin in a subdirectory):

{
  "source": {
    "source": "github",
    "repo": "owner/my-project",
    "path": "./packages/claude-plugin"
  }
}

Use path when the plugin lives alongside application code in a monorepo. Common patterns:

Monorepo Structure path Value
packages/claude-plugin/ ./packages/claude-plugin
.claude-plugin/ at root (omit — this is the default)
tools/claude-plugin/ ./tools/claude-plugin
Field Type Description
repo string Required. GitHub repository in owner/repo format
path string Optional. Subdirectory containing .claude-plugin/plugin.json
ref string Optional. Branch name or tag (omit to use default branch)
sha string Optional. Full 40-character commit SHA for exact version pinning

Git URL

For GitLab, Bitbucket, or self-hosted:

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

With specific branch or SHA pinning:

{
  "source": {
    "source": "url",
    "url": "https://gitlab.com/team/plugin.git",
    "ref": "develop",
    "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
  }
}
Field Type Description
url string Required. Full git repository URL (must end with .git)
path string Optional. Subdirectory containing .claude-plugin/plugin.json
ref string Optional. Branch name or tag (omit to use default branch)
sha string Optional. Full 40-character commit SHA for exact version pinning

Private Repository Authentication

Claude Code supports installing plugins from private repositories. Set the appropriate authentication token in your environment:

Provider Environment Variables Notes
GitHub GITHUB_TOKEN or GH_TOKEN Personal access token or GitHub App token
GitLab GITLAB_TOKEN or GL_TOKEN Personal access token or project token
Bitbucket BITBUCKET_TOKEN App password or repository access token

Set the token in your shell configuration (.bashrc, .zshrc) or pass it when running Claude Code:

export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx

Authentication tokens are only used when a repository requires authentication. Public repositories work without tokens.

Marketplace Types

Team/Organization

{
  "name": "company-internal",
  "owner": {
    "name": "Engineering",
    "email": "eng@company.com"
  },
  "metadata": {
    "description": "Internal development tools"
  },
  "plugins": [
    {"name": "deploy-tools", "source": "./plugins/deploy"},
    {"name": "compliance", "source": "./plugins/compliance"}
  ]
}

Hosting: Private GitHub repo or internal Git

Project-Specific

{
  "name": "project-tools",
  "owner": {
    "name": "Project Team",
    "email": "project@company.com"
  },
  "plugins": [
    {"name": "project-workflow", "source": "./plugins/workflow"}
  ]
}

Hosting: In project at .claude-plugin/marketplace.json

Public/Community

{
  "name": "awesome-plugins",
  "owner": {
    "name": "Community"
  },
  "metadata": {
    "description": "Curated Claude Code plugins"
  },
  "plugins": [
    {
      "name": "markdown-tools",
      "source": {"source": "github", "repo": "user/markdown-tools"},
      "license": "MIT"
    }
  ]
}

Team Configuration

Automatic Installation

Configure in .claude/settings.json:

{
  "extraKnownMarketplaces": {
    "team-tools": {
      "source": {
        "source": "github",
        "repo": "company/claude-plugins"
      }
    }
  }
}

Automatically installed when team members trust the folder.

Multi-Environment

{
  "extraKnownMarketplaces": {
    "development": {
      "source": {
        "source": "github",
        "repo": "company/plugins",
        "ref": "develop"
      }
    },
    "production": {
      "source": {
        "source": "github",
        "repo": "company/plugins"
      }
    }
  }
}

Use ref to point development at a non-default branch. Production uses the default branch (no ref needed).

Marketplace Commands

Adding Marketplaces

# GitHub (short form)
/plugin marketplace add owner/repo

# GitHub (full URL)
/plugin marketplace add https://github.com/owner/repo

# Git repository
/plugin marketplace add https://gitlab.com/company/plugins.git

# Local directory
/plugin marketplace add ./path/to/marketplace

# Remote JSON URL
/plugin marketplace add https://example.com/marketplace.json

Management

# List marketplaces
/plugin marketplace list

# Update specific
/plugin marketplace update marketplace-name

# Update all
/plugin marketplace update --all

# Remove (also uninstalls plugins)
/plugin marketplace remove marketplace-name

# View details
/plugin marketplace info marketplace-name

Plugin Installation

# From marketplace
/plugin install plugin-name@marketplace-name

# Specific version
/plugin install plugin-name@marketplace-name@1.2.0

# List available
/plugin list marketplace-name

# Search across marketplaces
/plugin search keyword

Validation

Validate JSON

# Syntax check
jq empty .claude-plugin/marketplace.json

# Required fields
jq -e '.name, .owner, .plugins' .claude-plugin/marketplace.json

# Plugin entries
jq -e '.plugins[] | .name, .source' .claude-plugin/marketplace.json

Validate Sources

# Check relative paths
for plugin in $(jq -r '.plugins[] | select(.source | type == "string") | .source' .claude-plugin/marketplace.json); do
  if [[ ! -d "$plugin" ]]; then
    echo "Missing: $plugin"
  fi
done

# Check GitHub repos
for repo in $(jq -r '.plugins[] | select(.source.source == "github") | .source.repo' .claude-plugin/marketplace.json); do
  gh repo view "$repo" > /dev/null || echo "Invalid: $repo"
done

Hosting Strategies

Advantages:

  • Version control
  • Issue tracking
  • Collaboration
  • Free hosting
  • Easy sharing

Setup:

  1. Create repository
  2. Add .claude-plugin/marketplace.json
  3. Push
  4. Share: /plugin marketplace add owner/repo

GitLab/Bitbucket

/plugin marketplace add https://gitlab.com/company/plugins.git

Advantages:

  • Self-hosted options
  • Enterprise integration

Local Development

/plugin marketplace add ./my-marketplace

Advantages:

  • Fast iteration
  • No network required
  • Easy testing

CI/CD Integration

GitHub Actions

name: Validate Marketplace

on:
  push:
    paths: ['.claude-plugin/marketplace.json']
  pull_request:
    paths: ['.claude-plugin/marketplace.json']

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate JSON
        run: jq empty .claude-plugin/marketplace.json

      - name: Check fields
        run: jq -e '.name, .owner.name, .plugins' .claude-plugin/marketplace.json

      - name: Check sources
        run: |
          for plugin in $(jq -r '.plugins[] | select(.source | type == "string") | .source' .claude-plugin/marketplace.json); do
            if [[ ! -d "$plugin" ]]; then
              echo "Missing: $plugin"
              exit 1
            fi
          done          

Best Practices

Organization

  • Group related plugins together
  • Use categories for discovery
  • Maintain consistent naming
  • Document plugin purposes

Versioning

  • Use semantic versioning
  • Track versions in entries
  • Maintain CHANGELOG
  • Tag releases in Git

Security

  • Review plugins before adding
  • Verify sources
  • Document requirements
  • Use private repos for sensitive tools

Maintenance

  • Keep versions updated
  • Remove deprecated plugins
  • Test after updates
  • Monitor feedback

Troubleshooting

Marketplace not loading:

  • Verify URL accessible
  • Check .claude-plugin/marketplace.json exists
  • Validate JSON syntax
  • Confirm access for private repos

Plugin installation failures:

  • Verify source URLs accessible
  • Check plugin directories exist
  • Test sources manually
  • Review error messages

Team configuration not working:

  • Verify .claude/settings.json syntax
  • Check marketplace sources accessible
  • Ensure folder trusted
  • Restart Claude Code