gadget
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Prebuilt, interactive HTML widgets for MCP Apps in Go — data tables and forms, self-contained in a single binary, host-themed, spec-compliant.
gadget
Prebuilt, parameterized, interactive HTML widgets for MCP Apps — in Go, out of the box.
gadget lets an MCP server ship CRUD-style UI — data tables, card carousels,
forms — as fully self-contained HTML template resources: inline CSS, inline JavaScript,
zero external files, everything embedded in your single Go binary. Widgets
speak the official MCP Apps extension (io.modelcontextprotocol/ui, spec2026-01-26) and render in any compliant host (Claude, ChatGPT, VS Code,
Cursor, Goose, Postman, …).
Status: pre-release. APIs are not stable yet.
Table and Form widgets rendered by the examples/harness fake host — light and host dark themes.
CardList lays a collection out as a horizontally scrolling card carousel that fits a narrow chat pane (same filter/sort/pagination/selection as Table); Card renders a single record.
Quickstart
package main
import (
"context"
"net/http"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/techthos/gadget"
"github.com/techthos/gadget/gosdk"
)
func main() {
table := &gadget.Table{
URI: "ui://myapp/users",
Title: "Users",
Columns: []gadget.Column{
gadget.Text("name", "Name"),
gadget.Number("balance", "Balance", "currency:EUR"),
gadget.Badge("status", "Status", map[string]gadget.BadgeVariant{
"active": gadget.BadgeSuccess,
}),
},
Filterable: true,
PageSize: 10,
}
server := mcp.NewServer(&mcp.Implementation{Name: "myapp"}, gosdk.EnableUI(nil))
type in struct{}
type out struct {
Rows []map[string]any `json:"rows"`
}
gosdk.AddWidgetToolFor(server, table,
&mcp.Tool{Name: "list_users", Description: "List users in a table."},
func(context.Context, *mcp.CallToolRequest, in) (*mcp.CallToolResult, out, error) {
rows, _ := gadget.RowsOf(loadUsers())
return nil, out{Rows: rows}, nil
})
h := mcp.NewStreamableHTTPHandler(func(*http.Request) *mcp.Server { return server }, nil)
http.ListenAndServe(":8080", h)
}
Ask a connected assistant to "list the users" and it renders an interactive,
host-themed table — sortable, filterable, paginated — inside the chat.
Features
- 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-*design tokens defaulting to
host-injected CSS variables (Claude/ChatGPT look automatic),Themestruct
overrides, dark mode. - Locale-aware: numbers/dates formatted via
Intlwith the host's
locale and time zone. - SDK-agnostic core + adapter for the official
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.
Documentation
- Widget reference — Table, Form, actions, data contract
- Theming — tokens, host variables, dark mode
- Architecture — rendering model, runtime, security
Examples
examples/demo— complete MCP server (streamable HTTP or-stdio):
list/edit/save/delete/archive users. Point MCPJam or any MCP Apps host athttp://localhost:8080/mcp.examples/harness— 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, openhttp://localhost:8090.
Development
The TypeScript/CSS runtime lives in ui/ and is bundled with esbuild intointernal/assets/dist/ (committed, go:embed-ed — consumers never need
Node).
make assets # npm ci + build the runtime bundle
make test # go test ./... + vitest
make verify-dist # fail if committed dist doesn't match ui/ sources
Golden-file tests: go test ./ -update regenerates testdata/golden/.
License
MIT
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found