highchart-mcp-server
You can use this server to turn structured input or raw Highcharts options into validated chart configurations and rendered images over MCP, CLI, or SDKs.
Create charts from simple structured input (
create_chart) for line, bar, column, area, scatter, pie, spline, and areaspline types.Render/export full Highcharts configurations to SVG, PNG, or PDF (
render_chart/export_chart), including width, height, scale, and constructor overrides.Discover chart types with
list_chart_types, grouped by family with data-shape hints and examples.Use any MCP client (Claude Desktop, Cursor, VS Code) over STDIO or Streamable HTTP.
Run programmatically via a CLI (
highchart-mcp) or published JS/TS and Python SDKs.Secure network deployments with API-key, JWT, or OAuth auth, rate limiting, health checks, and Prometheus metrics.
Deploy with Docker, including an offline Highcharts script cache for headless rendering.
Provides dashboard templates and structured logging to visualize metrics and monitor server behavior.
Exposes server metrics for monitoring performance, usage, and health via Prometheus.
Click on "Install 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., "@highchart-mcp-serverGenerate a pie chart of market share by product."
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.
Highcharts MCP Server
A Model Context Protocol (MCP) server that turns structured input or raw Highcharts options into validated chart configurations and rendered images (SVG / PNG / PDF). It works with any MCP-capable client (Claude Desktop, Cursor, VS Code, etc.) over STDIO or Streamable HTTP.
Status: actively developed. Chart generation, rendering/export, discovery, metrics, auth + rate limiting (HTTP), and Docker packaging are implemented and tested. The server/CLI and both SDKs are published (see Packages).
Packages
Package | Registry | Install |
npm |
| |
npm |
| |
PyPI |
|
Related MCP server: mcp-highcharts
Features
All 70 Highcharts 12.x series types — cartesian, pie/funnel, bubble, financial (candlestick/OHLC,
stockChart), heatmap/tilemap, treemap/sunburst, sankey/networkgraph/organization, gauges, boxplot/statistical, xrange/timeline, maps (mapChart), and gantt (ganttChart).Two-tier tools — a guided
create_chartplus raw passthroughrender_chart/export_chartfor full Highcharts control.Discovery —
list_chart_typesreturns every type grouped by family with data-shape hints and examples.Rendering to SVG / PNG / PDF via
highcharts-export-server(headless Chromium), with the correct constructor selected automatically.Zod v4 validation with clear, per-type error messages.
Production hardening — export timeouts, configurable worker pool, request body limits, and per-session HTTP transport management.
Security (HTTP) — API-key or HS256-JWT auth with scopes, and token-bucket rate limiting.
Observability —
GET /healthand PrometheusGET /metrics.Docker image that bakes the Highcharts script cache offline (no CDN needed at runtime).
Tools
Tool | Purpose |
| Build a Highcharts config from structured input for any supported type. Returns |
| Render a full Highcharts options object (any type). Returns config + rendered output. |
| Like |
| List every supported chart type grouped by family, with data shapes and examples. |
Install
Requires Node.js 20+.
From npm (published package — no clone needed):
npm install -g @highchart-mcp/server
highchart-mcp serve --transport stdio # or: highchart-mcp serve --transport http --port 3000From source (for development or Docker packaging):
npm ci
npm run build
npm startUsage
Local (STDIO) — desktop AI clients
mcp.json (or Claude Desktop / Cursor config):
{
"mcpServers": {
"highchart-mcp-server": {
"command": "node",
"args": ["/absolute/path/to/highchart-mcp-server/dist/index.js"],
"env": { "TRANSPORT": "stdio", "LOG_LEVEL": "info" }
}
}
}Networked (Streamable HTTP)
TRANSPORT=http PORT=3000 node dist/index.js
# MCP endpoint: POST http://localhost:3000/mcp
# Health: GET http://localhost:3000/health
# Metrics: GET http://localhost:3000/metricsEnable auth + rate limiting for any network exposure (see below).
Example: create_chart
{
"type": "line",
"title": "Monthly Sales",
"xAxisCategories": ["Jan", "Feb", "Mar"],
"series": [{ "name": "Revenue", "data": [10, 20, 15] }]
}Call list_chart_types to discover the expected data shape for any type
(e.g. financial [x, open, high, low, close], heatmap [x, y, value],
sankey { from, to, weight }, gantt tasks[], maps topology + data).
Rendering (offline)
Rendering uses highcharts-export-server (headless Chromium), which fetches
Highcharts scripts from a CDN on first run and caches them. To work offline, the
scripts are sourced from the installed highcharts package:
npm run seed:cache # populate the cache from the local package (no network)
npm run render:samples # render one SVG per constructor to .render-samples/The Docker image bakes this cache at build time.
Configuration
All configuration is via environment variables — see .env.example.
Highlights:
Area | Variables |
Transport |
|
Rendering |
|
HTTP limits |
|
Auth |
|
Rate limit |
|
Metrics |
|
Licensing |
|
Deployment
Docker:
docker build -t highchart-mcp-server .
docker run -p 3000:3000 -e AUTH_STRATEGY=apikey -e API_KEYS=client1:changeme \
--shm-size=512m highchart-mcp-server
# or: docker compose -f docker/docker-compose.yml up --buildAlways enable auth + rate limiting for any network exposure and terminate TLS at a reverse proxy or the platform's load balancer.
Connecting from Claude.ai / ChatGPT (remote MCP connectors)
Claude.ai's and ChatGPT's "custom connector" UIs can't accept a pasted bearer
token — they only know how to drive an OAuth 2.1 authorization-code + PKCE flow
with dynamic client registration (per the MCP Authorization spec). Set
AUTH_STRATEGY=oauth to have this server act as both the authorization server
and resource server for that flow:
AUTH_STRATEGY=oauth PUBLIC_URL=https://charts.example.com API_KEYS=demo:changemePUBLIC_URLmust be the externally-reachable HTTPS origin of this server (no trailing slash) — it's used as the OAuth issuer/audience and in the.well-knowndiscovery documents, since the process can't infer it behind a reverse proxy.API_KEYSdoes double duty: the sameid:key[:scopes]entries used by theapikeystrategy are shown as a login form (GET /authorize) when a platform starts the OAuth flow — enter theidandkeythere once per connector install to grant it a token scoped to that entry'sscopes.No extra dependency or database is required: client registrations, authorization codes, and refresh tokens are held in-process (see
src/auth/oauth/store.ts), the same tradeoff already made for HTTP sessions and rate limiting — fine for a single-instance deployment.In Claude.ai, add a Custom Connector pointing at
https://charts.example.com/mcp; in ChatGPT, add it as an MCP connector with the same URL. Both will discover/.well-known/oauth-protected-resource, self-register via/register, and redirect the user through/authorizeautomatically.
CLI
The build installs a highchart-mcp CLI (bin → dist/cli/index.js):
highchart-mcp list-types # list all types grouped by family
highchart-mcp list-types --family maps --json
echo '{"series":[{"data":[1,2,3]}]}' | highchart-mcp create --type line --input -
highchart-mcp create --type line --input chart.json --format svg --out chart.svg
highchart-mcp render --input options.json --format png --out chart.png
highchart-mcp export --input options.json --format pdf --width 1000 --out chart.pdf
highchart-mcp serve --transport http --port 3000render/export require a seeded render cache (npm run seed:cache) or network.
SDKs
Published client libraries (source in packages/, in-repo npm workspaces):
JS/TS:
@highchart-mcp/sdk(source)npm install @highchart-mcp/sdkimport { HighchartClient } from '@highchart-mcp/sdk'; const client = await HighchartClient.connectHttp('http://localhost:3000/mcp', { apiKey }); const { options } = await client.createChart({ type: 'line', series: [{ data: [1, 2, 3] }] });Python:
highchart-mcp-sdk(source)pip install highchart-mcp-sdkasync with HighchartClient.connect_stdio(command="node", args=["dist/index.js"]) as client: cfg = await client.create_chart(type="line", series=[{"data": [1, 2, 3]}])
Development
npm run dev # tsx --watch src/index.ts
npm run build # tsc (server + CLI)
npm test # vitest run (server + CLI)
npm run build --workspace @highchart-mcp/sdk # build the JS/TS SDK
npm test --workspace @highchart-mcp/sdk # test the JS/TS SDKVersioning & Publishing
All three published packages are versioned independently with
semver, each in its own package.json /
pyproject.toml:
Package | Version file |
| |
| |
|
Rule: bump the version of every package you change before publishing —
never publish the same version twice. Patch (x.y.Z) for fixes, minor
(x.Y.0) for backwards-compatible features/additions, major (X.0.0) for
breaking changes. A change to src/** bumps @highchart-mcp/server; a change
to packages/sdk-js/** bumps @highchart-mcp/sdk; a change to
packages/sdk-python/** bumps highchart-mcp-sdk. Shared/cross-cutting
changes (e.g. a protocol change affecting the tools) bump all affected
packages together.
Automated (CI) — the normal path
.github/workflows/publish.yml publishes
automatically on every push to master. For each package it compares the
version in the repo against the version currently on the registry; if it's
different, it builds, tests, and publishes that package (and only that one).
So publishing a new version is just:
Bump the version(s) that changed (see the rule above).
Commit and push/merge to
master.CI builds, tests, and publishes automatically — no local
npm publish/twine upload, no tokens to manage. It uses npm and PyPI trusted publishing (OIDC), so nothing is stored as a GitHub secret.
One-time setup (do this once per package; repeat only if the workflow file is renamed/moved, or for a new package):
npmjs.com → package Settings → Publishing access → Trusted Publisher, add this GitHub repo +
.github/workflows/publish.yml— for both@highchart-mcp/serverand@highchart-mcp/sdk.pypi.org → project Settings → Publishing, add this GitHub repo +
.github/workflows/publish.yml— forhighchart-mcp-sdk.
You can also trigger it manually from the Actions tab (workflow_dispatch)
if you need to re-run a publish without a new push.
Manual (fallback)
If CI is down or you need to publish from your machine:
# 1. Bump the version(s) that changed, build, and test.
npm version <patch|minor|major> --no-git-tag-version # root package
npm version <patch|minor|major> --no-git-tag-version -w @highchart-mcp/sdk
# packages/sdk-python/pyproject.toml: bump `version = "..."` by hand
npm run build && npm test
npm run build -w @highchart-mcp/sdk && npm test -w @highchart-mcp/sdk
# 2. Publish (npm requires an OTP if 2FA is enabled).
npm publish --access public --otp=<code>
npm publish -w @highchart-mcp/sdk --access public --otp=<code>
# 3. Publish the Python SDK.
cd packages/sdk-python
rm -rf dist && python -m build
twine check dist/*
twine upload dist/* # __token__ / a PyPI API tokenCommit the version bump(s) (e.g. chore(release): @highchart-mcp/server@1.1.0)
alongside or right after the code change that motivated them.
Licensing
This wrapper is under the license in package.json. Highcharts itself is
proprietary: free for non-commercial use with the credit attribution kept on
(the default here), and requires a paid license for commercial/production use.
See LICENSING.md.
Roadmap
Done: full chart-type coverage, rendering/export, discovery, offline cache, metrics/health, HTTP auth + rate limiting, per-session transport, robustness limits, Docker + CI, CLI + JS/TS & Python SDKs.
Next (Phase 3): optional AI / natural-language features.
Available Tools
2 toolscreate_chartB
Generate a Highcharts configuration object from structured input. Returns valid Highcharts JSON that can be rendered in any Highcharts-compatible environment.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | ||
| title | No | ||
| xAxisCategories | No | ||
| series | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It describes the tool as generating and returning a configuration object, which implies no side effects. However, it does not explicitly state that the tool is non-destructive or lacks side effects, and it omits any discussion of rate limits or auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences, no wasted words, and front-loads the primary action. It effectively communicates the core function without unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 4 parameters and no output schema. The description does not detail the return structure (e.g., what a valid Highcharts JSON looks like) nor any error conditions. It is adequate but lacks depth that would help with complex usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description adds no parameter-level detail. The description only says 'structured input' without explaining the meaning of fields like 'type', 'title', 'xAxisCategories', or 'series'. For example, it doesn't clarify that 'type' must be one of the provided enums.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: 'Generate a Highcharts configuration object from structured input.' It specifies the verb (generate) and resource (Highcharts configuration object), and differentiates from sibling 'render_chart' by indicating it returns the config JSON that can be rendered elsewhere.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for generating chart configuration, but it does not explicitly say when to use this tool versus the sibling 'render_chart'. No guidance on prerequisites or exclusions is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_chartA
Render a chart from a full Highcharts configuration object. Accepts any valid Highcharts Options — the server validates structure (chart.type, series) but passes all other options through to Highcharts.
| Name | Required | Description | Default |
|---|---|---|---|
| chartOptions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the server validates `chart.type` and `series` and passes other options through. However, it does not describe the return value, side effects, or any required authentication, leaving gaps for a mutation-like operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose. Every sentence provides essential information without redundancy or unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of a nested object parameter and no output schema, the description covers input behavior well but omits return value details and potential constraints (e.g., output format, limits). More context would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds significant meaning beyond the raw schema by clarifying that the parameter accepts any valid Highcharts Options and that all properties are passed through. This compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Render a chart from a full Highcharts configuration object,' specifying the action and resource. It distinguishes from the sibling 'create_chart' by implying rendering versus creation, but does not explicitly differentiate usage scenarios.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for rendering when a full Highcharts config is available, but it does not provide explicit guidance on when not to use it or how it compares to 'create_chart'. No exclusions or alternatives are mentioned.
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. Dates show when Glama detected each change.
2 tool updates
v1.0.0- First observed
create_chart - First observed
render_chart
TDQS
The two tools have clearly distinct purposes: create_chart generates a Highcharts configuration object, while render_chart takes a full configuration and renders it. No overlap or ambiguity exists.
Both tool names follow a consistent verb_noun pattern (create_chart, render_chart) in snake_case, making them predictable and easy to understand.
With only 2 tools, the server is minimal. While it covers core chart creation and rendering, it feels thin for a full-featured charting service, potentially missing operations like listing or managing chart configurations.
The server covers the essential lifecycle of generating and rendering a chart configuration. Minor gaps exist, such as lacking update or delete operations, but the domain is straightforward and the provided tools suffice for basic use.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Renders interactive Chart.js charts and dashboards inline in AI conversations.
Renders interactive Chart.js charts and dashboards inline in AI conversations. Supports bar, line, area, pie, doughnut, scatter, and radar charts with multi-chart dashboard grids.
Create, inspect, manage, and render charts and data visualizations as SVG/PNG or interactive embeds.
Generate production-ready chart code (Recharts, Chart.js, ECharts, Plotly) from a prompt.
Related MCP Servers
- AlicenseAqualityBmaintenanceRenders 45+ interactive chart types, dashboards, and KPI widgets directly inside AI conversations. Supports drill-down, live API polling, 20 themes, and one-click export to PNG, PowerPoint, and A4 documents.4021544Functional Source , Version 1.1, MIT Future
- AlicenseAqualityCmaintenanceEnables AI agents to render interactive Highcharts visualizations directly within VS Code chat conversations. It supports over 17 chart types with GitHub Primer styling and advanced features like drilldown and WebGL rendering.640MIT
- AlicenseAqualityDmaintenanceEnables AI agents to generate and render charts as PNG, SVG, or WebP images directly in chat interfaces. Supports Chart.js specifications and natural language descriptions for creating visualizations from data.3341MIT
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI agents to generate beautiful, presentation-ready charts (SVG + PNG) with zero setup, supporting various chart types and styling options.25MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hasnaintypes/highchart-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server