From marketplace-plugin-creator
Convert a skill, plugin, or project into a GitHub-hosted Cowork marketplace plugin that installs correctly from the "Add marketplace" dialog. Use this skill whenever the user wants to publish a skill to a marketplace, create a marketplace repo, fix a plugin that shows "no skills or agents", package a skill for distribution via GitHub, or troubleshoot plugin installation issues. Also trigger when the user says things like "make this a marketplace", "publish this skill", "why doesn't my plugin show skills", "set up my repo as a plugin", or "fix my marketplace plugin".
How this skill is triggered — by the user, by Claude, or both
Slash command
/marketplace-plugin-creator:marketplace-plugin-creatorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Turn any skill or set of skills into a GitHub-hosted Cowork marketplace plugin that
Turn any skill or set of skills into a GitHub-hosted Cowork marketplace plugin that installs and shows up correctly in the Cowork desktop app.
When a user enters a GitHub owner/repo in the "Add marketplace" dialog, Cowork:
.claude-plugin/marketplace.json at the repo root — fails if missingplugins array to find individual plugins.claude-plugin/plugin.json for metadataskills/{skill-name}/SKILL.md directoriescommands/{command-name}.md files.remote-plugins/ or .local-plugins/cache/The cached version is what Cowork actually reads. After pushing changes to GitHub, the user must re-sync or uninstall/reinstall for the cache to update.
.claude-plugin/marketplace.jsonThis is the marketplace manifest at the repo root. Without it, the "Add marketplace" dialog will show: "This repository isn't a marketplace — no manifest found."
{
"\$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "marketplace-name",
"description": "What this marketplace offers",
"owner": {
"name": "github-username-or-org"
},
"plugins": [
{
"name": "plugin-name",
"description": "What this plugin does",
"source": "./",
"category": "productivity",
"keywords": ["keyword1", "keyword2"]
}
]
}
For a single-plugin marketplace (most common case), set "source": "./" to point
at the repo root itself.
For a multi-plugin marketplace, each plugin lives in its own subdirectory:
{
"plugins": [
{ "name": "plugin-a", "source": "./plugin-a", "description": "..." },
{ "name": "plugin-b", "source": "./plugin-b", "description": "..." }
]
}
.claude-plugin/plugin.jsonThis is the plugin manifest — metadata about the individual plugin.
{
"name": "plugin-name",
"version": "1.0.0",
"description": "What this plugin does in detail",
"author": {
"name": "Author Name"
}
}
For single-plugin marketplaces, this goes alongside marketplace.json in the same
.claude-plugin/ directory. For multi-plugin marketplaces, each plugin subdirectory
has its own .claude-plugin/plugin.json.
Skills must live at skills/{skill-name}/SKILL.md — this is the directory structure
Cowork scans to discover skills. A SKILL.md at the repo root will NOT be discovered.
repo-root/
├── .claude-plugin/
│ ├── marketplace.json
│ └── plugin.json
├── skills/
│ └── my-skill-name/
│ ├── SKILL.md
│ ├── scripts/ (optional)
│ └── references/ (optional)
├── commands/ (optional)
│ └── do-thing.md
└── README.md
Every SKILL.md must have YAML frontmatter with name and description:
---
name: skill-identifier
description: >
What this skill does and when to trigger it. Include specific phrases
users might say so Claude knows when to activate this skill.
---
# Skill Title
Instructions for Claude go here...
Commands go in commands/{command-name}.md with frontmatter:
---
description: What this command does
argument-hint: optional hint for arguments
---
Instructions for Claude when this command is invoked...
Commands show up separately from skills in the plugin UI.
.claude-plugin/marketplace.json with the schema above.claude-plugin/plugin.json with plugin metadataskills/{skill-name}/ — the directory name becomes the
skill identifier. Move SKILL.md, scripts/, references/, and any other supporting
files into this subdirectoryskills/.skill ZIP files if present — those are a different packaging format
and will confuse thingsCause: Missing .claude-plugin/marketplace.json at repo root.
Fix: Create the file with the marketplace schema.
Cause: One of these issues (check in order):
skills/{name}/SKILL.mdskills/ directory entirelyname and description in YAML front matterCause: Cowork caches plugin content per-session. Changes to the repo only take effect after syncing the marketplace and starting a new Cowork session.
Cause: The local cache under .remote-plugins/ or .local-plugins/cache/ is stale.
Fix: Sync the marketplace in plugin settings, or uninstall and reinstall the plugin.
Here is the exact structure of a working single-skill marketplace plugin:
posthaste-skill/ (GitHub repo root)
├── .claude-plugin/
│ ├── marketplace.json (marketplace manifest)
│ └── plugin.json (plugin manifest)
├── skills/
│ └── posthaste-file-management/ (skill directory)
│ ├── SKILL.md (skill instructions + frontmatter)
│ ├── scripts/
│ │ ├── create_project.py
│ │ ├── list_projects.py
│ │ ├── new_template.py
│ │ └── read_template.py
│ └── references/
│ └── template-format.md
├── .gitignore
└── README.md
And its marketplace.json:
{
"\$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "posthaste-skill",
"description": "Manage PostHaste project templates and file structures",
"owner": { "name": "alnutile" },
"plugins": [
{
"name": "posthaste-skill",
"description": "Manage PostHaste project templates and file structures.",
"source": "./",
"category": "productivity",
"keywords": ["posthaste", "film", "project-management"]
}
]
}
name field: kebab-case, should match directory name.md files, filename becomes the command nameCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub alnutile/marketplace-plugin-creator --plugin marketplace-plugin-creator