Build a CSV importer by asking for one.
The CSVbox MCP server turns importer-sheet management into tools your AI client can call directly. Describe the importer you want in plain language from Claude, Cursor, Windsurf, Cline, Roo Code or VS Code — and get a validated CSVbox sheet generated, created and live, without hand-writing JSON against the REST API.
- Package
- @csvbox/mcp-server
- Executable
- csvbox-mcp-server
- Transport
- stdio
- Surface
- 9 tools · 2 prompts
- Requires
- Node.js ≥ 18
- License
- MIT
A sentence in. A working importer out.
CSVbox handles the CSV and XLSX import widget your app embeds. This server handles the configuration side — the importer “sheet” that defines columns, validation rules, destinations and webhooks. Point any Model Context Protocol client at it and that whole step collapses into a request in plain language.
Create an importer for supplier records — company name, GSTIN, contact email, phone, and the onboarding date.
No JSON. No dashboard. No REST calls.
- 1
generate_sheet_jsonPrompt → complete sheet JSON5 columns - 2
validate_schemaChecked against CSVbox’s rules0 errors - 3
create_sheetPOST /1.1/sheet201
Same tool calls in every client.
supplier_nametextsupplier_gstinregexcontact_emailemailcontact_phonephone_numberonboarded_ondateValidation and mapping ready for your users.
There are deliberately no get_sheet or list_sheet tools: the CSVbox API itself exposes no GET or LIST endpoints for sheets.
Nine tools, two prompts
Everything the server registers on connect. Five tools call the CSVbox API and need credentials; the rest run locally or against a model.
| Tool | Purpose | API call |
|---|---|---|
| create_sheet | Create a CSVbox sheet | POST /1.1/sheet |
| update_sheet | Replace an existing sheet (PUT semantics) | PUT /1.1/sheet/{key} |
| patch_sheet | Partially update a sheet (merge semantics) | PATCH /1.1/sheet/{key} |
| generate_sheet_json | Natural-language prompt → complete sheet JSON | LLM only |
| create_importer_from_prompt | Prompt → validate → create, in one call | POST /1.1/sheet |
| generate_import_code | Integration snippet for vanilla JS, React, Vue or Angular | None |
| generate_sheet_functions | Prompt → virtual columns, validation functions, transforms | LLM only |
| validate_schema | Local schema validation against CSVbox’s rules | None |
| submit_file | Submit a file for import, by URL or direct upload | POST /1.1/file |
MCP prompts
Two prompts hand generation to the client’s own model instead of the server’s — the path to take when you would rather not configure a server-side LLM key at all.
create_csvbox_sheetGuides the host client’s own model to build a complete CSVbox sheet — no server-side LLM key needed.
csvbox_sheet_functionsGuides the host client’s own model to author virtual columns, validation functions and data transforms — again key-free.
From a sentence to a sheet
generate_sheet_json and create_importer_from_prompt turn a free-form request into a complete sheet — title, columns, destinations, webhooks, security settings and steps. Only real data fields become columns; destination, domain, region and file-type settings are routed to their own config sections.
Server-side LLM
ANTHROPIC_API_KEY or OPENAI_API_KEY is set, so the server calls the model itself and returns finished sheet JSON.
MCP prompt
No server key. The host client — Claude Desktop, Cursor, Cline — runs generation with its own model, then calls validate_schema and create_sheet.
Neither
No LLM anywhere. You get a structured error pointing at the MCP prompt, and the CSVbox API is never called.
Generation resolves through these tiers in order — the first one available wins.
Extraction mode
DefaultThe prompt names concrete fields — “columns name, email, phone” — and only those become columns. Nothing is invented.
Expansion mode
On requestTriggered by a named business module, a request for a “comprehensive” schema, or an explicit column-count floor. A module like Suppliers expands into realistic prefixed columns — supplier_id, supplier_gstin — with every name kept globally unique.
Type inference
Field names and requested types are mapped onto CSVbox column types automatically, with the obvious validators attached.
| Field pattern | Column type | Validators |
|---|---|---|
| Dropdown, status, fixed category | list | values: [...] |
| Percentage | number | min_value: 0, max_value: 100 |
| Quantity, cost, age (positive) | number | min_value: 0 |
| — | ||
| Phone, mobile | phone_number | — |
| URL, website | url | — |
| Price, salary, amount | currency | — |
| Date fields | date | format: "YYYY-MM-DD" |
| Boolean, is_* | boolean | — |
| GST, GSTIN, tax id | regex | GSTIN pattern |
| Indian PIN code | regex | ^[1-9][0-9]{5}$ |
Schemas over 100 columns. Override the cheap default model (claude-haiku-4-5 or gpt-4o-mini) with a stronger one via LLM_MODEL. Oversized output is flagged TRUNCATED rather than silently cut or mis-parsed, and the CSVbox API is not called.
Virtual columns, validators, transforms
Beyond the six core sheet properties, CSVbox accepts three collections whose items carry a js_code string that CSVbox executes during a real import.
| Collection | Identified by | Max | js_code must… |
|---|---|---|---|
| virtual_columns | column_name | 20 | return the computed cell value |
| validation_functions | function_name | 10 | return an array of error strings ([] = valid) |
| data_transforms | transform_name | 10 | mutate the csvbox object and return it |
The csvbox object
Inside js_code, the csvbox object exposes row, column, virtual, user, import and environment.
A virtual column reads csvbox.row.<name> — one row, a scalar. A column-scoped function reads csvbox.column.<name> — the whole column, an array. The two are not interchangeable, and confusing them is the most common way a generated function fails at import time.
Third-party scripts
An item may load up to five third-party scripts, restricted to a fixed CDN allowlist: cdn.jsdelivr.net, unpkg.com and cdnjs.cloudflare.com — https only, a .js or .mjs path, and no query string, fragment, userinfo or port.
{
"url": "https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js",
"globals": ["dayjs"],
"integrity": "sha384-..."
}The MCP server never executes js_code. It is an opaque, unreviewed string here, and only runs later inside CSVbox during a real import. Read generated code before applying it with patch_sheet. A dependency without an integrity digest can change under your users at any time — validate_schema warns when one is missing.
PUT vs PATCH
The difference matters most on the function collections, where a PUT that omits an item deletes it. Validate with the matching verb before applying — mode is create (default), put or patch.
| Behaviour | update_sheet (PUT) | patch_sheet (PATCH) |
|---|---|---|
| Collection sent | Authoritative — unnamed existing items are deleted | Merged — unnamed items are left untouched |
| "virtual_columns": [] | Deletes all 20 | No-op |
| Key omitted entirely | Untouched | Untouched |
| _delete: true | Not valid | Removes that one item |
One config block, every client
Install it, or skip the install entirely and let npx fetch it on demand. The JSON below is identical in every supported client — only the file it lives in changes.
npm install @csvbox/mcp-server{
"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"
}
}
}
}| Client | Config file |
|---|---|
| Claude Desktop | Claude Desktop MCP settings |
| Cursor | ~/.cursor/mcp.jsonor per-project .cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| Roo Code | mcp_settings.json |
| Cline | cline_mcp_settings.json |
| VS Code | .vscode/mcp.jsonthe key is "servers", not "mcpServers" |
Credentials are only needed for the API-backed tools — create_sheet, update_sheet, patch_sheet, create_importer_from_prompt and submit_file. validate_schema and generate_import_code run with no credentials at all, so you can wire the server up and try it before it touches your account.
Environment variables
| Variable | Required for |
|---|---|
| CSVBOX_API_KEY | Every CSVbox API-backed tool |
| CSVBOX_API_SECRET | Every CSVbox API-backed tool |
| ANTHROPIC_API_KEY | Server-side generation (tier 1), Claude models |
| OPENAI_API_KEY | Server-side generation (tier 1), OpenAI models |
| LLM_PROVIDER | Disambiguates when both LLM keys are set |
| LLM_MODEL | Overrides the default model — recommended for 100+ column schemas |
Supported column types
Every type the generator can emit and validate_schema will accept.
MCP server questions
- It is a Model Context Protocol server that exposes CSVbox importer-sheet management — creating, updating, patching, validating and generating CSV/XLSX import schemas — as tools an AI client can call directly. It runs over stdio and behaves identically in Claude Desktop, Cursor, Windsurf, Roo Code, Cline, VS Code and any other MCP-compatible client.
- No. If you set ANTHROPIC_API_KEY or OPENAI_API_KEY, the server generates schemas itself. Without a key, the create_csvbox_sheet and csvbox_sheet_functions MCP prompts hand generation to the host client’s own model — Claude Desktop, Cursor and Cline all work this way at no extra cost, with no server-side LLM key at all.
- update_sheet issues a PUT: it is authoritative, so any virtual column, validation function or data transform not named in the request is deleted, and an empty array wipes the whole collection. patch_sheet issues a PATCH: it merges, leaving unnamed items untouched, and supports a per-item _delete flag to remove a single function without touching the rest. Default to patch for incremental changes.
- No. js_code for virtual columns, validation functions and data transforms is generated as an opaque string and is never executed by the MCP server — it only runs later, inside CSVbox, during a real import. Because it is unreviewed model output, read generated js_code before applying it with patch_sheet.
- Nine tools — create_sheet, update_sheet, patch_sheet, generate_sheet_json, create_importer_from_prompt, generate_import_code, generate_sheet_functions, validate_schema and submit_file — plus two MCP prompts, create_csvbox_sheet and csvbox_sheet_functions. There are no get_sheet or list_sheet tools because the CSVbox API itself has no GET or LIST endpoints for sheets.
- Run npm install @csvbox/mcp-server, or point your MCP client at npx --package=@csvbox/mcp-server csvbox-mcp-server with no local install at all. Add CSVBOX_API_KEY and CSVBOX_API_SECRET to the client’s env block; the config JSON is identical across Claude Desktop, Cursor, Windsurf, Roo Code, Cline and VS Code — only the config file location differs.
- Yes. The submit_file tool calls CSVbox’s POST /1.1/file endpoint, accepting either a public file URL or a base64-encoded upload, which is decoded server-side into a true multipart/form-data part rather than being sent to CSVbox as base64 text.
- The MCP server is free and MIT licensed. It talks to your existing CSVbox account, so the only cost is your normal CSVbox plan — and, if you opt into server-side generation, your own Anthropic or OpenAI API usage. See CSVbox pricing →