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.
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_sheetequery_sheetrealizam 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_chartpara 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 contraWinError 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>.lockirmã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 geraAccessDeniedError. 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
.bakantes de modificar a pasta de trabalho sebackup=True(que tem como padrãoXLSX_MCP_AUTO_BACKUP=true). Userestore_backuppara reverter alterações atomicamente. - Proteção contra injeção de fórmulas —
write_cellseappend_rowsrejeitam fórmulas que contenhamWEBSERVICE,HYPERLINK,INDIRECT,RTD,CALL,REGISTERou comandos DDE (|) por padrão para evitar exfiltração de dados ou links maliciosos. Passeallow_external_formulas=Truepara 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 XMLxlsxhostil não possa se expandir em exaustão de recursos. - Pré-carregar arquivos na inicialização — defina
XLSX_MCP_FILESpara pré-carregar uma ou mais pastas de trabalho (separadas por vírgula ou ponto e vírgula); as ferramentas podem então ser chamadas compathomitido ou com um alias curto em vez de um caminho completo do sistema de arquivos.
Estatísticas de Download
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
pathcompletamente 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
| Ferramenta | Descriçã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
| Ferramenta | Descriçã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ável | Padrão | Descrição |
|---|---|---|
XLSX_MCP_FILES | vazio | alias=path ou path separados por vírgula ou ponto e vírgula para pré-carregar na inicialização. |
XLSX_MCP_ALLOWED_DIRS | vazio | Diretó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_BACKUP | true | Cria automaticamente uma cópia .bak antes de modificar uma pasta de trabalho. |
XLSX_MCP_BACKUP_DIR | vazio | Diretório personalizado para arquivos de backup (padrão: ao lado do arquivo de destino). |
XLSX_MCP_RECALC_TIMEOUT | 60 | Tempo limite em segundos para o recálculo de fórmulas headless do LibreOffice. |
XLSX_MCP_LOCK_TIMEOUT | 10 | Tempo 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 geraAccessDeniedError. 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
.bakantes de modificar a pasta de trabalho sebackup=True(que assume como padrãoXLSX_MCP_AUTO_BACKUP=true). UseXLSX_MCP_BACKUP_DIRpara salvar backups em uma pasta específica. Userestore_backuppara reverter alterações atomicamente. - Proteção contra injeção de fórmulas —
write_cellseappend_rowsrejeitam fórmulas contendoWEBSERVICE,HYPERLINK,INDIRECT,RTD,CALL,REGISTERou comandos DDE (|) por padrão para evitar exfiltração de dados ou execução de comandos. Passeallow_external_formulas=Truepara ignorar essa verificação. - Validação segura de consultas via AST —
query_sheetusa 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.xlsxmalicioso (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(viafilelock). 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ão60) limita quanto tempo a passagem de recálculo do LibreOffice pode executar. - Tempo limite de bloqueio —
XLSX_MCP_LOCK_TIMEOUT(segundos, padrão10) limita quanto tempo uma ferramenta esperará para adquirir o bloqueio por arquivo antes de falhar.
Solução de problemas
errors_foundestá vazio mesmo com minha fórmula quebrada — o recálculo provavelmente não foi executado. Verifique o campomessage: 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, masrecalculatedseráfalseemessagediz que o recálculo expirou. LockTimeoutErrorem acesso concorrente — outra operação está segurando o bloqueio. AumenteXLSX_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.
pathobrigatório / nenhum arquivo configurado — você chamou uma ferramenta sempathmas nenhum (ou múltiplos) arquivo(s) está(ão) pré-carregado(s). Pré-carregue um arquivo viaXLSX_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