Skip to content

real-case/sigil

Repository files navigation

Sigil

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

Demo GIFs coming soon β€” once E2E-tested in Claude.

Tools

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.

Optional: Ritual Mode

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.


Install

Claude Desktop

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.

VS Code (GitHub Copilot Chat)

Add to .vscode/mcp.json:

{
  "servers": {
    "sigil": {
      "command": "npx",
      "args": ["-y", "@real-case/sigil"]
    }
  }
}

Claude Web (Custom Connector)

Requires a Claude.ai paid plan.

  1. Run Sigil in HTTP mode somewhere publicly reachable (Railway, Cloudflare Workers, or a tunnel during development).
  2. 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 URL

Tool reference

render_bar_chart

Render 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_line_chart

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_pie_chart

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_table

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_scatter_chart

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_treemap

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_heatmap

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

Development

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 server

Architecture overview

src/
β”œβ”€β”€ 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.


License

MIT β€” see LICENSE.

About

Live, interactive chart widgets for Claude and other MCP Apps hosts.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors