# Contract: a2ui MCP tool surface (producer side)

<!-- VENDORED TWIN: adia-factory ships references/contracts/a2ui-mcp-surface.md
     (consumer side). Changes here must be reconciled in BOTH copies. -->

The forge SHIPS the generation MCP, in-repo source `packages/gen-ui/mcp/gen-ui/`,
package `@adia-ai/mcp`'s `gen-ui` surface (ADR-0048 P2 planned
`@adia-ai/gen-ui-mcp`; gh#1240 folded it and the protocol MCP into
`@adia-ai/mcp` before either name ever published). The ADR-0048 P7 cut
shipped in v0.8.37: `@adia-ai/mcp` is the single live name and the old
`@adia-ai/a2ui-mcp` is retired. The factory PINS it in `.mcp.json` and
consumer skills drive it. Source of truth for the full tool surface:
`packages/gen-ui/mcp/TOOLS.md` (the `gen-ui` section, 31 tools, generated from
`server.js`, update both together).

## Stability rule (the load-bearing clause)

- **Changing an existing tool's input/output contract is a breaking change for
  every external MCP client** (Claude Desktop, Cursor, the factory plugin).
  It requires: a dry-run diff of the schema, an explicit operator proceed, a
  version bump of `@adia-ai/mcp`, and a factory-side pin update.
- **Adding tools is additive and safe.** Removing or renaming is breaking.
- The factory pins an exact version (`npx -y @adia-ai/mcp@<exact> gen-ui`);
  producers must not assume consumers float.

## The consumer-load-bearing subset

Tools the factory's skills depend on by name, treat their contracts as
frozen-unless-versioned:

| Tool | Consumer use |
|---|---|
| `generate_ui`, `refine_ui` | gen-UI generation loop (gen-ui-wiring) |
| `plan_app_state` | app-state-context feed for `generate_ui` (REQ-03, gh#1208; renamed from "ontology-context" gh#3385 so "ontology" is owned by the archetype/facet vocabulary, ADR-0112), the agent operator's (P4's) only Reasoning Ladder surface; mechanizes ~Tier 0/1 only, honestly (see the tool's own description) |
| `validate_schema`, `check_anti_patterns` | the trust gate on LLM-emitted A2UI (screen-composition-agent) |
| `search_chunks`, `lookup_component`, `get_component_map`, `get_traits` | catalog literacy (screen-composition, "the MCP is the live catalog, don't memorize names") |
| `convert_html` | migration aid (app-migration) |
| `server_status` | connectivity probe (surface-qa) |

`refine_ui` note: present in the pinned server; keep TOOLS.md's entry in sync
with `server.js` when either changes (the 2026-06 red-team caught it missing).

`plan_app_state`'s `experience.shell` enum (`admin | chat | editor | simple | embed | none`) matches the Orientation Record's own Shell axis (`app-planning`'s `record-lint` AXES), REQ-03(d)'s reconciliation, a BREAKING change to the tool's prior vocabulary (`admin-shell | chat-shell | a2ui-root`), landed under this contract's stability rule above.
