How Vendored Plugins Are Handled in the Claude Plugins Marketplace
Vendored plugins in the Claude marketplace are self-contained plugins shipped directly inside the anthropics/claude-plugins-community repository, validated by CI invariants that ensure each plugin directory contains a valid .claude-plugin/plugin.json manifest.
The Claude plugins marketplace supports two distribution models for plugin code. While external plugins fetch code from remote URLs at runtime, vendored plugins live entirely within the marketplace repository itself. This approach guarantees availability without network dependencies and enables tighter quality control through automated validation.
How Vendored Plugins Are Defined in marketplace.json
All marketplace entries are stored in .claude-plugin/marketplace.json. The source field determines how Claude retrieves plugin code:
- External plugins: Use an object with
"source": "url"and remote fetch details - Vendored plugins: Use a string path relative to the repository root
Here is the JSON structure for a vendored plugin entry:
{
"name": "quickdesign",
"description": "Create short video assets with AI-upscaled frames.",
"source": "./quickdesign",
"homepage": "https://github.com/anthropics/claude-plugins-community/tree/main/quickdesign"
}
The string value "./quickdesign" tells the marketplace that this plugin's code is already present in the repository at that path.
CI Validation for Vendored Plugins
The repository enforces strict validation through GitHub Actions. The validate-plugins action runs on every pull request, executing .github/actions/validate-plugins/scripts/11-validate-invariants.sh to verify marketplace integrity.
The I8 Invariant: Vendored Path Exists
The I8 invariant ensures every vendored plugin reference points to a valid, loadable plugin directory. According to the anthropics/claude-plugins-community source code, the script:
- Selects entries where
sourceis a string (vendored plugins) - Strips the leading
./from the path - Verifies that
.claude-plugin/plugin.jsonexists in that directory
Here is the relevant excerpt from 11-validate-invariants.sh (lines 72-84):
# I8 — vendored source path exists
while IFS= read -r entry; do
name="$(jq -r '.name' <<<"$entry")"
p="$(jq -r '.source' <<<"$entry")"
p_clean="${p#./}"
if [[ ! -f "$p_clean/.claude-plugin/plugin.json" ]]; then
flag "I8" "$name: vendored source '$p' has no .claude-plugin/plugin.json" "$name"
fi
done < <(jq -c '.plugins[] | select(.source | type == "string")' -- "$MP")
If this check fails, the workflow flags error I8 and blocks the PR merge. This guarantees that vendored plugins are fully self-contained.
The I9 Invariant: Path Safety
Before the existence check, the I9 invariant validates that vendored paths contain no unsafe characters—specifically shell metacharacters or .. directory traversal sequences (lines 75-78). This prevents injection attacks and path escape vulnerabilities.
How to Add a Vendored Plugin to the Marketplace
Follow these steps to submit a vendored plugin:
- Create the plugin directory with all required files, including
.claude-plugin/plugin.json:
plugins/my-plugin/
├── .claude-plugin/
│ └── plugin.json
├── src/
│ └── …
└── README.md
- Add the marketplace entry to
.claude-plugin/marketplace.jsonwith a stringsourcepath:
{
"name": "my-plugin",
"description": "My local, vendored plugin.",
"source": "./plugins/my-plugin",
"homepage": "https://github.com/anthropics/claude-plugins-community/tree/main/plugins/my-plugin"
}
- Open a pull request. The
validate-pluginsworkflow automatically runs:- I8 validates that
plugins/my-plugin/.claude-plugin/plugin.jsonexists - I9 validates path safety
- Other invariants check additional marketplace rules
- I8 validates that
Once merged, users can install the plugin immediately:
# Install the vendored plugin from the marketplace
/plugin marketplace add quickdesign
# Verify local installation
ls ~/.claude/plugins/quickdesign
Key Files in the Vendored Plugin System
| File | Purpose |
|---|---|
.claude-plugin/marketplace.json |
Master registry; vendored entries use string paths in source |
.github/actions/validate-plugins/scripts/11-validate-invariants.sh |
Implements I8 (existence) and I9 (safety) invariants for vendored plugins |
.github/actions/validate-plugins/README.md |
Documents all 11 invariants and validation procedures |
*/.claude-plugin/plugin.json |
Required manifest in each vendored plugin directory |
Benefits of the Vendored Approach
- Immediate availability: No external network fetch required during installation
- Version consistency: Plugin code is locked to the marketplace repository state
- Auditable source: All code undergoes repository review and CI validation
- Reliability: Eliminates dependency on third-party hosting uptime
Summary
- Vendored plugins use a string path in
marketplace.jsoninstead of a URL object - The I8 invariant enforces that every vendored path contains a valid
.claude-plugin/plugin.json - The I9 invariant blocks unsafe path characters before validation
- Validation runs in
11-validate-invariants.shvia thevalidate-pluginsGitHub Action - Successfully validated plugins become instantly installable via
/plugin marketplace add
Frequently Asked Questions
What happens if a vendored plugin is missing its plugin.json file?
The CI workflow fails with I8 error flagging. The pull request cannot be merged until the missing .claude-plugin/plugin.json is added to the referenced directory. This ensures no broken plugin references enter the marketplace.
Can vendored plugin paths use absolute paths or parent directory references?
No. The I9 invariant explicitly blocks .. traversal sequences and shell metacharacters. Paths must be relative strings like ./plugins/my-plugin that stay within the repository boundary.
How do vendored plugins differ from external plugins in the marketplace?
External plugins specify "source": { "source": "url", "url": "...", "sha": "..." } and fetch code at runtime from remote repositories. Vendored plugins specify "source": "./local/path" with code already present in the marketplace repository, enabling offline installation and stricter quality control.
Where is the vendored plugin validation logic implemented?
The core validation resides in .github/actions/validate-plugins/scripts/11-validate-invariants.sh at lines 72-84 for the I8 existence check and lines 75-78 for the I9 safety check, as implemented in anthropics/claude-plugins-community.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →