From claude-rudder
Use when the user points at a GitHub repo (an agent skill, MCP server, or "Claude plugin"-ish project) and wants to install or register it. Routes between native plugin install, MCP server registration, and adding to the user's third-party marketplace. Triggers on phrases like "install this from GitHub", "add this skill to my setup", "register this as a third-party plugin", "is this available as a Claude plugin".
npx claudepluginhub danielrosehill/claude-code-plugins --plugin claude-rudderThis skill uses the workspace's default tool permissions.
The user has found something on GitHub — a skill, an MCP server, a "Claude plugin" — and wants it integrated into their Claude Code setup **without leaving loose, untracked artefacts on disk**. The goal of this skill is to be a router: figure out what the project actually is, and pick the cleanest install path so the result is reproducible across machines.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
The user has found something on GitHub — a skill, an MCP server, a "Claude plugin" — and wants it integrated into their Claude Code setup without leaving loose, untracked artefacts on disk. The goal of this skill is to be a router: figure out what the project actually is, and pick the cleanest install path so the result is reproducible across machines.
Guiding principle: everything the user installs should be reachable through a server-controlled surface (the Skill-Substrate, when available; otherwise a marketplace they control), so a fresh machine can be reconstituted by reconnecting to the substrate or re-adding marketplaces. Loose skills dropped into ~/.claude/skills/ or one-off MCP entries scattered across configs are the failure mode this skill exists to prevent.
When a repo classifies as claude-plugin or claude-marketplace:
Skill-Substrate-Admin plugin installed and the substrate is reachable), register the repo as a marketplace there. Subscriptions are server-side, so the install is reproducible across all the user's hosts without per-host bookkeeping. This is the default for Daniel.Detect substrate availability by checking for ~/.claude/plugins/Skill-Substrate-Admin/ or by attempting ssh ubuntuvm "docker ps --filter name=skill-substrate --format '{{.Names}}'" (returns non-empty on substrate hosts). Skip the substrate path silently if neither indicator is present.
This skill assumes the user has a dedicated third-party marketplace repo: a marketplace whose entries are wrappers around upstream projects authored by other people, kept distinct from the user's own original plugins.
Read config from:
${CLAUDE_USER_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/claude-plugins}/claude-rudder/config.json
Expected shape:
{
"third_party_marketplace": {
"repo": "<owner>/<repo-name>",
"local_path": "<absolute path to local clone>"
},
"primary_marketplace": {
"repo": "<owner>/<repo-name>",
"local_path": "<absolute path to local clone>"
}
}
If third_party_marketplace is missing:
claude plugins marketplace add)..claude-plugin/marketplace.json with empty plugins: [], a README explaining "this marketplace contains wrappers around third-party Claude Code skills and MCP servers", MIT license. Push to GitHub. Suggested name: Claude-Third-Party-Plugins.config.json. Create the file (and its parent dir) if missing.Never proceed past this step without a populated third_party_marketplace.repo.
The user will give you a GitHub URL or owner/repo. Fetch enough to classify:
gh repo view <owner>/<repo> --json name,description,defaultBranchRef,url
gh api repos/<owner>/<repo>/contents -q '.[].name'
Then pull the files that disambiguate:
.claude-plugin/plugin.json — it's a Claude Code plugin.claude-plugin/marketplace.json — it's a marketplace (multiple plugins inside)SKILL.md at root, or skills/*/SKILL.md without a plugin.json — loose skill(s)package.json with a bin field, or README mentioning npx, mcpServers, claude_desktop_config.json — MCP serverpyproject.toml / setup.py exposing a CLI that speaks MCP — Python MCP serverUse gh api repos/<owner>/<repo>/contents/<path> or gh api repos/<owner>/<repo>/readme to read files without cloning.
Record what you found in a short summary you'll show the user before acting.
Pick exactly one of:
| Class | Signal |
|---|---|
claude-plugin | Has .claude-plugin/plugin.json |
claude-marketplace | Has .claude-plugin/marketplace.json |
loose-skill | Has SKILL.md or skills/*/SKILL.md but no plugin.json |
mcp-server | NPX/Python package documented for MCP, no Claude plugin manifest |
other | None of the above (CLI tool, library, demo) |
If the repo is mixed (e.g. an MCP server that also ships an example skill), prefer the most installable surface — usually mcp-server — and mention the secondary surface to the user.
Show the user the classification and the proposed action, then act on confirmation.
claude-pluginBest case — it's already structured for native install.
Check whether the repo is already known to any of the user's surfaces:
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 skills marketplace list" — match on source_repo.claude plugins marketplace list, then for each, check its marketplace.json for an entry whose source.repo matches.If found on the substrate as marketplace M, the install command is:
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills install <M>:<plugin-name>"
(Or call the Skill-Substrate-Admin:admin-subscribe skill.) Subscription is server-side; no further action needed.
If found in a local marketplace M (legacy / external host), the install command is:
claude plugins install <plugin-name>@<M>
Show the command. Do not auto-install at user scope. Mention --scope project for ad-hoc use.
If not found anywhere, offer routes in precedence order:
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills marketplace add <owner>-<repo> --repo https://github.com/<owner>/<repo>.git \
--visibility private --authorship third_party"
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills marketplace ingest <owner>-<repo>"
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills install <owner>-<repo>:<plugin-name>"
Use --authorship third_party for upstream-by-others (engages the trust gate for review-on-update). Use --authorship user only if the upstream is also Daniel's. Prefer calling the Skill-Substrate-Admin:admin-marketplace-add and admin-marketplace-ingest and admin-subscribe skills directly when available.plugin.json as the source of truth.claude plugins install <owner>/<repo>
Warn that this is the loose-install case the skill is meant to avoid. Only suggest if the user is testing.claude-marketplaceThe repo is itself a marketplace.
Substrate route (preferred when available):
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills marketplace add <owner>-<repo> --repo https://github.com/<owner>/<repo>.git \
--visibility private --authorship third_party"
ssh ubuntuvm "docker exec skill-substrate-skills-ingester-1 \
skills marketplace ingest <owner>-<repo>"
Then skills marketplace show <owner>-<repo> to list its plugins, and skills install <owner>-<repo>:<plugin-name> for the ones the user wants. Prefer the corresponding admin skills when available.
Local-marketplace route (fallback for non-substrate hosts):
claude plugins marketplace add <owner>/<repo>
List its plugins and ask the user which one(s) to install. Same scoping caveat as 3a — show the command, don't auto-install at user scope.
mcp-serverDelegate to claude-rudder:add-mcp-server — it already knows how to generate a valid claude mcp add invocation. Pass through the repo URL and what you learned (npx invocation, env vars from the README, transport type).
If the user explicitly wants the MCP server also trackable through their marketplace setup (so a fresh machine reconstitutes it), additionally register a stub entry in the third-party marketplace whose description documents the MCP add command. This is a workaround until Claude Code marketplaces natively carry MCP entries — be honest about that in the entry's description.
loose-skillThis is the case the user described. The upstream repo has skill content but isn't packaged as a Claude Code plugin. Wrap it.
Ask the user which wrapping strategy:
Fork + thin manifest (preferred for active upstreams).
gh repo fork <owner>/<repo> --clone --remote.claude-plugin/plugin.json at the root naming it <upstream-name>-wrapped (or similar — confirm name with user). Keep the upstream's existing skills/, commands/, agents/ layout if it already matches the plugin convention; if not, reshape minimally and document what changed.claude-plugin-wrap branch so main stays mergeable from upstream.origin is the user's account; upstream points at the original — record that so updates can be pulled.Per-skill wrapper repo (for tiny single-skill cases).
~/repos/github/my-repos/Third-Party-<Name>-Plugin/ with a fresh .claude-plugin/plugin.json and a skills/<name>/ that git subtree or vendors the upstream skill content..upstream file at repo root recording repo, commit, path so a companion update flow can refresh later.Default to (1). Only fall back to (2) if forking the upstream is awkward (monorepo, license issues, the skill is one file in a giant repo).
After wrapping, proceed to Step 4 to register the wrapper in the third-party marketplace.
otherNot installable as a Claude Code surface. Tell the user what the repo actually is and stop. Don't try to force-fit it.
For every path that produced a Claude-installable plugin (3a-register, 3d-wrap), append an entry to <third_party_marketplace.local_path>/.claude-plugin/marketplace.json:
{
"name": "<plugin-name>",
"source": {
"source": "github",
"repo": "<owner-of-fork-or-wrapper>/<repo>"
},
"description": "<one line — note 'wrapper around <upstream owner/repo>' if applicable>",
"version": "<version from plugin.json>",
"author": {
"name": "<upstream author if known, else Daniel Rosehill>"
},
"license": "<upstream license>",
"tags": ["third-party", "<topical tag>"]
}
Also append to the marketplace's README under a "Third-Party Wrappers" section noting the upstream link and the wrapping strategy used.
Validate JSON, commit, push:
cd <third_party_marketplace.local_path>
python3 -c "import json; json.load(open('.claude-plugin/marketplace.json'))"
git add -A
git commit -m "Add <plugin-name> (wraps <upstream owner/repo>)"
git push
Refresh the local marketplace cache so the new entry is discoverable:
claude plugins marketplace update <owner>
Show the user:
rejected[] entries.claude plugins install <plugin-name>@<marketplace> command they can run if/when they want it active. Don't run it for them unless they explicitly ask.upstream, or .upstream file path) so a future update flow can pull changes.Wrapped third-party skills will eventually drift from upstream. This skill does not implement the update sweep — that's a future companion skill (update-third-party-skills). What this skill must do is leave enough metadata that the update sweep is mechanical:
git remote -v shows upstream. The wrapping branch is named claude-plugin-wrap so main can fast-forward from upstream..upstream file at repo root, format:
repo=<owner>/<repo>
commit=<sha at wrap time>
path=<path within upstream that was vendored>
strategy=<subtree|vendor>
Don't skip these — without them, the third-party marketplace becomes its own untrackable mess, defeating the purpose.