> ## Documentation Index
> Fetch the complete documentation index at: https://help.csvbox.io/llms.txt
> Use this file to discover all available pages before exploring further.

# CSVbox MCP Server

> Create, validate, and update CSVbox sheets from any MCP client, such as Claude Desktop, Cursor, or VS Code, using plain-language prompts.

The CSVbox MCP server exposes importer sheet management as tools that any [Model Context Protocol](https://modelcontextprotocol.io/) client can call directly. Claude Desktop, Cursor, Windsurf, Roo Code, Cline, and VS Code all work identically over one stdio transport.

Instead of hand-writing JSON against the CSVbox REST API, describe the importer you want in plain language and let your AI client create, validate, and push a compliant CSVbox schema for you.

| Property | Value |
| - | - |
| **Package** | `@csvbox/mcp-server` |
| **Executable** | `csvbox-mcp-server` |
| **Transport** | stdio |
| **Tools / Prompts** | 9 tools · 2 prompts |
| **Requires** | Node.js ≥ 18 |
| **License** | MIT |
| **Source** | [github.com/csvbox-io/csvbox-mcp-server](https://github.com/csvbox-io/csvbox-mcp-server) |
| **Package registry** | [npmjs.com/package/@csvbox/mcp-server](https://www.npmjs.com/package/@csvbox/mcp-server) |

<Note>
  CSVbox handles the CSV/XLSX import widget your app embeds. This server handles the *configuration* side: the importer sheet that defines columns, validation, destinations, and webhooks.
</Note>

## Installation

No local install is required. Every supported client can run the server directly with `npx`:

```json theme={null}
{
  "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"
      }
    }
  }
}
```

Or install it locally:

```bash theme={null}
npm install @csvbox/mcp-server
```

The config block above is identical across clients. Only the file it goes in changes:

| Client | Config file |
| - | - |
| Claude Desktop | Claude Desktop MCP settings |
| Cursor | `~/.cursor/mcp.json` (or 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.json`. The top-level key is `"servers"`, not `"mcpServers"`. |

### Environment variables

| Variable | Required for |
| - | - |
| `CSVBOX_API_KEY` | All CSVbox API-backed tools |
| `CSVBOX_API_SECRET` | All CSVbox API-backed tools |
| `ANTHROPIC_API_KEY` | Server-side schema generation using Claude models |
| `OPENAI_API_KEY` | Server-side schema generation using OpenAI models |
| `LLM_PROVIDER` | Disambiguates when both LLM keys are set |
| `LLM_MODEL` | Overrides the default model. Recommended for 100+ column schemas. |

<Note>
  `CSVBOX_API_KEY` and `CSVBOX_API_SECRET` are only required for the API-backed tools (`create_sheet`, `update_sheet`, `patch_sheet`, `create_importer_from_prompt`, `submit_file`). `validate_schema` and `generate_import_code` run with no credentials at all.
</Note>

You don't need an LLM API key to use the server. Without one, the `create_csvbox_sheet` and `csvbox_sheet_functions` prompts hand schema generation to your AI client's own model, for free and with no server-side key.

## Tools

| 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, no API call |
| `create_importer_from_prompt` | Prompt → validate → create, in one call | `POST /1.1/sheet` |
| `generate_import_code` | Integration snippet for vanilla-js / React / Vue / Angular | None |
| `generate_sheet_functions` | Prompt → virtual columns, validation functions, data transforms | LLM only, no API call |
| `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` |

<Note>
  There are no `get_sheet` or `list_sheet` tools. The CSVbox API itself has no GET or LIST endpoints for sheets.
</Note>

### update\_sheet vs. patch\_sheet

| | `update_sheet` (PUT) | `patch_sheet` (PATCH) |
| - | - | - |
| Collection sent | **Authoritative**: items not named are deleted | **Merged**: items not named are untouched |
| `"virtual_columns": []` | Deletes all existing virtual columns | No-op |
| Key omitted entirely | Untouched | Untouched |
| `_delete: true` on an item | Not valid | Removes that one item, leaves the rest |

Default to `patch_sheet` for incremental changes. Validate with the matching `mode` (`create`, `put`, or `patch`) before applying.

### submit\_file

Calls `POST /1.1/file` with either a `public_file_url` or a base64-encoded upload. The base64 payload is decoded server-side into a true `multipart/form-data` part before it reaches CSVbox. It is never sent to CSVbox as base64 text.

## MCP prompts

Two prompts hand schema generation to your AI client's own model instead of the server's. This is useful when no server-side LLM key is configured.

| Prompt | Purpose |
| - | - |
| `create_csvbox_sheet` | Guides the client's LLM to build a complete CSVbox sheet, key-free |
| `csvbox_sheet_functions` | Guides the client's LLM to author virtual columns, validation functions, and data transforms, key-free |

## Prompt-to-sheet generation

`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 and never mistaken for columns.

### Generation tiers

Generation resolves through three tiers, in order:

1. **Server LLM**: if `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` is set, the server calls the model directly. Usage is billed to your own API key.
2. **MCP prompt**: with no server key, the host client (Cursor, Claude Desktop, Cline, etc.) runs generation with its own model, then calls `validate_schema` and `create_sheet`. Free.
3. **None**: with no LLM anywhere, the server returns a structured error pointing at the MCP prompt. The CSVbox API is never called.

### Extraction vs. expansion mode

* **Extraction mode** (default): the prompt names concrete fields, for example *"columns name, email, phone"*, and only those become columns. Nothing is invented.
* **Expansion mode**: triggered by a named business module, a request for a "comprehensive" schema, or an explicit column-count floor. Each module (for example, *Suppliers*) expands into realistic, prefixed columns (`supplier_id`, `supplier_gstin`, …), with every name kept globally unique.

For 100+ column schemas, override the default cheap model (`claude-haiku-4-5` / `gpt-4o-mini`) with a stronger one via `LLM_MODEL`. Oversized output is flagged `TRUNCATED` rather than silently truncated or mis-parsed, and the CSVbox API is not called in that case.

### Column type mapping

Field names and requested types are mapped to CSVbox column types automatically:

| 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` |
| Email | `email` | — |
| 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}$` |

### 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`

## Function collections

Beyond the 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 items | `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 |

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.

<Warning>
  The MCP server never executes `js_code`. Here it's an opaque, unreviewed string that only runs later inside CSVbox. Read generated code before applying it with `patch_sheet`.
</Warning>

### Third-party scripts

An item may load up to five third-party scripts, restricted to a fixed CDN allowlist:

```json theme={null}
{
  "url": "https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js",
  "globals": ["dayjs"],
  "integrity": "sha384-..."
}
```

Allowed hosts: `cdn.jsdelivr.net`, `unpkg.com`, `cdnjs.cloudflare.com`. HTTPS only, `.js`/`.mjs` path, and no query string, fragment, userinfo, or port.

<Warning>
  A dependency without an `integrity` digest can change under your users at any time. `validate_schema` warns when one is missing.
</Warning>

## FAQ

<AccordionGroup>
  <Accordion title="Do I need an LLM API key to use it?">
    No. Without one, the `create_csvbox_sheet` and `csvbox_sheet_functions` prompts hand generation to the host client's own model, for free and with no server-side key required.
  </Accordion>

  <Accordion title="What's the difference between update_sheet and patch_sheet?">
    `update_sheet` is a destructive PUT: anything not named in a collection gets deleted. `patch_sheet` merges and supports a per-item `_delete` flag. Default to `patch_sheet` for incremental changes.
  </Accordion>

  <Accordion title="Is the generated js_code executed by the MCP server?">
    No. It's treated as an opaque string and only runs later, inside CSVbox, during a real import. Read it before applying it with `patch_sheet`.
  </Accordion>

  <Accordion title="How many tools does it expose?">
    Nine tools and two MCP prompts. There's no `get_sheet` or `list_sheet`, because the CSVbox API itself has no GET or LIST endpoints for sheets.
  </Accordion>

  <Accordion title="How do I install it?">
    Run `npm install @csvbox/mcp-server`, or point any MCP client at `npx --package=@csvbox/mcp-server csvbox-mcp-server` with no local install at all.
  </Accordion>

  <Accordion title="Can it submit files directly, not just configure the importer?">
    Yes. `submit_file` calls `POST /1.1/file` with either a public file URL or a base64 upload, decoded server-side into true multipart binary before it reaches CSVbox.
  </Accordion>
</AccordionGroup>

## Resources

MIT licensed · `@csvbox/mcp-server` · [Source on GitHub](https://github.com/csvbox-io/csvbox-mcp-server) · [npm](https://www.npmjs.com/package/@csvbox/mcp-server) · [csvbox.io](https://csvbox.io/) · [modelcontextprotocol.io](https://modelcontextprotocol.io/)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.