Status: Accepted (v1 subset shipped in 0.2.3) Date: 2026-06-12 Deciders: PatrickJS Index: Design decisions
Shipped in 0.2.3 per Option A:
async-pipeline mcpas a hand-rolled line-delimited JSON-RPC 2.0 stdio server withinitialize/ping/tools/list/tools/call, read-only tools (list_tasks,graph,explain_task,metadata,list_runs,read_run,diff_inputs), andrun_jobgated behind--allow-runwith the same lock, records, and cache as CLI runs — see api.md for the reference and registered claims. Not yet shipped: resources/prompts capabilities, HTTP transport, andmatrix/sync tools (consequences “revisit” list).
The README promises inspectable commands “for humans, tools, and AI agents”: list, graph, explain, metadata, matrix, doctor. Today an agent consumes them by spawning the CLI and parsing output. That works, but every agent re-derives the same glue: which commands exist, which flags emit JSON, which are safe to run, what the output shape is. The metadata promise — reads execute nothing, clone nothing, evaluate no deferred callbacks — is exactly the introspection contract an agent wants, and it is currently discoverable only by reading the docs.
MCP (Model Context Protocol) is the emerging standard for exposing tools to agents: JSON-RPC 2.0 over stdio, with tool discovery and schemas. Claude Code, Cowork, and other agent hosts speak it natively.
Forces: zero runtime dependencies is a published promise; the package is pre-1.0 and the CLI surface freezes at 1.0; the run lock already serializes runs per project; the exit code contract is part of the frozen surface.
Add async-pipeline mcp: a stdio MCP server implemented by hand in pipeline-node, exposing the existing inspection commands as discoverable tools.
initialize, tools/list, and tools/call over JSON-RPC 2.0 on stdio. That is a few hundred lines against a pinned protocol version — well under the bar that would justify breaking the zero-dependency promise.list, graph, explain, metadata, runs (read execution records and summaries from .async/runs/), doctor. All are inert by the same definition as metadata today.run and run-task are exposed only when the server is started with --allow-run. They acquire the same .async/run.lock, write the same records, and report the same exit-code semantics in the tool result. No tool ever bypasses the scheduler or store.--format json, so the CLI and MCP surfaces cannot drift apart.pipeline-node (proposed)| Dimension | Assessment |
|---|---|
| Complexity | Medium — small protocol subset, but owned forever |
| Dependency cost | Zero |
| Compatibility | Pinned MCP protocol version; additive evolution |
| Drift risk | Low — delegates to existing command internals |
Pros: keeps the zero-dependency promise; tool schemas become executable documentation of the JSON output shapes; works in every MCP host. Cons: protocol conformance is on us (spec churn, capability negotiation edge cases); temptation to grow bespoke extensions.
@async/pipeline-mcp package| Dimension | Assessment |
|---|---|
| Complexity | Low per feature, high per release (SDK churn) |
| Dependency cost | Real but contained to an opt-in package |
| Compatibility | Tracks spec automatically |
| Drift risk | Medium — second package to version and sync |
Pros: full protocol coverage (resources, prompts, notifications) for free; less protocol code to own.
Cons: another publishable package with its own engines floor, claims, and drift checks; the core CLI still wants mcp as a discoverable subcommand, so the seam is awkward.
--format json as the agent contract| Dimension | Assessment |
|---|---|
| Complexity | Zero |
| Dependency cost | Zero |
| Compatibility | Works with any agent that can shell out |
| Drift risk | None new |
Pros: the contract already mostly exists; nothing to freeze at 1.0. Cons: no discovery (agents must be told what exists), no schemas, every host re-implements spawning/parsing; “inspectable by agents” stays a docs claim rather than a wire protocol.
C is the do-nothing baseline and it is not bad — the JSON output contract is genuinely agent-friendly. The case for A over C is discovery and schema: an MCP host can offer pipeline tools with zero configuration, and the tool schemas pin the output shapes that today live only in api.md. The case for A over B is the dependency promise plus surface control: the protocol subset needed is small and stable, while an SDK dependency imports someone else’s release cadence into a package that markets having no dependencies at all. If the hand-rolled subset ever needs resources/prompts/streaming, B becomes the migration path — A’s tool definitions port directly.
The 1.0 consideration cuts both ways: shipping mcp pre-1.0 means the tool names and schemas join the freeze; shipping after 1.0 means agents wait. Proposed: ship pre-1.0 marked experimental, freeze at 1.0 alongside the CLI per Path to 1.0.
runs tool).matrix and sync commands belong in the tool set.--format json outputs.pipeline-node with a pinned protocol version; reuse existing command internals.run/run-task behind --allow-run; verify lock and record behavior under MCP-initiated runs.tests/claims.json; CHANGELOG entry; docs page; example host configuration.