CSVBox MCP Server

Servidor MCP para criar, validar e gerenciar importadores CSVBox e fluxos de trabalho de dados CSV.

Documentação

csvbox-mcp-server

Um servidor universal Model Context Protocol (MCP) para CSVBox. Ele expõe o gerenciamento de planilhas de importação do CSVBox como ferramentas MCP, permitindo criar, substituir, corrigir, gerar, validar e estruturar importadores a partir de qualquer cliente compatível com MCP — Claude Desktop, Cursor, Windsurf, Roo Code, Cline, VS Code, ChatGPT MCP e outros.

Funciona via stdio, então opera da mesma forma em todos os clientes.

Ferramentas

FerramentaFinalidadeChamada de API
create_sheetCriar uma planilha CSVBoxPOST /1.1/sheet
update_sheetSubstituir uma planilha existentePUT /1.1/sheet/{key}
patch_sheetAtualizar parcialmente uma planilhaPATCH /1.1/sheet/{key}
generate_sheet_jsonPrompt em linguagem natural → JSON completo da planilha (via LLM)nenhuma (chama o LLM)
create_importer_from_promptPrompt em linguagem natural → validar → criarPOST /1.1/sheet (+ LLM)
generate_import_codeCódigo de integração (vanilla-js/react/vue/angular)nenhuma
generate_sheet_functionsPrompt em linguagem natural → colunas virtuais / funções de validação / transformações de dados (via LLM)nenhuma (chama o LLM)
validate_schemaValidação local de esquemanenhuma

O CSVBox atualmente não possui endpoints GET ou LIST, portanto não há intencionalmente ferramentas get_sheet / list_sheet.

Ele também expõe dois prompts MCP:

PromptFinalidade
create_csvbox_sheetFazer o LLM do próprio cliente host construir uma planilha CSVBox completa (sem necessidade de chave LLM no servidor).
csvbox_sheet_functionsFazer o LLM do próprio cliente host criar colunas virtuais, funções de validação e transformações de dados (sem necessidade de chave LLM no servidor).

Geração de prompt → planilha

generate_sheet_json e create_importer_from_prompt usam um LLM para converter uma solicitação de formato livre em uma planilha CSVBox completatitle, sheet_columns, destinations, webhooks, security_settings e steps. Apenas campos de dados reais se tornam colunas; destinos, webhooks, domínios, regiões, configurações de upload de arquivo e etapas são colocados em suas seções de configuração apropriadas, nunca transformados em colunas. Existem três níveis:

  1. LLM do servidor — quando ANTHROPIC_API_KEY ou OPENAI_API_KEY está definido, o servidor chama o LLM diretamente. Funciona no MCP Inspector e em modo headless.
  2. Prompt MCP (create_csvbox_sheet) — quando você não tem chave de servidor, clientes host (Cursor, Claude Desktop, Cline) executam a geração com seu próprio modelo e depois chamam validate_schema e create_sheet. Gratuito.
  3. Nenhum configuradogenerate_sheet_json retorna um erro estruturado de "nenhum provedor LLM configurado" apontando para o prompt MCP, e create_importer_from_prompt não chama a API do CSVBox. Não há fallback por regex.

Expansão de categoria / módulo

O gerador opera em um de dois modos, escolhidos automaticamente a partir do prompt:

  • Extração (padrão) — o prompt nomeia campos concretos (ex.: "colunas nome, email, telefone"). Apenas esses se tornam colunas; nada é inventado.
  • Expansão — o prompt nomeia módulos / categorias de negócio como uma lista (ex.: "módulos para: Informações da Empresa, Fornecedores, Folha de Pagamento, Fatura"), solicita um esquema abrangente/detalhado ou pede uma contagem de colunas ("pelo menos 100 colunas"). Cada módulo nomeado é expandido em várias colunas realistas, prefixadas e com tipos corretos (ex.: Fornecedores → supplier_id, supplier_name, supplier_gstin, supplier_email, …). Uma contagem mínima explícita é respeitada e cada column_name é globalmente único.

Tipos de dados e validações são inferidos a partir dos nomes dos campos e de quaisquer tipos solicitados:

Solicitado / implícitoColuna typeValidadores
Dropdown / status / categoria com opções fixaslistvalues: [...] opções candidatas
Porcentagem / percentualnumbermin_value: 0, max_value: 100
Numérico positivo (quantidade, contagem, estoque, custo, idade)numbermin_value: 0
ID / código / número de referênciatext
Emailemail
Telefone / celularphone_number
URL / siteurl
Preço / custo / valor / saláriocurrency
Campos de datadateformat: "YYYY-MM-DD"
Booleano / is_* / ativoboolean
GST / GSTIN / id fiscalregexpadrão GSTIN
Código PIN / código postal (Índia)regex^[1-9][0-9]{5}$

Esquemas grandes: os modelos padrão (claude-haiku-4-5, gpt-4o-mini) são baratos, mas produzem esquemas visivelmente melhores com 100+ colunas quando você substitui por um modelo mais forte via LLM_MODEL (ex.: claude-sonnet-4-6). O limite de saída é elevado para acomodar planilhas grandes; se uma solicitação ainda for grande demais, a resposta é sinalizada como TRUNCATED (um resultado distinto, não um erro de análise) e a API do CSVBox não é chamada — reduza a contagem de colunas / módulos ou use um modelo com maior orçamento de saída e tente novamente.

Coleções de funções (colunas virtuais, funções de validação, transformações de dados)

Além das seis propriedades da planilha, a API de Planilhas do CSVBox aceita três coleções cujos itens carregam uma string js_code que o CSVBox executa durante uma importação:

ColeçãoIdentificada porMáx.js_code deve…
virtual_columnscolumn_name20retornar o valor calculado da célula
validation_functionsfunction_name10retornar um array de strings de erro ([] = válido)
data_transformstransform_name10modificar o objeto csvbox e retorná-lo

Dentro de js_code, o objeto csvbox expõe row, column, virtual, user, import e environment. Os dois acessadores não são intercambiáveis — uma coluna virtual é por linha e usa csvbox.row.<name> (um escalar), enquanto uma função com escopo de "column" vê a coluna inteira via csvbox.column.<name> (um array).

Campos opcionais compartilhados: scope (column | row; não em colunas virtuais), run_at (before_validation | after_validation; apenas transformações de dados), columns / dynamic_columns, active, dependencies e _delete (apenas PATCH).

Como criá-las

// 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": [ ... ] }
}

Retorna { "virtual_columns": [...], "validation_functions": [...], "source": ..., "validation": {...} }. Coleções que a solicitação não implica são omitidas, nunca retornadas como arrays vazios.

Esta ferramenta não chama a API do CSVBox. Leia o js_code gerado e aplique-o você mesmo com patch_sheet. Passe sheet para que o modelo referencie nomes reais de colunas e o validador possa verificar essas referências — o CSVBox não tem endpoint de leitura, então ele deve ser fornecido inline. Sem chave LLM, use o prompt MCP csvbox_sheet_functions.

PUT vs PATCH — leia antes de aplicar

update_sheet (PUT)patch_sheet (PATCH)
Coleção enviadaautoritativa — qualquer item existente não nomeado é excluídomesclada — itens não nomeados são mantidos
"virtual_columns": []exclui todos os 20sem efeito
Chave omitidaintocadaintocada
_delete: truenão válidoremove esse item (todos os outros campos ignorados)

Use patch_sheet para aplicar funções geradas. Valide primeiro com o verbo correspondente:

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

mode é create (padrão), put ou patch. Afeta apenas as coleções de funções — sob put, um array vazio é um erro grave em vez de um aviso, e _delete é rejeitado fora de patch.

Dependências

Um item pode carregar até 5 scripts de terceiros:

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

Apenas cdn.jsdelivr.net, unpkg.com e cdnjs.cloudflare.com são permitidos; somente https, caminho .js/.mjs, sem query string, fragmento, userinfo ou porta.

Segurança. Este servidor nunca executa js_code — é uma string opaca aqui. JavaScript gerado é saída de modelo não revisada, então leia antes de aplicar via PATCH em um importador ativo. Uma dependência sem digest integrity pode mudar sob seus clientes a qualquer momento; validate_schema avisa quando um está ausente.

Consulte docs/sheet-functions-example.json para um payload completo.

Instalação

npm install @csvbox/mcp-server

Ou compile a partir do código-fonte:

git clone <this-repo> csvbox-mcp-server
cd csvbox-mcp-server
npm install
npm run build

Isso produz dist/index.js — o entrypoint que os clientes MCP iniciam.

Variáveis de ambiente

Copie .env.example para .env e preencha suas credenciais do CSVBox:

CSVBOX_API_KEY=your_api_key
CSVBOX_API_SECRET=your_api_secret

As credenciais do CSVBox são apenas necessárias para as ferramentas com suporte de API (create_sheet, update_sheet, patch_sheet, create_importer_from_prompt). validate_schema e generate_import_code funcionam sem nenhuma credencial.

Nota sobre o cabeçalho de autenticação: o cliente envia x-csvbox-api-key e x-csvbox-secret-api-key (correspondendo aos payloads de referência do CSVBox). Eles são definidos como constantes em src/services/csvbox-api.ts se sua conta usar nomes de cabeçalho diferentes.

Provedor LLM (para geração de prompt → planilha)

generate_sheet_json e create_importer_from_prompt precisam de um LLM. Defina um de:

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

O provedor é detectado automaticamente:

CondiçãoProvedorModelo padrão
LLM_PROVIDER=anthropic (e sua chave definida)Anthropicclaude-haiku-4-5
LLM_PROVIDER=openai (e sua chave definida)OpenAIgpt-4o-mini
ANTHROPIC_API_KEY definido (sem LLM_PROVIDER)Anthropicclaude-haiku-4-5
OPENAI_API_KEY definido (sem LLM_PROVIDER)OpenAIgpt-4o-mini
nenhuma chave definidanenhum — as ferramentas retornam um erro apontando para o prompt MCP create_csvbox_sheet

LLM_PROVIDER desambigua quando ambas as chaves estão presentes; LLM_MODEL substitui o modelo para o provedor escolhido. Para esquemas grandes de categoria/módulo (100+ colunas), defina LLM_MODEL para um modelo mais forte (ex.: claude-sonnet-4-6) — consulte Expansão de categoria / módulo.

MCP Inspector: defina a chave LLM no painel de variáveis de ambiente do Inspector para usar o caminho LLM do servidor. O Inspector não tem LLM host próprio, então pode renderizar o prompt create_csvbox_sheet mas não pode executá-lo — para o caminho sem chave, use um cliente com modelo (Cursor, Claude Desktop, Cline).

Execução local

# After building:
npm start

# Or run the built file directly:
node dist/index.js

O servidor fala MCP via stdio e registra csvbox-mcp-server running on stdio em stderr (stdout é reservado para o protocolo).

Configuração do cliente

Para uma instalação publicada, use o pacote npm com npx. Defina CSVBOX_API_KEY / CSVBOX_API_SECRET no bloco env.

Nota: O pacote npm é @csvbox/mcp-server e o executável é csvbox-mcp-server.

Claude Desktop

Adicione o seguinte à sua configuração MCP do Claude Desktop:

{
  "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

Edite ~/.cursor/mcp.json (global) ou .cursor/mcp.json (por projeto):

{
  "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

Edite ~/.codeium/windsurf/mcp_config.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

Nas configurações MCP do Roo Code (mcp_settings.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

Nas configurações MCP do Cline (cline_mcp_settings.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

Adicione a .vscode/mcp.json (ou ao mcp.json global):

{
  "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"
      }
    }
  }
}

Exemplos de chamadas de ferramentas

Gerar uma planilha completa a partir de um prompt (LLM, sem chamada à API do CSVBox):

// 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" }

Retorna { "sheet": { "title": ..., "sheet_columns": [...], "destinations": [...], "steps": {...} }, "source": "llm:anthropic:claude-haiku-4-5", "validation": { "valid": true, ... } }. Campos de dados se tornam colunas (salary → currency, joining date → date); o destino e a configuração xlsx vão para destinations / steps, não para colunas. Sem chave LLM, retorna um erro apontando para o prompt create_csvbox_sheet.

Validar um esquema antes de enviá-lo:

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

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

Criar uma planilha:

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

Gerar + criar em uma única etapa:

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

Retorna { "generated_schema": { ... }, "source": ..., "validation": { ... }, "api_response": { ... } }. Aborta sem chamar a API se nenhum provedor LLM estiver configurado ou se o esquema gerado falhar na validação.

Substituir uma planilha:

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

Destrutivo para qualquer coleção enviada — consulte PUT vs PATCH.

Corrigir uma planilha:

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

Remover uma função sem tocar no restante:

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

Gerar código de integração:

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

Tipos de coluna suportados

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.

Desenvolvimento

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

Testes

npm test compila src/tests/ e o executa com o executor de testes integrado do Node — sem framework de testes, sem biblioteca de mocks.

A suíte é hermética. Ela nunca contata um host externo, nunca lê suas variáveis de ambiente CSVBOX_API_* / ANTHROPIC_API_KEY / OPENAI_API_KEY e nunca toca em uma conta CSVBox real, portanto passa de forma idêntica, independentemente de você ter credenciais configuradas. O HTTP é interceptado no adaptador do axios; o LLM é um fake com script; o único teste que precisa de codificação real de requisição inicia um listener efêmero em 127.0.0.1 e o fecha em seguida. Testes que leem variáveis de ambiente definem o que precisam explicitamente e restauram os valores anteriores.

Testes E2E

npm run test:e2e         # run the Playwright suite
npm run test:e2e:report  # open the HTML report from the last run

As especificações ficam em e2e/, configuradas por playwright.config.ts. Assim como a suíte de unidades, esta suíte é hermética: ela inicia servidores mock de CSVBox e LLM em loopback (e2e/support/mock-csvbox-server.ts, e2e/support/mock-llm-server.ts) e aciona o servidor real compilado (dist/index.js) por meio do MCP Inspector com credenciais falsas apontadas para esses mocks — ela nunca contata uma conta CSVBox real ou provedor de LLM, e nunca lê seu .env. Uma instância separada do Inspector, sem credenciais, cobre os caminhos de erro de "credenciais ausentes". Requer npm run build primeiro (as entradas de test:e2e webServer são construídas automaticamente).

Incorporando o servidor

createServer() é exportado do módulo de entrada. Ele registra todas as ferramentas e prompts e retorna o McpServer sem anexar um transporte, para que você possa conectá-lo a um dos seus próprios:

import { createServer } from "@csvbox/mcp-server";

const server = createServer();
await server.connect(myTransport);

Importar o módulo não inicia nada; o servidor stdio é executado apenas quando dist/index.js é executado diretamente.

Licença

MIT