[FEATURE] Support `ref` and `path` parameters in plugin source schema
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Currently, the plugin source schema in marketplace.json does not support ref (git reference) or path (subdirectory) parameters for individual plugin sources. This creates significant friction for plugin development workflows and forces developers into suboptimal repository structures.
Current Limitations:
- No Version Control for Individual Plugins
- Cannot pin plugins to specific git tags, branches, or commits
- Must version the entire marketplace.json instead of individual plugins
- Difficult to test different plugin versions without modifying marketplace configuration
- No Subdirectory Support in Plugin Sources
- Entire repository is cloned for plugins, even if plugin lives in a subdirectory
- Forces either monorepo approach or moving plugin to repository root
- Creates namespace conflicts during local development
- Development Environment Pollution
- When developing a plugin within its repo and launching Claude Code for development work, the plugin's
.mcp.jsonis automatically loaded into the Claude Code session - Development files (tests, build scripts, documentation) mix with plugin distribution files
- No clean separation between "what gets distributed" and "what's for development"
- Unclear whether Claude Code caches entire repo or just plugin contents
- Cumbersome Current Workarounds
- Component configuration fields (
commands,agents,skills, etc.) are verbose and repetitive - Must manually specify every component type
- Easy to miss a component type when configuring
- Doesn't solve development environment pollution or version control issues
Proposed Solution
Add ref and path parameters to the plugin source schema, matching the existing syntax already used in strictKnownMarketplaces for marketplace sources.
Proposed Syntax:
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "my-plugins",
"owner": {
"name": "Developer"
},
"plugins": [
{
"name": "terraform-core",
"source": {
"source": "url",
"url": "https://gitea.example.com/org/terraform-plugin.git",
"ref": "v1.0.0", // NEW: Branch, tag, or commit SHA
"path": "plugin" // NEW: Subdirectory within repository
},
"description": "Terraform standards plugin",
"version": "1.0.0"
},
{
"name": "terraform-aws",
"source": {
"source": "github",
"repo": "org/terraform-aws-plugin",
"ref": "develop", // NEW: Test pre-release versions
"path": "plugin" // NEW: Plugin in subdirectory
},
"description": "AWS-specific Terraform plugin"
}
]
}
Field Specifications:
ref(optional)- Type:
string - Valid values: git branch name, tag, or commit SHA
- Examples:
"main","v1.0.0","abc123def456" - Default: repository's default branch if not specified
path(optional)- Type:
string - Valid values: relative path to subdirectory within repository
- Examples:
"plugin","packages/claude-plugin","tools/plugins/formatter" - Default: repository root if not specified
Key Benefits:
- Clean Development Environment - Plugin subdirectory keeps development files separate from distribution files, preventing
.mcp.jsonconflicts - Version Control - Pin plugins to specific git tags, branches, or commits for stability and testing
- Simplified Configuration - Concise syntax instead of verbose component field specifications
- API Consistency - Matches existing
strictKnownMarketplacessyntax (these parameters already exist for marketplace sources) - Cache Optimization - Could cache only the subdirectory contents instead of entire repository
Implementation Behavior:
When path is specified:
- Clone the git repository
- Navigate to the specified subdirectory
- Look for
.claude-plugin/in that subdirectory (or usestrict: false) - Cache only the subdirectory contents (optimization)
When ref is specified:
- Clone/checkout the specified git reference
- Use that version of the plugin
- Track the
reffor updates
Alternative Solutions
Workaround 1: Component Configuration Fields (Current)
{
"source": {
"source": "github",
"repo": "org/plugin-repo"
},
"strict": false,
"commands": ["./plugin/commands/"],
"agents": ["./plugin/agents/"],
"skills": ["./plugin/skills/"],
"mcpServers": "./plugin/.mcp.json"
}
Limitations:
- Verbose and error-prone (must list every component type)
- Entire repository still cloned
- Still causes development environment pollution (
.mcp.jsonat any level is loaded) - No version control support
- Easy to miss a component type
Workaround 2: Monorepo Approach
marketplace-repo/
└── plugins/
├── plugin-1/
├── plugin-2/
└── plugin-3/
Limitations:
- Forces all plugins into one repository
- Complex version management (all-or-nothing)
- Can't have per-plugin development workflows
- Doesn't solve development environment pollution
Workaround 3: Plugin at Repository Root
plugin-repo/
├── .claude-plugin/
├── commands/
├── agents/
└── README.md
Limitations:
- Entire repo is just the plugin
- Can't have substantial development infrastructure
- No space for tests, build tools, documentation
- Inflexible structure
Priority
High - Significant impact on productivity
Feature Category
Configuration and settings
Use Case Example
Real-World Scenario: Multi-Cloud Infrastructure Plugin Ecosystem
- Setup: I'm building a Terraform plugin ecosystem with separate plugins for AWS, GCP, Azure, and a core standards plugin. Each needs its own repository with:
- Plugin files in a
plugin/subdirectory - Development infrastructure (tests, build scripts, documentation) in repo root
- Different release cycles and versions
- Current Problem:
- When I launch Claude Code in my
terraform-aws-pluginrepo to develop/test the plugin, Claude Code automatically loads the plugin's.mcp.jsonfile - This pollutes my development session with MCP servers meant for plugin users, not plugin developers
- I have to either:
- Move the plugin to repo root (limiting dev infrastructure)
- Use verbose component field configuration (error-prone)
- Accept the pollution (confusing development experience)
- With This Feature:
Marketplace configuration:
{
"plugins": [
{
"name": "terraform-core",
"source": {
"url": "https://gitea.internal.company.com/iac/terraform-core.git",
"ref": "v1.2.0",
"path": "plugin"
}
},
{
"name": "terraform-aws",
"source": {
"url": "https://gitea.internal.company.com/iac/terraform-aws.git",
"ref": "v2.1.3",
"path": "plugin"
}
},
{
"name": "terraform-gcp-beta",
"source": {
"url": "https://gitea.internal.company.com/iac/terraform-gcp.git",
"ref": "develop",
"path": "plugin"
}
}
]
}
Repository structure:
terraform-aws-plugin/
├── plugin/ # Clean plugin code - only this distributed
│ ├── .claude-plugin/
│ ├── commands/
│ ├── agents/
│ ├── skills/
│ └── .mcp.json # Only loaded when plugin is installed
├── src/ # Development utilities
├── tests/ # Test infrastructure
├── docs/ # Documentation
└── README.md
- Benefits:
- Clean development environment: plugin's
.mcp.jsondoesn't interfere with dev sessions - Version control: production uses
v2.1.3, testing usesdevelopbranch - Simple configuration: just
pathparameter instead of listing all component types - Optimized: only
plugin/subdirectory cached, not entire repo - Self-hosted: works with our internal Gitea server
- Time Saved:
- No more manually specifying all component paths
- No more fighting with MCP server conflicts during development
- Easy testing of pre-release versions alongside stable
- Quick rollback by changing
refparameter
Additional Context
API Consistency:
The ref and path parameters already exist for marketplace sources in strictKnownMarketplaces. This feature request simply extends the same syntax to plugin sources.
From Settings Documentation:
{
"strictKnownMarketplaces": [
{
"source": "github",
"repo": "acme-corp/plugins",
"ref": "main",
"path": "marketplace"
},
{
"source": "git",
"url": "https://gitlab.com/plugins.git",
"ref": "v3.1",
"path": "approved"
}
]
}
API Parity Comparison:
| Feature | Marketplace Sources | Plugin Sources | Status |
|---------|-------------------|----------------|--------|
| source | ✅ Supported | ✅ Supported | Parity |
| repo / url | ✅ Supported | ✅ Supported | Parity |
| ref | ✅ Supported | ❌ Missing | Gap |
| path | ✅ Supported | ❌ Missing | Gap |
Related Issues:
- #10238 - Subdirectory support for skills (related but different scope)
- #11243, #11278 - Path resolution bugs for local marketplaces
Expected Outcome:
After implementing this feature:
- ✅ Clean separation between plugin code and development infrastructure
- ✅ No development environment pollution (
.mcp.jsonconflicts eliminated) - ✅ Version control for individual plugins
- ✅ Flexible repository architecture
- ✅ Consistency with existing marketplace source API
- ✅ Self-hosted git server support (Gitea, GitLab, Bitbucket)
- ✅ Optimized caching behavior
- ✅ Simplified marketplace.json configuration
Showing cached comments. Read the full discussion on GitHub ↗
6 Comments
Please add support for this. I think this is essential for implementing custom marketplaces with non-trivial size.
Please add support for this
Hey!
This would be a big deal for us. We run an internal Claude Code plugin marketplace that includes both our own plugins and curated references to verified external ones. Currently, this issue blocks us from referencing specific plugins within marketplace repositories like https://github.com/anthropics/claude-plugins-official — so resolving it would directly unblock our workflow.
Please add support for this. It would simplify pretty much the management of curated marketplace.json.
When Claude Code clones a plugin from this source, it looks for
.claude-plugin/plugin.jsonat the repository root. If the plugin lives in a subdirectory (e.g.,plugins/deploy-on-aws/), it is never found. The debug log confirms:"Plugin deploy-on-aws has no entry.skills defined".This is already causing real issues in the official marketplace:
plugin/, not at the repo rootawslabs/agent-pluginsmonorepo plugins individually, but each entry pointed to the same repo URL with no way to specify subdirectoriesThe marketplace-level source types (
github,git) instrictKnownMarketplaces/extraKnownMarketplacessettings already supportpathandsparsePaths:But the plugin-level source types within
marketplace.jsondo not. This inconsistency means plugin authors and marketplace curators must resort to workarounds for any monorepo-hosted plugin.Proposed Solution
Add an optional
pathfield to thegithubandurlplugin source objects inmarketplace.json:GitHub source:
Git URL source:
Expected behavior when
pathis specified on a plugin source:ref/shaif present)<clone_dir>/<path>instead of<clone_dir>.claude-plugin/plugin.jsoninside that resolved directorySchema change — add
path: z.string().optional()to both object variants in the plugin source Zod union:Alternative Solutions
| Workaround | Limitation |
|---|---|
| Use the monorepo as a full marketplace (
/plugin marketplace add) | Forces users to adopt the entire marketplace; doesn't work when curating plugins from multiple sources into a single marketplace || Create standalone repos per plugin | Repository sprawl; breaks development workflows; requires maintaining mirrors |
| Use git submodules in the marketplace repo | Adds complexity; fragile sync; poor DX |
| Verbose component fields (
commands,skills,agents, etc.) with relative paths | Error-prone; the full repo is still cloned; doesn't solve.claude-plugin/plugin.jsondiscovery |fix15439.patch
Yes please, need this.