Live, interactive data widgets for Claude and other MCP Apps hosts.
A sigil is a symbol that carries compressed meaning. Same idea, applied to data: a chart you can hover, click, and copy β embedded directly in your conversation, instead of a flat PNG.
Unlike existing MCP chart servers that return static images, Sigil renders live widgets β hover tooltips, click-to-highlight, Copy-as-CSV / PNG β inside the host's sandboxed iframe via the MCP Apps extension.
π sigil.live Β· TESTING.md Β· INCANTATIONS.md Β· SPEC.md
Status: v0.2.0 β 7 widgets + payload-guard / registry / registration test harness.
Demo GIFs coming soon β once E2E-tested in Claude.
| Tool | When it fires | Renders |
|---|---|---|
render_bar_chart |
comparing discrete categories, rankings | vertical/horizontal bars with hover tooltips, click-to-highlight |
render_line_chart |
time-series, trends, continuous data | multi-series lines with shared crosshair tooltip |
render_pie_chart |
part-of-whole proportions, composition | pie or donut with percentage labels |
render_table |
structured data exploration | sortable + filterable data table |
render_scatter_chart |
(x, y) relationships, correlation, clusters | multi-series scatter with optional point-size encoding |
render_treemap |
hierarchical part-of-whole, many leaves | nested rectangles sized by value, palette-tinted by branch |
render_heatmap |
2D categorical Γ numeric intensity | matrix with palette gradient, hover tooltip per cell |
All chart widgets expose Copy CSV and Copy PNG buttons; the table exposes Copy CSV.
Sigil ships with an optional INCANTATIONS.md preset β copy it into Claude's Project Instructions and you can summon charts in ritual register:
Astrologers proclaim a week of Q1 sales: US 1200, EU 950, APAC 670.
View Air on monthly temperatures for Berlin and Madrid.
Animate Dead from revenue by region.
Includes Might & Magic homages (Town Portal, View Earth/Air, Resurrection, Scry, Animate Dead) for genre fans.
Add to your Claude Desktop config (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"sigil": {
"command": "npx",
"args": ["-y", "@real-case/sigil"]
}
}
}Restart Claude Desktop. You should now see sigil in the tools list.
Add to .vscode/mcp.json:
{
"servers": {
"sigil": {
"command": "npx",
"args": ["-y", "@real-case/sigil"]
}
}
}Requires a Claude.ai paid plan.
- Run Sigil in HTTP mode somewhere publicly reachable (Railway, Cloudflare Workers, or a tunnel during development).
- In Claude β Settings β Connectors β Add custom connector β paste the HTTPS URL ending in
/mcp.
For local development with Claude Web, use cloudflared:
npm run dev # terminal 1 β starts on :3001
npx cloudflared tunnel --url http://localhost:3001 # terminal 2 β gives HTTPS URLRender an interactive bar chart for comparing discrete categories or showing rankings. Supports vertical/horizontal orientation, hover tooltips, click-to-highlight.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title above the bars |
data |
Array<{ label, value, color? }> |
yes | At least one bar |
data[].label |
string |
yes | Category label |
data[].value |
number |
yes | Bar length |
data[].color |
string |
no | Per-bar color override (e.g. "#6366F1") |
orientation |
"vertical" | "horizontal" |
no | Default "vertical" |
xlabel |
string |
no | X-axis label |
ylabel |
string |
no | Y-axis label |
Render an interactive line chart with one or more series. Use for time-series, trends, or any continuous numeric data.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title |
series |
Array<{ name, data }> |
yes | One or more series |
series[].name |
string |
yes | Series name (legend + tooltip) |
series[].data |
Array<{ x, y }> |
yes | Points; x can be string or number |
xlabel |
string |
no | X-axis label |
ylabel |
string |
no | Y-axis label |
All-numeric x triggers a numeric axis (correct spacing for sparse values); any string switches to a category axis.
Render an interactive pie or donut chart for part-of-whole proportions.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title |
data |
Array<{ label, value, color? }> |
yes | Slices; values must be β₯ 0 |
variant |
"pie" | "donut" |
no | Default "donut" |
Slices under 4% hide their inline percentage label (still visible in the tooltip).
Render an interactive data table with sortable columns and text-search filtering.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Table title |
columns |
Array<{ key, label, align? }> |
yes | Column definitions in display order |
columns[].key |
string |
yes | Row property name |
columns[].label |
string |
yes | Header text |
columns[].align |
"left" | "right" | "center" |
no | Default: right for numeric, left otherwise |
rows |
Array<Record<string, string | number>> |
yes | Rows keyed by column.key |
sortable |
boolean |
no | Default true |
filterable |
boolean |
no | Default true |
Render an interactive scatter plot for showing the relationship between two numeric variables. Optional point size encodes a third metric.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title |
series |
Array<{ name, data }> |
yes | One or more series; rendered in distinct palette colors |
series[].name |
string |
yes | Series name (legend + tooltip) |
series[].data |
Array<{ x, y, size? }> |
yes | Points; x and y are numeric; optional positive size |
xlabel |
string |
no | X-axis label |
ylabel |
string |
no | Y-axis label |
Render an interactive treemap for hierarchical part-of-whole data with many leaves where a pie chart would be unreadable.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title |
data |
Array<{ label, value, color?, children? }> |
yes | Top-level nodes; nested children are recursively the same shape |
data[].label |
string |
yes | Node label shown in the rectangle and tooltip |
data[].value |
number |
yes | Non-negative; for parents may be 0 since children sum is used |
data[].color |
string |
no | Per-node color override |
data[].children |
same shape | no | Nested groupings |
Render an interactive heatmap matrix: a 2D grid where each cell's color encodes a numeric intensity. The cell color scales linearly from the surface background (low) to the primary palette accent (high), so the same gradient adapts cleanly to dark and light themes.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string |
yes | Chart title |
xLabels |
string[] |
yes | Column labels along the x-axis |
yLabels |
string[] |
yes | Row labels along the y-axis |
cells |
Array<{ x, y, value }> |
yes | x indexes xLabels, y indexes yLabels, value is the cell intensity. Missing combinations render as empty cells. |
xlabel |
string |
no | X-axis title |
ylabel |
string |
no | Y-axis title |
npm install
npm run dev # HTTP server on :3001 (for Claude Web via cloudflared)
npm run dev:stdio # stdio server (for Claude Desktop / VS Code)
npm run dev:sandbox # in-browser widget sandbox β pick any widget + preset, toggle theme / viewport / debug overlay
npm run typecheck # tsc --noEmit
npm test # vitest: payload guards, registry, tool registration
npm run build # bundle 7 widgets + compile server
npm start # run compiled HTTP server
npm run start:stdio # run compiled stdio serversrc/
βββ server.ts # HTTP entry (Express + StreamableHTTPServerTransport)
βββ stdio.ts # stdio entry β npx sigil
βββ mcp-server.ts # shared factory β registers tools + resources
βββ tools/ # tool definitions + input schemas
β βββ bar-chart.ts
β βββ line-chart.ts
β βββ pie-chart.ts
β βββ table.ts
β βββ scatter-chart.ts
β βββ treemap.ts
β βββ heatmap.ts
βββ resources/ # ui:// resource serving for bundled widget HTMLs
βββ registry.ts # single source of truth β server tools, resources, build
βββ shared/payloads.ts # contract types between server and widgets
βββ __tests__/ # vitest suites: registry, payload guards, registration
βββ widgets/ # React + Recharts widget entries
βββ shared/ # theme tokens, export utils, Toolbar, mountWidget shell
βββ bar-chart/
βββ line-chart/
βββ pie-chart/
βββ table/
βββ scatter-chart/
βββ treemap/
βββ heatmap/ # hand-rolled SVG (no Recharts)
Each widget bundles to a standalone single-file HTML via Vite + vite-plugin-singlefile, then gets served as a ui://sigil/<widget> resource by the MCP server. The host renders it in a sandboxed iframe and communicates with it via postMessage per the MCP Apps spec.
MIT β see LICENSE.