{"slug": "prebuilt-parameterized-interactive-html-widgets-for-mcp-apps", "title": "Prebuilt, parameterized, interactive HTML widgets for MCP Apps", "summary": "Techthos released Gadget, a Go library that lets MCP servers ship prebuilt, parameterized, interactive HTML widgets such as data tables, card grids, and forms as self-contained embedded resources. The widgets implement the official MCP Apps extension spec (io.modelcontextprotocol/ui, 2026-01-26) and render in compliant hosts including Claude, ChatGPT, VS Code, Cursor, Goose, and Postman. The library is pre-release with unstable APIs.", "body_md": "Prebuilt, parameterized, interactive HTML widgets for [MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview) — in Go, out of the box.\n\n`gadget`\n\nlets an MCP server ship CRUD-style UI — data tables, card grids,\nforms — as fully self-contained HTML template resources: inline CSS, inline JavaScript,\nzero external files, everything embedded in your single Go binary. Widgets\nspeak the official MCP Apps extension (`io.modelcontextprotocol/ui`\n\n, spec\n`2026-01-26`\n\n) and render in any compliant host (Claude, ChatGPT, VS Code,\nCursor, Goose, Postman, …).\n\nStatus: pre-release.APIs are not stable yet.\n\nTable and Form widgets rendered by the examples/harness fake host — light and host dark themes.\n\nCardList lays a collection out as a card grid (same filter/sort/pagination/selection as Table); Card renders a single record.\n\n```\npackage main\n\nimport (\n    \"context\"\n    \"net/http\"\n\n    \"github.com/modelcontextprotocol/go-sdk/mcp\"\n    \"github.com/techthos/gadget\"\n    \"github.com/techthos/gadget/gosdk\"\n)\n\nfunc main() {\n    table := &gadget.Table{\n        URI:   \"ui://myapp/users\",\n        Title: \"Users\",\n        Columns: []gadget.Column{\n            gadget.Text(\"name\", \"Name\"),\n            gadget.Number(\"balance\", \"Balance\", \"currency:EUR\"),\n            gadget.Badge(\"status\", \"Status\", map[string]gadget.BadgeVariant{\n                \"active\": gadget.BadgeSuccess,\n            }),\n        },\n        Filterable: true,\n        PageSize:   10,\n    }\n\n    server := mcp.NewServer(&mcp.Implementation{Name: \"myapp\"}, gosdk.EnableUI(nil))\n\n    type in struct{}\n    type out struct {\n        Rows []map[string]any `json:\"rows\"`\n    }\n    gosdk.AddWidgetToolFor(server, table,\n        &mcp.Tool{Name: \"list_users\", Description: \"List users in a table.\"},\n        func(context.Context, *mcp.CallToolRequest, in) (*mcp.CallToolResult, out, error) {\n            rows, _ := gadget.RowsOf(loadUsers())\n            return nil, out{Rows: rows}, nil\n        })\n\n    h := mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server { return server }, nil)\n    http.ListenAndServe(\":8080\", h)\n}\n```\n\nAsk a connected assistant to \"list the users\" and it renders an interactive, host-themed table — sortable, filterable, paginated — inside the chat.\n\n**Table**: typed columns (text/number/date/badge/link/actions), client-side sort/filter/pagination, row selection with bulk actions, per-row actions → MCP tool calls, inline destructive-action confirmation, empty/loading states.**Form**: 10 field types, native + inline client validation, submit as a tool call, server-side field errors mapped inline, prefill for edit flows.**Host-aware theming**:`--gadget-*`\n\ndesign tokens defaulting to host-injected CSS variables (Claude/ChatGPT look automatic),`Theme`\n\nstruct overrides, dark mode.**Locale-aware**: numbers/dates formatted via`Intl`\n\nwith the host's locale and time zone.**SDK-agnostic core**+ adapter for the official[go-sdk](https://github.com/modelcontextprotocol/go-sdk); the core works with any Go MCP implementation.**Self-contained by construction**: documents satisfy the spec's default locked-down CSP; no CDN, no network, no files on disk.\n\n[Widget reference](/Techthos/gadget/blob/main/docs/widgets.md)— Table, Form, actions, data contract[Theming](/Techthos/gadget/blob/main/docs/theming.md)— tokens, host variables, dark mode[Architecture](/Techthos/gadget/blob/main/docs/architecture.md)— rendering model, runtime, security\n\n`examples/demo`\n\n— complete MCP server (streamable HTTP or`-stdio`\n\n): list/edit/save/delete/archive users. Point MCPJam or any MCP Apps host at`http://localhost:8080/mcp`\n\n.`examples/harness`\n\n— a fake MCP Apps host in one HTML page: renders widgets in a sandboxed iframe, answers the JSON-RPC handshake, logs all traffic, simulates tool results/errors and theme changes.`go run ./examples/harness`\n\n, open`http://localhost:8090`\n\n.\n\nThe TypeScript/CSS runtime lives in `ui/`\n\nand is bundled with esbuild into\n`internal/assets/dist/`\n\n(committed, `go:embed`\n\n-ed — consumers never need\nNode).\n\n```\nmake assets       # npm ci + build the runtime bundle\nmake test         # go test ./... + vitest\nmake verify-dist  # fail if committed dist doesn't match ui/ sources\n```\n\nGolden-file tests: `go test ./ -update`\n\nregenerates `testdata/golden/`\n\n.\n\nMIT", "url": "https://wpnews.pro/news/prebuilt-parameterized-interactive-html-widgets-for-mcp-apps", "canonical_source": "https://github.com/Techthos/gadget", "published_at": "2026-07-24 09:50:42+00:00", "updated_at": "2026-07-24 10:22:32.304881+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "artificial-intelligence"], "entities": ["Techthos", "Gadget", "MCP", "Claude", "ChatGPT", "VS Code", "Cursor", "Goose"], "alternates": {"html": "https://wpnews.pro/news/prebuilt-parameterized-interactive-html-widgets-for-mcp-apps", "markdown": "https://wpnews.pro/news/prebuilt-parameterized-interactive-html-widgets-for-mcp-apps.md", "text": "https://wpnews.pro/news/prebuilt-parameterized-interactive-html-widgets-for-mcp-apps.txt", "jsonld": "https://wpnews.pro/news/prebuilt-parameterized-interactive-html-widgets-for-mcp-apps.jsonld"}}