nteract/semiotic
This server provides AI coding assistants with MCP tools to discover, generate, validate, and report on Semiotic data visualizations.
getSchema— Retrieve the prop schema for a specific Semiotic chart component (e.g.,LineChart) or list all available components, including which are renderable to static SVG.suggestChart— Pass 1–5 sample data objects and an optional intent (e.g.,comparison,trend,distribution) to receive ranked chart type recommendations with example props tailored to your data.renderChart— Generate a static SVG image of a chart by passing a component name and its props. Supports chart types includingLineChart,BarChart,ForceDirectedGraph,SankeyDiagram,ChoroplethMap, and more.diagnoseConfig— Analyze a chart configuration for common problems such as empty data, missing accessors, bad dimensions, or wrong data shape, and receive actionable fixes.reportIssue— Generate a pre-filled GitHub issue URL for bug reports or feature requests, optionally including labels and reproduction steps.
Provides an MCP server and machine-readable schemas for generating and validating React-based chart components, supporting everything from standard line charts to complex network graphs and geographic visualizations.
Supports the translation of Vega-Lite specifications into Semiotic configurations, enabling AI agents to convert standardized chart definitions into React-based visualizations.

A React data visualization library designed for AI-assisted development.
Simple charts in 5 lines. Network graphs, streaming data, and coordinated dashboards when you need them. Structured schemas and an MCP server so AI coding assistants generate correct chart code on the first try.
What's New in 3.8.0
3.8.0 makes chart status, layout, and review workflows more explicit:
ChartContainernotifications add a non-intrusive bell/popover for chart-level findings.ForceDirectedGraph can run expensive layouts in a Web Worker with synchronous SSR/hydration parity.
x-bandannotations, minimum-width interval lanes, and custom-layout readback make dense, time-oriented charts easier to inspect.The DataPitfalls bridge and GoFish DisplayList adapter remain experimental and are exposed from
semiotic/experimentalwithunstable_names.
import { LineChart } from "semiotic/xy"
<LineChart
data={salesData}
xAccessor="month"
yAccessor="revenue"
/>Related MCP server: nakkas
Why Semiotic
Semiotic is a data visualization library for React that combines broad chart coverage with first-class AI tooling. It handles the chart types that most libraries skip — network graphs, streaming data, statistical distributions, coordinated views — and ships with machine-readable schemas so LLMs can generate correct code without examples.
Built for AI-assisted development
Semiotic ships with everything an AI coding assistant needs to generate correct visualizations without trial and error:
semiotic/ai— a single import with the schema-backed chart capability catalog (XY, ordinal, network, realtime, geo, value), optimized for LLM code generation. Seeai/surface-manifest.jsonfor the generated current inventory. Note: the published entry files are pre-bundled, so importing one chart fromsemiotic/aistill ships most of the bundle — treat it as a codegen/tooling surface and use family subpaths (semiotic/xy,semiotic/geo,semiotic/value, …) in production code, at roughly half the single-chart cost.ai/schema.json— machine-readable prop schemas for every componentnpx semiotic-mcp— an MCP server for tool-based chart rendering in any MCP clientnpx semiotic-ai --doctor— validate component + props JSON from the command line with typo suggestions and anti-pattern detectiondiagnoseConfig(component, props)— programmatic anti-pattern detector with actionable fixes, spanning validation, encoding, accessibility, and misleading-design (deception) checksCLAUDE.md— instruction files auto-synced for Claude, Cursor, Copilot, Windsurf, and Clinellms.txt— machine-readable documentation following the emerging standard
Every chart includes a built-in error boundary, dev-mode validation
warnings with typo suggestions, and accessibility features (canvas
aria-label, keyboard-navigable legends, aria-live tooltips, SVG
<title>/<desc>) so AI-generated code fails gracefully with
actionable diagnostics instead of a blank screen.
Beyond standard charts
Network visualization. Force-directed graphs, Sankey diagrams, chord diagrams, tree layouts, treemaps, circle packing, and orbit diagrams — all as React components with the same prop API as LineChart.
Streaming data. Realtime charts render on canvas at 60fps with a ref-based push API. Built-in decay, pulse, and staleness encoding for monitoring dashboards.
Coordinated views. LinkedCharts provides hover cross-highlighting,
brush cross-filtering, coordinate-based linked crosshairs, and selection
synchronization across any combination of chart types — zero wiring.
Geographic visualization. Choropleth maps, proportional symbol maps, flow maps with animated particles, and distance cartograms — all canvas-rendered with d3-geo projections, zoom/pan, tile basemaps, and drag-rotate globe spinning.
Statistical summaries. Box plots, violin plots, swarm plots, histograms, LOESS smoothing, forecast with confidence envelopes, and anomaly detection. Marginal distribution graphics on scatterplot axes with a single prop.
First-class annotations. Annotations are data-bound objects, not post-hoc artwork. Labels, callouts, thresholds, enclosures, statistical overlays, and React widgets move with the chart and render through browser, SSR, and export paths. Opt into placement, hierarchy, density, progressive disclosure, audience-aware amount, provenance, and editorial lifecycle when the chart needs to communicate more than its encoding alone.
Start simple, go deep
Layer | For | Example |
Charts | Common visualizations with sensible defaults |
|
Frames | Full control over rendering, interaction, and layout |
|
Every Chart component accepts a frameProps prop to access the underlying
Frame API without leaving the simpler interface.
Serialization and interop
Charts serialize to JSON and back: toConfig, fromConfig, toURL,
copyConfig, configToJSX. Have Vega-Lite specs? fromVegaLite(spec)
translates them to Semiotic configs — works with configToJSX() for
full round-trip from notebooks and AI-generated specs.
Need an external pitfall review? The experimental unstable_toDataPitfallsChain() builds a
dependency-free chain input for datapitfalls,
combining the Semiotic config, JSX, reader grounding, diagnostics,
accessibility audit, and optional rendered SVG/image evidence:
import { unstable_toDataPitfallsChain } from "semiotic/experimental"
import { detectPitfalls } from "datapitfalls"
const input = unstable_toDataPitfallsChain("LineChart", props, {
narrative: "Monthly sales are accelerating.",
rendered: { svg, evidence },
})
const report = await detectPitfalls(input, { apiKey: process.env.ANTHROPIC_API_KEY })The return path stays dependency-free too. Use whole-chart findings as
ChartContainer notifications, and only turn findings into annotations after
your app can anchor them to marks or semantic positions:
import { ChartContainer } from "semiotic"
import { LineChart } from "semiotic/xy"
import {
unstable_toDataPitfallsAnnotations,
unstable_toDataPitfallsNotifications,
} from "semiotic/experimental"
const notifications = unstable_toDataPitfallsNotifications(report)
const annotations = unstable_toDataPitfallsAnnotations(report, {
anchorFor: (finding) =>
finding.ruleId === "truncated-axis" ? { x: 9, y: 9000 } : null,
})
<ChartContainer notifications={notifications}>
<LineChart {...props} annotations={annotations} />
</ChartContainer>When to use something else
Need a standard bar or line chart for a dashboard you'll never need to customize beyond colors and labels? Recharts has a larger ecosystem and more community examples. Need GPU-accelerated rendering for millions of data points? Apache ECharts handles that scale.
Semiotic is for projects that outgrow those libraries — when you need network graphs alongside time series, streaming data alongside static snapshots, or coordinated views across chart types.
Install
npm install semioticRequires React 18.1+ or React 19.
Quick Examples
Coordinated Dashboard
Hover one chart, highlight the same data in another — zero wiring:
import { LinkedCharts, Scatterplot, BarChart } from "semiotic"
<LinkedCharts>
<Scatterplot
data={data} xAccessor="age" yAccessor="income" colorBy="region"
linkedHover={{ name: "hl", fields: ["region"] }}
selection={{ name: "hl" }}
/>
<BarChart
data={summary} categoryAccessor="region" valueAccessor="total"
selection={{ name: "hl" }}
/>
</LinkedCharts>Streaming Metrics with Decay
Live data fades old points, flashes new ones, flags stale feeds:
import { RealtimeLineChart } from "semiotic"
const chartRef = useRef()
chartRef.current.push({ time: Date.now(), value: cpuLoad })
<RealtimeLineChart
ref={chartRef}
timeAccessor="time"
valueAccessor="value"
decay={{ type: "exponential", halfLife: 100 }}
staleness={{ threshold: 5000, showBadge: true }}
/>Network Graphs
Force-directed graphs and Sankey diagrams — same API as LineChart:
import { ForceDirectedGraph, SankeyDiagram } from "semiotic"
<ForceDirectedGraph
nodes={people} edges={friendships}
colorBy="team" nodeSize={8} showLabels
/>
<SankeyDiagram
edges={budgetFlows}
sourceAccessor="from" targetAccessor="to" valueAccessor="amount"
/>Geographic Visualization
Choropleth maps, flow maps, and distance cartograms with canvas rendering, zoom/pan, tile basemaps, and animated particles:
import { ChoroplethMap, FlowMap, DistanceCartogram } from "semiotic/geo"
<ChoroplethMap
areas={geoJsonFeatures} valueAccessor="gdp"
colorScheme="viridis" projection="equalEarth" zoomable tooltip
/>
<FlowMap
nodes={airports} flows={routes} valueAccessor="passengers"
showParticles particleStyle={{ color: "source", speedMultiplier: 1.5 }}
/>
<DistanceCartogram
points={cities} center="rome" costAccessor="travelDays"
showRings costLabel="days" lines={routes}
/>Streaming System Monitor
Live service topology with threshold alerting and click-to-inspect:
import { StreamNetworkFrame, ChartContainer, DetailsPanel, LinkedCharts } from "semiotic"
const chartRef = useRef()
chartRef.current.push({ source: "API", target: "Orders", value: 15 })
<LinkedCharts>
<ChartContainer title="System Monitor" status="live"
detailsPanel={
<DetailsPanel position="right" trigger="click">
{(datum) => <div>{datum.id}: {datum.value} req/s</div>}
</DetailsPanel>
}>
<StreamNetworkFrame ref={chartRef} chartType="sankey"
showParticles particleStyle={{ proportionalSpeed: true }}
thresholds={{ metric: n => n.value, warning: 100, critical: 250 }}
/>
</ChartContainer>
</LinkedCharts>Standard Charts
Line, bar, scatter, area — all the basics, with sensible defaults:
import { LineChart, BarChart } from "semiotic"
<LineChart
data={salesData}
xAccessor="month" yAccessor="revenue"
curve="monotoneX" showPoints
/>
<BarChart
data={categoryData}
categoryAccessor="department" valueAccessor="sales"
orientation="horizontal" colorBy="region"
/>All Chart Components
Category | Components |
XY |
|
Categorical |
|
Network |
|
Geo |
|
Realtime |
|
Coordination |
|
Layout |
|
Frames |
|
Vega-Lite Translation
Paste a Vega-Lite spec, get a Semiotic chart:
import { fromVegaLite } from "semiotic/data"
import { configToJSX, fromConfig } from "semiotic"
const config = fromVegaLite({
mark: "bar",
data: { values: [{ a: "A", b: 28 }, { a: "B", b: 55 }] },
encoding: {
x: { field: "a", type: "nominal" },
y: { field: "b", type: "quantitative" },
},
})
// Render directly
const { componentName, props } = fromConfig(config)
// → componentName: "BarChart", props: { data, categoryAccessor: "a", valueAccessor: "b" }
// Or generate JSX code
configToJSX(config)
// → <BarChart data={[...]} categoryAccessor="a" valueAccessor="b" />Supports bar, line, area, point, rect, arc, tick marks with encoding translation for color, size, aggregation, and binning.
Conversation Arc Telemetry
Capture and replay the path an AI-assisted chart session took:
import {
createLocalStorageConversationArcSink,
enableConversationArc,
getConversationArcStore,
loadConversationArc,
registerConversationArcSink,
} from "semiotic/ai"
const sink = createLocalStorageConversationArcSink({ key: "my-app:arc" })
registerConversationArcSink(sink)
enableConversationArc({ sessionId: "session-abc" })
getConversationArcStore().record({ type: "chart-rendered", component: "LineChart" })
loadConversationArc(sink.load(), { enabled: false })Bundle Sizes
Semiotic ships 17 stable module entry points. Don't import from "semiotic" unless you need everything — use the sub-path that matches your chart type.
The numbers below are first-party artifact cost: the gzip size of Semiotic's own code for each sub-path. They exclude React and other runtime dependencies, so they are not a prediction of a cold application bundle. Do not add artifact rows to estimate an app: dependency resolution and cross-import deduplication happen in the consumer bundler and are measured separately below.
Entry Point | gzip | What's inside |
| 101 KB | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |
| 82 KB | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |
| 85 KB | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |
| 62 KB | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |
| 111 KB | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |
| 110 KB | Streaming chart types, HOCs, and buffer helpers |
| 1 KB | Stream status and synced push hooks |
| 189 KB | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
| 189 KB | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |
| 188 KB | renderChart, renderChartWithEvidence, renderToStaticSVG, renderDashboard |
| 71 KB | ThemeProvider, validators, serialization — no chart components |
| 70 KB | Theme helpers and serialization utilities |
| 4 KB | ThemeProvider, useTheme, useReducedMotion, useHighContrast, useStreamStatus |
| 53 KB | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
| 52 KB | Pure layout functions (waffle, marimekko, flextree, dagre, …) |
| 1 KB | Glyph and React layout-selection helpers |
| 6 KB | Theme presets only (tufte, carbon, etc.) |
| 6 KB | Theme presets and token helpers |
| 4 KB | ThemeProvider/useTheme and hooks |
| 3 KB | bin, rollup, groupBy, pivot, fromVegaLite |
| 6 KB | BigNumber — focal-value KPI / scorecard (SingleValueFrame POC) |
| 98 KB | GaltonBoardChart, EventDropChart, PhysicsPileChart, CollisionSwarmChart, PhysicalFlowChart, PhysicsCustomChart |
| 1 KB | Matter.js migration helpers + optional peer guard (no chart components) |
| 1 KB | Rapier peer guard + adapter decision metadata (no chart components) |
| 394 KB | All schema-backed charts + validation — optimized for LLM code generation |
| 79 KB | suggestCharts, validateProps, describeChart, repairChartConfig, tool adapters — no chart components |
| 5 KB | DirectManipulationControl, CircularBrush, MobileStandardControls, auditVisualizationControls — no frame renderer |
| 258 KB | Everything below (full bundle) |
Cold-consumer named imports
The table above is first-party artifact cost, not an application bundle. The generated table
below measures a different thing: a fresh consumer bundles one retained named import from a packed
semiotic tarball through the public export path. It includes Semiotic and its resolved runtime dependencies,
but externalizes React/React DOM and optional adapter peers that the host application owns. Each row
starts cold, so use it to compare one public import choice—not to add together an application's rows.
The checked machine-readable baseline is benchmarks/setup/cold-consumer-imports.json; refresh it
after a production build with npm run docs:cold-consumer.
Method: fresh npm pack --ignore-scripts tarball → temporary consumer → minified/tree-shaken esbuild ESM bundle → gzip -9. React/React DOM and optional adapter peers are external; Semiotic and its resolved runtime dependencies are included.
Public named import | Runtime | gzip cold-consumer bundle |
| browser | 290.2 KiB |
| browser | 138.9 KiB |
| browser | 114.3 KiB |
| browser | 118.2 KiB |
| browser | 157.2 KiB |
| browser | 157.2 KiB |
| browser | 0.6 KiB |
| browser | 109.5 KiB |
| browser | 0.2 KiB |
| browser | 0.2 KiB |
| node | 249.5 KiB |
| node | 190.7 KiB |
| node | 249.9 KiB |
| browser | 414.4 KiB |
| browser | 44.0 KiB |
| browser | 0.4 KiB |
| browser | 102.8 KiB |
| browser | 3.4 KiB |
| browser | 3.4 KiB |
| browser | 4.4 KiB |
| browser | 20.4 KiB |
| browser | 18.9 KiB |
| browser | 1.8 KiB |
| browser | 1.3 KiB |
| browser | 1.3 KiB |
| browser | 0.9 KiB |
| browser | 5.6 KiB |
| browser | 1.3 KiB |
// Import from the sub-path, not from "semiotic"
import { LineChart } from "semiotic/xy"
import { BarChart } from "semiotic/ordinal"
import { SankeyDiagram } from "semiotic/network"
import { ChoroplethMap } from "semiotic/geo"Tree-shaking: Each sub-path is a separate, pre-bundled artifact marked "sideEffects": false, so importing from semiotic/xy never pulls in semiotic/ordinal or semiotic/network. Note the boundary: within a family artifact the charts are already combined into one module, so importing only LineChart from semiotic/xy still loads the whole XY family artifact (≈98 KB gz) — bundlers cannot tree-shake individual charts back out of a pre-bundled family. Cross-family separation is real; per-chart separation within a family is not (granular per-chart entries are planned). Pick the narrowest sub-path for your charts.
When to use "semiotic": Only if your app uses charts from 3+ categories (XY + ordinal + network) and you'd rather have one import than three. The full bundle is roughly the sum of every sub-path bundle above — see the semiotic row of the table for the current number.
TypeScript
Built with strict: true. Full type definitions ship with the package.
Generics for type-safe accessors:
interface Sale { month: number; revenue: number }
<LineChart<Sale>
data={sales}
xAccessor="month" // TS validates this is keyof Sale
yAccessor="revenue"
/>Server-Side Rendering
All chart components render SVG automatically in server environments — no special imports or configuration needed:
// Works in Next.js App Router, Remix, Astro — same component, same props
import { LineChart } from "semiotic"
// Server: renders <svg> with path/circle/rect elements
// Client: renders <canvas> with SVG overlay for axes
<LineChart data={data} xAccessor="date" yAccessor="value" />For standalone SVG/PNG/GIF generation (email, OG images, PDF, Slack), use the server entry point:
import { renderChart, renderToImage, renderToAnimatedGif } from "semiotic/server"
// SVG — sync, no dependencies
const svg = renderChart("LineChart", {
data, xAccessor: "date", yAccessor: "value",
theme: "tufte", title: "Revenue Trend",
})
// PNG — async, requires sharp
const png = await renderToImage("BarChart", { data, ... }, { format: "png", scale: 2 })
// Animated GIF — async, requires sharp + gifenc
const gif = await renderToAnimatedGif("line", data, { ... }, { fps: 12 })MCP Server
mcp-name: io.github.nteract/semiotic
Semiotic ships with an MCP server that lets AI coding assistants render charts, diagnose configuration problems, discover schemas, read packaged AI guidance, and get chart recommendations via tool calls.
Setup
Add to your MCP client config (e.g. claude_desktop_config.json for Claude Desktop):
{
"mcpServers": {
"semiotic": {
"command": "npx",
"args": ["semiotic-mcp"]
}
}
}No API keys or authentication required. The server runs locally via stdio. HTTP mode is also available for inspectors, web clients, and ChatGPT Apps SDK experiments: npx semiotic-mcp --http --port 3001. It binds to 127.0.0.1 by default; intentionally expose another interface with --host 0.0.0.0 or MCP_HOST=0.0.0.0. Since 3.7.2, HTTP mode is stateless: each request gets a fresh read-only MCP server + transport, so it can autoscale on serverless hosts without sticky sessions.
For ChatGPT developer mode, expose the HTTP endpoint over HTTPS with a tunnel and create a connector that points at https://<your-tunnel>/mcp. The experimental Apps SDK surface is renderInteractiveChart, which returns a text/html;profile=mcp-app widget template plus a hidden SVG payload rendered by Semiotic on the MCP server.
For a hosted deployment, see deploy/cloud-run. The wrapper runs the published semiotic-mcp
binary, exposes /mcp plus health endpoints, and supports MCP_ALLOWED_HOSTS for production
host-header allowlisting. For ChatGPT Apps domain verification, set
OPENAI_APPS_CHALLENGE_TOKEN so HTTP mode serves the raw token from
/.well-known/openai-apps-challenge.
Tools
Tool | Description |
| Render a Semiotic chart to static SVG. Supports the components returned by |
| Render a static-data chart as a ChatGPT Apps widget. Uses the same Semiotic server render path as |
| Return the prop schema for a specific component. Pass |
| Legacy sample-row recommender. Pass |
| Capability-based recommender for bounded row data. Returns ranked chart suggestions with scores, reasons, caveats, import paths, and ready-to-use props. |
| Recommend realtime charts from a stream schema, throughput, and retention hints. |
| Build a multi-panel dashboard suggestion that covers distinct analytical intents. |
| Recommend audience-literacy stretch picks from an |
| Check whether a requested chart fits a dataset and return ranked alternatives when it does not. |
| Return a statistical summary and chart-aware context for answering natural-language questions with optional annotations. |
| Check a chart configuration for common problems — empty data, bad dimensions, missing accessors, wrong data shape, and more. Returns a human-readable diagnostic report with actionable fixes. |
| Generate a pre-filled GitHub issue URL for bug reports or feature requests. Pass |
| List named theme presets or return ThemeProvider/CSS/token usage for a preset such as |
Resources
Resource | Description |
| Full machine-readable component schema JSON. |
| Component index showing renderable/browser-only status and MCP categories. |
| Generated inventory of the current AI schema, exports, renderability, tools, resources, and prompts. |
| Agent-visible semantic rules for color precedence, required prop combinations, push refs, and renderability. |
| Compact AI instructions with import rules, chart props, SSR guidance, and pitfalls. |
| Copy-paste chart examples by data shape. |
| ChatGPT Apps / MCP Apps widget template used by |
Prompts
Prompt | Description |
| Reusable workflow for choosing a chart, reading schema, diagnosing props, and rendering a preview. |
| Reusable workflow for debugging invalid props, rendering failures, and issue reports. |
Example: get schema for a component
Tool: getSchema
Args: { "component": "LineChart" }
→ Returns: { "name": "LineChart", "description": "...", "parameters": { "properties": { "data": ..., "xAccessor": ..., ... } } }Example: suggest a chart for your data
Tool: suggestChart
Args: {
"data": [
{ "month": "Jan", "revenue": 120, "region": "East" },
{ "month": "Feb", "revenue": 180, "region": "West" }
]
}
→ Returns:
1. BarChart (high confidence) — categorical field (region) with values (revenue)
2. StackedBarChart (medium confidence) — two categorical fields (month, region)
3. DonutChart (medium confidence) — 2 categories — proportional compositionExample: render a chart
Tool: renderChart
Args: {
"component": "BarChart",
"props": {
"data": [
{ "category": "Q1", "revenue": 120 },
{ "category": "Q2", "revenue": 180 },
{ "category": "Q3", "revenue": 150 }
],
"categoryAccessor": "category",
"valueAccessor": "revenue"
}
}
→ Returns: <svg>...</svg>Example: render a ChatGPT Apps widget
Tool: renderInteractiveChart
Args: {
"component": "BarChart",
"props": {
"title": "Revenue by Quarter",
"data": [
{ "quarter": "Q1", "revenue": 120 },
{ "quarter": "Q2", "revenue": 180 }
],
"categoryAccessor": "quarter",
"valueAccessor": "revenue"
}
}
→ Returns: structured chart summary for the model + hidden SVG/widget metadata for ChatGPT.Example: diagnose a broken config
Tool: diagnoseConfig
Args: { "component": "LineChart", "props": { "data": [] } }
→ Returns: ✗ [EMPTY_DATA] data is an empty array — Fix: provide at least one data pointExample: report an issue
Tool: reportIssue
Args: {
"title": "Bug: BarChart tooltip shows undefined for custom accessor",
"body": "When using valueAccessor='amount', tooltip displays 'undefined'.\n\ndiagnoseConfig output: ✓ no issues detected.",
"labels": ["bug"]
}
→ Returns: Open this URL to submit the issue: https://github.com/nteract/semiotic/issues/new?...CLI alternative
For quick validation without an MCP client:
npx semiotic-ai --list # list components with import paths and renderability
npx semiotic-ai --list --json # machine-readable component index
npx semiotic-ai --schema GaugeChart
npx semiotic-ai --suggest '{"data":[{"category":"A","value":10}],"intent":"comparison"}'
npx semiotic-ai --doctor # validate component + props JSON
npx semiotic-ai --schema # dump all chart schemas
npx semiotic-ai --compact # compact schema (fewer tokens)--doctor uses the full diagnoseConfig checks when dist is available and falls back to schema-only validation in clean source checkouts.
Where to find Semiotic for AI assistants
Semiotic is indexed by AI-coding-agent documentation tools so your assistant (Claude Code, Cursor, Cline, Copilot, etc.) can pull current docs and tools without copy-paste:
Context7 — context7.com/nteract/semiotic (configured via
context7.json)DeepWiki — deepwiki.com/nteract/semiotic
GitMCP — gitmcp.io/nteract/semiotic (exposes the repo as an MCP endpoint directly)
Official MCP Registry — search "semiotic" at registry.modelcontextprotocol.io
Smithery — smithery.ai/server/nteract/semiotic
Agent-facing API surface:
CLAUDE.md,ai/schema.json,ai/surface-manifest.json,ai/behaviorContracts.cjs— bundled in the npm tarball (seepackage.json#files); agents that install Semiotic locally read these directly.CLAUDE.mdis the quick-start cheat sheet (HOC props, push API, theming, usage notes);ai/schema.jsonis the JSON Schema for every chart's prop surface;ai/surface-manifest.jsonis the generated inventory;ai/behaviorContracts.cjscarries the agent-visible semantic rules (color precedence, push-mode requirements, ID-accessor contracts).semiotic.nteract.io/llms.txt+/llms-full.txt— deployed at the docs site per the llms.txt standard. Agents fetch the navigation map (llms.txt) or the full inlined docs (llms-full.txt) over HTTP; they're not part of the npm package itself.
Documentation
Charts — chart types with live examples
Frames — full Frame API reference
Features — axes, tooltips, interaction, responsive behavior, and composition
Annotations — first-class annotation types, design guidance, provenance, and lifecycle
Cookbook — advanced patterns and recipes
Playground — interactive prop exploration
Upgrading
Migration Guide — upgrading from v1.x or v2.x
Changelog — full release history
Contributing
See CONTRIBUTING.md. Our community follows the nteract Code of Conduct.
Acknowledgments
Development of this library owes a lot to Susie Lu, Jason Reid, James Womack, Matt Herman, Shelby Sturgis, and Tristan Reid.
The Sankey layout engine is based on sankey-plus
by Tom Shanley, which improved on his earlier
d3-sankey-circular with better cycle detection, hierarchical arc stacking,
and dynamic extent adjustment.
Semiotic icon based on an icon by Andre Schauer.
License
Maintenance
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nteract/semiotic'
If you have feedback or need assistance with the MCP directory API, please join our Discord server