Csvbox Mcp Server

io.github.csvbox-io由 GitHub 账号 csvbox-io 发布v1.0.1更新于 Oct 24, 2026

CSVBox MCP server for creating, updating, validating and generating CSVBox importer sheets.

概览

AI 生成的概览

CSVBox MCP 服务器,让助手创建、替换、局部更新、校验并生成 CSVBox 导入表及其集成代码。

可以做什么
  • 通过 CSVBox API 创建、整体替换或局部更新导入表
  • 用自然语言提示生成完整表结构,可用服务端 LLM 密钥,也可用由宿主客户端模型执行的 MCP 提示
  • 在本地校验表结构,支持 create、put、patch 三种模式
  • 生成 vanilla JS、React、Vue 或 Angular 的集成代码
  • 起草虚拟列、校验函数和数据转换的 JavaScript 代码供人工审阅
适用场景
适合在搭建或维护 CSVBox 导入表时使用:让助手根据描述起草表结构、发送前先做校验,并在不手写 JSON 的情况下修改线上导入表。
运行要求
以 stdio 方式在本机运行,通常通过 npx 使用 npm 包 @csvbox/mcp-server(需要 Node.js)。调用 API 的工具需要 CSVBOX_API_KEY 和 CSVBOX_API_SECRET;validate_schema 与 generate_import_code 无需凭据。提示生成表结构需要 ANTHROPIC_API_KEY 或 OPENAI_API_KEY,或在自带模型的客户端中使用无需密钥的 MCP 提示方式。需要访问 CSVBox API 和所选 LLM 服务的网络。
安装前请注意
会在客户端环境中保存 CSVBox API 凭据,可能还有 LLM 服务密钥。update_sheet 会整体替换表并删除未列出的集合项,patch_sheet 则合并;两者都会改动线上导入表。为虚拟列、校验函数和数据转换生成的 JavaScript 是未经审阅的模型输出,CSVBox 会在导入时执行,应用前务必阅读。缺少 integrity 摘要的第三方脚本依赖日后可能被替换。每个 API 请求都会附带固定的客户端标识请求头。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Csvbox Mcp Server,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

csvbox-mcp-server

A universal Model Context Protocol (MCP) server for CSVBox. It exposes CSVBox importer-sheet management as MCP tools so you can create, replace, patch, generate, validate, and scaffold importers from any MCP-compatible client — Claude Desktop, Cursor, Windsurf, Roo Code, Cline, VS Code, ChatGPT MCP, and more.

Runs over stdio, so it works the same way in every client.

Tools

ToolPurposeAPI call
create_sheetCreate a CSVBox sheetPOST /1.1/sheet
update_sheetReplace an existing sheetPUT /1.1/sheet/{key}
patch_sheetPartially update a sheetPATCH /1.1/sheet/{key}
generate_sheet_jsonNL prompt → complete sheet JSON (via LLM)none (calls LLM)
create_importer_from_promptNL prompt → validate → createPOST /1.1/sheet (+ LLM)
generate_import_codeIntegration code (vanilla-js/react/vue/angular)none
generate_sheet_functionsNL prompt → virtual columns / validation functions / data transforms (via LLM)none (calls LLM)
validate_schemaLocal schema validationnone

CSVBox currently has no GET or LIST endpoints, so there are intentionally no get_sheet / list_sheet tools.

It also exposes two MCP prompts:

PromptPurpose
create_csvbox_sheetMake the host client's own LLM build a complete CSVBox sheet (no server-side LLM key needed).
csvbox_sheet_functionsMake the host client's own LLM author virtual columns, validation functions, and data transforms (no server-side LLM key needed).

Prompt → sheet generation

generate_sheet_json and create_importer_from_prompt use an LLM to convert a free-form request into a complete CSVBox sheet — title, sheet_columns, destinations, webhooks, security_settings, and steps. Only actual data fields become columns; destinations, webhooks, domains, regions, file-upload and step settings are placed in their proper configuration sections, never turned into columns. There are three tiers:

  1. Server LLM — when ANTHROPIC_API_KEY or OPENAI_API_KEY is set, the server calls the LLM directly. Works in MCP Inspector and headless.
  2. MCP prompt (create_csvbox_sheet) — when you have no server key, host clients (Cursor, Claude Desktop, Cline) run the generation with their own model, then call validate_schema and create_sheet. Free.
  3. None configured — generate_sheet_json returns a structured "no LLM provider configured" error pointing to the MCP prompt, and create_importer_from_prompt does not call the CSVBox API. There is no regex fallback.
Category / module expansion

The generator runs in one of two modes, chosen automatically from the prompt:

  • Extraction (default) — the prompt names concrete fields (e.g. "columns name, email, phone"). Only those become columns; nothing is invented.
  • Expansion — the prompt names business modules / categories as a list (e.g. "modules for: Company Information, Suppliers, Payroll, Invoice"), asks for a comprehensive/detailed schema, or asks for a column count ("at least 100 columns"). Each named module is expanded into several realistic, prefixed, correctly-typed columns (e.g. Suppliers → supplier_id, supplier_name, supplier_gstin, supplier_email, …). An explicit minimum count is honored and every column_name is globally unique.

Data types and validations are inferred from the field names and any requested types:

Requested / impliedColumn typeValidators
Dropdown / status / category with fixed optionslistvalues: [...] candidate options
Percentage / percentnumbermin_value: 0, max_value: 100
Positive numeric (quantity, count, stock, cost, age)numbermin_value: 0
ID / code / reference numbertext—
Emailemail—
Phone / mobilephone_number—
URL / websiteurl—
Price / cost / amount / salarycurrency—
Date fieldsdateformat: "YYYY-MM-DD"
Boolean / is_* / activeboolean—
GST / GSTIN / tax idregexGSTIN pattern
PIN code / postal code (India)regex^[1-9][0-9]{5}$

Large schemas: the default models (claude-haiku-4-5, gpt-4o-mini) are cheap but produce noticeably better 100+ column schemas when you override with a stronger model via LLM_MODEL (e.g. claude-sonnet-4-6). The output cap is raised to fit big sheets; if a request is still too large the response is flagged TRUNCATED (a distinct result, not a parse error) and the CSVBox API is not called — reduce the column count / modules or use a model with a larger output budget and retry.

Function collections (virtual columns, validation functions, data transforms)

Beyond the six sheet properties, the CSVBox Sheet API accepts three collections whose items carry a js_code string that CSVBox executes during an import:

CollectionIdentified byMaxjs_code must…
virtual_columnscolumn_name20return the computed cell value
validation_functionsfunction_name10return an array of error strings ([] = valid)
data_transformstransform_name10mutate the csvbox object and return it

Inside js_code the csvbox object exposes row, column, virtual, user, import, and environment. The two accessors are not interchangeable — a virtual column is per-row and uses csvbox.row.<name> (a scalar), while a "column"-scoped function sees the whole column via csvbox.column.<name> (an array).

Shared optional fields: scope (column | row; not on virtual columns), run_at (before_validation | after_validation; data transforms only), columns / dynamic_columns, active, dependencies, and _delete (PATCH only).

Authoring them

json
// generate_sheet_functions  (requires ANTHROPIC_API_KEY or OPENAI_API_KEY){  "prompt": "add a virtual column joining first and last name, and check every email contains an @",  "sheet": { "title": "Customers", "sheet_columns": [ ... ] }}

Returns { "virtual_columns": [...], "validation_functions": [...], "source": ..., "validation": {...} }. Collections the request does not imply are omitted, never returned as empty arrays.

This tool does not call the CSVBox API. Read the generated js_code, then apply it yourself with patch_sheet. Pass sheet so the model references real column names and the validator can check those references — CSVBox has no read endpoint, so it must be supplied inline. Without an LLM key, use the csvbox_sheet_functions MCP prompt instead.

PUT vs PATCH — read this before applying

update_sheet (PUT)patch_sheet (PATCH)
Collection you sendauthoritative — any existing item not named is deletedmerged — unnamed items are left alone
"virtual_columns": []deletes all 20no-op
Key omitteduntoucheduntouched
_delete: truenot validremoves that item (all its other fields ignored)

Use patch_sheet to apply generated functions. Validate first with the matching verb:

json
// validate_schema{ "sheet": { "data_transforms": [ ... ] }, "mode": "patch" }

mode is create (default), put, or patch. It only affects the function collections — under put an empty array is a hard error rather than a warning, and _delete is rejected outside patch.

Dependencies

An item may load up to 5 third-party scripts:

json
{ "url": "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js",  "globals": ["dayjs"],  "integrity": "sha384-..." }

Only cdn.jsdelivr.net, unpkg.com, and cdnjs.cloudflare.com are allowed; https only, .js/.mjs path, no query string, fragment, userinfo, or port.

Security. This server never executes js_code — it is an opaque string here. Generated JavaScript is unreviewed model output, so read it before you PATCH it into a live importer. A dependency without an integrity digest can change under your customers at any time; validate_schema warns when one is missing.

See docs/sheet-functions-example.json for a full payload.

Installation

bash
npm install @csvbox/mcp-server

Or build from source:

bash
git clone <this-repo> csvbox-mcp-servercd csvbox-mcp-servernpm installnpm run build

This produces dist/index.js — the entrypoint MCP clients launch.

Environment variables

Copy .env.example to .env and fill in your CSVBox credentials:

bash
CSVBOX_API_KEY=your_api_keyCSVBOX_API_SECRET=your_api_secret

CSVBox credentials are only required for the API-backed tools (create_sheet, update_sheet, patch_sheet, create_importer_from_prompt). validate_schema and generate_import_code work without any credentials.

Auth header note: the client sends x-csvbox-api-key and x-csvbox-secret-api-key (matching the CSVBox reference payloads). These are defined as constants in src/services/csvbox-api.ts if your account uses different header names.

Client identification

Every request this server sends to the CSVBox API carries two extra headers:

x-csvbox-client: mcpx-csvbox-client-version: <the version in package.json>

CSVBox records how each sheet was created; without these, sheets and imports made through MCP are indistinguishable from any other REST caller. The version is read from package.json and is the same one the server advertises to your MCP client, so the two can never disagree.

These are always sent — there is no environment variable or tool input that disables or changes them. They carry no credentials and nothing derived from your tool inputs. Tools that make no API call (generate_sheet_json, generate_sheet_functions, generate_import_code, validate_schema) send no request and therefore no headers.

LLM provider (for prompt → sheet generation)

generate_sheet_json and create_importer_from_prompt need an LLM. Set one of:

bash
ANTHROPIC_API_KEY=sk-ant-...OPENAI_API_KEY=sk-...

The provider is auto-detected:

ConditionProviderDefault model
LLM_PROVIDER=anthropic (and its key set)Anthropicclaude-haiku-4-5
LLM_PROVIDER=openai (and its key set)OpenAIgpt-4o-mini
ANTHROPIC_API_KEY set (no LLM_PROVIDER)Anthropicclaude-haiku-4-5
OPENAI_API_KEY set (no LLM_PROVIDER)OpenAIgpt-4o-mini
neither key setnone — tools return an error pointing to the create_csvbox_sheet MCP prompt—

LLM_PROVIDER disambiguates when both keys are present; LLM_MODEL overrides the model for whichever provider is chosen. For large category/module schemas (100+ columns) set LLM_MODEL to a stronger model (e.g. claude-sonnet-4-6) — see Category / module expansion.

MCP Inspector: set the LLM key in the Inspector's environment-variables panel to use the server-LLM path. Inspector has no host LLM of its own, so it can render the create_csvbox_sheet prompt but cannot execute it — for the keyless path use a client with a model (Cursor, Claude Desktop, Cline).

Running locally

bash
# After building:npm start
# Or run the built file directly:node dist/index.js

The server speaks MCP over stdio and logs csvbox-mcp-server running on stdio to stderr (stdout is reserved for the protocol).

Client configuration

For a published installation, use the npm package with npx. Set CSVBOX_API_KEY / CSVBOX_API_SECRET in the env block.

Note: The npm package is @csvbox/mcp-server and the executable is csvbox-mcp-server.

Claude Desktop

Add the following to your Claude Desktop MCP configuration:

json
{  "mcpServers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

Cursor

Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):

json
{  "mcpServers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

Windsurf

Edit ~/.codeium/windsurf/mcp_config.json:

json
{  "mcpServers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

Roo Code

In the Roo Code MCP settings (mcp_settings.json):

json
{  "mcpServers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

Cline

In the Cline MCP settings (cline_mcp_settings.json):

json
{  "mcpServers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

VS Code MCP

Add to .vscode/mcp.json (or the global mcp.json):

json
{  "servers": {    "csvbox": {      "command": "npx",      "args": [        "-y",        "--package=@csvbox/mcp-server",        "csvbox-mcp-server"      ],      "env": {        "CSVBOX_API_KEY": "your_api_key",        "CSVBOX_API_SECRET": "your_api_secret"      }    }  }}

Example tool calls

Generate a complete sheet from a prompt (LLM, no CSVBox API call):

json
// generate_sheet_json  (requires ANTHROPIC_API_KEY or OPENAI_API_KEY){ "prompt": "Create employee importer with name, email, salary, joining date; destination as testapi; allow only xlsx files" }

Returns { "sheet": { "title": ..., "sheet_columns": [...], "destinations": [...], "steps": {...} }, "source": "llm:anthropic:claude-haiku-4-5", "validation": { "valid": true, ... } }. Data fields become columns (salary → currency, joining date → date); the destination and xlsx setting go to destinations / steps, not columns. With no LLM key, returns an error pointing to the create_csvbox_sheet prompt.

Validate a schema before sending it:

json
// validate_schema{ "sheet": { "title": "Customers", "sheet_columns": [  { "column_name": "email", "display_label": "Email", "type": "email" }] } }

Returns { "valid": true, "errors": [], "warnings": [ ... ] }.

Create a sheet:

json
// create_sheet{ "sheet": { "title": "Customer Import", "sheet_columns": [  { "column_name": "name", "display_label": "Name", "type": "text" },  { "column_name": "email", "display_label": "Email", "type": "email" }] } }

Generate + create in one step:

json
// create_importer_from_prompt  (requires an LLM key + CSVBox credentials){ "prompt": "Create customer importer with name, email, phone; allow for example.com" }

Returns { "generated_schema": { ... }, "source": ..., "validation": { ... }, "api_response": { ... } }. Aborts without calling the API if no LLM provider is configured or the generated schema fails validation.

Replace a sheet:

json
// update_sheet{ "sheet_license_key": "abc123", "sheet": { "title": "Updated", "sheet_columns": [ ... ] } }

Destructive for any collection you send — see PUT vs PATCH.

Patch a sheet:

json
// patch_sheet{ "sheet_license_key": "abc123", "changes": { "title": "New Title" } }

Remove one function without touching the rest:

json
// patch_sheet{ "sheet_license_key": "abc123",  "changes": { "virtual_columns": [ { "column_name": "full_name", "_delete": true } ] } }

Generate integration code:

json
// generate_import_code{ "framework": "react" }

Supported column types

text, number, email, date, time, boolean, regex, ip, url, credit_card, phone_number, currency, list, dependent_list, dynamic_list, dependent_dynamic_list, multiselect_list, multiselect_dynamic_list.

Development

bash
npm run build   # compile TypeScript → dist/npm start       # run the built servernpm run lint    # type-check without emittingnpm test        # compile and run the unit suite (alias: npm run test:unit)

Tests

npm test compiles src/tests/ and runs it with Node's built-in test runner — no test framework, no mocking library.

The suite is hermetic. It never contacts an external host, never reads your ambient CSVBOX_API_* / ANTHROPIC_API_KEY / OPENAI_API_KEY, and never touches a real CSVBox account, so it passes identically whether or not you have credentials configured. HTTP is intercepted at the axios adapter; the LLM is a scripted fake; the one test that needs real request encoding starts an ephemeral listener on 127.0.0.1 and closes it afterwards. Tests that read environment variables set what they need explicitly and restore the previous values.

E2E tests
bash
npm run test:e2e         # run the Playwright suitenpm run test:e2e:report  # open the HTML report from the last run

Specs live in e2e/, configured by playwright.config.ts. Like the unit suite, this suite is hermetic: it starts mock CSVBox and LLM servers on loopback (e2e/support/mock-csvbox-server.ts, e2e/support/mock-llm-server.ts) and drives the real built server (dist/index.js) through MCP Inspector with fake credentials pointed at those mocks — it never contacts a real CSVBox account or LLM provider, and never reads your .env. A separate, zero-credential Inspector instance covers the "missing credentials" error paths. Requires npm run build first (the test:e2e webServer entries build automatically).

Embedding the server

createServer() is exported from the entry module. It registers every tool and prompt and returns the McpServer without attaching a transport, so you can connect it to one of your own:

ts
import { createServer } from "@csvbox/mcp-server";
const server = createServer();await server.connect(myTransport);

Importing the module does not start anything; the stdio server runs only when dist/index.js is executed directly.

License

MIT

来源:README.md,提交 a8ac91d

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v1.0.1最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分