chartlink-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CHARTLINK_API_KEY | Yes | Your chartlink API key (format: viz_...). Obtained via POST /api/signup. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| signupA | 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. |
| whoamiA | Returns key name + workspace. Call this first — non-destructive auth check. Everything you write is stamped createdBy/updatedBy = key name. |
| list_asset_typesA | Chart/table types you can create, with links to per-type schemas. |
| get_spec_schemaA | Returns the JSON Schema for the type's config, the data schema, two worked examples (minimal + rich), and |
| list_assetsA | Filterable list; rows elide config/data. Use get_asset for full bodies. |
| get_assetB | Full asset envelope. includePreview=true also returns an inline PNG of the current draft. |
| list_geographiesA | 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. |
| list_templatesA | 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 |
| create_assetA | 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. |
| update_assetA | 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 |
| replace_asset_dataA | 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). |
| set_data_sourceA | 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. |
| clear_data_sourceA | Stops scheduled fetches; the chart keeps its current data. |
| fetch_data_sourceB | Runs one fetch on top of the schedule. Returns {ok, rows, published, error}. |
| publish_assetA | 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'. |
| unpublish_assetA | Embeds and PNGs return 410 until republished. |
| duplicate_assetB | New id, new embed URLs. Useful for rebranding a chart for another audience. |
| delete_assetA | Embeds go dark. Restorable via the REST API (POST /api/assets/{id}/restore). |
| list_brandsA | Style-only token sets applied under your config. Pass a slug as |
| create_brandA | 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. |
| update_brandA | 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. |
| get_billingA | 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. |
| create_checkout_linkA | 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). |
| upgrade_to_premiumA | Same URLs, instantly rebranded: badge removed, 2400px PNG and SVG unlocked, custom branding applies. Idempotent for already-premium charts. |
| create_edit_linkA | 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. |
| revoke_edit_linkA | The URL stops working immediately. List links (prefixes + tokenIds) via GET /assets/{id}/edit-links. |
| submit_feedbackA | 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). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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.