blueprint-chart/mcp
This server lets LLMs author, validate, render, and share Blueprint Chart (.bpc) charts using MCP tools, resources, and prompts.
Validate DSL: Parse and semantically validate
.bpcsource, returning structured errors and warnings with suggestions.Inspect DSL: Summarize a chart's type, scenes, series, rows, highlights, annotations, and other structural details.
Recommend chart type: Get ranked chart-type suggestions based on column types, row count, and a goal.
Render charts: Render to SVG, PNG, or HTML with width/height control, optional disk saving, and stateless hosted URLs.
List chart types: Enumerate all renderable chart types with aliases and summaries.
Describe chart type: Get when-to-use, when-not-to-use, properties, directives, and data shape for a specific chart type.
Get example: Fetch canonical
.bpcsamples by sample name or chart type.Search examples: Find canonical examples by topic keywords and/or chart type.
Get grammar: Retrieve the full DSL grammar reference or a focused section.
List palettes: List named color palettes and their hex colors for
colorPalette.Export charts: Create editable and embeddable shareable URLs with an inline preview.
Reference resources: Read
bpc://resources like handbook pages, guides, chart-type docs, grammar, and samples.Authoring prompt: Use the
author_chartprompt to guide end-to-end chart creation, validation, and iteration.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@blueprint-chart/mcpcreate a bar chart of monthly revenue"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Status | |
CI checks | |
Latest version | |
Release date | |
Open issues | |
Websites |
|
Smithery |
The MCP exposes Blueprint Chart's dataviz handbook, DSL grammar reference, chart-type docs, and canonical samples as MCP resources, plus eleven deterministic tools: validate_dsl, inspect_dsl, recommend_chart_type, render, list_chart_types, describe_chart_type, get_example, get_grammar, export_chart, search_examples, and list_palettes. Your LLM writes the .bpc; the MCP grounds it in real dataviz pedagogy and gives it a tight feedback loop.
Install
npx @blueprint-chart/mcp # stdio (for Claude Desktop, Claude Code, Cursor)
npx @blueprint-chart/mcp --http # HTTP/SSE on 127.0.0.1:4321Related MCP server: sales-analytics
Use with Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"blueprint-chart": {
"command": "npx",
"args": ["-y", "@blueprint-chart/mcp"]
}
}
}Use with Claude Code
claude mcp add blueprint-chart \
-e BLUEPRINT_CHART_EDITOR_URL=https://blueprintchart.com \
-e BLUEPRINT_CHART_DOCS_URL=https://docs.blueprintchart.com \
-- npx -y @blueprint-chart/mcpTools
Tool | Purpose |
| Parse |
| Parse and summarize: |
| Rank chart types for a given column shape and row count |
| Render to SVG (default), PNG, or HTML; with |
| List all renderable chart types (tool equivalent of |
| Properties, when-to-use, when-NOT-to-use, and data-shape for one chart type (tool equivalent of |
| Fetch a canonical |
| Find canonical examples by topic keywords and/or chart type (returns pointers; fetch full DSL with |
| Full DSL syntax reference (tool equivalent of |
| List named colour palettes with hex colours for |
| Validate a |
The discovery tools (list_chart_types, describe_chart_type, get_example, search_examples, get_grammar, list_palettes) let clients without MCP resource support access the same reference material that the bpc:// URIs expose.
Saving rendered output
The render tool can write its output to disk via save: <path>. This is disabled by default. Set MCP_FS_WRITE_DIR to a directory to enable it — ideally an absolute path; a relative value is resolved from the server's working directory at startup. Every write lands inside that directory (a sandbox), so you never have to worry about where a client puts files: relative save paths are joined to it, an absolute path already inside it is used as-is, and any other absolute path is re-anchored under it (the leading slash is stripped and the rest joined on, so save: "/tmp/foo.png" becomes <dir>/tmp/foo.png). Only paths that still escape via ../ traversal are rejected. Missing subdirectories are created automatically. Containment is checked lexically (no realpath), so a symlink whose lexical path is inside the sandbox still passes the check and is then resolved by the OS at write time — if its target is outside the sandbox, the write reaches it. Avoid placing symlinks in the sandbox if isolation matters to you.
Add the -e flag to your claude mcp add command:
claude mcp add blueprint-chart \
-e MCP_FS_WRITE_DIR=/path/to/output \
-- npx -y @blueprint-chart/mcpResources
bpc://grammar— full DSL syntax referencebpc://handbook/<slug>— dataviz pedagogy (choosing, design-principles, color, typography, annotations, accessibility, ...)bpc://guide/<slug>— usage guides (scenes, palettes, data-transforms, ...)bpc://chart-types/<slug>— per-chart-type docsbpc://samples/<id>— canonical.bpcexamplesbpc://reference/dsl/<slug>,bpc://reference/api/<slug>— full reference
Prompts
author_chart— primes the LLM end-to-end (read → write → validate → render → iterate)
Examples
Quickstart with Claude
Once the MCP is connected, ask Claude to make a chart:
You: Make a horizontal bar chart of English letter frequencies — top 10, highlight E.
Claude: (calls
list_chart_types,get_example({ chartType: "bar-horizontal" }), writes the.bpc, callsvalidate_dslto confirm it parses, callsrenderwithformat: 'png'and shows you the image and the source)Here's the chart:
![image]
chart bar-horizontal { title = "E is the most frequent letter in English" sort = descending valueLabels = true highlight "E" data { "E" = 12.70; "T" = 9.06; "A" = 8.17; ... } }
The MCP grounds Claude in real dataviz pedagogy (the handbook) before it writes a single line of DSL, then closes the loop with deterministic parse + render feedback.
What .bpc looks like
chart bar-vertical {
title = "E is the most frequent letter in English"
description = "How often each letter appears in typical English text"
source = "Lewand, Cryptological Mathematics"
colorPalette = "London"
sort = descending
valueLabels = true
highlight "E"
data {
"E" = 12.70
"T" = 9.06
"A" = 8.17
"O" = 7.51
...
}
}Full grammar at bpc://grammar; 17 canonical samples at bpc://samples/<id> (letter-frequency, co2-emissions, quarterly-revenue, browser-market, temperature-anomaly, population-stacked-bar, ...).
validate_dsl — parse with structured diagnostics
Request:
{
"name": "validate_dsl",
"arguments": { "source": "chart bar-vertical {\n title = \"oops\n}" }
}Response — valid is false; each entry in errors[] carries a code, human-readable message, and an actionable suggestion:
{
"valid": false,
"errors": [
{
"code": "E_PARSE",
"message": "Expected \"\\\"\" but end of input found.",
"suggestion": "Close the string literal on line 2."
}
],
"warnings": []
}inspect_dsl — structured summary
Request:
{ "name": "inspect_dsl", "arguments": { "source": "<.bpc source>" } }Response:
{
"ok": true,
"data": {
"chartType": "bar-vertical",
"scenes": [{ "index": 1, "hasTransition": false }],
"hasAnnotations": false,
"hasColorizes": false,
"hasHighlights": true,
"hasAreaFills": false,
"seriesCount": 0,
"rowCount": 26
}
}recommend_chart_type — ranked suggestions
Request:
{
"name": "recommend_chart_type",
"arguments": { "columnTypes": ["date", "number", "number", "number"], "rowCount": 24 }
}Response:
{
"ok": true,
"data": {
"recommendations": [
{ "chartType": "line-multi", "label": "Multi-Line Chart", "fitness": "best",
"reason": "1 date + 3 numeric columns — compare trends" },
{ "chartType": "bar-multi", "label": "Grouped Bar Chart", "fitness": "alternative",
"reason": "Can also show as grouped bars" }
]
}
}render — SVG (default), PNG, or HTML
Request:
{
"name": "render",
"arguments": { "source": "<.bpc source>", "format": "png", "width": 800, "height": 500 }
}Response:
{
"ok": true,
"data": {
"svg": "<svg ...>...</svg>",
"png": "<base64-encoded image>",
"mimeType": "image/png",
"urls": {
"png": "https://mcp.blueprintchart.com/render.png?bpc64=…",
"svg": "https://mcp.blueprintchart.com/render.svg?bpc64=…",
"bpc": "https://mcp.blueprintchart.com/render.bpc?bpc64=…"
}
}
}The urls field is only present when MCP_PUBLIC_URL is configured; every render and export_chart response then includes these stateless links, with the chart data travelling inside the URL (as bpc64, a URL-safe base64 encoding of the .bpc source) — no session, no server state required. Set modelVisible:false in the request to drop the inline image from the response entirely, spending no image tokens.
If rasterization fails (rare), errors[] is non-empty — each entry has a code ("E_RENDER") and a suggestion — and the response still includes the SVG that was successfully produced, so partial success is preserved.
Hosted render URLs
Embed a chart directly in a page:
<img src="https://<your-mcp-host>/render.png?bpc64=<bpc64value>&width=800&height=500" alt="My chart" width="800" height="500">/render.bpc serves the raw .bpc source — it's "view source" for any chart URL, handy for sharing or reproducing a chart from its link alone.
Sources whose encoding exceeds 8 KB return 413 from the endpoints (and the tool omits urls, returning urlsOmitted: "source-too-large" instead) — use the inline PNG for very large charts.
Reading a resource
{ "uri": "bpc://handbook/choosing" }Returns the full Markdown of the "Choosing the Right Chart" handbook page (same content as docs.blueprintchart.com).
{ "uri": "bpc://samples/letter-frequency" }Returns the raw .bpc source for the letter-frequency sample as text/plain — exactly what the LLM should imitate.
License
MIT
Available Tools
11 toolsdescribe_chart_typeARead-onlyIdempotent
Return everything an LLM needs to write a .bpc for a given chart type — typically your second call, after recommend_chart_type. Input: { chartType: "bar-horizontal" } (or any canonical/alias name). Returns summary, when-to-use, when-NOT-to-use, full property list with enum choices, data-shape example, and a pointer to a canonical sample.
| Name | Required | Description | Default |
|---|---|---|---|
| chartType | Yes | A chart type or alias to describe, e.g. "bar-horizontal" or "line". |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Canonical chart-type identifier. |
| aliases | Yes | Accepted alias names. |
| docsUrl | No | Public docs URL. |
| summary | Yes | One-line description. |
| dataShape | Yes | The data shape this chart type expects. |
| whenToUse | Yes | Situations this chart type fits. |
| directives | Yes | Supported directives. |
| properties | Yes | Supported chart properties. |
| exampleSlug | No | Id of a canonical sample for this type. |
| whenNotToUse | Yes | Situations to avoid it. |
export_chartARead-onlyIdempotent
Turn a validated .bpc source into shareable URLs plus an inline visual preview of what was published. Returns { copyUrl, embedUrl, urls?, frame } and a scene-0 PNG image block so you can confirm the chart looks right before sharing. copyUrl opens an editable copy in the editor; embedUrl is a read-only iframe target; urls.{png,svg,bpc} (when MCP_PUBLIC_URL is set) are stateless rendered-image/source links. Set modelVisible:false to show the preview to the user only. Requires BLUEPRINT_CHART_EDITOR_URL; preview failures never block the export.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | The .bpc chart source to validate and publish to shareable URLs. | |
| modelVisible | No | When false, the preview image is shown to the user but not sent to the model. |
Output Schema
| Name | Required | Description |
|---|---|---|
| urls | No | Stateless hosted render URLs (only when MCP_PUBLIC_URL is set). |
| frame | Yes | Frame metadata extracted from the chart. |
| copyUrl | Yes | Editor URL that opens an editable copy of the chart. |
| embedUrl | Yes | Read-only iframe-embeddable URL. |
| previewOmitted | No | Set when the scene-0 preview render failed. |
get_exampleARead-onlyIdempotent
Return a canonical .bpc example. Pass { name } for a specific sample id, { chartType } for the first sample of that type, or no args for a starter sample.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Return a specific sample by its id, e.g. "co2-emissions". | |
| chartType | No | Return the first canonical sample for this chart type (or alias). |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Sample id. |
| dsl | Yes | The full .bpc source of the sample. |
| title | Yes | Sample title. |
| chartType | Yes | Chart type of the sample. |
get_grammarCRead-onlyIdempotent
Return the .bpc DSL grammar as markdown. Pass { section: "chart" | "data" | "properties" | "scenes" | "annotations" } for a focused subset, or no args for the full grammar.
| Name | Required | Description | Default |
|---|---|---|---|
| section | No | Limit to one grammar section: "chart", "properties", "scenes", or "annotations". Omit (or "all") for the full grammar. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | The grammar reference as markdown. |
| section | Yes | The grammar section returned. |
inspect_dslARead-onlyIdempotent
Parse a .bpc source and return a structured summary: chartType, scenes, data (rowCount, entryCount, labels, seriesNames, multiSeries), annotation/colorize/highlight/area-fill presence flags, series count.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | The .bpc chart source to parse and summarize. |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | Summary of the data block. |
| scenes | Yes | Per-scene summaries (always at least one). |
| chartType | Yes | Declared chart type. |
| seriesCount | Yes | Number of series. |
| hasAreaFills | Yes | Whether any area-fill is present. |
| hasColorizes | Yes | Whether any non-highlight colorize is present. |
| hasHighlights | Yes | Whether any highlight is present. |
| hasAnnotations | Yes | Whether any annotation/range/note is present. |
list_chart_typesARead-onlyIdempotent
Reference list of every chart type the renderer supports, with aliases and one-line summaries. To choose a type for a dataset, call recommend_chart_type instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| chartTypes | Yes | Every renderable chart type. |
list_palettesARead-onlyIdempotent
List every named colour palette with its label and hex colours, for use in colorPalette = "<name>".
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| palettes | Yes | Every named palette. |
recommend_chart_typeARead-onlyIdempotent
Start here before writing any .bpc. Takes column types, row count, and the user's goal (a prose sentence — it determines the chart family: comparison/ranking/part-to-whole/composition-over-time/trend/range). Returns ranked chart-type recommendations plus guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| goal | No | Optional prose sentence describing what the chart should show. Determines the chart family (comparison / ranking / part-to-whole / composition-over-time / trend / range). | |
| rowCount | Yes | Number of data rows in the dataset. | |
| columnTypes | Yes | The type of each data column, in order: "string", "number", or "date". |
Output Schema
| Name | Required | Description |
|---|---|---|
| guidance | No | Prose next-step guidance for the top recommendation. |
| recommendations | Yes | Ranked chart-type recommendations, best first. |
renderAIdempotent
Render a .bpc source to SVG (default), PNG, or HTML. With format:"png" the chart comes back as an inline IMAGE you and the user can both see — render, look at the result, fix issues, re-render. Always returns structured frame metadata. When MCP_PUBLIC_URL is set the response includes stateless urls ({png,svg,bpc}). Set modelVisible:false to display the image to the user without spending model image tokens. Pass save:<path> to write the output into MCP_FS_WRITE_DIR instead of returning it inline. Width/height are capped at 1600; PNGs are rasterized at 2× for retina sharpness.
| Name | Required | Description | Default |
|---|---|---|---|
| save | No | Optional output path, always resolved inside MCP_FS_WRITE_DIR (relative paths are joined to it; absolute paths are re-anchored under it). When set, the output is written to disk and omitted from the response. Requires MCP_FS_WRITE_DIR. | |
| scene | No | Zero-based scene index to render, for charts that define scenes. Omit for the base chart (scene 0). | |
| width | No | Output width in pixels (max 1600). PNGs are rasterized at 2x for retina sharpness. | |
| format | No | Output format. "svg" (default) and "html" return text; "png" returns an inline image you and the user can both see. | svg |
| height | No | Output height in pixels (max 1600). | |
| source | Yes | The .bpc chart source to render. | |
| modelVisible | No | When false, the inline PNG is shown to the user but not sent to the model (saves image tokens on bulk renders). |
Output Schema
| Name | Required | Description |
|---|---|---|
| urls | No | Stateless hosted render URLs (only when MCP_PUBLIC_URL is set). |
| frame | Yes | Frame metadata extracted from the chart. |
| savedTo | No | Absolute path the output was written to, when `save` was used. |
| mimeType | Yes | MIME type of the rendered output. |
| urlsOmitted | No | Set when URLs were omitted because the source exceeded the URL cap. |
search_examplesARead-onlyIdempotent
Find canonical .bpc examples by topic keywords and/or chart type. Returns ranked pointers { id, title, description, chartType } — call get_example with an id to fetch the full DSL.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return (max 20). | |
| query | No | Topic keywords to match against sample titles and descriptions. | |
| chartType | No | Restrict results to this chart type (or alias). |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | Ranked sample pointers, best first. |
validate_dslARead-onlyIdempotent
Parse and semantically validate a .bpc source. Returns { valid, errors[], warnings[] }. Errors include unknown chart types, unknown properties, and empty data blocks with nearest-neighbour suggestions.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | The .bpc chart source to parse and validate. |
Output Schema
| Name | Required | Description |
|---|---|---|
| valid | Yes | True when the source parses and passes semantic validation. |
| errors | Yes | Fatal structural and value-level errors. |
| warnings | Yes | Non-fatal advisories. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.2.0- First observed
describe_chart_type - First observed
export_chart - First observed
get_example - First observed
get_grammar - First observed
inspect_dsl - First observed
list_chart_types - First observed
list_palettes - First observed
recommend_chart_type - First observed
render - First observed
search_examples - First observed
validate_dsl
TDQS
Scored across 11 tools
Each tool targets a distinct task: palette listing, DSL validation, inspection, chart type recommendation, grammar reference, rendering, chart type listing/details, example retrieval/search, and export. The only potential overlap is validate_dsl vs. inspect_dsl, but their outputs (errors/warnings vs. structured summary) are clearly different.
Most tool names follow a verb_noun snake_case pattern (e.g., list_palettes, validate_dsl, describe_chart_type). The sole deviation is 'render', a verb-only name, but it remains clear and stylistically consistent with the imperative, lowercase convention.
11 tools is well within the ideal 3-15 range and each tool earns its place in the chart-authoring workflow, covering discovery, validation, rendering, and export without redundancy or bloat.
The tool set provides a complete lifecycle for working with .bpc DSL: discovery (palettes, chart types, examples), guidance (recommend, describe), grammar reference, validation/analysis, rendering, and export. No obvious dead ends or missing operations for the apparent purpose.
Maintenance
Related MCP Connectors
Renders interactive Chart.js charts and dashboards inline in AI conversations.
Clean messy tabular data and render publication-ready PNG charts from your AI assistant.
Generate production-ready chart code (Recharts, Chart.js, ECharts, Plotly) from a prompt.
Create, inspect, manage, and render charts and data visualizations as SVG/PNG or interactive embeds.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to generate safe, runnable HTML chart pages from structured JSON data using Apache ECharts. It provides tools for chart type recommendation, page generation, validation, and patching with controlled, deterministic output.6 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables LLMs to load tabular data from CSV/Excel/JSON, clean and analyze it, generate charts, and write a report with conclusions.MIT
- FlicenseNot gradedqualityCmaintenanceEnables LLM clients to load, clean, visualize, and analyze tabular datasets, and to generate multi-format analytic reports through natural language instructions.-
- FlicenseNot gradedqualityCmaintenanceEnables agents to compile a semantic chart description (data, semantic types, chart intent) into native specs for five charting libraries and headlessly render three of them to SVG or PNG, delivered inline or as signed, expiring artifact URLs. It also exposes tools for validating charts, listing chart types and themes, plus resources and prompts that supply chart-authoring and theming conventions.-