CP

Compose Preview Catalogs

io.github.yschimke/compose-preview

Browse, inspect and render Jetpack Compose Material 3 and Wear component catalogs.

Yes, your AI can use this right now.Answered a live MCP handshake in 1127 ms with no sign-in needed and exposes 70 tools.

Connect it

Settings → Connectors → Add custom connector
URL: https://preview.coo.ee/mcp

70 tools, verified live

Pulled straight from the server with tools/list on 2026-10-17.
request_access

Ask a human for access to this server. Returns an approveUrl and a userCode: show BOTH to the person you are working with, ask them to open the link and check that the code on the page matches, then call poll_access. When the client supports URL elicitation, call poll_access with urlMode=true instead of pasting the link into chat; clients without it keep this complete text fallback. The link grant

poll_access

Collect the outcome of a request_access, proving possession of its deviceSecret. It HOLDS THE CALL OPEN and answers the moment the human decides — one call instead of a dozen, since each poll here costs a whole round trip through you. It waits 8 seconds by default; pass waitSeconds (up to 30) if your client tolerates a longer call. Pass urlMode=true when the client supports URL elicitation: while

status

Report readiness, the aggregate catalog set, and which host this is: `origin`, the canonical origin designs here are homed at, and `originAliases`, other hostnames that reach this same server.

catalog_list_projects

List every remote catalog with its stable id and preview count. Call this first: catalog_list_previews and catalog_list_data_products take one of these ids as 'catalog'.

catalog_library

Open the hosted preview catalog browser app. With no arguments it lists every catalog with its preview count only; pass projectId to list one catalog's previews. To find previews without the app, call catalog_list_projects, then catalog_list_previews with a catalog id. Also opens from the ChatGPT/Codex sidebar.

ui_builder_open

Open the UI Builder's design list: pick a design to see it as the editor draws it. Takes no arguments. Also opens from the ChatGPT/Codex sidebar, and a deep link to /design/<id> opens one design.

catalog_list_previews

List the Compose previews and published metadata of one hosted catalog. 'catalog' is required (ids from catalog_list_projects). Pass 'query' (a component name such as EdgeButton) to narrow by id or label; results are paged (100 by default, 'offset'/'limit' for more). This server holds published library catalogs only: previews of the project you are editing come from the local compose-preview-mcp s

catalog_render_preview

Render one preview. Like local compose-ai-tools, the default semantics observation is token-frugal; request observe=png for pixels, observe=svg for the compose/figma-svg vector export as SVG source, or observe=scroll-png / observe=scroll-svg for the full-page capture of a scrollable screen rather than the viewport crop. Overrides, other observations and fresh renders require live grant scope; with

catalog_render_matrix

Render one preview across the cross-product of the given override axes in a single call, returning a hash/size observation per cell (observe=png adds the pixels). Prefer this over a catalog_render_preview per combination: the cells share one catalog lease and are reported together, so comparing axes costs one round trip instead of N. Capped at 24 cells. Requires live grant scope.

catalog_list_devices

List the `@Preview(device = ...)` ids this server's render lane recognises, with each one's dp size and density. The `device` override takes one of these ids; an unrecognised name renders the default frame rather than failing, so check here instead of guessing.

catalog_diff_semantics

Compare two previews' semantics by testTag: which tags are only in one side, which moved, and which changed occupancy count. Identity is the authored testTag, not a positional ref, so a tag that stops resolving is reported rather than silently retargeted at different pixels. Requires live grant scope.

catalog_history_list

The render timeline for one preview: which versions of its rendered bytes exist, when each appeared, and whether the preview is unstable (re-renders differently on every publish) rather than genuinely changing. Where this server holds the timeline it is returned inline; where the catalog is published from a delivery branch the manifest lives on that branch and this reports where to fetch it.

catalog_history_diff

Compare two of a preview's recorded renders. Defaults to the two newest — did the last publish move this preview? A metadata comparison: the timeline's versions are already collapsed distinct renders, so whether the bytes changed is answered without fetching either image. Reports `unstable` so a difference on a nondeterministic preview is not mistaken for a real change.

catalog_history_read

Fetch one historical render's pixels through this server, by `commit` or `blob` (a prefix is enough). Use when an agent cannot reach the delivery branch itself, or wants the bytes rather than the timeline.

ui_builder_list_catalogs

List the component catalogs a UI-builder design can pin to. Start here: a design's `catalogPin` must name a revision this server actually serves, and each catalog's `catalogPin` here is exactly that. By default a summary of what authoring needs, a few KB rather than the whole capability: per component its id, role, traits, `slots` as `name[min..max]:accepted|roles` and `properties` as `name:type`,

ui_builder_search_components

Find catalog components by id, display name, Compose symbol, role or trait, e.g. `TextField`, `text field`, `OutlinedTextField`, `Button`, `Card`. Case, spaces, hyphens, underscores, slashes and camelCase are ignored, and the components the query names come first: an exact name, then a prefix, then a name containing it, then role and traits. Returns the same summary as ui_builder_list_catalogs (id

ui_builder_list_designs

List the UI-builder designs on this server, newest first, with the cursor to continue.

ui_builder_get_design

Read one design: its whole document — nodes, slots, properties, modifiers, state variables and catalog pin — plus the revision to quote as `baseRevision` when editing it. The catalog the design pins is left out unless `includeCatalog` is true: it is the same for every design on the pin, ui_builder_list_catalogs serves it, and it is most of the bytes. `home`, at the top of the reply, is where the d

ui_builder_preview_catalog_recovery

Dry-run recovery of a design whose stored catalog pin no longer resolves. The server selects the exact currently served pin for the same catalog system and returns a CatalogUpgradePreviewV1 with changes, issues and the hashes required by a later `upgradeCatalog` mutation through ui_builder_apply. This call never writes.

ui_builder_await_design

Wait for somebody else to change a design and return what they changed, rather than asking again whether they have. Returns the moment a designer in the browser or another agent commits an edit, as the same update frame the browser's own live socket receives; returns a `timedOut` reply if nothing happens within `waitSeconds`, which you answer by calling again with the same cursor. Quote as `afterS

ui_builder_create_design

Create a design, either from a whole `document` you supply or by copying an existing design named by `fromDesignId`. Copying is usually right: a document's `catalogPin` must match a catalog revision this server serves, and a copy carries one that does. A `document` whose `home` is an existing design on this server is refused with a `compose-preview-decision/v1` choice to put to the person — or, wh

ui_builder_apply

Apply design mutations — insertNode, setProperty, deleteNode, moveNode and the rest of DesignMutationV1 — as one operation. `baseRevision` is the revision you read; the outcome reports conflicts or rejected edits. This is how an agent adds a scaffold, fills its slots and sets modifiers. Use `setStateVariable` with `name` and `declaration` to add or edit state, `removeStateVariable` with `name` to

ui_builder_move_design_home

Move a design's canonical home between this server and a repository checkout. This changes real authoritative state: quote the exact `baseRevision` and current `sourceHome` from ui_builder_get_design, provide a stable `operationId`, and name the new `targetHome`. The old server record remains as a retained copy pointing at the new home. The reply is an idempotent operation outcome with the new rev

ui_builder_replace_design_document

Replace one stored design from a complete DesignDocumentV1 copy — the authoritative save-back and re-import operation. The document must name the same design and the same canonical home you read from ui_builder_get_design; `baseRevision` must still be current. The runtime validates the complete document and quotas, preserves server-owned identity, access and creation time, retains the old revision

ui_builder_export

Export a design. `compose` returns the Kotlin the generator writes, or — when the design holds something it cannot express — diagnostics naming each reason. This is the same gate the browser's code pane shows, so an agent and a designer get the same answer about the same design.

ui_builder_validate

Check a design without saving it: a whole `document`, a stored design by `designId`, or `operations` against a stored design exactly as ui_builder_apply would apply them. Runs the same checks the real call does — document shape, catalog pin, the catalog's own validation, the mutation reducer — and then the Compose export gate, which is the list the editor's problems panel shows. Returns `{valid, p

ui_builder_put_asset

Put a picture behind an `assetKey`, so an `asset/image` node naming that key draws it instead of a placeholder. Send the PNG, JPEG, GIF or WebP bytes base64-encoded in `imageBase64`; the server stores them by content digest and pins {mediaType, contentDigest, source: uploaded} into the design's `assets` map under the key. This moves the design's revision, and the reply carries the new one to quote

ui_builder_design_access

Read who can open a design: its owner, and every actor it has been shared with, each with the role and the actions that grant carries. Only the owner may ask — this is the answer to "who else is in here" and to "what is the id I must name when sharing".

ui_builder_share_design

Share a design with somebody else, or take that sharing back. `actorId` is the other party's actor id as this server spells it — `github:<login>` for a signed-in person, `operator` for the token holder, `agent:<fingerprint>` for another agent's grant; ui_builder_design_access lists the ones a design already carries. A `viewer` may read and export, an `editor` may also change the design, and neithe

ui_builder_get_links

Read what a design is **for**: the `issue` it was drawn for, the `reference` frame in the design tool it reproduces, the `pr` that implemented it, the `thread` it is being discussed in, and the `previous` design it continues. Start a session on somebody else's design here — it is the brief, and it is what ui_builder_get_design cannot tell you. Every field is optional; a reply with none of them mea

ui_builder_set_links

Say what a design is for. **Replaces the whole record**: send every link you want kept, and omit one to clear it — so read ui_builder_get_links first if you are adding to what is already there. `issue`, `reference`, `pr` and `thread` are absolute http or https URLs, at most 2 KB each; `previous` is a design id on this host, not a URL. Anything else is refused with the reason. Sending an empty reco

ui_builder_rename_design

Give a design a new title. The title is the one thing about a design nothing else could change: it is set at creation, shown in every listing and the editor, and not part of any mutation. Anybody who may write the design may rename it. The revision does not move — a title is not design content — so `baseRevision` is not needed and an edit in flight is unaffected. Not the released envelope: the con

ui_builder_delete_design

Delete a design: it moves to the trash with its history, access list, overlay and discussion, and is gone from every listing and tool until ui_builder_restore_design brings it back, which works until `restorableUntilEpochMillis` in the reply (a day). After that it is purged for good. Only the owner may delete, or an agent deleting a design it created itself under its current grant — not an editor,

ui_builder_list_trash

The designs in the trash that you could restore — ones you deleted, or ones you own — most recently deleted first, each with who deleted it and its `restorableUntilEpochMillis`. Use it to undo a ui_builder_delete_design you regret, or to check what a cleanup removed. Takes no arguments.

ui_builder_restore_design

Bring a deleted design back out of the trash exactly as it was: the same revision, history, access list, overlay and discussion. Allowed to whoever could have deleted it, until its `restorableUntilEpochMillis`; after that it is not found. The reply is the design's listing entry.

ui_builder_list_comments

Read the discussion on a design: every thread, where each is pinned — a markup stroke, a design node, or a point on the frame — whether it is resolved, and every reply under it. `sequence` rises on each change and is the cursor to quote to ui_builder_await_comments. Comments are kept beside the design and are never part of it: no node holds them and no export sees them. Each thread carries `acknow

ui_builder_post_comment

Say something on a design — a reply into `threadId`, or a new thread when it is omitted. Pin a new thread with `markId` (a stroke on the reference overlay), `nodeId` (a node in the design), or `x`/`y` in frame fractions, so the person reading it can see what you meant. The comment is attributed to your own grant; you cannot post as somebody else.

ui_builder_resolve_comment_thread

Close a comment thread once it is answered, or reopen one by passing `resolved: false`. The resolution is attributed to you and is reversible.

ui_builder_acknowledge_comment

Say that you have read a comment thread — which is **not** the same as resolving it. Resolving claims the question is settled; acknowledging claims only that you have seen it, which is the honest thing to say while you are still working on what it asked for. Omit `threadId` to acknowledge the whole discussion, which is what you mean after reading it with ui_builder_list_comments. Acknowledgement i

ui_builder_react_to_comment

React to one comment with an emoji, or take the reaction back with `on: false`. The lightest thing you can say: 👀 on a comment you have just picked up, 👍 on a fix somebody made, where a reply would be noise in a thread a person has to read. `commentId` is the `id` of a comment inside a thread, from ui_builder_list_comments. Reacting also acknowledges that thread for you, so it counts as the lighte

ui_builder_await_comments

Wait for the discussion to move past `afterSequence` and return it, rather than polling for it. Returns as soon as anybody — a designer in the browser or another agent — posts, resolves or deletes; returns a `timedOut` reply if nothing happens within `waitSeconds`, which you answer by calling again with the same cursor. This is how you hold a conversation about a design: post, wait, read, act.

ui_builder_render_native

Compile a design and render it with real Compose on this host, rather than in the browser's Wasm canvas — the way to see what a design looks like on Android. Returns the first frame, the token the live frame stream is opened with, and the design node ids the render is tagged with, so `catalog_get_preview_data` can report each node's bounds and a client can put selectable regions over the image. Th

ui_builder_view

See a design the way a person in the editor sees it: a PNG of the canvas with the overlays drawn on — the `selection` outline, the `reference` picture when one is attached, the discussion's `comments` pins, and the layout `bounds` — and beside it JSON with the revision, each visible node's id and box, each pin's thread and position, all in the returned image's pixels. The picture is a short-lived

ui_builder_check_design

Check a design before you show it to anybody — one call instead of validate, view and an accessibility pass. Runs `schema` (document shape), `catalog` (the pinned catalog's validation, the mutation reducer and the Compose export gate — what ui_builder_validate runs) and `a11y`: controls with no label, icons and pictures with no `contentDescription`, touch targets under 48dp, text and icon contrast

ui_builder_guidelines_prompt

Read the exact prompt a design-guidelines model is given for a design, before anybody spends a key on it: the rules for the design's platform (Android design guidance from developer.android.com, each with its source), the fixed system prompt, the user message with the design tree and Compose source, the JSON schema the verdicts must follow, a sentence on where each part comes from, and the picture

ui_builder_get_guidelines

Read a design's latest design-guidelines result, whoever ran it — a person in the editor on their own key, ui_builder_check_design on this host's key, or an agent that recorded verdicts with ui_builder_record_guidelines. Returns the record (model, revision, rules asked, verdicts, `ranBy`), the findings it implies, and `stale: true` when the design has changed since it was checked.

ui_builder_record_guidelines

Record your own model's verdicts on ui_builder_guidelines_prompt as the design's latest design-guidelines result, so the editor's Issues panel and other agents show them. Pass the `revision` and rule ids the prompt asked (`rules.asked[].id`), and one verdict per rule you answered: `pass`, `fail` or `not_applicable`, with `confidence` 0..1, the `nodeIds` it is about and a one-sentence `reason`. `ra

ui_builder_render_design_matrix

See one design on several devices in ONE picture: a contact sheet with a captioned cell per device × theme × font scale, plus each cell's device, size and box on the sheet. Nothing is saved — the design's environment is swapped on a scratch copy for each cell. Name `devices` by preset (phone_small, phone, phone_landscape, foldable_folded, foldable_unfolded, tablet_portrait, tablet_landscape, wear_

ui_builder_record_decision

Record a review verdict — `approve` or `reject` — on one revision of a design, with an optional note. Kept beside the design, like comments: it never moves the revision. Recorded as an agent's decision, so a person waiting with ui_builder_await_decision's default `from: "human"` is not answered by it. Pass your own `decisionId` to make a retry idempotent.

ui_builder_await_decision

Wait for somebody to approve or reject a design, rather than asking again whether they have. Returns as soon as a decision lands after `afterSequence` — by default only a person's (`from: "human"`), on any revision unless you name one — or a `timedOut` reply after `waitSeconds`. Every reply carries `latest` (the newest matching verdict, new or not) and `approved`, so `waitSeconds: 0` is a cheap, i

ui_builder_set_implementation

Record the pull request that implements a design: its URL, its `status` (draft, open, merged, closed), the design `revision` it implements, and — once you have compared the PR's rendered previews with the design — `previewMatch` {status: match|mismatch|unknown, evidence: a URL to the comparison, note}. Replaces the whole record; pass only `designId` to clear it. Writing the same record again chang

ui_builder_implementation_status

Everything the code side needs to implement a design, in one call: the revision, its links (issue, reference, PR, thread), the implementation PR with its status and whether its previews were found to match, the latest verdict on this revision, and the Compose export with the generator's diagnostics. `summary` says in one line whether the PR implements this revision and whether it was approved. `in

ui_builder_find_design_for_pr

From a pull request back to the design(s) it implements: every design you can read whose implementation record or links name `pr`, with the implementation status and revision. Then call ui_builder_implementation_status for what the design expects.

ui_builder_set_reference

Attach the picture a design is being built against — a Figma frame, a screenshot of a shipped screen, a mock — as its reference overlay, or `clear` it. The same overlay the browser editor's Frame, density and reference panel shows, so a person opening the design sees what you attached. Kept beside the design and never part of it: no node holds it, no export sees it, the revision does not move. Sen

ui_builder_compare_reference

Measure a design against its reference overlay (attach one with ui_builder_set_reference). Returns what the picture is against the frame and whether a pixel comparison means anything (`facts.pixelComparable` — a 328×56 dp crop stretched over a screen is not comparable until measured at its `actual` size); with `differences`, the share of pixels that differ and up to eight regions in dp, each with

ui_builder_list_revisions

A design's retained revisions, newest first: each one's number, who made it, when, the operation that produced it (`setProperty ×2, insertNode`, `undo`, `restored r3`) and its document digest. `retention` says how far back the history still reaches — older revisions are gone, and get, diff, restore and fork stop at that floor. Page with `before`. Read access.

ui_builder_diff_designs

Compare two designs, or two retained revisions of one: nodes added, removed and moved, and properties, modifiers and other fields changed, each with its node id and path (`root/slot[index]/node`), plus changed document fields (title, environment, state). Works across a design and its fork. `b` defaults to the current revision of `a`'s design. Values are the protocol's own JSON, ready to send back

ui_builder_restore_revision

Make a retained revision the design's current content again, **forward**: it is committed as a new revision and nothing after it is lost, so a restore is undone by restoring again. `baseRevision` must be the current revision (a restore that raced an edit is refused as stale). `dryRun: true` writes nothing and returns the diff the restore would apply. Needs write access to the design.

ui_builder_fork_design

Make a new design from one revision of another — yours to edit, owned by you, with its parent recorded: the fork's `forkedFrom` (design, revision, document digest) and the parent's `forks` both show in ui_builder_get_links. A fork is not a branch: it never inherits the parent's canonical home and nothing flows back on its own, so tell the person it exists and bring a chosen change back with ui_bui

ui_builder_branch_design

Fork a design at a revision into a **branch** to explore an alternative, or to change it without trampling somebody editing it live. A branch is a design with its own id: edit it with ui_builder_apply, look at it with ui_builder_view or ui_builder_get_design, compare it with ui_builder_diff_designs, then bring it back with ui_builder_merge_branch or drop it with ui_builder_archive_branch. Branch N

ui_builder_list_branches

A design's branches, newest first: each one's id, name, owner, status (open, merged, archived), fork revision, head revision and the number of commands a merge would replay; for a merged one the parent revision it landed at, for an archived sibling the branch whose merge superseded it. Read access to the design.

ui_builder_merge_branch

Replay a branch's edits onto its parent's current revision through the same reducer every edit goes through — all or nothing. The reply reports every command: `applied` with the revision it landed at and any `STALE_*` notice of what it overwrote, or `refused` with the rejection code that stopped the run (nothing is then written), plus `skippedOperationIds` and how many were never tried. Run `dryRu

ui_builder_archive_branch

Close a branch without merging it: it stays readable and listed, and can no longer be edited or merged. Needs write access to the parent, or to have made the branch.

ui_builder_compare_branches

Put a design's alternatives side by side in one call: the parent's head and each open branch (or the `branchIds` named) rendered into ONE picture — a short-lived signed https link, numbered by caption — plus, per branch, what it changes against the parent at its fork (counts and a few lines, as ui_builder_diff_designs reports them). Show the person the picture and the numbered list, then ask with

ui_builder_pick_branch

Ask the person which alternative (open branch) of a design to keep, and return their choice. In ChatGPT or Codex it is a thumbnail picker, one option per branch; with plain form elicitation it is a single-choice form; otherwise — and in chat tools like Slack — it returns a numbered list and one picture for YOU to post, and the person replies with a number. It never waits on a client that cannot an

catalog_list_data_products

List the structured data-product kinds of one catalog, optionally one preview. Name the catalog with 'catalog' (ids from catalog_list_projects) or a preview 'uri'.

catalog_get_preview_data

Fetch the merged accessibility or annotation product for a preview. This lane requires live grant scope.

list-all-documentation

Storybook-MCP-compatible alias that lists every preview as a story.

get-documentation-for-story

Storybook-MCP-compatible preview metadata lookup.

preview-stories

Storybook-MCP-compatible rendering of one or more story ids. Requires live scope.

Alternatives in Developer Tools

Compare →
Try “Notion”, “Stripe”, “create invoice”, “browser”