XLSX Tools MCP

Um servidor MCP para ler, analisar e editar com precisão pastas de trabalho do Excel (.xlsx), preservando a estrutura existente, estilos, fórmulas e a integridade dos dados. Suporta operações de células, gerenciamento de planilhas e de linhas/colunas, formatação, agregação de dados, recálculo de fórmulas e acesso seguro e concorrente a arquivos.

Documentação

xlsx-tools-mcp

Um servidor MCP para ler e escrever arquivos Excel (.xlsx) com alta precisão, preservando a estrutura, os estilos e as fórmulas existentes do arquivo.

CI PyPI Version Downloads/month Listed on mcpservers.org


Visão Geral

xlsx-tools-mcp expõe 29 ferramentas do Model Context Protocol (MCP) que dão a um agente de LLM acesso preciso de leitura e escrita que preserva a estrutura de arquivos Excel .xlsx. Ele roda como um servidor MCP padrão via stdio: você o instala e o registra em um cliente MCP (Claude Code, OpenCode, etc.), e o agente do cliente pode listar planilhas, ler intervalos de células, pesquisar valores, agregar dados, escrever células/fórmulas, gerenciar planilhas/linhas/colunas, aplicar estilos e forçar o recálculo de fórmulas.

Ele é construído em torno do princípio de que editar uma pasta de trabalho existente não deve destruir o que não toca.

Recursos

  • Escritas que preservam a estrutura via openpyxl — as escritas carregam a pasta de trabalho existente e a salvam de volta, preservando estilos, células mescladas, comentários e qualquer aspecto que a edição não toque.
  • Resultados de fórmulas nunca desatualizados via recálculo do LibreOffice — o openpyxl escreve strings de fórmulas, mas nunca as avalia. Após cada escrita de valor/fórmula, o servidor executa uma passagem headless do LibreOffice para recalcular os resultados reais e então retorna errors_found — quaisquer valores de erro do Excel (#REF!, #DIV/0!, #N/A, …) produzidos pelo recálculo.
  • Leituras rápidas via python-calamine — um parser baseado em Rust para inferência de tipos precisa e rápida, com fallback automático para openpyxl quando você precisa de fórmulas/estilos/comentários ou quando o calamine não consegue analisar o arquivo.
  • Agrupamento/agregação e consultas baseados em pandas — aggregate_sheet e query_sheet realizam operações sem destruir a estrutura de origem, equipados com validação de expressão AST para bloquear injeção de código.
  • Objetos Excel nativos — crie Tabelas Excel formais (create_table) com autofiltro e estilos, e gráficos nativos (create_chart para barras, linhas, pizza, dispersão).
  • Ciclo de vida e formatação de planilhas — renomeie planilhas (rename_sheet), duplique planilhas com estilos intactos (copy_sheet), limpe intervalos (clear_range) e ajuste automaticamente a largura das colunas (autofit_columns).
  • Confiabilidade multiplataforma (Windows, macOS, Linux) — confinamento de caminhos sem diferenciar maiúsculas/minúsculas, delimitadores de ambiente ; por vírgula ou ponto e vírgula, substituição atômica segura de arquivos com nova tentativa de bloqueio transitório (defesa contra WinError 32 / antivírus) e recálculo headless silencioso sem oscilação de janela.
  • Bloqueio por arquivo — chamadas de ferramentas concorrentes (ou outros processos) que tocam na mesma pasta de trabalho são serializadas via um arquivo <path>.lock irmão (filelock), para que as escritas nunca se intercalem e corrompam o arquivo.
  • Confinamento de caminhos — XLSX_MCP_ALLOWED_DIRS (separado por vírgula ou ponto e vírgula) restringe todas as leituras e escritas a diretórios específicos. Se definido, qualquer tentativa de acessar um arquivo fora desses limites gera AccessDeniedError. Comparações de caminhos sem diferenciar maiúsculas/minúsculas e caminhos com múltiplas unidades no Windows são suportados.
  • Backup e restauração automáticos — as ferramentas de escrita criam automaticamente um arquivo irmão .bak antes de modificar a pasta de trabalho se backup=True (que tem como padrão XLSX_MCP_AUTO_BACKUP=true). Use restore_backup para reverter alterações atomicamente.
  • Proteção contra injeção de fórmulas — write_cells e append_rows rejeitam fórmulas que contenham WEBSERVICE, HYPERLINK, INDIRECT, RTD, CALL, REGISTER ou comandos DDE (|) por padrão para evitar exfiltração de dados ou links maliciosos. Passe allow_external_formulas=True para ignorar essa verificação.
  • Proteção contra bombas XML — o pacote defusedxml é uma dependência automática; o openpyxl o detecta e usa seu parser XML endurecido, para que XML xlsx hostil não possa se expandir em exaustão de recursos.
  • Pré-carregar arquivos na inicialização — defina XLSX_MCP_FILES para pré-carregar uma ou mais pastas de trabalho (separadas por vírgula ou ponto e vírgula); as ferramentas podem então ser chamadas com path omitido ou com um alias curto em vez de um caminho completo do sistema de arquivos.

Estatísticas de Download

Downloads/month Downloads/week

Ao vivo via pypistats.org, downloads sem espelhos. Eles contam eventos de download, não usuários únicos ou instalações — um usuário pode gerar muitos downloads (CI, reinstalações, reconstruções de Docker, espelhos).


Arquitetura

┌──────────────────────── Supervisor (MCP transport, stdio)
│  src/xlsx_tools_mcp/server.py     29 MCP tools + instructions
│  src/xlsx_tools_mcp/settings.py   env vars, preloaded files, path resolution
│  src/xlsx_tools_mcp/locking.py    per-file <path>.lock serialization
│  src/xlsx_tools_mcp/errors.py     domain error types
│  src/xlsx_tools_mcp/recalc.py     LibreOffice headless recalc + error scanning
│
├─ Read path
│  src/xlsx_tools_mcp/io/reader.py      calamine primary → openpyxl fallback
│  src/xlsx_tools_mcp/io/transform.py   pandas aggregation on read results
│
└─ Write path
   src/xlsx_tools_mcp/io/writer.py      openpyxl → LibreOffice recalc → scan errors

A camada de io (io/) é deliberadamente desacoplada do transporte MCP (server.py). Cada ferramenta MCP é um wrapper fino que resolve o caminho de destino, adquire o bloqueio por arquivo e chama uma função da camada de io. Isso mantém a lógica central independente do MCP, para que possa ser testada diretamente (veja tests/).

A compensação do recálculo

Após uma escrita que toca valores de células ou fórmulas, o servidor executa soffice --headless --convert-to xlsx no arquivo para que cada fórmula obtenha um valor calculado real. Esse ciclo reexporta a pasta de trabalho inteira e recalcula fórmulas — é uma compensação, não uma garantia de preservação bit a bit. Recursos que o openpyxl preservaria podem não sobreviver de forma idêntica: tabelas dinâmicas, gráficos, validação de dados, alguns formatos e alguns nomes definidos.

Se você estiver trabalhando em uma pasta de trabalho estruturalmente complexa onde esse risco importa, você pode passar recalculate=False nas ferramentas de escrita de valor/fórmula (write_cells, append_rows, insert_rows, delete_rows, insert_columns, delete_columns) para salvar apenas com openpyxl e pular o ciclo completamente.


Requisitos

  • Python ≥ 3.10
  • LibreOffice — opcional, mas recomendado. Necessário apenas para recálculo de fórmulas. Sem ele, as escritas ainda funcionam (salvas via openpyxl), mas as fórmulas não são recalculadas e um aviso é retornado no campo message.

Instale o LibreOffice:

# macOS
brew install --cask libreoffice

# Debian / Ubuntu
sudo apt-get install -y libreoffice-calc

# Windows
winget install TheDocumentFoundation.LibreOffice

O servidor encontra o LibreOffice verificando soffice / libreoffice em PATH, o local de instalação padrão do macOS (/Applications/LibreOffice.app/Contents/MacOS/soffice) e caminhos padrão do Windows (%ProgramFiles%\LibreOffice\program\soffice.exe, etc.). No Windows, o recálculo headless roda silenciosamente sem oscilação de janela (CREATE_NO_WINDOW) e com perfis de usuário isolados.


Instalação

O servidor fala o transporte stdio (MCP padrão): após a instalação, ele aguarda um cliente MCP conectar e chamar ferramentas. Você normalmente não o executa diretamente; você o registra em um cliente.

1. Do PyPI via uvx (recomendado — sem clone)

uvx xlsx-tools-mcp

uvx busca e executa o pacote publicado sem poluir seu projeto. Esta é a maneira mais simples de ativar um cliente MCP (veja os trechos de configuração abaixo).

2. Do código-fonte

git clone https://github.com/ruriazz/xlsx-tools-mcp.git
cd xlsx-tools-mcp
uv sync
# run the server (useful for local dev / debugging):
uv run xlsx-tools-mcp

3. Via pip

pip install xlsx-tools-mcp

Isso instala o ponto de entrada do console, para que você possa executar o servidor diretamente:

xlsx-tools-mcp

Configuração para clientes MCP

O registro mais simples para cada cliente usa uvx xlsx-tools-mcp (sem clone, sempre a versão publicada).

Dica para Windows: Em arquivos de configuração JSON do cliente (.mcp.json, opencode.json), use barras normais (ex.: "C:/path/to/data.xlsx") ou barras invertidas escapadas (ex.: "C:\\\\path\\\\to\\\\data.xlsx") para evitar erros de sequência de escape JSON.

Claude Code

claude mcp add xlsx-tools-mcp -- uvx xlsx-tools-mcp

Ou via .mcp.json no seu projeto:

{
  "mcpServers": {
    "xlsx-tools-mcp": { "command": "uvx", "args": ["xlsx-tools-mcp"] }
  }
}

OpenCode

Em opencode.json (projeto) ou ~/.config/opencode/opencode.json (global):

{
  "mcp": {
    "xlsx-tools-mcp": { "type": "local", "command": ["uvx", "xlsx-tools-mcp"], "enabled": true }
  }
}

Ao executar a partir de um clone do código-fonte

Se você clonou o repositório em vez de instalar do PyPI, aponte o cliente para seu checkout local trocando uvx xlsx-tools-mcp pela forma dinâmica uv run (use o caminho absoluto para o clone):

Claude Code .mcp.json:

{
  "mcpServers": {
    "xlsx-tools-mcp": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/xlsx-reader", "run", "xlsx-tools-mcp"]
    }
  }
}

OpenCode:

{
  "mcp": {
    "xlsx-tools-mcp": {
      "type": "local",
      "command": ["uv", "--directory", "/absolute/path/to/xlsx-reader", "run", "xlsx-tools-mcp"],
      "enabled": true
    }
  }
}

Substitua /absolute/path/to/xlsx-reader pela localização real do seu clone.


Pré-carregando arquivos (XLSX_MCP_FILES)

Defina a variável de ambiente XLSX_MCP_FILES na seção env da configuração do servidor MCP (não no seu shell interativo — o servidor é iniciado pelo cliente) para pré-carregar pastas de trabalho na inicialização. Formato: entradas alias=absolute/path separadas por vírgula ou ponto e vírgula, ou caminhos absolutos simples:

XLSX_MCP_FILES=name=/abs/path/to/name.xlsx,report=/data/report.xlsx

Caminhos simples recebem um alias que assume como padrão o nome do arquivo:

XLSX_MCP_FILES=/abs/path/to/sales.xlsx

Com alias/filename como o alias:

  • Um arquivo configurado → toda ferramenta pode ser chamada com path completamente omitido.
  • Múltiplos arquivos configurados → passe o alias (ou nome do arquivo) como path.
  • list_configured_files() retorna o mapeamento alias → caminho absoluto.
  • Caminhos absolutos e relativos crus ainda funcionam para arquivos que você não pré-carregou.

Claude Code — .mcp.json com pré-carregamento:

{
  "mcpServers": {
    "xlsx-tools-mcp": {
      "command": "uvx",
      "args": ["xlsx-tools-mcp"],
      "env": {
        "XLSX_MCP_FILES": "report=/data/report.xlsx,sales=/data/sales.xlsx"
      }
    }
  }
}

OpenCode com pré-carregamento:

{
  "mcp": {
    "xlsx-tools-mcp": {
      "type": "local",
      "command": ["uvx", "xlsx-tools-mcp"],
      "env": { "XLSX_MCP_FILES": "report=/data/report.xlsx,sales=/data/sales.xlsx" },
      "enabled": true
    }
  }
}

Referência de ferramentas

Todas as 29 ferramentas. Salvo indicação em contrário, path aceita um caminho do sistema de arquivos, um alias/nome de arquivo pré-carregado, ou pode ser omitido quando exatamente um arquivo está pré-carregado. create_workbook é a exceção — seu path é obrigatório porque um novo arquivo nunca é pré-carregado.

Formato de resposta (todas as ferramentas de escrita): toda ferramenta de escrita retorna {"saved": bool, "recalculated": bool, "errors_found": list, "message": str}. Quando não vazio, errors_found é uma lista de {"sheet": "...", "cell": "B2", "error": "#DIV/0!"}.

Inspecionar / Ler

FerramentaDescrição
list_configured_files()Lista arquivos pré-carregados na inicialização via XLSX_MCP_FILES, como um mapa alias → caminho absoluto. Chame isso primeiro se não tiver certeza do que está disponível.
list_sheets(path?)Lista todas as planilhas da pasta de trabalho com contagens aproximadas de linhas/colunas (calamine).
get_workbook_info(path?)Metadados no nível da pasta de trabalho: dimensões exatas por planilha, max_row/max_column, estado da planilha, a planilha ativa e nomes definidos.
read_sheet(sheet, cell_range?, max_rows?, offset_row?, format?, path?)Lê valores de células. cell_range limita a área de leitura. max_rows limita as linhas. offset_row pula um número de linhas para paginação. format pode ser "array" (lista 2D), "records" (lista de dicionários usando a primeira linha como chaves) ou "markdown" (string de tabela).
get_cell(sheet, cell, path?)Detalhe completo para uma única célula: valor (calculado em cache), fórmula, formato numérico, fonte (negrito/itálico/tamanho/cor), cor de preenchimento, estado de mesclagem, comentário.
search_workbook(query, sheet?, match_case?, limit?, path?)Pesquisa de substring em uma ou todas as planilhas. sheet restringe a uma planilha; match_case=True torna a pesquisa sensível a maiúsculas/minúsculas; limit limita as correspondências. Retorna {"sheet", "cell", "value"}.
aggregate_sheet(sheet, group_by, agg, cell_range?, has_header?, path?)Agrupa e agrega com pandas. group_by é uma lista de nomes de colunas (tirados da linha de cabeçalho); agg mapeia nome da coluna → função de agregação, ex.: {"amount": "sum"}. has_header=True (padrão) lê os nomes das colunas da primeira linha. Retorna {columns, records, row_count}.
profile_sheet(sheet, sample_rows?, path?)Perfila metadados da planilha: tipos inferidos, contagens de nulos, mínimo/máximo, valores de amostra.
query_sheet(sheet, filter_query, columns?, max_rows?, cell_range?, path?)Filtra dados da planilha usando expressões pandas com defesa de injeção de código endurecida por AST.

Escrita

FerramentaDescrição
create_workbook(path, sheets?, overwrite?)Cria uma nova pasta de trabalho .xlsx/.xlsm. sheets assume como padrão ["Sheet1"]. overwrite=True substitui um arquivo existente. path é obrigatório (arquivos novos nunca são pré-carregados).
write_cells(sheet, cells, create_sheet_if_missing?, recalculate?, allow_external_formulas?, backup?, path?)Escreve valores e/ou fórmulas em células específicas. cells é uma lista de {"cell": "A1", "value": ...} ou {"cell": "B1", "formula": "=A1*2"}. Opcionalmente, crie a planilha primeiro; recalculate=True (padrão) executa o recálculo do LibreOffice.
append_rows(sheet, rows, create_sheet_if_missing?, recalculate?, allow_external_formulas?, backup?, path?)Acrescenta linhas após a última linha usada. rows é uma lista de linhas, cada uma sendo uma lista de valores de células na ordem das colunas.
create_sheet(sheet, index?, path?)Adiciona uma nova planilha vazia. index é uma posição de inserção baseada em zero; omita para acrescentar no final.
delete_sheet(sheet, path?)Exclui uma planilha. Falha se for a única planilha restante.
rename_sheet(old_name, new_name, path?)Renomeia uma planilha existente.
copy_sheet(source_sheet, target_sheet, path?)Duplica uma planilha, incluindo seu conteúdo, fórmulas e estilos.
insert_rows(sheet, start_row, count?, recalculate?, path?)Insere linhas em branco antes de start_row (baseado em 1), deslocando as linhas existentes para baixo. count assume como padrão 1.
delete_rows(sheet, start_row, count?, recalculate?, path?)Exclui linhas a partir de start_row (baseado em 1), deslocando as linhas abaixo para cima. count assume como padrão 1.
insert_columns(sheet, start_column, count?, recalculate?, path?)Insere colunas em branco antes de start_column (baseado em 1), deslocando as colunas existentes para a direita. count assume como padrão 1.
delete_columns(sheet, start_column, count?, recalculate?, path?)Exclui colunas a partir de start_column (baseado em 1), deslocando as colunas à direita para a esquerda. count assume como padrão 1.
merge_cells(sheet, cell_range, path?)Mescla um intervalo retangular (ex.: "A1:C1") em uma única célula.
unmerge_cells(sheet, cell_range, path?)Desfaz uma mesclagem em um intervalo previamente mesclado.
set_cell_style(sheet, cell_range, style, path?)Aplica formatação a um intervalo (ex.: "A1:D1"). Chaves de style: bold, italic, font_size, font_color (RGB hexadecimal, ex.: "FF0000"), bg_color (RGB hexadecimal), horizontal, vertical (alinhamento), border ("thin", "medium", "thick", …), number_format (ex.: "#,##0.00").
autofit_columns(sheet, min_width?, max_width?, padding?, path?)Ajusta automaticamente as larguras das colunas com base no comprimento máximo do texto para evitar cortes.
clear_range(sheet, cell_range, clear_values?, clear_styles?, path?)Limpa valores de células e/ou estilos dentro de um intervalo especificado sem excluir linhas ou colunas.
create_table(sheet, cell_range, table_name, style_name?, show_filter?, show_row_stripes?, path?)Cria uma Tabela formal do Excel sobre um intervalo.
create_chart(sheet, chart_type, data_range, categories_range?, title?, target_cell?, path?)Adiciona um gráfico nativo do Excel (barras, linhas, pizza, dispersão).
recalculate_workbook(path?)Força uma passagem de recálculo headless do LibreOffice e relata quaisquer erros de fórmula encontrados.
restore_backup(backup_path, target_path)Restaura um arquivo de backup .bak sobre uma pasta de trabalho de destino atomicamente.

Exemplo de payload — write_cells

Uma chamada que escreve uma fórmula e um valor:

{
  "sheet": "Sheet1",
  "cells": [
    { "cell": "A1", "value": 100 },
    { "cell": "B1", "formula": "=A1*2" }
  ],
  "recalculate": true,
  "path": "/data/budget.xlsx"
}

Resposta correspondente:

{
  "saved": true,
  "recalculated": true,
  "errors_found": [],
  "message": "Recalculated with LibreOffice headless."
}

Se uma fórmula tocada por isso produziu um erro, errors_found seria assim:

{
  "saved": true,
  "recalculated": true,
  "errors_found": [
    { "sheet": "Sheet1", "cell": "C5", "error": "#DIV/0!" }
  ],
  "message": "Recalculated with LibreOffice headless."
}

Exemplo de payload — query_sheet

{
  "sheet": "Sales",
  "filter_query": "Revenue > 500 and Status == 'PAID'",
  "columns": ["Customer", "Revenue"],
  "max_rows": 10
}

Exemplo de payload — create_table & create_chart

{
  "sheet": "Summary",
  "cell_range": "A1:D10",
  "table_name": "SalesTable",
  "style_name": "TableStyleMedium9"
}
{
  "sheet": "Summary",
  "chart_type": "bar",
  "data_range": "B1:B10",
  "categories_range": "A2:A10",
  "title": "Monthly Revenue",
  "target_cell": "F2"
}

Variáveis de ambiente

VariávelPadrãoDescrição
XLSX_MCP_FILESvazioalias=path ou path separados por vírgula ou ponto e vírgula para pré-carregar na inicialização.
XLSX_MCP_ALLOWED_DIRSvazioDiretórios separados por vírgula ou ponto e vírgula para confinar o acesso a arquivos (caminhos fora deles geram AccessDeniedError). Suporta insensibilidade a maiúsculas/minúsculas no Windows.
XLSX_MCP_AUTO_BACKUPtrueCria automaticamente uma cópia .bak antes de modificar uma pasta de trabalho.
XLSX_MCP_BACKUP_DIRvazioDiretório personalizado para arquivos de backup (padrão: ao lado do arquivo de destino).
XLSX_MCP_RECALC_TIMEOUT60Tempo limite em segundos para o recálculo de fórmulas headless do LibreOffice.
XLSX_MCP_LOCK_TIMEOUT10Tempo limite em segundos para adquirir o bloqueio por arquivo antes de falhar.

Segurança e concorrência

  • Confinamento de caminho — XLSX_MCP_ALLOWED_DIRS (separado por vírgula ou ponto e vírgula) restringe todas as leituras e escritas a diretórios específicos. Se definido, qualquer tentativa de acessar um arquivo fora desses limites gera AccessDeniedError. Comparações de caminho insensíveis a maiúsculas/minúsculas e caminhos com múltiplas unidades no Windows são suportados.
  • Backup automático e restauração — As ferramentas de escrita criarão automaticamente um arquivo irmão .bak antes de modificar a pasta de trabalho se backup=True (que assume como padrão XLSX_MCP_AUTO_BACKUP=true). Use XLSX_MCP_BACKUP_DIR para salvar backups em uma pasta específica. Use restore_backup para reverter alterações atomicamente.
  • Proteção contra injeção de fórmulas — write_cells e append_rows rejeitam fórmulas contendo WEBSERVICE, HYPERLINK, INDIRECT, RTD, CALL, REGISTER ou comandos DDE (|) por padrão para evitar exfiltração de dados ou execução de comandos. Passe allow_external_formulas=True para ignorar essa verificação.
  • Validação segura de consultas via AST — query_sheet usa um analisador AST para permitir estritamente apenas comparações, lógica booleana e operadores seguros, bloqueando @ de variáveis, chamadas de execução de código e atributos dunder privados.
  • Proteção contra bombas XML — defusedxml é uma dependência automática deste pacote. O openpyxl o detecta automaticamente e usa seu analisador XML endurecido, então um .xlsx malicioso (um zip de XML) não pode acionar exaustão de recursos por expansão de entidades. Nenhuma configuração necessária.
  • Bloqueio por arquivo — cada leitura/escrita adquire um arquivo irmão <path>.lock (via filelock). Chamadas de ferramentas concorrentes ou outros processos que tocam a mesma pasta de trabalho são serializados para que as escritas nunca se intercalem e corrompam o arquivo.
  • Resiliência a bloqueios transitórios — no Windows NTFS, trocas atômicas de arquivos podem encontrar temporariamente violações de compartilhamento (WinError 32 / 33) enquanto scanners antivírus ou indexadores de pesquisa inspecionam arquivos recém-salvos. O servidor executa uma nova tentativa com backoff exponencial para ter sucesso transparentemente após a liberação, ou fornece uma mensagem de orientação clara se o arquivo estiver permanentemente aberto no Microsoft Excel.
  • Tempo limite de recálculo — XLSX_MCP_RECALC_TIMEOUT (segundos, padrão 60) limita quanto tempo a passagem de recálculo do LibreOffice pode executar.
  • Tempo limite de bloqueio — XLSX_MCP_LOCK_TIMEOUT (segundos, padrão 10) limita quanto tempo uma ferramenta esperará para adquirir o bloqueio por arquivo antes de falhar.

Solução de problemas

  • errors_found está vazio mesmo com minha fórmula quebrada — o recálculo provavelmente não foi executado. Verifique o campo message: se ele disser que o LibreOffice não foi encontrado, o arquivo foi salvo via openpyxl como está e as fórmulas não foram recalculadas (valores em cache podem estar desatualizados). Instale o LibreOffice (veja Requisitos).
  • O recálculo está lento ou expira — aumente XLSX_MCP_RECALC_TIMEOUT (padrão 60s). Em caso de tempo limite, o arquivo ainda é salvo, mas recalculated será false e message diz que o recálculo expirou.
  • LockTimeoutError em acesso concorrente — outra operação está segurando o bloqueio. Aumente XLSX_MCP_LOCK_TIMEOUT (padrão 10s) ou tente novamente quando a outra operação terminar.
  • Workbook is locked by another process / WinError 32 — no Windows, o Microsoft Excel e alguns aplicativos bloqueiam arquivos abertos exclusivamente. Feche a pasta de trabalho no Excel e tente novamente. Bloqueios transitórios de scanners antivírus ou indexadores de pesquisa são automaticamente tentados novamente pelo servidor antes de falhar.
  • "Planilha não encontrada" — a mensagem de erro lista os nomes das planilhas disponíveis, para que você possa escolher a correta.
  • path obrigatório / nenhum arquivo configurado — você chamou uma ferramenta sem path mas nenhum (ou múltiplos) arquivo(s) está(ão) pré-carregado(s). Pré-carregue um arquivo via XLSX_MCP_FILES, passe um alias explícito ou passe um caminho bruto.

Desenvolvimento / Contribuição

Veja CONTRIBUTING.md. Execute a suíte de testes com:

uv run pytest