widget-studio
Generate and display rich UI widgets inline via Widget Studio (MCP tools + skills).
Open source Open in the app JSON README (API)
About
Generate and display rich UI widgets inline via Widget Studio (MCP tools + skills).
Details
- Kind
- Plugins
- Topic
- No topic detected
- Publisher
- ericlewis
- Origin
- gemini
- Category
- ferramentas
- Version
- 0.2.0
- Last push
- 2026-08-09T09:06:45Z
- Repository state
- ativo
- Language
- TypeScript
- Added
- 2026-08-30 14:13:39
- Updated
- 2026-08-30 14:13:39
- Origin id
ericlewis/widget-studio-mcp
README
# widget-studio
An agent capability for creating and displaying rich UI widgets (cards, dashboards,
task lists, charts, forms, tables) **inline in conversations** — packaged as a
Claude Code plugin, an Agent Skill, standalone CLI scripts, and an MCP server with
[MCP Apps](https://github.com/modelcontextprotocol/ext-apps) support. Widgets use the
ChatKit widget JSON format, generated by prompting
[Widget Studio](https://widgets.chatkit.studio)'s hosted generator; the JSON is
edited directly only for small tweaks.
## Architecture
The MCP server is optional — the skills + CLI deliver the full generate→render
loop on their own. The server is the layer that adds *interactive* inline
widgets in MCP Apps hosts. Each host gets the richest rendering it supports:
| Layer | What it provides | Who uses it |
| --- | --- | --- |
| **Skills** ([skills/](skills/)) | `/widget-studio:make` — how to *prompt* the generator well; `:tweak` — instant JSON edits + re-display; `:preview` — render saved JSON to PNG/HTML; `:doctor` — install/render/API health checks | Any skills-capable agent |
| **Reference** ([skills/make/references/chatkit-widgets.md](skills/make/references/chatkit-widgets.md)) | ChatKit component schema for reading and making small edits to generated widgets before re-display | The model, on demand |
| **Scripts** ([scripts/](scripts/), [bin/](bin/)) | `widget-generate` (prompt → widget via hosted API), `widget-render` (JSON → PNG / standalone HTML), `widget-export` (→ `.widget` file for the Widget Studio editor) — self-locating, on PATH in plugin sessions | The full capability, no MCP needed |
| **MCP server** ([src/](src/)) | `generate_widget`, `display_widget`, and `export_widget` (.widget files) tools; interactive MCP Apps iframe with a copy/export action bar in capable hosts, automatic PNG fallback elsewhere | MCP Apps hosts (interactive) + any other MCP client (PNG) |
| **Evals** ([evals/](evals/)) | Deterministic golden-render suite (`npm run eval`) + skill-creator-format LLM eval cases ([skills/make/evals/evals.json](skills/make/evals/evals.json)) | CI / skill iteration |
### Rendering paths
- **MCP Apps hosts** (Claude Desktop, claude.ai, ChatGPT): interactive iframe via the
standard `_meta.ui.resourceUri` → `ui://widget-studio/widget.html`, a fully
self-contained HTML renderer (CSP-safe, light/dark, actions post back to chat).
Legacy `openai/outputTemplate` alias included for older ChatGPT builds.
- **Non-UI MCP clients** (Claude Code CLI, others): the server detects the missing
MCP Apps capability at initialize and attaches a **PNG image** of the widget to the
tool result instead (see [PNG rendering](#png-rendering)). Override with
`WIDGET_STUDIO_IMAGE=auto|always|never`.
- **No MCP at all**: `widget-render` (`scripts/render-widget.mjs`) produces the same
PNG or a self-contained HTML preview from a widget JSON file.
## Install
> **Note:** the `npx` forms and one-click badges below go live with the first
> npm release of `widget-studio-mcp`. Until then, use the
> [from-source form](#from-source) — everything else is identical.
[](https://cursor.com/en/install-mcp?name=widget-studio&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndpZGdldC1zdHVkaW8tbWNwQGxhdGVzdCJdfQ==) [](https://insiders.vscode.dev/redirect/mcp/install?name=widget-studio&config=%7B%22name%22%3A%22widget-studio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22widget-studio-mcp%40latest%22%5D%7D) [](https://lmstudio.ai/install-mcp?name=widget-studio&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndpZGdldC1zdHVkaW8tbWNwQGxhdGVzdCJdfQ==)
### As a Claude Code plugin (recommended for Claude)
```
/plugin marketplace add ericlewis/widget-studio-mcp
/plugin install widget-studio@widget-studio
```
The plugin registers the MCP server, puts `widget-generate`/`widget-render`/`widget-export`
on PATH, and installs the skill family (`/widget-studio:make`, `:tweak`, `:preview`,
`:doctor`). `dist/` ships self-contained bundles — no `npm install` needed.
### MCP server, per host
<details><summary><b>Claude Code</b></summary>
```bash
claude mcp add widget-studio -- npx -y widget-studio-mcp@latest
```
</details>
<details><summary><b>Claude Desktop</b></summary>
`claude_desktop_config.json` (Settings → Developer → Edit Config):
```json
{ "mcpServers": { "widget-studio": { "command": "npx", "args": ["-y", "widget-studio-mcp@latest"] } } }
```
</details>
<details><summary><b>Cursor</b></summary>
Use the install badge above, or `.cursor/mcp.json`:
```json
{ "mcpServers": { "widget-studio": { "command": "npx", "args": ["-y", "widget-studio-mcp@latest"] } } }
```
</details>
<details><summary><b>VS Code</b></summary>
```bash
code --add-mcp '{"name":"widget-studio","command":"npx","args":["-y","widget-studio-mcp@latest"]}'
```
</details>
<details><summary><b>Codex CLI</b></summary>
```bash
codex mcp add widget-studio -- npx -y widget-studio-mcp@latest
```
Or `~/.codex/config.toml`:
```toml
[mcp_servers.widget-studio]
command = "npx"
args = ["-y", "widget-studio-mcp@latest"]
```
</details>
<details><summary><b>Gemini CLI</b></summary>
As an extension (bundles the MCP server and skills):
```bash
gemini extensions install https://github.com/ericlewis/widget-studio-mcp
```
</details>
<details><summary><b>Windsurf</b></summary>
`~/.codeium/windsurf/mcp_config.json`:
```json
{ "mcpServers": { "widget-studio": { "command": "npx", "args": ["-y", "widget-studio-mcp@latest"] } } }
```
</details>
<details><summary><b>Goose</b></summary>
```bash
goose session --with-extension "npx -y widget-studio-mcp@latest"
```
</details>
<details><summary><b>Amp</b></summary>
```bash
amp mcp add widget-studio -- npx -y widget-studio-mcp@latest
```
</details>
<details><summary><b>ChatGPT (and other remote-only hosts)</b></summary>
ChatGPT connects to remote MCP servers only. Run the HTTP transport behind a
tunnel or deploy, then add the URL under Settings → Connectors (developer mode):
```bash
npx -y widget-studio-mcp@latest --http 3400 # stateless streamable HTTP, POST /mcp
```
ChatGPT implements the MCP Apps standard natively, so widgets render
interactively; in `--http` mode the server also always attaches the PNG.
Bridge for stdio-only hosts hitting a remote:
`npx -y mcp-remote https://your-host/mcp`.
</details>
<details><summary><b>From source</b></summary><a name="from-source"></a>
```bash
git clone https://github.com/ericlewis/widget-studio-mcp && cd widget-studio-mcp
npm install && npm run build
claude mcp add widget-studio -- node "$(pwd)/dist/index.js" # or the equivalent for your host
```
</details>
### PNG rendering
Built in — pure JS/WASM (satori + resvg with bundled Inter fonts). No browser,
no playwright/puppeteer, no native dependencies, nothing to install.
## Develop
```bash
npm run build # typecheck + bundle the iframe app and self-contained server into dist/
npm test # protocol smoke test (incl. one real API generation)
npm run eval # render golden fixtures to PNG + offline protocol checks
```
Manual preview of any widget JSON:
```bash
node scripts/render-widget.mjs --in evals/golden/sales-dashboard.json --png dashboard.png
node scripts/render-widget.mjs --in evals/golden/sales-dashboard.json --html dashboard.html
```
`dist/` is committed on purpose: plugin installs copy the repo as-is, so the
bundles must ship prebuilt. Rebuild before committing changes under `src/`.
## Notes
- The Widget Studio API is the unauthenticated hosted service behind the public
editor; requests carry a stable random user ID (`WIDGET_STUDIO_USER_ID` to pin).
- The renderer covers the full ChatKit component set; unknown components degrade to
rendering their children. External images are blocked by host CSP in interactive
mode (placeholder shown) but fine in PNG/HTML output.