marketplace-sync is a GitHub Action that syncs Claude Code plugins from upstream marketplaces, allowing you to gate plugin changes on a pull request.
Add a workflow like .github/workflows/marketplace-sync.yml in the repo you want to use as your curated marketplace:
name: Sync plugins
on:
schedule:
- cron: '0 8 * * 1' # 8AM every Monday
workflow_dispatch: # Manual syncing
permissions:
contents: write
pull-requests: write
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Sync plugins from upstream marketplaces
- uses: argemma-oss/marketplace-sync@main # You likely want to pin to a commit or release here!
with:
repo: https://github.com/anthropics/claude-plugins-official
plugins: skill-creator
- uses: argemma-oss/marketplace-sync@main
with:
repo: https://github.com/coreyhaines31/marketingskills
plugins: marketing-skills
# Generate marketplace.json and README after all syncs
- uses: argemma-oss/marketplace-sync/generate@main
id: generate
with:
marketplace-name: my-curated-marketplace
readme-path: README.md
readme-table-prefix: |
> README.md generated by argemma-oss/marketplace-sync/generate
# Create a PR if anything changed
- uses: peter-evans/create-pull-request@v7
if: steps.generate.outputs.changed == 'true'
with:
title: "sync: update plugins from upstream"
branch: marketplace-sync/update
commit-message: "[marketplace-sync] Update plugins from upstream"After the action runs, you can add your repo to Claude through the /plugin command.
If you want marketplace-sync to open PRs in your curated marketplace repo, go to Settings → Actions → General → Workflow permissions and:
- Select Read and write permissions
- Check Allow GitHub Actions to create and approve pull requests to allow the workflow to open PRs.
Syncs plugins from a single upstream marketplace. Call once per upstream marketplace.
| Input | Required | Default | Description |
|---|---|---|---|
repo |
yes | GitHub HTTPS URL of the upstream marketplace repo | |
branch |
no | main |
Branch to sync from |
plugins |
yes | Comma-separated list of plugin names to sync (must match names in upstream marketplace.json) |
|
plugins-dir |
no | plugins |
Directory where plugin directories are written |
Each synced plugin gets a sync-metadata field added to its plugin.json with the source repo URL and commit SHA. Plugins that don't have a plugin.json get one synthesized from the marketplace entry.
The entire plugin source directory is copied (excluding .git), matching how Claude Code itself caches plugins. This ensures relative-path references between skills, tools, and other plugin files are preserved.
If you want to reduce diff noise — for example, removing test files from an upstream plugin or stripping skills you don't need — add workflow steps after marketplace-sync to delete unwanted paths before the generate step:
- run: rm -rf plugins/my-plugin/tests plugins/my-plugin/docsNote that if your repo contains additional plugins that aren't synchronized from a repo (e.g. your own custom plugins), they will remain untouched.
Generates marketplace.json and optionally a README from the synced plugins on disk. Run once after all sync steps.
| Input | Required | Default | Description |
|---|---|---|---|
plugins-dir |
no | plugins |
Directory containing synced plugins |
marketplace-name |
no | marketplace-sync |
Name for the marketplace |
marketplace-description |
no | (default) | Description in marketplace metadata |
owner-name |
no | marketplace-sync |
Owner name for the marketplace |
readme-path |
no | (none) | Output path for README. No README generated if unset |
readme-table-prefix |
no | (none) | Markdown text placed before the plugin table |
| Output | Description |
|---|---|
changed |
true or false — whether any files were modified |
-
Only plugins with relative-path sources (e.g.
"source": "./plugins/foo") are supported. Remote plugin sources likegithub,url, andnpmare not yet supported. -
Renaming plugins is not supported. If you sync multiple upstream marketplaces with the same plugin name into the same
plugins-dir, they will conflict.
This idea was inspired by andrew-d's setup, though our implementations differ.