openanalyst-mcp-server

openanalyst-mcp-server

MCP server that turns coding agents into data analysts: attach CSV/Parquet/JSON/XLSX or databases, profile data, run read-only SQL, and render Vega-Lite charts as SVG files.

Category
访问服务器

README

<p align="center"><img src="docs/assets/logo.svg" alt="OpenAnalyst logo" width="96" height="96" /></p> <h1 align="center">OpenAnalyst</h1>

<p align="center"><b>Turn your coding agent into a data analyst.</b><br/> Attach a CSV, get an automatic profile, ask questions in SQL, and see real charts rendered inside the conversation.</p>

<p align="center"> <a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat" /></a> <img alt="tests" src="https://img.shields.io/badge/tests-74%20passing-brightgreen?style=flat" /> <img alt="runtime" src="https://img.shields.io/badge/DuckDB-in--process-fff100?style=flat" /> <img alt="charts" src="https://img.shields.io/badge/charts-Vega--Lite-4c78a8?style=flat" /> </p>

<p align="center">English · <a href="README.zh.md">中文</a></p>

A real DeepSeek Harness session — the agent attached a CSV, profiled it, and drew these charts as conversation nodes (headless-Chrome capture of the live UI; see the verification record):

<p align="center"> <img src="docs/assets/conversation-full.png" alt="Full DeepSeek Harness window: a heatmap and a boxplot rendered inside the conversation, with the session sidebar and composer visible" width="100%" /> </p>

Status: M1 + M2 + M3 complete. The dsh plugin is live-verified inside dsh web 0.1.0-rc.8 — the full attach → profile → query → chart chain ran in a real session and both charts rendered as conversation nodes (verification record). The MCP server passes protocol-level tests plus a stdio smoke. See Known limitations.


What it does

data_attach     →  register a CSV / Parquet / JSON / XLSX file as a queryable table
data_attach_db  →  attach PostgreSQL / MySQL / SQLite read-only and list its tables
data_profile    →  types, missing values, exact distinct counts, outliers, quality issues, chart ideas
data_query      →  one read-only SQL statement, results as lossless JSON
data_chart      →  bar / line / scatter / histogram / area / heatmap / boxplot — with color
                   series, stacked/grouped layout, facet small multiples; line & scatter pan/zoom
data_report     →  a self-contained HTML report (profile + charts as inline SVG); prints to PDF
data_sources    →  what is currently attached

The same five tools ship on two hosts from one engine:

Host Package Chart delivery
DeepSeek Harness plugin openanalyst live conversation node (Vega canvas)
MCP server (Claude Code / Codex / Cursor / any MCP client) openanalyst-mcp-server SVG file + full Vega-Lite spec in structuredContent

Every tool is also reachable from Code Mode as await tools.data_*(args), so the agent can chain the whole analysis inside one program instead of spending a round trip per step.

The workbench — a session-header panel listing this session's data sources, a chart gallery with click-to-scroll, and generated reports:

<p align="center"> <img src="docs/assets/workbench-panel.png" alt="The OpenAnalyst workbench panel open over a dsh conversation: data sources, chart gallery with locate buttons, and the report archive" width="100%" /> </p>

More in-conversation chart kinds (same theme, exported from a live session):

<p align="center"> <img src="docs/assets/chart-heatmap.png" alt="Heatmap: revenue by region and product" width="32%" /> <img src="docs/assets/chart-boxplot.png" alt="Boxplot: revenue distribution and outliers per region" width="32%" /> <img src="docs/assets/chart-grouped-bar.png" alt="Grouped bars: revenue per region split by product" width="32%" /> </p>

Install

DeepSeek Harness:

dsh plugin --profile web add openanalyst

Claude Code (or any MCP client, via stdio):

claude mcp add openanalyst -- npx -y openanalyst-mcp-server

Architecture

Three decisions shape the codebase.

The engine knows nothing about the harness. @openanalyst/core takes paths and SQL and returns lossless JSON. It imports no dsh, MCP, or CLI type. That is what lets the same analysis ship to Claude Code, Codex, and Cursor through an MCP adapter later without a second implementation — the single largest factor in whether a plugin reaches an audience beyond one host.

DuckDB does the statistics. SUMMARIZE returns min/max/avg/std/quartiles/ approx_unique/null_percentage for every column in one pass, and reads CSV, Parquet and JSON directly with full-file type inference. Only IQR outliers, duplicate-row detection, and the judgement about what is worth flagging are written by hand.

Charts are Vega-Lite specs carried on session events. The harness tool-card kinds are a closed set — generic, terminal, diff, search, web — with no chart member, so a tool result can only ever degrade a chart to text. A real chart has to come from a conversation node, which the client half registers.

That constraint turned out to pick the chart format too. A conversation node must rebuild its view as a pure function of durable events — no clock, no random, no live state — and the engine prefers whole-value checkpoints over deltas. A Vega-Lite spec with its data inlined is exactly that: one plain JSON value that replays byte-for-byte. Vega-Lite was chosen because it satisfies the replay rule, not because it is a popular chart library.

@openanalyst/core            engine, profiling, DB connectors, chart specs  (host-agnostic)
  ├── @openanalyst/report    Vega-Lite -> SVG (pure JS) + self-contained HTML reports
  ├── openanalyst            dsh host half: 7 tools + chart event
  │     └── ./client         dsh browser half: conversation node + Vega canvas
  └── openanalyst-mcp-server stdio MCP server: same 7 tools, charts as SVG files

Development

pnpm install
pnpm -r run build
pnpm -r run test

74 tests: 46 over the core (SQL policy, JSON conversion, profiling with exact distinct counts, charts, and live PostgreSQL/MySQL connector tests that auto-skip without the Docker fixtures), 5 over the report builder, 14 driving the real dsh plugin tools end to end against DuckDB (including per-agent isolation), and 9 protocol-level MCP tests over the SDK's in-memory transport (plus a scripted stdio smoke). Live verification against a running dsh web is scripted in scripts/mock-llm-scripted.mjs + scripts/verify-live.patch.yml — see docs/VERIFICATION.md.

Known limitations

These are real and worth reading before building on this.

  • PTC 模式 (Code Mode) presets reject direct tool calls — the model must wrap them in a run_code program there. Under the Standard preset the tools are called directly. Verified behavior, documented in docs/VERIFICATION.md.
  • dsh per-agent engines are bounded, not lifecycle-tracked. Each dsh agent session gets its own engine (no alias collisions), but the harness does not notify plugins on agent disposal, so the plugin holds at most 32 engines and evicts the least-recently used — that session transparently re-attaches on its next call.
  • The client bundle is ~860 kB. Vega is inlined because the harness serves exactly one file per plugin and has no route for sibling chunks, so a chart-free session still pays for it.
  • data_attach takes any path the host process can read. There is no workspace fencing yet; it inherits whatever the harness sandbox allows.
  • XLSX depends on DuckDB's read_xlsx, which may need an extension download on first use. CSV, Parquet and JSON are covered by tests; XLSX is not.

Notes on the dsh npm packages

Two things cost time here and are worth recording for anyone else building a harness plugin:

  • latest points at a broken line. npm view @deepseek-ai/dsh-tools version reports 0.0.1-rc.1, but the current line is 0.1.0-rc.8. Several 0.0.1-rc.1 packages cannot be installed at all — @deepseek-ai/dsh-client-runtime@0.0.1-rc.1 depends on @deepseek-ai/dsh-compact and @deepseek-ai/dsh-session@0.0.1-rc.1 depends on @deepseek-ai/dsh-type-meta; neither is published. Pin 0.1.0-rc.8.
  • pnpm's minimumReleaseAge policy blocks the rc line while it is fresh. This repo lifts it in pnpm-workspace.yaml, with a note to restore it once dsh has a stable release.

Roadmap

M1 Core + dsh plugin, charts in the conversation — done, live-verified
M2 MCP server: same capability in Claude Code / Codex / Cursor — done ← you are here
M3 HTML report export (prints to PDF), PostgreSQL / MySQL / SQLite, per-agent isolation — done
M4 Workbench panel: data sources, chart gallery with click-to-scroll, report archive — done, live-verified

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选