Skip to main content
Glama

smart-charts-mcp

Turn CSV/TSV/TXT/JSON data into standalone interactive ECharts HTML charts — 32 chart types, 3 themes, fully offline (ECharts JS is bundled, zero CDN, works behind corporate firewalls and in air-gapped environments).

Ships as an MCP server so any MCP-capable agent (Claude, Cursor, VS Code, WorkBuddy, ...) can profile a dataset and render charts as a tool call, getting the HTML artifact plus rendering statistics back in the same response.

Why this exists — the traps it removes

Without it you will hit...

This server handles it

Charts that silently use a CDN and render blank offline

ECharts is inlined into every HTML file

Agent guessing chart types and columns from vibes

profile_data returns objective facts (dtype/cardinality/missingness/signals) first; the agent decides from evidence

Captions citing numbers that are not in the chart

render_chart returns plot_stats + data_preview; those are the only numbers a caption may quote

Aggregating by data row instead of by entity (double counting)

source_rows / plotted_rows / unique_entities audit fields on every render

LLM-written pandas snippets doing unsafe things

transform_code runs in a sandbox (AST whitelist + blacklisted builtins, no file/network I/O)

Misleading gauge/liquid "achievement" numbers

achievement is only computed when you pass an explicit business target

Related MCP server: ECharts MCP Server

Tools

  • doctor() — dependency + asset preflight.

  • profile_data(data_text, filename="data.csv") — dataset profile (read-only, nothing rendered).

  • render_chart(data_text, chart_type, title=..., x_axis=..., y_axis=..., transform_code=..., annotation=..., theme=..., target=..., ...) → {ok, html, chart}.

  • list_chart_types() — selection table (best-for + required data shape per type).

data_text is the raw file content as a string; only the extension of filename is used to pick a parser. Binary Excel files are not supported by this transport — export to CSV first.

Install & run

pip install -e .          # mcp + pandas + numpy (+ openpyxl if you need xlsx via local CLI)
python scripts/fetch_assets.py   # one-time ~2.6MB download (ECharts JS + map GeoJSON)
python server.py          # stdio transport

After the one-time fetch the server is fully offline. Distribution zips ship the assets pre-bundled, so zip installs can skip the fetch step. Without the assets, the 29 non-map chart types still work; map, lines, wordcloud and liquid need them.

Or add to your MCP client config:

{
  "mcpServers": {
    "smart-charts": {
      "command": "python",
      "args": ["/path/to/smart-charts-mcp/server.py"]
    }
  }
}

Smoke test

pip install -r requirements-dev.txt
python test_smoke.py      # handshake + tool count + live profile/render round trip

Notes

  • Map charts (map, lines) bundle China province-level and world country GeoJSON offline. For China maps you are responsible for using compliant, officially sanctioned map data in your own jurisdiction.

  • Regression suite: python smart_charts/scripts/regression_check.py.

  • License: MIT.

Available Tools

4 tools
doctorA

Environment preflight: dependency versions and asset readiness. Run once after install.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses what is inspected (dependency versions, asset readiness) but not whether the check is purely read-only or may modify state ('asset readiness' is ambiguous), nor what failure output or exit status looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the purpose front-loaded and the usage trigger second. No filler, no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter diagnostic with no output schema, the definition covers what it does and when to run it. It is slightly incomplete in not hinting at the result format or what to do on a failing check, but that is minor for such a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. The empty schema is consistent with the description, which correctly implies no caller-supplied inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a concrete function - checking dependency versions and asset readiness - which is a specific diagnostic task distinct from the sibling charting tools (profile_data, list_chart_types, render_chart). 'Preflight' is slightly jargonistic but the colon clause disambiguates it clearly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit trigger: 'Run once after install,' which tells the agent exactly when this tool is appropriate. It does not name alternatives or exclusions, but the siblings are unrelated charting utilities so no routing guidance is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_chart_typesA

Chart selection table: each chart type with best-for, trigger keywords and required data shape.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral burden. It discloses the shape of the returned content (per-type best-for, trigger keywords, data shape), which is useful, but does not state that it is a read-only listing or describe its scope/size. Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words. It is a fragment rather than a full sentence, but every clause (best-for, trigger keywords, data shape) earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must convey the return value, and it does so by listing the three fields each entry carries. For a simple zero-param listing tool this is essentially complete, though it could note there are no inputs expected.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. There is no parameter semantics to compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource — a chart selection table — and enumerates its contents (best-for, trigger keywords, required data shape). Combined with the name list_chart_types, an agent can tell this enumerates available chart types, distinct from render_chart which draws one. It stops short of explicitly naming the sibling it complements.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Chart selection table' implies this is used to pick a chart type, likely before calling render_chart, but no explicit when-to-use or when-not-to-use instruction is given. The routing to siblings is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

profile_dataA

Profile a tabular dataset BEFORE choosing a chart.

Returns objective facts: per-column dtype/cardinality/missingness/samples/ statistics, entity grain, candidate insight signals (trend, divergent category, head concentration, outliers, strong correlations) and suspected non-data rows. Use these facts to decide which column is an ID, a dimension or a measure, and which chart deserves drawing.

Args: data_text: raw file content (CSV/TSV/TXT/JSON text; xls/xlsx are binary and NOT supported by this tool - use a CSV export instead) filename: original file name, only the extension is used to pick a parser

ParametersJSON Schema
NameRequiredDescriptionDefault
filenameNodata.csv
data_textYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden and it does disclose real behavioral traits: profiling is an objective-fact pass, xls/xlsx binaries are explicitly NOT supported and a CSV export is required, and the parser is chosen solely from the filename extension. It stops short of stating read-only/no-side-effect semantics, size limits, or what happens to the suspected non-data rows it reports.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the key routing constraint, then the return payload, then per-argument notes in a clean Args block. Slightly verbose in the middle sentence, but every clause (returned facts, unsupported xls/xlsx, extension-only filename) carries actionable information rather than restating the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and 0% parameter coverage, the description accepts the full explanatory burden and delivers: it enumerates the returned fact categories, the down-stream decision they support, and the input format limitations. An agent has everything needed to invoke it correctly and interpret the result without guessing at return shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it largely does: data_text is defined as raw file content with the accepted text formats (CSV/TSV/TXT/JSON) and the unsupported binary formats spelled out, and filename is clarified as only mattering for its extension. Still missing practical semantics like encoding expectations, size ceilings, and what happens when filename contradicts the actual content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Profile a tabular dataset') with an explicit temporal/decision scope ('BEFORE choosing a chart'), which cleanly separates it from sibling render_chart and list_chart_types. The description then enumerates exactly what facts it produces (dtype/cardinality/missingness/statistics, grain, insight signals), so an agent knows the output is analytical metadata, not a visualization.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selection condition clearly: run this before choosing a chart, and use the returned facts to decide column roles and which chart to draw. That implicitly routes the agent to render_chart afterward, but it never names render_chart or list_chart_types as the alternatives or states when not to call it (e.g., already-profiled data, non-tabular input).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_chartA

Render one interactive ECharts HTML chart from tabular data.

Returns {ok, html, chart:{...}} where chart carries the full stdout contract: plot_stats (quote ONLY these numbers in your caption), data_preview (first 10 rendered rows), source_rows/plotted_rows/ unique_entities (aggregation audit), assumptions and advisories (read them before delivering).

Args: data_text: raw file content as text (csv/tsv/txt/json) chart_type: one of line, bar, area, pie, scatter, radar, heatmap, treemap, graph, boxplot, waterfall, gauge, sankey, funnel, sunburst, wordcloud, histogram, stacked_bar, bubble, pareto, combo, venn, mindmap, orgchart, liquid, spreadsheet, map, lines, effect_scatter, calendar, pictorial_bar, theme_river title: conclusion-style title (subject + number), not a noun phrase subtitle: context - time range, filters, source x_axis / y_axis: column name(s); lists become multiple series transform_code: sandboxed pandas code; variables df/pd/np only, must produce a DataFrame named result (no import/open/try/class) annotation: your written interpretation, injected into the HTML footer theme: default | classic | dark label_col: identity column for scatter/bubble/boxplot target: business target for gauge/liquid achievement rate sheet: Excel sheet name (convert to CSV first if using data_text) header_row / skiprows / drop_rows: dirty-header repairs (1-based row)

ParametersJSON Schema
NameRequiredDescriptionDefault
sheetNo
themeNo
titleNo
targetNo
x_axisNo
y_axisNo
filenameNodata.csv
skiprowsNo
subtitleNo
data_textYes
drop_rowsNo
label_colNo
annotationNo
chart_typeYes
header_rowNo
transform_codeNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses the return contract {ok, html, chart:{...}} and names the audit fields (plot_stats, source_rows/plotted_rows/unique_entities, assumptions, advisories). It also discloses the transform_code sandbox restrictions (variables df/pd/np only, must produce `result`, no import/open/try/class), which is genuine behavioral detail. It stops short of stating failure modes or permissions, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose, then the return contract, then a clean Args block, so an agent can stop reading early. It is long, but the length is driven by a large param surface and the enumeration of chart types, so most sentences earn their place; the parenthetical asides are slightly dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-param, annotation-free tool with no output schema, the description covers the return shape and nearly all parameters. The unaddressed `filename` parameter and the absence of error/permission behavior are the only real gaps, so it is close to but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and largely does: it documents data_text, chart_type (with a full 30+ value enumeration absent from the schema), title, subtitle, axes, transform_code, annotation, theme, label_col, target, sheet, and the three header-repair params. Only `filename` is undocumented, leaving a minor gap against the 16-param surface.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+scope: 'Render one interactive ECharts HTML chart from tabular data', which is concrete and actionable. It does not differentiate itself from siblings like list_chart_types or profile_data, so an agent must infer the boundary, keeping it below a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is embedded guidance ('quote ONLY these numbers in your caption', 'read them before delivering', 'convert to CSV first if using data_text'), which is useful procedural context. However, it never states when to choose this tool over list_chart_types or profile_data, so usage vs alternatives is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observeddoctor
    • First observedlist_chart_types
    • First observedprofile_data
    • First observedrender_chart

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation5/5

Each tool occupies a clearly distinct slot in the workflow: profile_data analyzes data, list_chart_types is a static reference, render_chart produces output, and doctor checks the environment. There is no plausible case where an agent would mistake one for another.

Naming Consistency4/5

Three of four tools follow a clean verb_noun pattern (profile_data, list_chart_types, render_chart), with 'doctor' as the single stylistic deviation. That lone noun-style name is still conventional and unambiguous, so the break is minor.

Tool Count4/5

Four tools is lean but well-scoped for a charting server, with each earning its place in a profile-then-render pipeline. The heavy lifting is consolidated into one large render_chart tool, so the surface is slightly thin at the discovery/utility end but not problematic.

Completeness4/5

The core lifecycle (preflight, inspect data, choose chart, render HTML) is fully covered, and render_chart itself is extremely broad with 30+ chart types and many options. Minor gaps exist: no tool to persist/export the rendered HTML to a file or to list available datasets, but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers