Data shape
Each chart takes one data object in its own shape: the values, the scale they sit on and how labels read. The shape is fixed per type and published as a JSON Schema, so your editor and your agent can check it before anything renders.
A waterfall, for example
cash-bridge.ts
const cashBridge: WaterfallData = { max: 4, ticks: ["4M", "3M", "2M", "1M", "0"], fmt: (v) => v.toFixed(2) + "M", steps: [ { label: "OPEN", v: 1.82, total: true }, { label: "SALES", v: 1.24 }, { label: "REFUND", v: -0.09 }, { label: "CLOSE", v: 1.91, total: true }, ],}Check it
Every chart's docs page links its JSON Schema (usechartory.com/schemas/waterfall.json for this one), and the MCP server returns the same schema with get_chart_spec. A function such as fmt can't travel as JSON: the schema names it, your code passes it.
Loading, empty and error
A widget takes a state in place of its chart and blocks while data is on its way or isn't there.