Agents & MCP
You don’t need any of this to use compose-ai-tools — rendering @Previews to
PNG already lets an agent see its work. This page is for when you want a
tighter, push-based loop than “run a command, read a file.”
The agent loop
A token-frugal feedback loop over Compose UI — the way
Playwright gave web agents one over the DOM: act by
a stable reference, observe structure rather than pixels, and turn
exploration into durable tests. These are exposed by the preview daemon’s MCP
server (and the compose-preview CLI where noted).
- Target by semantic ref, not pixels.
interactive/inputandrecord_previewaccept atarget(testTag/role+text/ a stable noderef) that the daemon resolves to the node’s centre, so a click survives layout changes instead of breaking on a coordinate. Android (Robolectric) and Desktop (Skiko). - Token-frugal observation.
render_preview observe=semantics|hashreturns thecompose/semanticstree + a hash + dimensions instead of a base64 PNG — typically a few hundred tokens versus ~1.5k. Fetch pixels only when you actually need to look. - Semantics diff.
diff_semantics(MCP) andcompose-preview diff-semantics(CLI) diff two semantics trees and report what changed semantically (text, label, role, testTag, overflow…), matched by stable ref — a deterministic, pixel-free regression signal, the Compose analogue of Playwright’s aria-snapshot diff. - Matrix render.
render_matrix(andcompose-preview render-matrix) renders one preview across a cross-product ofdevice × locale × uiMode × fontScalein a single call, returning a per-cell hash and which cells changed — “does this survive small screen + RTL + large font?” without N screenshots. Opt into a stitched contact-sheet image when you want to eyeball every cell at once. - Recording → test.
record_preview emitTest=trueturns a scripted interaction into a runnable Compose UI test (semantic targets becomeonNodeWithTag(...).performClick()steps; eachrecording.probeis diffed against the previous probe’s captured semantics intoassertExists()/assertDoesNotExist()assertions). - Structured failures. A failed render reports a typed
kindplus a one-line fix hint for recognized signatures (classpath skew, Robolectric SDK mismatch, missing@Composable, …) instead of an opaque message.
Cost budget for these in
docs/TOKEN_USAGE.md.
The MCP server
The :mcp module exposes the preview daemon’s JSON-RPC over stdio, so
MCP-aware agents can render previews on demand and be notified when bytes
change — instead of running Gradle (10s+ cold) or polling PNGs off disk with
no way to request a re-render.
Each @Preview becomes one MCP Resource under a stable
compose-preview://<workspaceId>/<module>/<previewFqn> URI. The server
supports subscribe (per-resource update notifications) and listChanged
(the set of resources mutated), plus notifications/progress for
long-running calls. Data products are read via list_data_products,
subscribe_preview_data, and get_preview_data.
For the full tool surface, URI scheme, and wire protocol see
docs/daemon/MCP.md.
What we tell agents
Point the agent at the
compose-preview skill.
It’s the install-and-iterate playbook: it checks for the CLI, bootstraps it
via the installer if missing, and walks the agent through
rendering and verifying. The skill and the installer aren’t alternatives —
the installer is just the one command the skill runs to get the CLI in place.
</content>