Skip to main content
Glama
README.md
# furlen-mcp

[![furlen-mcp MCP server](https://glama.ai/mcp/servers/amitsha86/furlen-mcp/badges/score.svg)](https://glama.ai/mcp/servers/amitsha86/furlen-mcp)

**An MCP server for making charts.** Give Claude, Cursor, or any Model Context Protocol client a
table of numbers and it returns an animated chart video — and it recomputes every figure in the
narration against your rows before it will export anything.

Published to the official MCP registry as `io.github.amitsha86/furlen-mcp`. Backed by
[Furlen](https://furlen.pro).

## Why this one is different

Most chart tooling will draw whatever number you hand it, and an AI-assisted one will happily
generate a number to draw. This server won't: the story it writes is checked claim-by-claim against
the source rows server-side, and a claim that doesn't reconcile **blocks the export** rather than
shipping. You can watch that gate run at [furlen.pro/proof](https://furlen.pro/proof).

That matters more through an agent than through a UI. Nobody is watching the intermediate output,
so the check has to be the thing that refuses — not a human noticing.

## Setup

1. Create a Furlen API key at **furlen.pro → Settings → API keys**.
2. Add the server to your MCP client config. Nothing to install first; `npx` fetches it.

```json
{
  "mcpServers": {
    "furlen": {
      "command": "npx",
      "args": ["-y", "furlen-mcp"],
      "env": { "FURLEN_API_KEY": "sg_live_..." }
    }
  }
}
```

- **Claude Desktop:** add the block above to `claude_desktop_config.json` and restart.
- **Cursor:** add it to `.cursor/mcp.json`.
- Any other MCP client: run `npx -y furlen-mcp` with `FURLEN_API_KEY` set.

## Tools

### `furlen_public_data`

Fetch a real public dataset by describing it — no spreadsheet needed.

> "India GDP over the last 10 years" · "compare US and China population" · "Apple revenue over 6
> years" · "US healthy life expectancy" · "India exports to the US"

Resolves through Furlen's adapters for the **World Bank, IMF WEO, FRED, Eurostat, UN Comtrade,
WHO** and company filings (**SEC EDGAR, ESEF, DART, EDINET**). Returns the rows, a ready-to-use
`csv` string you can pass straight to `furlen_render`, and provenance naming the exact indicator.

If no connected source covers the subject it says so: a `422` with `code: "subject_unsupported"`
means the data doesn't exist here, **not** that the request was malformed — don't retry it
reworded. Exchange rates are the canonical example.

### `furlen_render`

Turns CSV text into an animated, claim-verified chart video. One call runs the whole pipeline —
profile the data, find the insights, write the story, verify every claim, render — and returns a
`renderId`.

| Arg | Values | Default |
|---|---|---|
| `csv` *(required)* | Raw CSV text, header row first | — |
| `audience` | `investor` · `executive` · `linkedin` · `youtube` · `internal_team` · `client_report` · `student` | `linkedin` |
| `outputFormat` | `video_16_9` · `video_9_16` · `video_1_1` | `video_16_9` |
| `format` | `mp4` · `gif` | `mp4` |
| `resolution` | `720p` · `1080p` · `4k` | `1080p` |

### `furlen_render_status`

Polls a `renderId`. Returns status (`queued` → `running` → `completed` \| `failed`), progress, and a
`downloadUrl` when finished. Renders usually take **30–90 seconds**, so poll every few seconds
rather than blocking.

## Example

> "Here's my quarterly revenue CSV — make a LinkedIn chart video from it with Furlen."

The agent calls `furlen_render`, polls `furlen_render_status`, and hands back the download link once
the video is ready.

## Example: chart public data end to end

> "Chart India's GDP over the last 10 years and make me a LinkedIn video."

The agent calls `furlen_public_data` with that request, gets back rows plus a `csv` string, passes
the `csv` to `furlen_render`, polls `furlen_render_status`, and returns the download link. No file
ever touches the agent's filesystem.

## What it can't do yet

Worth knowing before you wire it up:

- **No file uploads.** Data arrives as CSV text or by naming a public dataset — not as an attached
  spreadsheet.
- **Rendering is asynchronous.** There is no synchronous "give me a chart back now" call.
- **The sources are the sources.** If no connected provider publishes the figure, you get a refusal
  rather than an estimate. That is the design, not a gap.
- **It needs an API key** with the `data:read` and `renders:write` scopes, and your plan's limits on
  resolution, watermarking and render minutes apply exactly as in the app.

## Environment

- `FURLEN_API_KEY` (required) — your workspace API key.
- `FURLEN_BASE_URL` (optional) — defaults to `https://furlen.pro`.

## Links

- Product: https://furlen.pro
- API + MCP docs: https://furlen.pro/developers#mcp
- How claim verification works: https://furlen.pro/proof

MIT © Furlen

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool serves a distinct purpose: fetching data, rendering a video, and checking render status. There is no functional overlap between them.

Naming Consistency5/5

All tools follow a consistent 'furlen_<noun>' pattern with clear, descriptive names. The naming convention is uniform and predictable.

Tool Count5/5

With only 3 tools, the set is tightly scoped to the core workflow (fetch, render, poll). Each tool is essential and no tool feels redundant or missing.

Completeness5/5

The tool surface covers the entire data-to-video pipeline: data fetching, render initiation, and status polling. No obvious gaps exist for the stated purpose.

Maintenance

ActivityStale
ResponsivenessNo issues