vegavisuals

vegavisuals

Provides a stdio MCP server for rendering Vega-Lite and Vega specifications to SVG, PNG, or PDF with reproducible Docker isolation and immutable provenance.

Category
Visit Server

README

vegavisuals

vegavisuals is a reusable Vega-Lite and raw Vega visualization factory. It ships one central theme registry, one project manifest/lock contract, a stdio FastMCP adapter, and one Docker renderer based on vl-convert-python==1.9.0.post1. Consumer projects do not need Node, Chromium, or a host installation of Vega.

The host CLI requires Python 3.10 or newer and Linux because publication uses descriptor-relative I/O, flock, and fail-closed renameat2 operations. Rendering also requires Docker. Linux x86_64 is the release-tested host; source installations on other Linux architectures require compatible wheels for every pinned dependency.

The default compatibility profile is vl-convert-1.9.0: Vega 6.2.0, Vega-Lite 6.4 by default, SVG/PNG/PDF output, deterministic PDF normalization with qpdf, and the explicitly installed DejaVu font family. The base image is pinned by registry digest. The full supported Vega-Lite version set and runtime policy are exposed by vegavisuals compatibility-status; the source data is in src/vegavisuals/assets/compat/vl-convert-1.9.0.json.

Quick Start

git clone https://github.com/dosquartsdedocs/vegavisuals.git
cd vegavisuals
python3 -m pip install '.[mcp]'
vegavisuals build-renderer

vegavisuals --project /path/to/consumer validate charts/summary.vl.json
vegavisuals --project /path/to/consumer render \
  charts/summary.vl.json public/summary.svg
vegavisuals --project /path/to/consumer render-all
vegavisuals --project /path/to/consumer check

The first renderer build needs access to Debian and PyPI repositories. Render containers themselves run without network access and never pull images. No prebuilt renderer image is published; each installation builds its local image from the licensed source package and pinned compatibility profile.

The two repository examples cover a Vega-Lite bar chart with project-local CSV and a raw Vega chart:

vegavisuals render examples/vega-lite/bar.vl.json dist/examples/bar.svg
vegavisuals render examples/vega/raw.vg.json dist/examples/raw-vega.svg

Rendering Boundary

Every render uses a fixed worker entrypoint in the image. The host registry:

  • Parses JSON itself and rejects duplicate keys and non-finite numbers.
  • Confines source, data, input, manifest, cache, lock, and output paths to the consumer root.
  • Publishes cache, lock, and output files through descriptor-relative, no-follow Linux operations.
  • Serializes final commits with a project file lock, conditionally exchanges exact file snapshots with renameat2, and rolls output back if lock publication fails.
  • Atomically moves every retired publication inode under the mode-0700 .cache/vegavisuals/replaced/ directory, so late writes through an already-open descriptor remain recoverable until explicit cache cleanup.
  • Rejects HTTP/HTTPS data, image, hyperlink, and dynamic URL dependencies.
  • Resolves local data relative to the source file and fingerprints every dependency.
  • Never mounts the consumer project into the renderer.
  • Mounts only a prepared spec and staged output in an isolated host temporary directory at /output:rw.
  • Runs Docker with --network none, --read-only, all capabilities dropped, no-new-privileges, a non-root UID/GID, CPU/memory/PID/file limits, and a bounded tmpfs. Root callers use 65534:65534.
  • Validates PNG chunks and CRCs, normalized PDF structure, recursive SVG safety, and output size.
  • Copies the validated artifact to a temporary sibling and atomically replaces the destination from the host.

The container cannot publish directly into the consumer project. Failed renders leave an existing destination untouched.

Recovery archives are generated cache data and are never removed automatically. Inspect them after a reported publication conflict; make clean or manual cache removal is the explicit point at which they are discarded. The project lock, managed outputs, and .cache/vegavisuals/replaced/ must reside on the same filesystem so that publication and recovery remain atomic.

Source And Data Policy

Automatic engine selection first uses exact .vl.json and .vg.json suffixes, then a recognized $schema, and finally Vega-Lite mark or raw Vega marks structure. Explicit --engine vega-lite or --engine vega also works for JSON sources; a recognized suffix may not contradict the explicit engine.

File sources may use a static project-relative data.url. It is resolved from the source directory, must resolve to a UTF-8 regular file inside the project, and is staged as raw inline values with its declared or inferred CSV, TSV, or JSON format. This avoids file: loader ambiguity while preserving Vega's own format parser. Symlink and .. escapes are rejected. HTTP, HTTPS, protocol-relative, file:, data:, and dynamic data URLs are rejected. Image and hyperlink URL channels are also rejected so published SVG remains offline.

render-text applies the same dependency policy: every dependency url or href key is rejected, so only inline values are accepted. Input text is limited to 1 MiB. Its cache key includes source, engine, format, profile, and theme.

Project Manifest

.vegavisuals.yml is a versioned, explicit project contract:

version: 1
profile: vl-convert-1.9.0
family: benizar
visualizations:
  - name: quarterly-bars
    source: charts/quarterly.vl.json
    output: public/quarterly.svg
    engine: vega-lite
    format: svg
    inputs:
      - charts/data/quarterly.csv
  - name: raw-overview
    source: charts/overview.vg.json
    output: public/overview.pdf

engine, format, and inputs are optional. Inputs supplement data files discovered from the spec and participate in the fingerprint.

.vegavisuals.lock.json uses lock version 2. Each entry strictly records the source, output, engine, selected Vega-Lite version, format, profile, family, complete render fingerprint, output SHA-256, inputs, and immutable renderer image provenance. status reports these states:

The portable fingerprint uses the renderer contract, not the local Docker image ID: clean builds can have different image metadata IDs while using identical pinned inputs. The observed image ID remains recorded as provenance, and the image must carry the matching renderer-contract label before it can render.

State Meaning
fresh Fingerprint and managed output hash both match.
stale Inputs or render contract changed; the unmodified managed output may be replaced.
missing No output exists; the first render may create it.
unmanaged An output exists without a matching lock entry.
modified A managed output changed after rendering.
invalid Per-visualization source, dependency, or policy validation failed.

Fresh outputs are skipped unless --force is passed. Existing unmanaged and modified outputs are never replaced unless --replace is also passed. The same publication rule applies to direct file renders and explicit outputs from render-text.

An invalid manifest or lock aborts status and check instead of producing a per-visualization invalid state.

CLI

JSON-producing operational commands return structured JSON. Their errors also return JSON and a nonzero status. Help and --version use normal CLI text, and mcp serve speaks the MCP stdio transport rather than JSON command output.

vegavisuals [--project ROOT] version
vegavisuals [--project ROOT] profile-inventory
vegavisuals [--project ROOT] theme-inventory [--family FAMILY]
vegavisuals [--project ROOT] compatibility-status [--profile PROFILE]
vegavisuals [--project ROOT] factory-check
vegavisuals [--project ROOT] validate SOURCE [--engine auto|vega-lite|vega] [--input PATH]
vegavisuals [--project ROOT] render SOURCE OUTPUT [--format svg|png|pdf] [--name NAME]
vegavisuals [--project ROOT] render-text [--text JSON] [--output PATH]
vegavisuals [--project ROOT] status [--manifest .vegavisuals.yml]
vegavisuals [--project ROOT] check [--manifest .vegavisuals.yml]
vegavisuals [--project ROOT] render-all [--manifest .vegavisuals.yml]
vegavisuals [--project ROOT] factory-manifest
vegavisuals [--project ROOT] build-renderer [--profile PROFILE]
vegavisuals [--project ROOT] ensure-renderer [--profile PROFILE]
vegavisuals [--project ROOT] mcp serve
vegavisuals [--project ROOT] mcp client-config
vegavisuals [--project ROOT] mcp list-tools

Contract-aware commands also accept the documented --profile, --family, input, manifest, and publication-policy options. Run vegavisuals COMMAND --help for the complete synopsis.

render, render-text, and render-all accept --include-data, --replace, --force, and --dry-run. Inline artifact data is omitted by default. When requested, SVG is returned as artifact.svg; PNG and PDF are returned as artifact.data_base64. The compatibility profile limits artifact and response sizes.

validate performs strict JSON, depth, numeric, schema-version, URL-policy, and basic Vega/Vega-Lite structural checks. It does not claim complete JSON Schema or compiler validation; the pinned worker remains authoritative for full renderer semantics.

Python API

The public package exports Registry, __version__, and the typed exception hierarchy. One Registry instance fixes the consumer root:

from vegavisuals import Registry

registry = Registry("/path/to/consumer")
registry.validate_visualization("charts/chart.vl.json")
registry.render_visualization("charts/chart.vl.json", "public/chart.svg")
registry.render_visualization_text(spec_json, output_format="png")
registry.visualization_status()
registry.visualization_check()
registry.render_visualizations()
registry.theme_inventory()
registry.compatibility_status()
registry.factory_manifest()

Renderer lifecycle methods are build_renderer() and ensure_renderer(). Inventory helpers are profile_inventory(), factory_check(), and version_status().

MCP

The consumer root is resolved once before the FastMCP server starts and is not an MCP tool argument:

vegavisuals --project /path/to/consumer mcp serve

Tools:

validate_visualization
render_visualization
render_visualization_text
visualization_status
visualization_check
render_visualizations
theme_inventory
compatibility_status
factory_manifest

Resources:

vegavisuals://agent-guide
vegavisuals://themes
vegavisuals://compatibility
vegavisuals://project/status
vegavisuals://project/check
vegavisuals://factory-manifest

MCP tools preserve the documented dictionary result contract. Expected policy, validation, and render failures are typed application results with ok: false rather than MCP transport errors; clients must inspect ok.

Generate a client configuration template with:

vegavisuals mcp client-config --workspace-placeholder '${workspaceFolder}'

The default placeholder is a literal for clients that expand ${workspaceFolder}. Replace it with an absolute consumer path when the client does not perform that expansion. Use --command /absolute/path/to/vegavisuals when the executable is not on the client PATH, and --format vscode-workspace for VS Code's workspace shape.

Verification

python3 -m pip install -e '.[mcp,dev]'
make check
make tests
make tests-install
make docker-smoke
make mcp-smoke

make tests keeps Docker mocked. make docker-smoke renders all formats for both engines and checks delayed PDF byte repeatability. make mcp-smoke calls both render engines through stdio. Wheel verification installs non-editably, resolves assets from site-packages, and invokes both real render engines through the installed-wheel MCP executable.

See CONTRIBUTING.md for contribution checks and SECURITY.md for supported versions and private vulnerability reporting.

License

vegavisuals is licensed under the GNU General Public License v3.0 only (GPL-3.0-only). Vega, Vega-Lite, vl-convert, and the other runtime dependencies retain their original licenses; see THIRD_PARTY_NOTICES.md. Copyright (C) 2026 dosquartsdedocs.

Invoking the standalone CLI, Docker renderer, or MCP server does not by itself change the license of a consumer project or of generated SVG, PNG, and PDF artifacts. Applications that copy, modify, link, or directly distribute the Python package must comply with the GPLv3 terms.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured