ChartKitMCP docs

Chart input

The data, chart types, annotations and style options create_chart accepts.

create_chart, update_chart and get_live_chart_embed take the same chart input, except size, which only create_chart takes. Only chart_type is required by the schema. Every type except gantt and custom also needs table. Send numbers already scaled to the unit, such as 41.2 with "unit": "EUR m", not 41200000.

argumentsjson
{
  "chart_type": "clusteredBar",
  "table": {
    "categories": ["2021", "2022", "2023", "2024", "2025"],
    "series": [{ "name": "Online sales" }],
    "values": [[41.2, 48.9, 57.3, 66.0, 78.4]]
  },
  "unit": "EUR m"
}

Chart types

chart_typeUse it forTable shape
stackedBarComposition over timeSeries stack in each category. The first series is the top segment.
stackedBar100Mix shiftLike stackedBar; each stack is drawn as 100%.
clusteredBarTwo or three series side by side, or a plain single-series bar chartSeries sit next to each other in each category.
lineA trend over six or more pointsOne line per series.
scatterRelationship between two measuresCategories are the numeric x values as strings, such as "20". Each series holds y values.
waterfallA bridge from one total to anotherValues are signed steps. A cell set to "total" draws a subtotal bar.
donutOne part-of-whole with five slices or fewerOne series; each category is a slice.
mekkoMarket structure: segment size and shareCategories are columns, series are segments. A column's width is the sum of its values.
bubbleThree measures per itemCategories name the bubbles. Exactly three series, in the order x, y, size.
harveyBallCriteria against optionsSeries are rows, categories are columns, values are 0 to 100 fill.
ganttA project planSend gantt instead of table.
customWhat no native type draws: dumbbell, slope, heatmap, small multiplesA Vega-Lite spec in vega_lite. See custom charts.

For horizontal bars, send stackedBar, stackedBar100, clusteredBar or waterfall with "orientation": "horizontal". A single-series horizontal bar chart is a stackedBar with one series.

Fields

Data

chart_typestringrequired

The chart to draw. See chart types.

stackedBarstackedBar100clusteredBarlinescatterwaterfalldonutmekkobubbleharveyBallganttcustom
tableobject

The numbers. values is indexed values[seriesIndex][categoryIndex]. Required for every type except gantt and custom.

Table fields
categoriesstring[]required

The x-axis labels, one per column of data.

seriesobject[]required

One { "name": "…" } per row of data. Names identify series in highlight, colors and line_series.

valuesobject[][]required

One row per series with one value per category. Plain numbers are best. Strings such as "1,234", "12%" or "(5)" are read as numbers, and "total" marks a waterfall subtotal.

ganttobject

The project plan for chart_type: "gantt". See Gantt charts.

recordsobject

custom only. Record-shaped data for the Vega-Lite spec, instead of table. See custom charts.

vega_litestring | object

custom only. A Vega-Lite v5 spec, as a JSON string or object.

labelstring

custom only. A short name for the kind of chart, such as "Dumbbell".

Units

unitstring

The unit of every value, such as "EUR m", "%" or "k units". ChartKit picks one number format per chart from the data and the unit. "%" becomes a suffix on every label.

x_unitstring

The unit of a scatter or bubble chart's x values. "%" becomes a suffix on the x axis labels.

size_unitstring

The unit of a bubble chart's size series.

Callouts and focus

annotationsobject[]

Callouts drawn on the chart. Leave the field out to let ChartKit add the obvious one, send [] for none. See annotations.

highlightobject

Series or category names to keep in brand colour; everything else turns grey. Names must match the table exactly. Not used by gantt charts.

Highlight fields
seriesstring[]

Series names from table.series.

categoriesstring[]

Category names from table.categories.

sortstring

By default ChartKit sorts single-series bar charts and donuts largest first, unless the categories already read as a sequence: years, steps, stages, weekdays, numbers or arrows. "none" keeps your order, for funnels and processes. "value" sorts even a sequence.

valuenone

Layout and style

sizeobject

create_chart only. The box the image will fill on the slide, in points; a 16:9 Google Slides page is 720 × 405. ChartKit lays the chart out for the box and returns sizePt, the size to insert the image at, which fits inside it. update_chart keeps the box. Not for custom charts. See Put the chart on a slide.

Size fields
width_ptnumberrequired72 to 1440
height_ptnumberrequired72 to 1440
orientationstringdefault "vertical"

"horizontal" applies to stackedBar, stackedBar100, clusteredBar and waterfall.

verticalhorizontal
legendstring

Legend position, or "none" to hide it. Multi-series charts and donuts get a legend on the right by default.

righttopbottomleftnone
value_labelsboolean

false hides the value labels on bars, slices and points. Omit for the default, which labels every value.

value_axisbooleandefault true

The value axis with numbers, on bar, waterfall, line, scatter and bubble charts. false hides it.

gridlinesbooleandefault true

Light gridlines behind the marks, on the same chart types as value_axis.

colorsobject

Colour overrides by name, as hex or rgb(): a series name, or a category name in a one-series bar chart or donut. For example { "Revenue": "#1F4E79" }. Omit to use the brand palette.

line_seriesstring[]

Combo charts. Names of series drawn as lines over the bars, on stackedBar, stackedBar100 and clusteredBar. Put them last in the table; at least one series must stay a bar.

secondary_axisbooleandefault true

With line_series, gives the lines their own value axis on the right. false plots them on the bar axis.

center_labelobject

Donut only. A headline number in the hole with an optional caption under it.

Center label fields
valuestringrequired
captionstring

Text

Charts have no title, subtitle or footnote unless you send one. On a slide, the slide title usually carries the message and the source sits in a footnote outside the chart.

titlestring
subtitlestring
footnotestring

A line under the chart, such as the data source.

x_axis_titlestring

Title under the x axis. Do not repeat the unit given in x_unit.

y_axis_titlestring

Title beside the value axis. Do not repeat the unit given in unit.

Table shapes

The table is the same object for every native type except gantt. What the series and categories mean depends on the type, as the chart types table shows. A few near-miss shapes are accepted and converted.

  • A list of rows with a header row, where the first column holds the categories.
  • Series given as plain strings, or with their own values array.
  • Numeric categories, which become strings.
  • For a single series, values as a flat list.
table as rowsjson
[
  ["", "Revenue", "Cost"],
  ["2023", 10, 6],
  ["2024", 12, 7]
]

Waterfall totals

In a waterfall, each value is a step up or down. A cell set to "total" draws a bar from the axis to the running sum of every category before it. Give the first category its real starting value; a "total" there has nothing to sum.

argumentsjson
{
  "chart_type": "waterfall",
  "table": {
    "categories": ["2024", "Price", "Volume", "Mix", "FX", "2025"],
    "series": [{ "name": "Revenue" }],
    "values": [[120, 8.5, 6.2, -2.1, -3.4, "total"]]
  },
  "unit": "EUR m"
}

Annotations

annotations is a list of callouts, each with a kind: delta, cagr, refLine, band, level, axisBreak. Anchored kinds point at a bar or point by index.

An anchor is an object with a category_index and an optional series_index, both 0-based. Without series_index it points at the stack total. On stacked and waterfall charts, a delta or CAGR with series_index measures that series' own values. On clustered bars, lines and scatter, it anchors to that one series.

category_indexintegerrequired0 or more
series_indexinteger0 or more
annotationsjson
[{ "kind": "cagr", "from": { "category_index": 0 }, "to": { "category_index": 4 } }]

delta

fromobjectrequired
toobjectrequired
modestring

Leave it out for a relative change such as +22%. ChartKit switches to the absolute difference when either value is zero or negative, or the unit is %. Send "abs" to always show the difference in the chart's unit.

abspct

cagr

Compound annual growth between two anchors. Only for yearly categories such as 2021 or FY24; use a delta for months or quarters.

fromobjectrequired

The earlier year.

toobjectrequired

The later year.

refLine

A horizontal line at a target, average or threshold.

valuenumberrequired
labelstring

band

A value range drawn as two reference lines with one label.

fromnumberrequired
tonumberrequired
labelstring

Defaults to the range, such as 40–60.

level

A bracket between two anchors.

fromobjectrequired
toobjectrequired
labelstring

axisBreak

Breaks the value axis so one large bar stops flattening the rest. Use it when the largest value is more than about four times the next. Leave out from and to to cut the largest gap between bars automatically; give both to choose the hidden range. One per chart, and not on donut, mekko or Harvey ball charts.

fromnumber
tonumber

Must be greater than from.

argumentsjson
{
  "chart_type": "clusteredBar",
  "table": {
    "categories": ["Instagram", "TikTok", "YouTube", "Pinterest", "Snapchat"],
    "series": [{ "name": "Mentions" }],
    "values": [[1840, 312, 268, 141, 96]]
  },
  "unit": "k",
  "annotations": [{ "kind": "axisBreak" }],
  "highlight": { "categories": ["TikTok"] }
}

Automatic callouts

When annotations is left out of create_chart, ChartKit adds at most one callout and one axis break, and the result text says which. They are stored with the chart, so update_chart keeps them until you send new annotations.

AddedWhen
cagrstackedBar, clusteredBar or line with three or more categories that are all years. Measured first to last on the highlighted series, else the stack total on stacked bars, else the first series.
deltaThe same charts with three or more quarters, months or weeks. A relative change, first to last.
axisBreakstackedBar or clusteredBar with three or more categories whose tallest bar is more than four times the next.
Turning them off

Send "annotations": [] for a chart without callouts. No callout is added with sort: "value" or line_series, and no axis break with line_series.

Gantt charts

Send gantt instead of table. Dates are ISO, such as "2026-01-05", or natural language, such as "5 Jan 2026" or "Q1 2026". annotations, highlight, sort, unit and orientation do not apply.

argumentsjson
{
  "chart_type": "gantt",
  "gantt": {
    "activities": [
      { "name": "Data collection", "start": "2026-01-05", "end": "2026-02-13", "progress": 100 },
      { "name": "Social listening", "start": "2026-02-02", "end": "2026-03-20", "progress": 40 },
      { "name": "Client workshop", "milestone": "2026-03-26" },
      { "name": "Final report", "start": "2026-03-23", "end": "2026-04-17", "planned": true }
    ],
    "shades": [{ "from": "2026-04-06", "to": "2026-04-10", "label": "Easter" }],
    "dateLines": [{ "date": "today", "label": "Today" }]
  }
}
activitiesobject[]required

One entry per row of the plan.

Activity fields
namestringrequired
startstring

First day of the bar. Give start and end together, or neither.

endstring

Last day the bar covers, inclusive.

milestonestring

A single-day milestone on this row.

progressnumber0 to 100

Completion shading from the bar's left edge, in percent.

plannedboolean

Draws the bar as a dashed outline without fill.

calendarobject

The visible timeline as start and end dates. Omit either to fit the plan.

shadesobject[]

Vertical bands across all rows, such as a holiday, each with from, to and an optional label.

dateLinesobject[]

A vertical line with a label at one date, each with date and an optional label. date may be "today".

A table also works as a fallback: one series per activity and the categories Start, End and Milestone, with date strings or "" in the cells.

Custom charts

chart_type: "custom" draws a Vega-Lite v5 spec in ChartKit's styling, for charts no native type covers. Prefer a native type when one fits; native charts stay editable in the ChartKit editor and support annotations and label control.

  • The data is always { "name": "table" }. Without records, the table is read in long form with the fields category, series and value.
  • With records, each row is one category: key names the category field, and fields lists the other columns by id. Compute derived columns into the rows, because the spec cannot calculate.
  • No width, height or title in the spec, no calculate transforms and no expressions. Colours come from { "scheme": "chartkit" } or the tokens ck:1 to ck:8, ck:muted, ck:ink, ck:pos and ck:neg.
  • A spec that ChartKit rejects returns the errors in the message, so you can fix it and call again.
records.keystringrequired
records.fieldsobject[]required

Each with an id the spec uses and an optional name for the column header.

records.rowsobject[]required

Limits

  • The stored chart model and the stored input can each be up to 512 KB of JSON.
  • One axisBreak per chart.
  • Harvey ball values must be between 0 and 100. Waterfall is the only type that accepts "total" cells.