# Ecosystem: Pipeline × Marketplace Plugins × Dev-Toolkit MCP

This pipeline is not one repo. It's three, each owned separately, each versioned
separately, wired together at install time and at run time:

| Repo | What it owns | Ships as |
|---|---|---|
| **`multi-agent-pipeline`** (this repo) | Orchestration: the 8-phase flow, the 53 slash commands, quality gates, review/triage, cross-CLI parity | npm package (`@mmerterden/multi-agent-pipeline`), installs itself onto Claude Code / Copilot CLI / Codex CLI |
| **`multi-agent-plugins`** | Stack knowledge: per-platform component/lifecycle skills (iOS, Android, Frontend, Backend) + shared knowledge | Claude Code marketplace, 5 independently-versioned plugins |
| **`multi-agent-toolkit-mcp`** | The pipeline's hands on devices and browsers: 80 MCP tools across 6 categories (simulator/emulator control, accessibility audit, store compliance, web automation, Figma-vs-mock design audit, an agent-DSL batch runner) | npm package, registered as a standard stdio MCP server on every host |

None of the three depends on the others at the code level. They compose through two
narrow contracts: the **Skill tool** (pipeline → plugin, at Phase 3) and the **MCP
protocol** (pipeline skills → multi-agent-toolkit, at Phase 5 / design-check / store-ready).
Either can be swapped or removed without touching the other two's source.

```mermaid
graph LR
    subgraph PIPE ["multi-agent-pipeline (orchestrator)"]
        direction TB
        PHASES["8 phases · 53 commands"]
        GATES["deterministic gates + review triage"]
    end

    subgraph PLUG ["multi-agent-plugins (stack knowledge)"]
        direction TB
        IOSP["ai-ios-toolkit"]
        ANDP["ai-android-toolkit"]
        FEP["ai-frontend-toolkit"]
        BEP["ai-backend-toolkit"]
        COMP["ai-common-toolkit"]
        ANAP["ai-analyst-toolkit"]
    end

    subgraph DTK ["multi-agent-toolkit-mcp (device/browser hands)"]
        direction TB
        DEV["Device Control (58)"]
        A11Y["Accessibility Audit (2)"]
        STORE["Store Compliance (5)"]
        WEB["Web Automation (8)"]
        DESIGN["Design Audit (6)"]
        AGENTDSL["Agent DSL (1)"]
    end

    PHASES -->|"Phase 3: Skill tool<br/>taskType===component"| PLUG
    PHASES -->|"Phase 5 / design-check /<br/>store-ready: MCP tool calls"| DTK
    GATES -.->|"Phase 4 Security Auditor"| STORE

    style PIPE fill:#ffd,stroke:#333
    style PLUG fill:#dfd,stroke:#333
    style DTK fill:#dff,stroke:#333
```

---

## 1. Authoring flow: one source of truth, five sync targets

`~/.claude/` on the maintainer's machine is authoritative. Everything else is a
derived, synced, or independently-shipped artifact. `/multi-agent:sync` is the one
command that walks all five targets in order, detects which are stale, and updates
only those:

```mermaid
graph TD
    CC["Claude Code<br/>~/.claude/commands/multi-agent/<br/>(source of truth)"]

    CC -->|"Step 2: copy + reformat<br/>53 sub-command skills"| COP["Copilot CLI<br/>~/.copilot/skills/"]
    CC -->|"Step 2b: transform<br/>(install.js --codex)"| COD["Codex CLI<br/>1 router skill + 53 refs<br/>+ 8 agent TOML"]
    CC -->|"Step 3: genericize<br/>(strip personal data)"| REPO["multi-agent-pipeline repo<br/>pipeline/"]
    CC -->|"Step 4: version + feature sync"| WEB["Website<br/>projects.ts / i18n.tsx"]

    REPO -->|"Step 3c: build-stack-plugins.mjs<br/>rebuilds knowledge/ from<br/>shared/external"| PLUGREPO["multi-agent-plugins repo<br/>(5 stack plugins)"]

    DTK2["multi-agent-toolkit-mcp repo<br/>(own codebase, own gates,<br/>NOT generated from Claude)"]
    SYNC3D["Step 3d: detect movement →<br/>gate → commit → publish"]
    CC -.->|"sync only SHIPS this,<br/>never authors it"| SYNC3D
    SYNC3D -.-> DTK2

    REPO -->|"npm publish"| NPM["npm registry (public)"]
    WEB -->|"git push → auto-deploy"| VERCEL["Vercel"]
    PLUGREPO -->|"git push"| MKT["Claude Code marketplace"]
    DTK2 -->|"npm publish"| NPM2["npm registry<br/>(public)"]

    style CC fill:#f9f,stroke:#333
    style DTK2 fill:#dff,stroke:#333,stroke-dasharray: 5 5
```

**Why `multi-agent-toolkit-mcp` is drawn differently.** The other four targets are *derived*
from the Claude Code source - sync writes their content. `multi-agent-toolkit-mcp` is not:
it's a separate codebase developed on its own schedule. Sync's Step 3d only
*detects* whether it moved (dirty tree, unpushed commits, untagged version), runs
**its own** gate suite, and ships it - commit, tag, `npm publish`. If the pipeline
needs a tool that toolkit doesn't have yet, that's a two-repo change: add the tool
in `multi-agent-toolkit-mcp`, ship it, then bump the minimum version pin back in
`cross-cli-contract.md` (see section 4).

**Also not generated: the plugins' own authored skills.** `build-stack-plugins.mjs`
only rebuilds each plugin's `knowledge/` folder from `pipeline/skills/shared/external/`.
The plugins' lifecycle skills - `create-component`, `evolve-component`,
`figma-utility`, `code-connect`, `branch-and-pr`, `fix-bug`, and the rest - are
hand-authored *inside* `multi-agent-plugins` and are never touched by sync.

---

## 2. Plugin marketplace build: one authoring source, five versioned artifacts

```mermaid
graph TD
    EXT["pipeline/skills/shared/external/<br/>154 skills - single authoring source<br/>(the pipeline's own phases read these too)"]

    EXT -->|"cross-stack skills"| COMMONP["ai-common-toolkit<br/>11 skills · v0.2.7"]
    EXT -->|"outside facts for analysis"| ANAP["ai-analyst-toolkit<br/>5 skills · v0.1.1"]
    EXT -->|"Apple/Xcode-only"| IOSP["ai-ios-toolkit<br/>148 skills · v0.10.0"]
    EXT -->|"Android/Kotlin-only"| ANDP["ai-android-toolkit<br/>30 skills · v0.1.4"]
    EXT -->|"backend-only"| BEP["ai-backend-toolkit<br/>33 skills · v0.1.5"]
    EXT -->|"web/frontend-only"| FEP["ai-frontend-toolkit<br/>25 skills · v0.1.4"]

    COMMONP --> BUMP{"skill set<br/>changed?"}
    ANAP --> BUMP
    IOSP --> BUMP
    ANDP --> BUMP
    BEP --> BUMP
    FEP --> BUMP
    BUMP -->|yes| PATCH["bump that plugin's<br/>patch version"]
    BUMP -->|no| SKIP["idempotent no-op"]

    PATCH --> CONSUMER["/multi-agent:update<br/>→ claude marketplace update multi-agent-plugins"]

    style EXT fill:#ffd,stroke:#333
```

A skill counted in more than one platform plugin (a cross-stack knowledge skill
plus, say, an iOS-specific one) is why the plugins' skill counts sum to more than
the 151-skill source: `ai-common` skills are vendored into every stack plugin's
`knowledge/`, not deduplicated across them. Versioning is per-plugin and
patch-only from this generator - a repo enabling only `ai-ios-toolkit`
never pulls an Android-only change.

**Consumption is pull, not push.** A consumer repo enables a stack plugin once
(`/multi-agent:stack ios`, writing the enabled-plugins list into
`.claude/settings.json`) and picks up new plugin versions only when it runs
`/multi-agent:update`, which calls `claude marketplace update multi-agent-plugins`.
Publishing a new plugin version does not retroactively change anything already
running in a consumer's session.

---

## 3. Per-host delivery: the same three repos, three different shapes

The three repos land differently on each host, because each host's skill-loading
behavior is different (see `pipeline/multi-agent-refs/cross-cli-contract.md` for the
measurements behind this table):

| | Claude Code | Copilot CLI | Codex CLI |
|---|---|---|---|
| **Pipeline commands** | 53 slash-command skills, native | 53 skills, `multi-agent-{cmd}` naming, copied in | 1 router skill (`multi-agent`) + 53 command specs as reference files - Codex silently truncates its skills block past a few dozen entries, so sub-commands are not peer skills here |
| **Stack plugins** | Marketplace plugin, loaded natively, resolved by `.claude/settings.json` enabled-list | Enabled plugin's authored skills copied flat into `~/.copilot/skills/`; `knowledge/` **not** re-copied (already delivered via `shared/external`) | Copied as reference files under `~/.codex/multi-agent-refs/skills/`, plugin-prefixed on name clash (e.g. `architecture` → `ai-ios-toolkit-architecture`) |
| **Component dispatch (Phase 3)** | Marketplace plugin's `create-component`/`create-screen` skill via the Skill tool | No plugin loader - the enabled stack plugin's authored skills (incl. `create-component`) are copied flat into `~/.copilot/skills/` at install time (the old frozen `figma-*` copies are pruned, they were never a fallback) | Not part of the enforced parity axis; classification + state-shape must match, skill *inventory* does not |
| **multi-agent-toolkit-mcp** | `claude mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `copilot mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` | `codex mcp add multi-agent-toolkit -- npx -y @mmerterden/multi-agent-toolkit-mcp` (skipped with a warning if `codex` isn't on `PATH`) |

`smoke-cross-cli-behavior.sh` and `smoke-codex-install.sh` gate the axes that **do**
have to match (phase labels, placeholder vocabulary, output schemas, command↔skill
parity count); the table above marks the axes that are allowed to diverge by design.

---

## 4. Runtime: what actually happens during a task

Two independent hand-offs happen inside a single pipeline run, neither aware of the
other:

```mermaid
graph TD
    START["Task running: Phase 3 (Dev)"]
    START -->|"taskType !== component"| TDD["Standard TDD loop<br/>(pipeline's own code)"]
    START -->|"taskType === component<br/>+ figmaUrl present"| VALIDATE["ai-ios-toolkit:figma-validate<br/>(registry, Code Connect, token compliance)"]
    VALIDATE -->|pass| DISPATCH["Skill tool →<br/>create-component / create-screen<br/>/ evolve-component (dual-name fallback)"]
    VALIDATE -->|fail| HALT1["halt Phase 3, surface why"]
    DISPATCH --> REPORT1["plugin returns build/test status →<br/>dispatch layer writes state.phases['3'].subphases[]"]

    REPORT1 --> P4["Phase 4: Review"]
    P4 --> P5["Phase 5: Test"]

    P5 -->|"UI bug hunt / manual-test /<br/>design-check / store-ready"| MCP["MCP tool call over stdio<br/>e.g. ios_xcodebuild, design_visual_compare,<br/>ios_app_store_audit"]
    MCP --> DTKPROC["multi-agent-toolkit-mcp process<br/>(npx @mmerterden/multi-agent-toolkit-mcp)"]
    DTKPROC -->|"result: screenshot / xcresult ID /<br/>18-rule audit verdict"| P5

    style DISPATCH fill:#dfd,stroke:#333
    style MCP fill:#dff,stroke:#333
    style HALT1 fill:#fdd,stroke:#333
```

**Phase 3 → plugin** is a one-shot delegation: the plugin skill does its own
lifecycle (test → code → build → wiki) and reports back a coarse
`component-build` result; the pipeline does not re-implement any of that logic, and
a plugin failure counts against the pipeline's own retry cap (`retryCount === 3` →
hard stop, per `component-dispatch.md`).

**Phase 5 (and design-check / store-ready) → multi-agent-toolkit** is a long-lived MCP
session, not a one-shot call: the same stdio server process answers many tool
calls across a phase (boot simulator once, then screenshot/tap/screenshot/tap...).
Several pipeline skills pin a **minimum toolkit version** for a specific tool -
e.g. `apple-archive-compliance` requires `ios_app_store_audit` from
`multi-agent-toolkit-mcp ≥ v3.0.0` - enforced in `cross-cli-contract.md` and checked by
`/multi-agent:sync` Step 3d before any multi-agent-toolkit release ships (a version bump
that drops or renames a tool a pipeline skill depends on is a **major** bump, by
that step's own contract).

### multi-agent-toolkit-mcp's 83 tools, by category

| Category | Tools | Primary pipeline consumers |
|---|---|---|
| Device Control | 58 | `/multi-agent:test`, `test-dark-mode`, `test-accessibility`, `test-dynamic-type`, `test-screenshots`, `manual-test`, `design-check` |
| Accessibility Audit | 2 | `test-accessibility` |
| Store Compliance | 5 | `store-ready`, `testflight-validation`, `apple-archive-compliance` skill, Phase 4 Security Auditor |
| Web Automation | 8 | frontend-stack UI testing (via `test`) |
| Design Audit | 6 | `design-check` (mock-mode vs Figma conformance) |
| Autonomous Agent DSL | 1 | any skill that needs a scripted multi-step device flow in one round trip |

---

## 5. Why the boundary is drawn where it is

- **Pipeline ↔ plugins boundary = Skill tool, one direction.** The pipeline
  classifies (`taskType`, `componentScope`) and tracks state; it never reads or
  writes plugin-internal files. This is why a corporate marketplace can ship a
  same-named plugin (`ai-ios-toolkit:create-ui-component` vs the public
  `create-component`) and dispatch still resolves correctly - the dual-name
  fallback lives in the pipeline, the implementation stays entirely in whichever
  plugin is enabled.
- **Pipeline ↔ multi-agent-toolkit boundary = MCP protocol, versioned contract.** The
  pipeline never shells out to `xcrun simctl` or `adb` directly; every device/browser
  action is a declared MCP tool call with a minimum-version pin. That's what lets
  `multi-agent-toolkit-mcp` ship on its own release cadence (its own gates, its own
  `npm publish`) without a pipeline release, as long as pinned tools keep their
  contract.
- **Neither boundary is symmetric.** The pipeline depends on both other repos being
  present *for specific task types* (component work, UI testing) but functions
  without either - a non-component bugfix task never touches the plugin marketplace,
  and a task with no UI-testing step never opens the MCP connection.
