chartlink-mcp
This server provides programmatic access to chartlink: create, style, publish, and live-update embeddable charts, maps, and tables via API key.
Authentication & workspace: sign up for a key, verify it with whoami, check billing/credits, and manage brands for reusable style tokens.
Discover assets: list asset types, fetch per-type config schemas with examples, list geographies, list templates/charts, and browse assets.
Create and edit charts: create drafts (with inline preview), update via deep-merge patches or full config replacement, duplicate, soft-delete, unpublish, and publish (including premium upgrades).
Live data & self-updating charts: replace or append data rows, attach an external CSV/JSON URL fetched on a schedule, refresh manually, and auto-republish published charts so embeds stay current.
Templates and gallery: start from published templates or any shown chart ID, and showcase your own published charts as templates.
Human handoff: mint no-login edit links for aesthetic tweaks, revoke them, and create checkout links for credit packs.
Feedback: submit structured bug reports or feature requests for gaps in capabilities.
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., "@chartlink-mcp Create a chart from this data and give me the embed link"
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.
chartlink for agents
chartlink makes charts and maps in your own brand, with live-updating embed links. You make the brand once in the studio, from your website; an agent sends the data and the words, looks at the preview, and hands back an embed that updates when the numbers do.
This repo is how agents connect.
Claude Code plugin
/plugin marketplace add oscarleoo/chartlink-agents
/plugin install chartlink@chartlinkThe plugin adds the chartlink MCP server and a skill that teaches the brand loop: pick the brand, create, look at the preview, publish, hand back the links. The first time, run /mcp, select chartlink and sign in in the browser; you pick the workspace it works in. No key is stored.
Related MCP server: Zendesk MCP Server
Claude and other AI apps
Add https://chartlink.app/mcp as a custom connector and sign in. The server follows the MCP authorization spec (OAuth 2.1 with PKCE and dynamic client registration), so any client that supports it signs in the same way.
Cursor
The repo root is a Cursor plugin: .cursor-plugin/plugin.json, mcp.json (the chartlink server over HTTP, signed in through the browser) and the same skill. Install from cursor.directory or add the server by hand:
{ "mcpServers": { "chartlink": { "url": "https://chartlink.app/mcp" } } }Scripts and CI
Tools that cannot sign in use an API key from the studio: Workspace → API keys for Claude Code and scripts. Send it as Authorization: Bearer viz_.... Keep keys out of chats.
Clients that only speak stdio can use the bridge, with the key in CHARTLINK_API_KEY:
npx chartlink-mcpIt bridges stdio to the HTTP server; nothing runs locally but the bridge. Source in packages/chartlink-mcp.
The default tools or all of them
https://chartlink.app/mcp exposes the tools for making, changing and publishing charts and maps in a brand. https://chartlink.app/mcp?full=1 adds brand editing, data sources and the rest. Manuals: https://chartlink.app/llms.txt and https://chartlink.app/llms-full.txt; OpenAPI at https://chartlink.app/api/openapi.json.
Listing kit
listing/ holds the text and image used on the directories chartlink is listed in.
Available Tools
27 toolsclear_data_sourceDetach a chart's data sourceAInspect
Stops scheduled fetches; the chart keeps its current data.
Inputs: id (required).
create_assetCreate a draft asset — returns an inline preview imageAInspect
Creates a draft. The response includes a low-res PNG preview INLINE — look at it, then iterate with update_asset. Nothing is public until publish_asset, or until you pass publish: true here (one call instead of two, once the chart is final). A success means the config validated AND rendered. Style comes from the defaults and your brand, if any — only set config fields the story needs. data = {columns: [{id,type,...}], rows: [[...], ...]} (row-major, matching column order). LIMITS: keep each call under ~100 KB of rows (asset cap 2 MB) — for larger datasets create with a few rows and attach set_data_source, or append chunks via replace_asset_data.
Inputs: data (required), type, brand, title, +3 more.
create_brandCreate a brand (reusable style token set)AInspect
A brand styles every asset that references it — and the workspace default brand styles everything created without an explicit brand. Create one, then render any asset with brand: "" to see it applied. Style only: brands can never inject data or text content.
Inputs: name (required), slug (required), tokens (required), isDefault.
create_checkout_linkPayment link for a credit pack — hand it to your humanAInspect
Returns a URL that opens straight into Paddle checkout: no login, no account. It can only add credits to THIS workspace, so it is safe to share. Credits arrive seconds after payment (get_billing).
Inputs: pack.
create_edit_linkMint a no-login tweak link — hand it to your humanAInspect
Returns a URL opening the visual tweak panel for ONE chart (text, colors, spacing, label nudges) with no login. PUBLISH FIRST: the editor saves and republishes a published chart, it cannot publish a draft. Scope: view, tweak, and republish that chart only — never delete, never spend credits, nothing else in the workspace. OFFER THIS whenever the human's request is aesthetic fine-tuning: handing over the wheel beats a nudge-by-nudge back-and-forth. The secret is shown once; links don't expire and can be revoked with revoke_edit_link.
Inputs: id (required).
delete_assetSoft-delete an assetADestructiveInspect
Embeds go dark. Restorable via the REST API (POST /api/assets/{id}/restore).
Inputs: id (required).
duplicate_assetDuplicate an asset into a new draftBInspect
New id, new embed URLs. Useful for rebranding a chart for another audience.
Inputs: id (required), brand, title.
fetch_data_sourceRefresh a chart from its data source right nowBInspect
Runs one fetch on top of the schedule. Returns {ok, rows, published, error}.
Inputs: id (required).
get_assetGet one asset (draft state)BRead-onlyIdempotentInspect
Full asset envelope. includePreview=true also returns an inline PNG of the current draft.
Inputs: id (required), includeData, includePreview.
get_billingThis workspace's credit balance and asset capARead-onlyIdempotentInspect
Hosting is free (unlimited badged charts, live updates included). One credit makes one chart premium forever: 2400px, SVG, your own branding, no badge. Updates are never metered.
Inputs: no named parameters.
get_spec_schemaGet the config schema + worked examples for a typeARead-onlyIdempotentInspect
Returns the JSON Schema for the type's config, the data schema, two worked examples (minimal + rich), and defaults — the complete config in force when nothing is set (every font, padding, color), which a brand and then the chart's own config merge over. Read this before your first create_asset of a given type; read a baseline value from defaults instead of guessing it.
Inputs: type (required).
list_assetsList assetsARead-onlyIdempotentInspect
Filterable list; rows elide config/data. Use get_asset for full bodies.
Inputs: type, limit, offset, search, +1 more.
list_asset_typesList available asset typesARead-onlyIdempotentInspect
Chart/table types you can create, with links to per-type schemas.
Inputs: no named parameters.
list_brandsList brandsARead-onlyIdempotentInspect
Style-only token sets applied under your config. Pass a slug as brand on create_asset.
Inputs: no named parameters.
list_geographiesWhich boundaries a map can draw, and how its regions are namedARead-onlyIdempotentInspect
countries, us-states, and every country's states/provinces as -regions (de-regions, ru-regions…). Pass id to get one geography's full region list — codes (ISO 3166-2 like DE-BY), names and aliases — and read it BEFORE naming regions in your data: unknown regions fail loudly. Set chart.geography to the id; chart.bounds crops.
Inputs: id.
list_templatesCharts offered as templates — start a new chart from oneARead-onlyIdempotentInspect
Published charts their owners offered as starting points, each with urls.png (show a few to your human), the chart's type and title, and columns: the column ids your data must supply. Then create_asset with template: and your data — the whole design comes along. Any chart id you were shown works as a template too, not only these. The human-facing version is the gallery link in the result.
Inputs: type.
publish_assetPublish — snapshot a version and update every embedAInspect
Makes the draft live. Returns urls: paste urls.embedIframe on iframe platforms; on Substack insert urls.png as an image and link it to urls.page. Pinned history: urls.png + '?v=N'.
Inputs: id (required), note, premium.
replace_asset_dataReplace data rows — published assets auto-republish (live embeds update)AInspect
THE core flow for refreshing numbers. publish defaults to auto: a published asset republishes immediately (every embed/PNG updates); a draft stays draft. Set publish=false to stage instead. LIMITS: an asset holds up to 2 MB of data, but keep each tool call under ~100 KB of rows — for larger datasets chunk with mode: "append" (publish: "false" on every chunk but the last), or skip inline entirely with set_data_source (the server fetches a URL, up to the full 2 MB).
Inputs: id (required), data (required), mode, note, +1 more.
revoke_edit_linkRevoke an edit linkAInspect
The URL stops working immediately. List links (prefixes + tokenIds) via GET /assets/{id}/edit-links.
Inputs: id (required), tokenId (required).
set_data_sourceMake a chart self-updating: attach a source URL, fetched on scheduleAInspect
The chart refetches this URL (CSV or JSON) hourly/daily/weekly, replaces its rows, and republishes itself if published — refreshes are free, updates are never metered. Columns stay as defined on the asset: CSV headers / JSON object keys match column ids or labels case-insensitively, with spaces, underscores and hyphens interchangeable (births_per_woman matches a column labeled 'Births per woman'). Fetches once immediately and returns that outcome — check fetch.ok and fix fetch.error before moving on. get_asset shows dataSource + dataSourceState when a source is attached. Clear with clear_data_source.
Inputs: id (required), url (required), format, refresh.
signupGet an API key — no account, one callAInspect
Creates a workspace and returns its API key (shown ONCE — keep it). Works on a keyless connection; every other tool needs the key. Then put the key where your client keeps it (plugin api_key setting, the Authorization header, or CHARTLINK_API_KEY for the npx bridge) and reconnect.
Inputs: ref, name.
submit_feedbackReport a gap — don't silently give upAInspect
If a capability is missing, a schema fights you, or docs are wrong: record it here so the owner can fix it. One report per distinct issue, with a real description — reports get fixed same-day when they say what you tried, what you expected, and what happened (title-only reports can't be acted on).
Inputs: type (required), title (required), description (required), assetId.
unpublish_assetTake an asset offlineADestructiveInspect
Embeds and PNGs return 410 until republished.
Inputs: id (required).
update_assetUpdate a draft (deep-merge patch, or replace the config) — returns an inline preview imageAInspect
configPatch is DEEP-MERGED: objects merge recursively, arrays replace wholesale, null clears a key — send only what changes. To REMOVE keys (drop document.aspect, delete one of texts[]) pass config instead: it REPLACES the whole config (get_asset returns the current one to edit). data (if given) replaces rows wholesale. Requires expectedVersion from the last envelope; on 409 re-merge onto the returned current. Updating does NOT publish by default — pass publish: true to publish in the same call, or call publish_asset separately.
Inputs: id (required), expectedVersion (required), data, brand, +5 more.
update_brandUpdate a brand (tokens deep-merge)AInspect
Deep-merges tokens (objects merge, arrays replace, null clears). Drafts restyle immediately; published assets pick the change up on their next publish. Requires expectedVersion from list_brands.
Inputs: idOrSlug (required), expectedVersion (required), name, tokens, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 27 tools
Every tool targets a distinct action and resource, with detailed descriptions that clearly separate overlapping operations like replace_asset_data vs set_data_source. No ambiguity between tools; each has a unique purpose.
All tool names follow a consistent snake_case verb-noun pattern (e.g., create_asset, update_asset, list_brands). Even exceptions like whoami and signup are concise verbs that fit the style, showing a coherent naming convention.
With 27 tools, the count exceeds the typical range for a single server. However, the breadth of functionality (asset lifecycle, data sources, branding, billing, edit links) justifies each tool, though it feels heavy compared to more focused servers.
The tool set provides comprehensive coverage of the charting domain: full CRUD for assets, data management, publishing, templates, geographies, brands, billing, and edit-link management. There are no obvious gaps that would prevent an agent from accomplishing typical tasks.
Maintenance
Related MCP Connectors
Create, inspect, manage, and render charts and data visualizations as SVG/PNG or interactive embeds.
Renders interactive Chart.js charts and dashboards inline in AI conversations.
Tools for charts, PDFs, tables, webpages, temporary sharing, webhooks, forms, and feeds.
The all-in-one data stack for agents. Upload files, run SQL, evolve tables, and render charts.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables fetching and analyzing Zendesk support tickets and Help Center articles for trend analysis, knowledge base management, and drafting new articles.465 npmMIT
- FlicenseNot gradedqualityAmaintenanceEnables users to fetch, create, and update Zendesk tickets and comments, analyze tickets and draft responses, and query Help Center articles as a knowledge base.-
- FlicenseNot gradedqualityAmaintenanceEnables users to retrieve and manage tickets and comments, analyze tickets and draft responses, and access Help Center articles as a knowledge base.-
- FlicenseNot gradedqualityAmaintenanceEnables retrieving and managing tickets and comments, analyzing tickets, drafting responses, and accessing Help Center articles as a knowledge base.-