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-zipainda não está publicado no npm, então um comandonpx -y @theluckystrike/mcp-zipfalhará. Os três caminhos acima são os que funcionam e cada um é testado pelo CI.

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
| ferramenta | o que faz |
|---|---|
zip_create | Empacota arquivos, ou uma árvore de diretórios com padrões glob, em um novo .zip |
zip_list | Cada entrada com seu tamanho, tamanho compactado e proporção, e tudo perigoso nela, sinalizado |
zip_extract | Descompacta em um diretório, com proteções contra traversal, symlink e zip-bomb e um dry_run |
zip_add | Adiciona arquivos a um arquivo que já existe |
zip_extract_text | Lê uma entrada de texto inline, sem descompactar nada |
zip_bundle_month | Um mês de faturas, cotações e exportações dos servidores irmãos, em um único arquivo |
zip_history | O que você criou e quanto da cota gratuita deste mês resta |
license_status, license_activate | Gratuito ou Pro, e ativação de uma chave |
Gratuito vs Pro
| Gratuito | Pro | |
|---|---|---|
| Arquivos por mês calendário | 20 | Ilimitado |
| Tamanho do arquivo | Até 25 MB | Ilimitado |
| Entradas por arquivo | Até 200 | Ilimitado |
Leitura: zip_list, zip_extract, zip_extract_text | Ilimitada | Ilimitada |
| Proteções contra bombas, traversal e symlinks | Sim | Sim |
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.
| arquivo | tipo | bytes | compactado | proporção |
|---|---|---|---|---|
uma fatura de 12 páginas de mcp-pdf | 15.125 | 14.118 | 1,07x | |
um contrato de 400 parágrafos de mcp-docx | DOCX | 9.897 | 7.311 | 1,35x |
| 4.000 linhas de CSV de cobrança, valores variados | CSV | 321.329 | 134.049 | 2,40x |
o próprio index.ts deste servidor | código-fonte | 39.498 | 11.938 | 3,31x |
package-lock.json | JSON | 138.835 | 33.223 | 4,18x |
| 20.000 linhas de um log de aplicativo | log | 1.603.390 | 106.261 | 15,09x |
| 4.000 linhas de CSV de cobrança, 40 clientes repetidos | CSV | 338.549 | 4.094 | 82,69x |
| 50 MB de bytes zero | bomba | 52.428.800 | 51.294 | 1022x |
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ção | medido |
|---|---|
zip_create, 200 arquivos, 4,0 MB | 74 ms |
zip_list, 200 entradas | 2 ms |
zip_extract, 200 entradas | 47 ms |
zip_extract_text, uma entrada | 1 ms |
| recusar uma bomba de 500 MB | 3 ms |
| suíte de testes inteira, 38 testes, cinco arquivos | 3,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:
- URL MCP dos documentos: https://gitmcp.io/theluckystrike/mcp-zip