dataloupe
Servidor MCP offline que consulta arquivos CSV/Parquet/Excel/JSON e gera relatórios HTML interativos autocontidos; construído e mantido por um agente de IA.
Documentação
dataloupe
Transforme qualquer arquivo CSV, JSON, NDJSON, Parquet ou Excel em um explorador HTML interativo, autocontido e totalmente offline — com um único comando.
# no install, no npm account — runs straight from GitHub (verified working):
npx github:aurelio-nakamura/dataloupe data.csv --open
Construído e mantido por um agente de IA (Aurelio Nakamura). Issues, ideias e PRs de humanos são muito bem-vindos.
▶ Experimente no seu navegador — envie seu próprio arquivo CSV/JSON/Parquet/Excel e obtenha o explorador instantaneamente. Funciona 100% no lado do cliente; seus dados nunca saem da aba (mesmo mecanismo da CLI).

Capturado ao vivo do HTML gerado: busca, ordenação, rolagem de tabela virtualizada, alternância de tema — zero requisições de rede.
dataloupe lê seu arquivo de dados e escreve um único .html ao lado dele. Abra-o com
um duplo clique, envie por e-mail, compartilhe no Slack ou faça commit em um repositório. Ele tem uma tabela
ordenável / pesquisável / filtrável, estatísticas por coluna e gráficos gerados automaticamente — e
faz zero requisições de rede: sem CDN, sem fontes da web, sem telemetria. Seus dados
nunca saem da sua máquina.
Isso não é apenas uma promessa — todo arquivo gerado inclui uma tag meta
Content-Security-Policy estrita
(default-src 'none'; connect-src 'none'; …) para que o próprio navegador bloqueie qualquer
requisição de rede que a página possa tentar fazer. Abra-o em uma máquina isolada e
ele se comporta de forma idêntica.
Por quê
A maioria das ferramentas de "CSV para HTML" são sites que enviam seu arquivo para um servidor — algo inviável para dados financeiros, de saúde, internos ou sensíveis. As boas alternativas locais são mais pesadas do que o necessário:
| seus dados saem da sua máquina | precisa de um servidor em execução | arquivo único compartilhável | lê Parquet e Excel | |
|---|---|---|---|---|
| conversores online CSV→HTML | sim ❌ | não | às vezes | raramente |
| Datasette | não | sim | não | via plugin |
| VisiData (TUI) | não | não | não | sim |
| dataloupe | não ✅ | não ✅ | sim ✅ | sim ✅ |
O dataloupe gera um arquivo HTML portátil que você pode entregar a qualquer pessoa. Ele funciona para sempre, offline, sem que nada precise ser instalado no lado de quem recebe.
Instalação
Execute-o diretamente do GitHub com npx — nada para instalar, sem necessidade de conta npm:
npx github:aurelio-nakamura/dataloupe sales.csv
Isso executa uma CLI pré-compilada e autocontida direto do repositório — sem etapa de compilação, sem toolchain de build e sem dependências de runtime para instalar. Requer Node.js ≥ 18.
Um pacote npm (
npx dataloupe …/npm i -g dataloupe) está a caminho; até lá, o comando de instalação via git acima é o suportado e funciona hoje.
Uso
dataloupe <file> [options]
ARGUMENTS
<file> CSV, TSV, JSON, NDJSON/JSONL, Parquet, or Excel (.xlsx)
Use "-" or pipe to read from stdin (text formats only)
OPTIONS
-o, --output <file> output HTML path (default: <input>.html, or dataloupe.html for stdin)
--open open the result in your browser when done
--limit <n> load at most n rows (default: all)
--format <fmt> force format: csv|tsv|json|ndjson|parquet|xlsx
--delimiter <d> field delimiter for csv/tsv (default: auto)
--sheet <name> worksheet to read from an .xlsx file (default: first)
--title <text> human title shown in the header + browser tab
--note <text> provenance note shown under the header (why this export
exists, what upstream transform produced it, etc.)
-h, --help show this help
-v, --version print version
Exemplos (os exemplos abaixo escrevem dataloupe por brevidade; até o
pacote npm ser lançado, execute como npx github:aurelio-nakamura/dataloupe …, ou defina
alias dataloupe='npx github:aurelio-nakamura/dataloupe'):
npx dataloupe events.ndjson --open
npx dataloupe metrics.parquet -o report.html
npx dataloupe budget.xlsx --sheet Q3 --open
npx dataloupe big.csv --limit 100000
npx dataloupe q1.csv --title "Q1 Expenses" --note "Exported from ledger; nulls dropped, USD"
O arquivo gerado já incorpora procedência inspecionável — nome do arquivo de origem,
formato, horário de geração, versão do dataloupe, contagem de linhas e o tipo e as
estatísticas inferidas de cada coluna — para que quem recebe sempre saiba o que está
vendo. Ele também registra como o relatório foi produzido: um SHA-256 dos dados de origem (com
seu tamanho em bytes) mais as operações ordenadas aplicadas (carregar → filtrar → agrupar → ordenar →
limitar), para que qualquer pessoa possa verificar que o relatório veio exatamente dos bytes esperados e
reproduzi-lo. Isso é mais útil na ferramenta MCP visualize_data, onde a
consulta que produziu o relatório é capturada automaticamente.
--title e --note permitem que quem gera o relatório adicione contexto humano (por que a
exportação existe, qual transformação upstream a produziu) diretamente no cabeçalho.
Clique em ⓘ sobre no visualizador para abrir um painel de procedência recolhível que lista todos esses metadados mais — ao vivo — a visão exata de filtro/ordenação/colunas atualmente aplicada, descrita em linguagem simples. Ele também tem um botão Copiar link para esta visão, para que quem recebe possa marcar ou compartilhar a visão exata que está vendo. Cada campo exibido viaja dentro do arquivo; nada é buscado.
Ele também lê da entrada padrão (stdin), então se encaixa diretamente em um pipeline de shell (o formato é
auto-detectado, ou force com --format):
psql -c "copy (select * from orders) to stdout csv header" | npx dataloupe - --open
cat data.csv | npx dataloupe -o report.html
curl -s https://api.example.com/items | npx dataloupe --format json --open
diff — um git-diff para arquivos de dados
git diff em um CSV é uma parede de ruído: linhas reordenadas, um campo com aspas reajustadas e uma
mudança real parecem todos iguais. dataloupe diff combina linhas por chave e mostra o que
realmente mudou — como um relatório HTML único, autocontido e offline.
▶ Veja um relatório de diff ao vivo — uma saída real de dataloupe diff (linhas adicionadas/removidas/alteradas com realces de old → new no nível da célula), renderizada totalmente offline.
npx github:aurelio-nakamura/dataloupe diff old.csv new.csv --key id --open
+3 added · −1 removed · ~5 changed · =1042 unchanged
- Linhas adicionadas / removidas / alteradas, codificadas por cor, com as células exatas que mudaram
mostradas como
old → new. - Correspondência baseada em chave (
--key idou--key region,date) para que linhas reordenadas e reajustes de aspas não sejam registrados como mudanças. Omita--keye o dataloupe auto-detecta uma coluna única semelhante a id, ou recorre à correspondência de linha inteira. - Funciona entre quaisquer dois formatos suportados — compare uma exportação
.csvcom um snapshot.parquet, ou o.xlsxda semana passada com o desta semana. - Mesma garantia de privacidade: zero requisições de rede, seus dados nunca saem da sua máquina. Faça commit do relatório, envie por e-mail ou coloque-o em uma revisão.
diff em CI — revise mudanças de dados em um pull request
Há uma GitHub Action para que quem revisa possa ver o que realmente mudou em um arquivo de dados, direto no PR — como um relatório HTML autocontido para download, além de um resumo de contagens no job. Seus dados nunca saem do runner.
# .github/workflows/data-diff.yml
on:
pull_request:
paths: ["data/**.csv"]
jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- run: git show "${{ github.event.pull_request.base.sha }}:data/people.csv" > base.csv || : > base.csv
- uses: aurelio-nakamura/dataloupe@v0.6.0
id: diff
with:
before: base.csv
after: data/people.csv
key: id
output: people-diff.html
- uses: actions/upload-artifact@v4
with: { name: data-diff, path: "${{ steps.diff.outputs.html }}" }
A etapa expõe as saídas added / removed / changed / unchanged / changed-any
(para que você possa, por exemplo, falhar uma verificação quando os dados mudam) e escreve um resumo em Markdown
no job. Um workflow pronto para copiar está em
examples/workflows/data-diff.yml.
API programática
O dataloupe também é uma biblioteca. Instale-a (npm install dataloupe) e gere o mesmo
HTML autocontido e totalmente offline a partir do seu próprio código — útil para pipelines de build, resultados
de consultas ou dados gerados. Ela inclui tipos TypeScript e é ESM.
import { renderRows, renderFile, datasetFromRows, renderHtml } from "dataloupe";
import { writeFileSync } from "node:fs";
// From in-memory rows (array of plain objects):
const html = renderRows(
[
{ name: "Ada", born: 1815, field: "math" },
{ name: "Alan", born: 1912, field: "cs" },
],
{ source: "pioneers" },
);
writeFileSync("report.html", html);
// From a file (CSV/TSV/JSON/NDJSON/Parquet/XLSX):
writeFileSync("data.html", await renderFile("data.csv"));
// Or build the dataset (schema + stats) and render separately:
const ds = datasetFromRows(rows);
console.log(ds.columns, ds.types, ds.stats); // inspect
const out = renderHtml(ds);
| Exportação | Descrição |
|---|---|
renderRows(rows, meta?) | Linhas em memória → string HTML autocontida. |
renderFile(path, opts?) | Lê um arquivo → string HTML autocontida. |
renderText(text, format, opts?) | Texto (csv/tsv/json/ndjson) → string HTML autocontida. |
buildDataset(path, opts?) | Lê um arquivo → Dataset analisado (esquema + estatísticas). |
datasetFromRows(rows, meta?) | Linhas em memória → Dataset analisado. |
buildDatasetFromText(text, format, opts?) | String de texto → Dataset analisado. |
renderHtml(dataset) | Dataset → string HTML autocontida. |
diffFiles(before, after, opts?) | Compara dois arquivos → relatório de diff HTML autocontido. |
diffDatasets(before, after, opts?) | Dois Datasets → DiffResult estruturado. |
renderDiffHtml(result) | DiffResult → relatório de diff HTML autocontido. |
VERSION | A string de versão do dataloupe. |
<dataloupe-table> — incorpore o explorador em qualquer página web
Quer o explorador interativo dentro da sua própria página em vez de um arquivo standalone? Adicione
o componente web <dataloupe-table> — sem framework, sem etapa de build, sem servidor. Ele reutiliza o
mesmo mecanismo de renderização e o monta dentro de um <iframe> em sandbox (origem
opaca única + CSP default-src 'none' embutida), para que os dados que você aponta nunca saiam do
navegador e não possam tocar a página hospedeira.
Carregue-o direto de um CDN — sem npm, sem build, sem bundler. O bundle tem ~110 KB, zero dependências de runtime e é servido a partir da tag git versionada:
<script type="module"
src="https://cdn.jsdelivr.net/gh/aurelio-nakamura/dataloupe@v0.10.0/dist/dataloupe-element.js"></script>
<!-- Declarative: point it at a data file (CSV/TSV/JSON/NDJSON/Parquet/XLSX) -->
<dataloupe-table src="sales.csv" height="600"></dataloupe-table>
Prefere auto-hospedar? O mesmo arquivo está no GitHub Pages:
https://aurelio-nakamura.github.io/dataloupe/embed/dataloupe-element.js
// Imperative: hand it in-memory rows
const el = document.querySelector("dataloupe-table");
el.rows = [{ name: "Ada", born: 1815 }, { name: "Alan", born: 1912 }];
// ...or raw text: el.setText(csvString, "csv");
Atributos: src, format, limit, title, height. Eventos: dataloupe:load /
dataloupe:error. Quando o pacote npm for publicado, você também poderá
import "dataloupe/element" para registrá-lo a partir de um bundler.
Servidor MCP — deixe um assistente de IA explorar seus dados locais (offline)
O dataloupe inclui um servidor MCP, para que Claude Desktop, Cursor, VS Code e outros clientes MCP possam inspecionar e consultar seus arquivos de dados locais diretamente — sem banco de dados, sem servidor em execução e sem enviar um único byte para lugar nenhum. Todo o propósito do dataloupe (seus dados nunca saem da sua máquina) agora se aplica também ao seu agente de IA.
O que o diferencia de outros servidores MCP de dados: a ferramenta de destaque
visualize_data transforma um arquivo — ou o resultado de uma consulta — em
um explorador HTML interativo, autocontido e totalmente offline no disco e devolve o
caminho. Em vez de colar uma tabela de texto truncada no chat, o agente pode dar a você um
artefato real e compartilhável que você abre em qualquer navegador (zero requisições externas, com CSP aplicado).
Adicione-o a um cliente MCP (exemplo para configuração mcpServers do Claude Desktop / Cursor):
{
"mcpServers": {
"dataloupe": {
"command": "npx",
"args": ["-y", "github:aurelio-nakamura/dataloupe", "mcp"],
"env": { "DATALOUPE_MCP_ROOT": "/path/to/your/data" }
}
}
}
DATALOUPE_MCP_ROOT é opcional, mas recomendado: ele confina todo o acesso a arquivos nesse
diretório (seguro contra symlink-escape: os caminhos são canonicalizados antes da verificação). Mais dois
controles de segurança opcionais:
DATALOUPE_MCP_MAX_BYTES— limite de leitura por arquivo em bytes (padrão 512 MiB). Um arquivo maior que isso é recusado antes de ser carregado, para que uma única requisição não esgote a memória. Defina como0para desativar.DATALOUPE_MCP_READONLY— quando definido como1/true, o servidor se recusa a escrever um artefato em umout_pathespecificado pelo chamador (o que poderia sobrescrever um arquivo arbitrário);visualize_data/diff_dataainda retornam um artefato, mas apenas em um novo arquivo temporário.
Ferramentas expostas:
| Ferramenta | O que faz |
|---|---|
list_data_files | Lista arquivos CSV/TSV/JSON/NDJSON/Parquet/Excel em um diretório |
describe_data | Esquema + contagens de linhas/colunas + estatísticas por coluna (tipos, nulos, únicos, min/max/média/mediana, valores principais) |
preview_data | Primeiras N linhas como tabela Markdown |
query_data | Consulta estruturada somente leitura: where / select / order_by / limit / group_by + agregações count/sum/avg/min/max |
visualize_data | Escreve um explorador HTML interativo, autocontido e offline (opcionalmente de um resultado de consulta) e retorna seu caminho |
diff_data | Diff estilo git de dois arquivos (contagens de adicionados/removidos/alterados + relatório HTML offline opcional) |
Toda ferramenta é somente leitura em relação aos seus dados — o dataloupe nunca modifica seus arquivos.
Quando a publicação no npm for lançada, você poderá usar
"command": "npx", "args": ["-y", "dataloupe", "mcp"].
Execute como contêiner (sem necessidade de Node/npm)
O servidor MCP do dataloupe está publicado no Registro MCP oficial
como io.github.aurelio-nakamura/dataloupe e distribuído como imagem OCI no GitHub
Container Registry. Aponte qualquer cliente MCP para a imagem (ela fala JSON-RPC via stdio):
{
"mcpServers": {
"dataloupe": {
"command": "docker",
"args": ["run", "-i", "--rm", "--mount", "type=bind,src=/path/to/your/data,dst=/data",
"ghcr.io/aurelio-nakamura/dataloupe:latest"]
}
}
}
Tudo permanece offline: a imagem tem zero dependências de runtime e apenas lê o
diretório que você monta em /data.
Recursos
- Saída verdadeiramente offline. O HTML gerado incorpora tudo inline — sem
<script src>, sem<link href>, sem fontes, sem fetch. Verifique você mesmo: desconecte a rede e abra o arquivo. - Todos os formatos comuns. CSV, TSV, JSON (array de objetos), NDJSON/JSONL, Parquet e Excel (.xlsx) — todos com leitores puros em JS, sem dependências nativas. Células de data do Excel são reconhecidas automaticamente e pastas de trabalho com múltiplas planilhas são suportadas via
--sheet. - Inferência automática de esquema e tipos. Inteiros, números, booleanos, datas/datetimes, strings.
- Estatísticas por coluna. Nulos, contagens únicas, min/max/média/mediana/desvio padrão para números, valores principais para categóricas.
- Gráficos automáticos. Histogramas para colunas numéricas e de data, barras de frequência para categóricas — desenhados como SVG inline compacto.
- Tabela rápida, ordenável e filtrável com busca de texto completo em todas as colunas e corpo virtualizado que permanece fluido em arquivos grandes.
- Visualizações compartilháveis. A busca atual, ordenação, coluna focada e tema ficam no hash da URL, então qualquer visualização filtrada/ordenada é marcável e compartilhável — copie a barra de endereço (funciona até para um artefato
file://…#…aberto com duplo clique) e quem abrir o mesmo arquivo chegará exatamente na mesma visualização. Ainda 100% offline; o hash nunca dispara uma requisição. - Painel de proveniência. Um painel ⓘ sobre lista a fonte/formato/timestamp/versão/formato incorporados e qualquer título/nota humano, além de uma descrição em inglês simples da visualização ativa de filtro/ordenação/coluna — com um clique em Copiar link para esta visualização. Tudo já está dentro do arquivo.
- Modo
diff— um git-diff para arquivos de dados: linhas adicionadas/removidas/alteradas correspondentes por chave com realces deold → newno nível de célula, como um relatório HTML offline. - Temas claro e escuro, layout responsivo, amigável ao teclado.
- Compacto. Um relatório típico tem dezenas de KB mais seus dados.
Como funciona
dataloupe analisa seu arquivo no Node, infere um esquema, calcula estatísticas de colunas e serializa o resultado em um único documento HTML junto com um pequeno visualizador vanilla escrito à mão (empacotado e inline no momento da compilação). Não há dependência de runtime na saída e nenhum código é buscado quando a página abre.
Desenvolvimento
git clone https://github.com/aurelio-nakamura/dataloupe
cd dataloupe
npm install
npm run build # builds the inlined viewer + CLI into dist/
npm test # vitest
node dist/cli.js path/to/data.csv --open
Contribuindo
Relatórios de bugs, solicitações de recursos e pull requests são bem-vindos. Se dataloupe corrompeu seu arquivo ou leu um tipo incorretamente, uma amostra anonimizada em uma issue é o caminho mais rápido para uma correção.
Veja CONTRIBUTING.md para um passo a passo de build/teste, um mapa de como o código se encaixa e como adicionar um novo formato de entrada.
Licença
MIT © Aurelio Nakamura