|
| 1 | +# Phase 1: Plugin Architecture for MCP Adapters |
| 2 | + |
| 3 | +**Status:** Not started — depends on antfly migration (core/phase-1) completing first. |
| 4 | + |
| 5 | +## Context |
| 6 | + |
| 7 | +dev-agent's MCP server currently has 9 adapters that follow a class-based pattern: |
| 8 | +extend `ToolAdapter`, implement `getToolDefinition()` + `execute()`, register manually |
| 9 | +in `bin/dev-agent-mcp.ts`. This works but is rigid — adding adapters requires touching |
| 10 | +multiple files, config is scattered, and there's no plugin lifecycle. |
| 11 | + |
| 12 | +[sdk-kit](https://github.com/lytics/sdk-kit) (a Lytics open-source project) provides a |
| 13 | +proven plugin architecture: `use()`, `ns()`, `expose()`, `defaults()`, event-driven |
| 14 | +coordination, and capability injection. This pattern maps naturally to MCP adapters. |
| 15 | + |
| 16 | +## Vision |
| 17 | + |
| 18 | +Each MCP adapter becomes a plugin that: |
| 19 | +- **Registers itself** via `use()` — no manual wiring in entry point |
| 20 | +- **Declares its config defaults** via `defaults()` — no scattered config |
| 21 | +- **Exposes its tools** via `expose()` — type-safe tool registration |
| 22 | +- **Emits events** — `tool:search:start`, `tool:search:complete` for observability |
| 23 | +- **Declares dependencies** — e.g., search adapter requires vector storage |
| 24 | + |
| 25 | +Third-party adapters become possible: `dev mcp add @someone/dev-agent-jira-adapter`. |
| 26 | + |
| 27 | +## What we'd lift from sdk-kit |
| 28 | + |
| 29 | +| sdk-kit concept | MCP adapter equivalent | |
| 30 | +|-----------------|----------------------| |
| 31 | +| `plugin.ns('transport')` | `adapter.ns('dev_search')` | |
| 32 | +| `plugin.defaults({...})` | `adapter.defaults({ limit: 10, threshold: 0.3 })` | |
| 33 | +| `plugin.expose({ send })` | `adapter.expose({ toolDefinition, execute })` | |
| 34 | +| `plugin.emit('transport:send')` | `adapter.emit('tool:search:start', query)` | |
| 35 | +| `plugin.hold({ log })` | `adapter.hold({ vectorStorage })` — shared capabilities | |
| 36 | +| `sdk.use(transportPlugin)` | `server.use(searchAdapter)` | |
| 37 | + |
| 38 | +## Also relevant from sdk-kit |
| 39 | + |
| 40 | +- **Transport plugin** — `sendWithRetry` pattern with exponential backoff, skip 4xx |
| 41 | +- **Poll plugin** — `waitFor` pattern for async conditions (server readiness, etc.) |
| 42 | +- **Lifecycle** — `sdk:init`, `sdk:ready`, `sdk:destroy` events for clean startup/shutdown |
| 43 | + |
| 44 | +## Why this matters |
| 45 | + |
| 46 | +1. **Community adapters** — third parties can build MCP tools as plugins |
| 47 | +2. **Config in one place** — each adapter declares defaults, user overrides via config file |
| 48 | +3. **Observability** — event emission gives free logging/metrics hooks |
| 49 | +4. **Testability** — plugins are pure functions, easy to test in isolation |
| 50 | +5. **Reduced boilerplate** — no manual registration, no entry point changes per adapter |
| 51 | + |
| 52 | +## Scope |
| 53 | + |
| 54 | +This is a significant architectural refactor: |
| 55 | +- Core plugin system (from sdk-kit patterns) |
| 56 | +- Rewrite 9 adapters as plugins |
| 57 | +- New adapter registration/discovery |
| 58 | +- Config system changes |
| 59 | +- Event bus integration |
| 60 | +- Third-party adapter loading |
| 61 | + |
| 62 | +## Parts (to be detailed) |
| 63 | + |
| 64 | +| Part | Description | |
| 65 | +|------|-------------| |
| 66 | +| 1.1 | Design: adapt sdk-kit core for MCP context (spike) | |
| 67 | +| 1.2 | Implement plugin core (use, ns, expose, defaults, emit) | |
| 68 | +| 1.3 | Convert SearchAdapter as first plugin (proof of concept) | |
| 69 | +| 1.4 | Convert remaining 8 adapters | |
| 70 | +| 1.5 | Third-party adapter loading (`dev mcp add`) | |
| 71 | +| 1.6 | Documentation and migration guide | |
| 72 | + |
| 73 | +## Dependencies |
| 74 | + |
| 75 | +- **core/phase-1 (antfly migration)** must complete first — the vector storage layer |
| 76 | + is a shared capability that adapters depend on, and it's changing |
| 77 | +- **sdk-kit source** — reference implementation at github.com/lytics/sdk-kit |
| 78 | + |
| 79 | +## Open questions |
| 80 | + |
| 81 | +1. Do we vendor sdk-kit core, fork it, or depend on it as a package? |
| 82 | +2. How do third-party adapters discover the MCP server? npm package convention? |
| 83 | +3. Does the event bus replace or complement the existing `AsyncEventBus` in core? |
| 84 | +4. How does this interact with the antfly client (shared capability via `hold()`)? |
| 85 | + |
| 86 | +--- |
| 87 | + |
| 88 | +*This plan will be fleshed out after the antfly migration lands. The overview here |
| 89 | +captures the vision and key decisions so the idea isn't lost.* |
0 commit comments