feat: split MCP servers into their own plugins, add per-target restrictions #3

Merged
rootiest merged 1 commits from feat-split-mcp-plugins-and-targets into main 2026-08-25 00:32:30 +00:00
Owner

Why

Two problems with the current core-essentials plugin:

  1. It bundled the GitHub and Gitea MCP servers together, forcing anyone
    who wants one to install both.
  2. It also bundles delegate-agy, a skill whose entire purpose is Claude
    Code shelling out to agy — which makes no sense installed inside
    agy, but the generator shipped it there anyway since nothing could
    express "this piece is for one tool only."

What

  • Split github-mcp and gitea-mcp out into their own plugins — install
    either, both, or neither.
  • Added an optional targets field, honored at two levels:
    • plugin.json: restricts the whole plugin (skills, hooks, mcp, rules,
      commands, agents) to specific targets.
    • a skill's own SKILL.md frontmatter: restricts just that skill,
      independent of its sibling skills, narrowed to (never wider than) its
      plugin's own targets.
    • Omitting it means "every target" — fully backward compatible with
      every existing plugin/skill.
    • A plugin left with no content at all for a given target is skipped
      entirely for that target (no empty output dir, no marketplace entry).
  • Applied it to the actual case: delegate-agy is now targets: [claude-code] and no longer appears anywhere under dist/agy — verified
    directly (find dist/agy -iname "*delegate*" returns nothing), including
    excluded from the agy build of the rootiest-ai-all bundle while still
    present in the Claude Code one.

Manual Verification Checklist

  • python3 scripts/generate_plugins.py --check passes
  • dist/agy/ has no core-essentials/ directory at all (it has zero agy content now); dist/claude-code/core-essentials/ still has delegate-agy
  • github-mcp/gitea-mcp each install independently via /plugin install github-mcp@rootiest-ai and python3 scripts/install_agy.py github-mcp
  • agy plugin validate dist/agy/<name> still passes for every agy plugin
  • A plugin/skill with no targets field behaves exactly as before (ships to both targets)
## Why Two problems with the current `core-essentials` plugin: 1. It bundled the GitHub and Gitea MCP servers together, forcing anyone who wants one to install both. 2. It also bundles `delegate-agy`, a skill whose entire purpose is Claude Code shelling out to `agy` — which makes no sense installed *inside* agy, but the generator shipped it there anyway since nothing could express "this piece is for one tool only." ## What - Split `github-mcp` and `gitea-mcp` out into their own plugins — install either, both, or neither. - Added an optional `targets` field, honored at two levels: - `plugin.json`: restricts the whole plugin (skills, hooks, mcp, rules, commands, agents) to specific targets. - a skill's own `SKILL.md` frontmatter: restricts just that skill, independent of its sibling skills, narrowed to (never wider than) its plugin's own targets. - Omitting it means "every target" — fully backward compatible with every existing plugin/skill. - A plugin left with no content at all for a given target is skipped entirely for that target (no empty output dir, no marketplace entry). - Applied it to the actual case: `delegate-agy` is now `targets: [claude-code]` and no longer appears anywhere under `dist/agy` — verified directly (`find dist/agy -iname "*delegate*"` returns nothing), including excluded from the agy build of the `rootiest-ai-all` bundle while still present in the Claude Code one. ## Manual Verification Checklist - [x] `python3 scripts/generate_plugins.py --check` passes - [x] `dist/agy/` has no `core-essentials/` directory at all (it has zero agy content now); `dist/claude-code/core-essentials/` still has `delegate-agy` - [x] `github-mcp`/`gitea-mcp` each install independently via `/plugin install github-mcp@rootiest-ai` and `python3 scripts/install_agy.py github-mcp` - [x] `agy plugin validate dist/agy/<name>` still passes for every agy plugin - [x] A plugin/skill with no `targets` field behaves exactly as before (ships to both targets)
rootiest added 1 commit 2026-08-25 00:28:52 +00:00
feat: split MCP servers into their own plugins, add per-target restrictions
Generate plugin manifests / generate (pull_request) Skipped
Generate plugin manifests / validate (pull_request) Successful in 18s
c6f40bcf6b
Split the GitHub/Gitea MCP servers out of core-essentials into their own
github-mcp/gitea-mcp plugins, so a user can install either, both, or
neither independently instead of always getting both bundled together.

Add an optional "targets" field, honored at both levels:
  - plugin.json: restricts the whole plugin (including any hooks/mcp/
    rules/commands/agents it bundles) to specific targets.
  - a skill's own SKILL.md frontmatter: restricts just that one skill,
    independent of its plugin's sibling skills (narrowed to, never wider
    than, the plugin's own targets).

Omitting it (the default everywhere) means every target in manifest.yaml,
so this is fully backward compatible. A plugin left with no content at
all for a given target is now skipped entirely for that target rather
than emitting an empty output directory / marketplace entry.

Applies this to the actual motivating case: delegate-agy only makes sense
run from Claude Code (it shells out to `agy`), so it's now marked
targets: [claude-code] and no longer ships into dist/agy at all — it was
previously being installed into agy for no reason.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YVWWAnvR5TDQzmfY3RXG9
rootiest merged commit 13dcfca27c into main 2026-08-25 00:32:30 +00:00
rootiest deleted branch feat-split-mcp-plugins-and-targets 2026-08-25 00:32:30 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rootiest/rootiest-ai#3