Repository avatar
Databases
v0.1.3
active

mcp-server-ava

io.github.DoubleCore/mcp-server-ava

Load data, inspect schemas, run SQL, analyze datasets, and build charts with AVA via MCP.

Documentation

mcp-server-ava

Model Context Protocol server for AVA. Load a dataset, inspect it, run SQL, ask questions in natural language, and get charts — from Claude Desktop, Cursor, ChatGPT, or any other MCP client.

AVA does the data access, SQL execution, and chart specs; your MCP client's own agent does the reasoning. No AVA CLI or extra API key is needed for deterministic work.

Install

npm install -g mcp-server-ava @antv/ava

@antv/ava v4 is a peer dependency — install it alongside. Without installing globally: npx -y -p mcp-server-ava -p @antv/ava mcp-server-ava.

Requires Node.js ≥ 22.13.

Client configuration

Add the server to your MCP client config. The env block is only needed for the model-backed tools (ava_analyze, ava_translate, ava_suggest, ava_visualize).

Claude Desktop (claude_desktop_config.json) / Cursor (~/.cursor/mcp.json) / most clients:

{
  "mcpServers": {
    "ava": {
      "command": "npx",
      "args": ["-y", "mcp-server-ava"],
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_MODEL": "gpt-4o-mini",
        "OPENAI_BASE_URL": "https://api.openai.com/v1",
        "AVA_MCP_MAX_ROWS": "200"
      }
    }
  }
}

Any OpenAI-compatible endpoint works — set OPENAI_BASE_URL for Azure, OpenRouter, a local vLLM, or an internal gateway.

Tools

ToolWhat it doesNeeds a model
ava_load_dataLoad inline CSV/JSON/text or a file path (.csv, .json, .parquet, .xlsx). Replaces the current dataset and returns the schema.only for text
ava_schemaTable names, columns, and types.no
ava_profileRow count, nulls, distinct, min/max/mean/median per column.no
ava_queryOne read-only SQL statement with DuckDB semantics; results capped at AVA_MCP_MAX_ROWS.no
ava_analyzeNatural-language question → AVA writes SQL, executes it, and summarizes the answer.yes
ava_translateNatural-language question → SQL, without executing it, so a human can review it.yes
ava_suggestSuggest questions worth asking about the loaded dataset.yes
ava_visualizeRecommend a chart for rows from a previous call; returns GPT-Vis JSON.yes

Every tool returns JSON text. Failures (no dataset loaded, invalid SQL, engine errors) come back as MCP error results, so the agent sees the message instead of a dead connection.

Example conversation

You: Load examples/sales.csv and tell me which region sells the most, then chart it.

Agent: calls ava_load_data → ava_query (SELECT region, SUM(sales)…) → ava_visualize, replies "West sells the most at 13 units" and returns chart JSON.

Rendering a returned chart

ava_visualize returns a spec, not HTML. Save the spec and render it with the AVA CLI:

npm install -g @antv/ava            # provides the `ava` binary
npx ava viz --spec @chart.json -o chart.html

Configuration

Env varDefaultNotes
OPENAI_API_KEY—Enables the model-backed tools. Without it they return a clear error.
OPENAI_MODELgpt-4o-miniAny chat model your endpoint exposes.
OPENAI_BASE_URLOpenAIPoint at an OpenAI-compatible gateway.
AVA_MCP_MAX_ROWS200Hard cap per query / analyze result. Truncation is reported in the payload.

Safety notes

  • One dataset per server process; loading again replaces it. Run separate servers for separate datasets.
  • SQL is read-only: writes, DDL, and multi-statement scripts are rejected by the engine.
  • Results are truncated to the row cap and flagged with truncated: true.
  • Diagnostics go to stderr — stdout is reserved for the MCP protocol.

Development

npm install
npm run build
npm test                              # vitest: in-memory MCP client over the real server
node scripts/smoke.mjs                # end-to-end over stdio against the built binary
OPENAI_API_KEY=... node scripts/smoke.mjs   # also exercises analyze + visualize

Publishing (npm trusted publishing / OIDC)

Releases are published through GitHub Actions with npm provenance — no NPM_TOKEN secret is stored. The workflow (.github/workflows/publish.yml) only runs on a version tag (v*.*.*) or a manual workflow_dispatch run, gives itself contents: read + id-token: write, then runs npm ci → typecheck → build → test → npm pack --dry-run → npm publish --provenance --access public. It uses Node 24 and npm 11.21.2 (Trusted Publishing requires Node ≥ 22.14.0 and npm ≥ 11.5.1), disables release-build caching, and requires a tag to exactly match v + the package.json version.

One-time npm bootstrap and trust

npm only exposes Trusted Publisher settings for a package that already exists; it has no pending-publisher flow for a never-published name. An npm owner must therefore bootstrap a new package through npm's authenticated staging flow (npm stage publish --access public) and approve that initial release with 2FA. Do not dispatch this workflow to claim an unknown package name. After bootstrapping, increment the version so the first OIDC release does not try to republish the bootstrap version.

Once the package exists, configure the trusted publisher on npmjs.com:

  1. Open Packages → mcp-server-ava → Settings → Trusted publishing and select GitHub Actions.
  2. Add a trusted publisher entry with:
    • Organization or user: DoubleCore
    • Repository: mcp-server-ava
    • Workflow filename: publish.yml (filename only, not .github/workflows/publish.yml)
    • Environment: leave empty — the workflow defines no GitHub environment
    • Allowed actions: explicitly allow npm publish; the default npm stage publish permission alone cannot authorize this workflow's direct publish command
  3. Save the entry and complete its first successful publish within two days, before the unvalidated configuration expires. The npm account must own the package and have 2FA enabled.

To cut an OIDC release, bump the version and push the resulting commit and tag:

npm version patch   # or minor / major
git push --follow-tags

The workflow then builds and tests before publishing with a public provenance statement. mcp-server-ava is a public, unscoped package, hence --access public. Verify the result with npm view mcp-server-ava version; a successful workflow alone is not proof of a Registry submission.

Publishing (official MCP Registry / GitHub OIDC)

server.json names this server io.github.DoubleCore/mcp-server-ava and currently maps version 0.1.3 to the mcp-server-ava@0.1.3 npm artifact. The GitHub OIDC namespace and npm mcpName comparison are case-sensitive, so this exact capitalization is required. Once that artifact is published with the same mcpName, updating Registry metadata at this version does not require another npm version bump or npm publish.

The independent .github/workflows/publish-mcp.yml uses GitHub OIDC with no npm credentials and no npm publish step. It checks that a manual run targets main, that a tag matches the package version and points to a commit merged into main, and that package.json, package-lock.json, server.json, and the published npm mcpName agree. It then runs the project checks and uses the pinned mcp-publisher v1.8.9 release only after verifying its Sigstore bundle with cosign.

For a metadata-only release of the current version, push the commits to main, confirm that npm view mcp-server-ava@0.1.3 mcpName returns the name above, then dispatch Publish to MCP Registry on main:

gh workflow run publish-mcp.yml --ref main

Version tags also trigger this workflow alongside the separate npm release workflow. It never waits for or republishes npm: if a tag run starts before the new npm artifact is visible, let it fail safely and rerun only the MCP workflow after the npm OIDC release succeeds. For a future package version, update package.json, both lockfile root versions, and server.json together; do not reuse an already-published npm version.

A successful workflow is not treated as proof of inclusion. Verify the actual Registry API response instead:

curl 'https://registry.modelcontextprotocol.io/v0.1/servers?search=mcp-server-ava'

License

MIT

NPM
mcp-server-ava
Install Command
npm install mcp-server-ava