--- name: make description: Creates and displays rich UI widgets (cards, dashboards, task lists, charts, forms, tables, boarding passes, receipts) inline in the conversation by prompting the Widget Studio generator. Use when the user asks for a widget, a visual card, a rendered summary of data, "show me X as a widget/card/chart", or when a small polished visual would communicate results better than text. Renders as interactive UI in MCP Apps hosts, or as a PNG image anywhere else. compatibility: Node 20+. The bundled MCP server is optional — it adds interactive inline widgets in MCP Apps hosts. --- # Widget Studio Create widgets by **prompting the Widget Studio generator** — a hosted designer that turns a natural-language prompt into a polished ChatKit widget. Your job is writing a good prompt; its job is design. ## The workflow 1. Write a generator prompt (rules below). 2. Call the **`generate_widget`** MCP tool (~20–60 s). Display is automatic: interactive inline UI in MCP Apps hosts (Claude Desktop, claude.ai, ChatGPT), and a PNG attached to the tool result everywhere else. Nothing else to do. 3. Iterate: structural changes → regenerate with a fuller prompt; a trivial label/color/value tweak → edit the returned widget JSON and call **`display_widget`** (instant, no regeneration). ## How to prompt the generator These rules are empirical, from probing the live service: **Anatomy of a good prompt:** *widget kind* + *every fact to display, verbatim* + *layout hints* + *style hints* + *interactivity contract*. > a server status card for prod-api-01: healthy, uptime 99.98%, latency 12 ms, > last incident 34 days ago — compact, dark-themed, green status dot next to the > title, display only, no buttons 1. **Enumerate every fact, written exactly as it should render.** Supplied values are transcribed near-verbatim, keeping your word order. The generator **never invents numbers** — omitted figures become "—" placeholders with a refresh affordance — but it **freely invents prose** (titles, step text, marketing copy) that looks finished. If you didn't write it, it's fabricated. 2. **Name concrete layout patterns.** "bar chart" → real Chart component; "two-column layout" → two flex columns; "numbered steps" → numbered badges. Exception: "as a table" produces a hand-rolled grid with alignment drift — say **"use the Table component"** to get real table alignment. 3. **Resolve every ambiguity yourself.** "highlight the recommended tier" made the generator *pick* a tier. Say "highlight Plus as recommended". Unpinned choices (card size, badge colors, row arrangement, which element carries an accent) vary between runs of the identical prompt. 4. **Specify the interactivity contract.** Action names pass through verbatim ("a submit button that sends action type submit_feedback" → `onSubmitAction: {type: "submit_feedback"}`). If you don't specify, the generator invents plausible action types and CTA buttons nobody handles — for static widgets, end with **"display only, no buttons"**. If a backend reads form fields, name them: "use field names rating and comment". 5. **Style adjectives work.** "compact" → small card, "dark-themed" → forced dark, "green accent" → green accent element (name the element if it matters). Status words ("healthy", "blocked") get semantic badge colors for free. Relative dates are safe — the service knows today's date. 6. **Known quirks.** Per-bar chart colors arrive as a split-series workaround (bars sit slightly off their tick labels) — skip the color split if centering matters, and ask for a legend explicitly. Don't phrase per-item features as lists ("+ free shipping + exclusive roasts" can compile to nothing) — give each item one flat display string. A 5-option horizontal rating overflows small cards — say "options stacked vertically" or "in a medium card". ## Iterating - **Regenerating:** the service is stateless — each prompt is the complete spec. Restate everything you want kept, plus the changes; anything unstated drifts. - **Tweaking:** edit the generated `widget` tree (see [references/chatkit-widgets.md](references/chatkit-widgets.md) for the schema) and re-display. Edit the tree, not `state` — the tree is already hydrated. - Widget actions (button clicks, form submits) arrive as user messages in interactive hosts — handle them in your next turn. - **Save / share:** `export_widget` with the generationId from a generate result writes a `.widget` file — importable in the Widget Studio editor at widgets.chatkit.studio (CLI: `widget-generate --widget-file card.widget`, or `widget-export --in saved.json`). In interactive hosts the rendered widget also has a hover action bar with "⤓ .widget" and "Copy JSON". ## No MCP tools? The CLI is the full capability The MCP server is optional — `widget-generate` and `widget-render` deliver the complete generate→render loop (on PATH when installed as a plugin; in a bare checkout: `node scripts/generate-widget.mjs` / `node scripts/render-widget.mjs`): ```bash widget-generate --prompt "" --out widget.json --png widget.png ``` Then **show the PNG to the user** — read/attach it so it appears inline in the conversation (2x scale, light theme by default). Variants via `widget-render` on the saved JSON: `--theme dark` for a dark PNG, or `--html preview.html` for a self-contained file that opens in any browser. PNG rendering is bundled (pure JS/WASM) — no browser, no installs. ## Quality bar Before showing the user: every fact came from the user or real data (audit any prose you didn't supply), and nothing overflows or truncates. Interactive hosts follow the user's theme automatically; for a PNG deliverable, render the theme you'll show.