Zip MCP

Compactar e descompactar arquivos pelo chat: empacotar pastas, extrair arquivos, listar conteúdos. Tudo local, sem upload.

Documentação

mcp-zip

Servidor MCP para arquivos zip: criar, inspecionar e extrair. Crie um zip, veja o que há dentro e descompacte um, inteiramente na sua máquina.

Funciona com Claude Desktop, Claude Code, Cursor e qualquer cliente do Model Context Protocol. Roda na sua própria máquina ou hospedado, sem instalação.

Página do produto: https://mcp.zovo.one/s/zip — o que ele faz, as ferramentas que expõe e um endpoint de token ao vivo.

Instalação

Hospedado, nada para instalar. Obtenha um token em https://mcp.zovo.one/mcp/connect (a página de conexão) ou https://mcp.zovo.one/mcp/token (o mesmo token como JSON); um token anônimo gratuito é emitido na hora e uma chave Pro funciona da mesma forma. Em seguida, aponte um cliente MCP para https://mcp.zovo.one/mcp/zip via streamable-http e envie o token como Authorization: Bearer <token>.

Se o seu cliente não puder definir cabeçalhos, coloque o token no caminho: https://mcp.zovo.one/mcp/zip/t/<token>. Ambas as formas funcionam. A URL simples sem token responde 401 em tools/call, então o token não é opcional.

Claude Desktop, um clique. Baixe zip.mcpb do último lançamento e clique duas vezes nele.

A partir do código-fonte. O espelho é autossuficiente: cada dependência @theluckystrike/* é incluída, então um clone novo compila sem configuração extra.

git clone https://github.com/theluckystrike/mcp-zip.git
cd mcp-zip
npm install && npm run build

Em seguida, aponte seu cliente para o ponto de entrada compilado:

{
  "mcpServers": {
    "zip": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-zip/dist/index.js"]
    }
  }
}

@theluckystrike/mcp-zip ainda não está publicado no npm, então um comando npx -y @theluckystrike/mcp-zip falhará. Os três caminhos acima são os que funcionam e cada um é testado pelo CI.

zip demo

Espelho somente leitura de mcp-servers/servers/zip. Veja MIRROR.md.

Crie um zip, veja o que há dentro e descompacte um, na conversa em que você já está. Empacote uma pasta com um glob (**/*.csv, tudo exceto node_modules). Leia o único README de um arquivo sem descompactá-lo. Pergunte o que há dentro de um zip que alguém lhe enviou e descubra antes de abri-lo: caminhos absolutos, .., symlinks, nomes duplicados e a entrada que afirma ter 200 MB dentro de um arquivo de 199 KB. Agrupe um mês de faturas, cotações e exportações em um único arquivo para enviar a um contador. Tudo roda na sua máquina: sem upload, sem conta, sem chave de API e sem chamada de rede de qualquer tipo.

No Registro Oficial de MCP (io.github.theluckystrike/zip-archive-create-extract-bomb-guard).

A publicação no npm para @theluckystrike/mcp-zip está pendente, então npx -y @theluckystrike/mcp-zip retorna 404 hoje. Até lá, o pacote de um clique .mcpb ou um clone + compilação é o caminho que funciona.

Instalação

Claude Desktop, ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) ou %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "zip": { "command": "npx", "args": ["-y", "@theluckystrike/mcp-zip"] }
  }
}

Claude Code:

claude mcp add zip -- npx -y @theluckystrike/mcp-zip

Cursor, .cursor/mcp.json:

{
  "mcpServers": {
    "zip": { "command": "npx", "args": ["-y", "@theluckystrike/mcp-zip"] }
  }
}

Ferramentas

ferramentao que faz
zip_createEmpacota arquivos, ou uma árvore de diretórios com padrões glob, em um novo .zip
zip_listCada entrada com seu tamanho, tamanho compactado e proporção, e tudo perigoso nela, sinalizado
zip_extractDescompacta em um diretório, com proteções contra traversal, symlink e zip-bomb e um dry_run
zip_addAdiciona arquivos a um arquivo que já existe
zip_extract_textLê uma entrada de texto inline, sem descompactar nada
zip_bundle_monthUm mês de faturas, cotações e exportações dos servidores irmãos, em um único arquivo
zip_historyO que você criou e quanto da cota gratuita deste mês resta
license_status, license_activateGratuito ou Pro, e ativação de uma chave

Gratuito vs Pro

GratuitoPro
Arquivos por mês calendário20Ilimitado
Tamanho do arquivoAté 25 MBIlimitado
Entradas por arquivoAté 200Ilimitado
Leitura: zip_list, zip_extract, zip_extract_textIlimitadaIlimitada
Proteções contra bombas, traversal e symlinksSimSim

A leitura nunca é medida. O nível gratuito é um limite sobre o que você escreve, porque um arquivo que alguém lhe enviou é exatamente o que você mais precisa inspecionar antes de abrir, e um paywall na frente disso seria um paywall na frente da verificação de segurança.

Obtenha Pro: https://mcp.zovo.one/buy/zip - $19 pagamento único, ou $39 para todos os servidores do conjunto, vitalício. As chaves verificam offline; nada é enviado a lugar algum.

Por que fflate e não um escritor escrito à mão

A escolha foi fflate (JS puro, 0 dependências, zipSync/inflateSync síncronos) contra escrever um escritor STORE/DEFLATE em node:zlib, que está disponível sem nenhuma dependência.

O formato do contêiner é escrito aqui de qualquer forma. Este servidor lê o diretório central por conta própria, em src/zipfile.ts, cerca de 200 linhas: tamanhos, nomes, métodos, CRCs, atributos externos. Ele precisa, porque cada proteção no servidor é uma decisão tomada a partir desses cabeçalhos antes de qualquer coisa ser inflada, e uma biblioteca que devolve {name: bytes} já descompactou a bomba no momento em que você pode olhar para ela. Então o argumento para uma biblioteca nunca foi "ela me poupa o formato".

O que resta é o compactador, e essa é a parte que não se deve escrever. node:zlib faria isso, mas suas chamadas raw-deflate são assíncronas primeiro, carregam uma ida e volta ao thread-pool por chamada, e as síncronas cada uma constrói um stream nativo; empacotar 200 arquivos pequenos são 200 dessas. O deflateSync do fflate é uma implementação em JS puro sem manipulador nativo, empacota 200 arquivos em 74 ms (medido abaixo), e significa que o pacote ainda não tem etapa de compilação nativa, que é a regra para todo este conjunto: npx tem que funcionar em qualquer lugar.

A troca é declarada claramente: o fflate constrói o arquivo em um único buffer, então este servidor recusa entradas acima de 512 MB em vez de fingir que faz streaming, e não lê ZIP64 (acima de 4 GB ou acima de 65.535 entradas), que é recusado pelo nome em vez de ser mal lido.

Medido: o tipo de arquivo não prevê a proporção de compactação, a repetição prevê

Cada arquivo abaixo foi compactado no nível 6 nesta máquina. A coluna "tipo" é o que uma pessoa chamaria o arquivo; a proporção é o que realmente aconteceu.

arquivotipobytescompactadoproporção
uma fatura de 12 páginas de mcp-pdfPDF15.12514.1181,07x
um contrato de 400 parágrafos de mcp-docxDOCX9.8977.3111,35x
4.000 linhas de CSV de cobrança, valores variadosCSV321.329134.0492,40x
o próprio index.ts deste servidorcódigo-fonte39.49811.9383,31x
package-lock.jsonJSON138.83533.2234,18x
20.000 linhas de um log de aplicativolog1.603.390106.26115,09x
4.000 linhas de CSV de cobrança, 40 clientes repetidosCSV338.5494.09482,69x
50 MB de bytes zerobomba52.428.80051.2941022x

PDF e DOCX mal se movem, e isso não é surpresa uma vez que você olha dentro deles: ambos já são contêineres deflate, então compactá-los novamente é empacotamento, não compactação. Agrupar um mês de faturas vale a pena pelo arquivo único, não pelo espaço.

As duas linhas de CSV são o par interessante. Mesma ferramenta, mesma forma, mesmo tamanho, 34x de diferença: a com quarenta nomes de clientes repetidos compacta 82,69x, a com valores únicos 2,40x. Nada sobre "é um CSV" prevê qual você tem.

Medido: por que o teto de bomba é 100x e não 50x

Uma bomba de compactação é recusada pela proporção, e o instinto óbvio é definir esse teto baixo, bem abaixo do 1022x que um arquivo de zeros alcança. A tabela acima diz por que isso está errado: uma exportação CSV real, do tipo que zip_bundle_month coleta do rastreador de despesas, alcançou 82,69x, que é 83% do caminho até um teto de 100x e bem além de um de 50x. Um teto ajustado para ficar confortavelmente abaixo de uma bomba recusaria uma exportação mensal real, e a pessoa do outro lado aprenderia a passar max_ratio em tudo, o que desliga a proteção permanentemente.

Então a proporção é a segunda proteção, não a primeira. A primeira é o total: os tamanhos não compactados declarados das entradas selecionadas são somados e comparados contra um teto (1 GB por padrão, max_total_mb para mudá-lo), porque 200 MB de um arquivo de 199 KB é uma decisão que você pode tomar sobre o arquivo como um todo sem julgar nenhuma entrada. Ambos são lidos do diretório central, então recusar uma bomba não custa nenhuma descompactação:

refuse a 500 MB bomb (497.8 KB on disk)   3 ms, nothing inflated, out_dir not even created

Medido: um buffer de saída limitado não é uma proteção contra bombas

fflate.inflateSync(data, { out: new Uint8Array(n) }) parece a resposta completa: limite o buffer, limite o dano. Não é, e a forma como falha é silenciosa. Uma entrada de 100.000 bytes inflada em um buffer de 10 bytes retorna 10 bytes e não lança nada. Um arquivo cujo cabeçalho declara 10 bytes para uma entrada de 100 KB seria extraído como um arquivo de 10 bytes, relatado como sucesso, com a truncagem invisível.

Então o buffer limita a memória e o CRC-32 no diretório central prova os bytes. Cada entrada que este servidor escreve é verificada contra o cabeçalho antes de chegar ao disco, e uma incompatibilidade recusa a entrada pelo nome. Esse é o check que transforma um cabeçalho mentiroso de perda silenciosa de dados em uma sentença.

Tempos

Laptop da série M, via stdio, por chamada, armazenamento frio:

operaçãomedido
zip_create, 200 arquivos, 4,0 MB74 ms
zip_list, 200 entradas2 ms
zip_extract, 200 entradas47 ms
zip_extract_text, uma entrada1 ms
recusar uma bomba de 500 MB3 ms
suíte de testes inteira, 38 testes, cinco arquivos3,9 s

Privacidade

Tudo permanece na sua máquina. Não há código de rede neste servidor: nenhum fetch, nenhum cliente HTTP, nenhuma telemetria. Os arquivos são escritos onde você diz, e um pequeno registro do que foi criado fica em ~/.local/share/mcp-servers/zip/ (ou $XDG_DATA_HOME). As chaves de licença verificam offline com uma chave pública.

Senhas de zip não são suportadas, e passar uma é recusado em vez de ignorado: a cifra zip clássica está quebrada e a criptografia AES zip é uma extensão de fornecedor na qual nenhuma ferramenta concorda, então um arquivo "protegido por senha" daqui seria uma promessa falsa.

Construído por theluckystrike. Suporte: support@zovo.one

Use estes documentos como um servidor MCP

Qualquer cliente MCP (Claude, Cursor, Windsurf, VS Code) pode ler a documentação deste repositório diretamente via GitMCP — sem instalação: