Skip to main content
Glama
root-ext-viz
by graphgrow

root-ext-viz

Data-visualization MCP tool server for ROOT Workspace (and any MCP host). Five pillars:

  1. Sessional kernel — data_load / py_run / session_state / session_reset: dataframes, imports, and variables survive across tool calls (pandas, numpy, scipy, matplotlib, plotly, altair). Resource-capped child interpreter; a wall-timeout names its state loss, never hides it.

  2. Charts as source documents — chart_spec writes the Vega-Lite .vl.json AND renders its PNG beside it. The workspace renders the spec live (bundled vega, same v6 major as our vl-convert), the user keeps editing it; pixels are derived.

  3. The vision loop — every render returns its path; the model reads the PNG back through the workspace's image-read path, looks, and refines.

  4. Recipes, not 25 tools — viz_recipes: line/scatter/bar/ histogram/cdf/log_axes/error_bars/tolerance_band/control_chart/ heatmap (Vega-Lite) + bode/fft/contour (python).

  5. Bounded data plumbing — data_profile first; inlined chart data capped; aggregate in the kernel, chart the summary.

Charter, binding and tested: compute and plot; outputs land only in derived or artifact directories, never on a source. Nothing reaches the network — rendering is local vl-convert (no node).

Develop

uv venv && uv pip install -e ".[dev]"
.venv/bin/pytest

Related MCP server: mcp-plots

Package (signed .rootx, ADR-0018)

uv build
.venv/bin/python tools/build_pack.py   # --unsigned for a test build

Available Tools

8 tools
chart_exportA
Idempotent

Render an existing .vl.json to svg, png, or SELF-CONTAINED interactive html (vega js inlined — opens in the browser, works offline). Refuses an out_path that collides with the spec (charter).

Inputs: out_path (required), spec_path (required), scale, image_format.

chart_specA
Idempotent

Write a Vega-Lite chart as a SOURCE DOCUMENT: .vl.json + a rendered .png land in out_dir (use the artifact scratch when the user asked to SEE it — the workspace opens it beside the conversation, live and editable). Pass data= to inline a frame (capped at max_rows — aggregate big data in the kernel first); a handle reads from the store, so it charts even after the kernel that made it died. THE RENDER COMES BACK ATTACHED TO THIS RESULT — look at it directly, no second read — alongside diagnostics, deterministic layout checks (label collisions, a zero baseline flattening the data, too many series) that name defects the image alone makes you squint for. Rendering is local (vl-convert, Vega-Lite v6).

Inputs: name (required), spec (required), out_dir (required), data, +1 more.

data_loadA

Load a data file into the session kernel as DATA[name] — loaded once, use it many times: transform with py_run, chart with chart_spec(data=name). Starts the kernel on first use.

RETURNS A frame_handle as well as the profile. The handle is the durable name for this frame: it is written to a store that outlives the kernel, so if a wall-timeout kills the interpreter you can pass the handle back to py_run's frame_handles and carry on instead of reloading. Treat it as opaque; it is valid for ttl_ms.

Inputs: name (required), path (required).

data_profileA
Read-only

Describe a data file (csv/tsv/parquet/xlsx/json) BEFORE plotting it: row count (sampled at 100k for huge csv), column dtypes, head, and numeric summary. Profile → design the chart → load. Reads the file on this machine; nothing leaves it.

Inputs: path (required).

py_runA

EXECUTES Python in the session kernel — pandas, numpy, scipy, matplotlib (Agg), plotly, altair are importable; DATA holds loaded frames; variables and imports survive to your next call. Use it to transform/aggregate before charting, or run a python recipe (matplotlib figures: savefig to an absolute path in the artifact scratch). Resource-capped (memory rlimit + your wall_s, max 570s).

Pass frame_handles as {name: handle} to put stored frames back in DATA before the code runs — this is how you RECOVER after a timeout killed the kernel, and how any call gets a frame it did not load itself. Returns frame_handles for every frame in DATA afterwards, re-addressed if your code changed them, so the next call always has a durable name for the work this one did. You get them back even when the code raises. stdout/stderr come back bounded.

Inputs: code (required), wall_s, frame_handles.

session_resetA

Empty the session kernel deliberately — loaded frames and variables are gone; the next data_load starts fresh.

Inputs: no named parameters.

session_stateA
Read-only

What the kernel holds right now — loaded frames (rows × columns, each with its frame_handle) and user variables — plus stored_handles, the frames that survive the kernel. A wall-timeout or session_reset empties the first list and leaves the second.

Inputs: no named parameters.

viz_recipesA
Read-only

Engineering chart recipes — call with no topic for the index, with a topic for a worked template: line, scatter, bar, histogram, cdf, log_axes, error_bars, tolerance_band, control_chart, heatmap (Vega-Lite, chart_spec-ready) and bode, fft, contour (python, via py_run). Templates teach the shape; adapt fields to your data.

Inputs: topic.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 8 tools

    Disambiguation5/5

    Each tool addresses a distinct stage of the visualization workflow: profiling, loading, state inspection, Python execution, reset, spec creation, export, and recipes. No two tools have overlapping purposes; data_profile describes a file, data_load imports it, and chart_spec creates a chart while chart_export converts existing specs.

    Naming Consistency4/5

    Tool names predominantly use snake_case with grouped prefixes (data_*, session_*, chart_*), but not all follow a strict verb_noun pattern (e.g., session_state, chart_spec, viz_recipes). Minor deviations in parts of speech do not significantly impede predictability.

    Tool Count5/5

    Eight tools is within the ideal range for a visualization server. Each tool covers a necessary function—data intake, kernel control, transformation, chart authoring, and output—without redundancy or bloat.

    Completeness5/5

    The tool surface covers the full lifecycle from data profiling and loading, to transformation via Python, to chart specification, rendering, and export, plus session management and recipe templates. There are no evident gaps for the stated purpose of creating and exporting visualizations.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      A MCP server for data visualization. It exposes tools to render charts (line, bar, pie, scatter, heatmap, etc.) from data and returns plots as either image/text/mermaid diagram.
      2
      4
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      A comprehensive MCP server that provides intelligent access to the HoloViz ecosystem, enabling AI assistants to help you build interactive dashboards and data visualizations with Panel, hvPlot, Lumen, Datashader, and your favorite Python libraries.
      20
      65 PyPI
      34
      BSD 3-Clause
    • A
      license
      A
      quality
      D
      maintenance
      An MCP server that enables AI assistants to create interactive visualizations, perform statistical analysis, run auto-EDA, and build dashboards using the HoloViz ecosystem with self-contained HTML output.
      36
      MIT