MCP Spreadsheet
Lee, consulta, edita y convierte archivos xlsx y csv de forma segura.
Documentación
mcp-spreadsheet
Entrégale una hoja de cálculo a tu asistente de IA y habla con ella. Apúntala a cualquier archivo .xlsx, .xlsm, .xlsb, .xls, .ods, .csv o .tsv en tu máquina y pregúntale qué contiene, fíltralo, calcula una nueva columna o guárdalo en otro formato. Se encarga de las partes complicadas de los archivos reales por ti: adivina qué fila contiene los encabezados, detecta si un CSV está separado por comas, punto y coma o tabulaciones, mantiene intactas las comas y saltos de línea entre comillas, lee números de texto con formato $1,250.00 e informa los tipos por columna y los recuentos de celdas vacías. Nunca edita tu archivo original: cada escritura va a una nueva ruta a menos que elijas explícitamente overwrite. Nada sale de la máquina y no hay ninguna clave de API que obtener.

Lee, consulta y amplía hojas de cálculo reales desde el chat sin tocar nunca el archivo original.
Instalación en 60 segundos
La publicación en npm para @theluckystrike/mcp-spreadsheet está pendiente. Hasta entonces, el paquete de un clic .mcpb o un clon + compilación
es la vía funcional: ambos están verificados a continuación.
Un clic (.mcpb): descarga spreadsheet.mcpb de la última versión y haz doble clic en Claude Desktop:
https://github.com/theluckystrike/mcp-servers/releases/latest
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"spreadsheet": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-spreadsheet"]
}
}
}
Claude Code:
claude mcp add spreadsheet -- npx -y @theluckystrike/mcp-spreadsheet
Cursor (.cursor/mcp.json):
{
"mcpServers": {
"spreadsheet": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-spreadsheet"]
}
}
}
El formulario npx anterior empieza a funcionar en cuanto se publique el paquete. Hasta entonces, usa el paquete .mcpb de arriba, o
compila desde el código fuente con exactamente estos tres comandos:
git clone https://github.com/theluckystrike/mcp-servers.git && cd mcp-servers
npm install
npm run build -w packages/mcp-license -w servers/spreadsheet
Luego apunta el command de tu cliente a node con un argumento: la ruta absoluta a servers/spreadsheet/dist/index.js.
Para ejecutar en modo Pro, establece MCP_LICENSE_KEY en el mismo bloque de configuración, o llama a license_activate una vez con tu clave.
Herramientas
| Herramienta | Qué hace |
|---|---|
sheet_info | Nombres de hojas, tamaño, fila de encabezado adivinada, tipo por columna, valores de muestra, recuentos de vacíos |
sheet_read | Lee filas como tabla de texto, registros JSON o CSV; paginación limit/offset o un range A1 |
sheet_query | Filtra con where, group_by + aggregate (suma, recuento, promedio, mínimo, máximo), selecciona columnas con select, sort (también alias de agregación), limit |
sheet_stats | recuento, vacío, distintos, mínimo, máximo, suma, media, mediana por columna (valores principales para columnas de texto) |
sheet_find | Busca texto en cualquier parte del libro; devuelve direcciones de celda y una vista previa de la fila |
sheet_write | Escribe filas (objetos o matrices) como archivo nuevo, una adición o una sobrescritura explícita |
sheet_add_column | Añade una columna calculada a partir de una fórmula, guardada en un archivo nuevo. Los resultados numéricos se redondean como sus entradas (2 decimales de entrada, 2 decimales de salida); decimals lo anula |
sheet_convert | Convierte una hoja a csv, xlsx o json |
license_status | Gratis o Pro, y dónde actualizar |
license_activate | Activa una clave Pro (verificada sin conexión) |
Plantilla de recurso: sheet://<path> devuelve el resumen sheet_info para ese archivo.
Recurso: sheet://recent enumera los archivos que este servidor ha abierto desde que se inició, los más recientes primero (solo en memoria: no se escribe nada en el disco, por lo que la lista vuelve a estar vacía después de un reinicio).
Indicación: explore_sheet recorre un archivo desconocido: sheet_info primero, luego llamadas sheet_query concretas construidas a partir de las columnas que realmente encontró.
Lo que puedes decir
| Tú dices | Herramienta |
|---|---|
| "Abre sales.xlsx y dime qué contiene." | sheet_info |
| "Muéstrame las primeras 50 filas." | sheet_read |
| "¿Qué representante vendió más unidades en la región Norte? Top 5 con totales." | sheet_query (group_by + aggregate) |
| "¿Cuántas celdas vacías hay en la columna Email y cuál es el tamaño de pedido mediano?" | sheet_stats |
| "Encuentra todas las filas que mencionen 'reembolso'." | sheet_find |
| "Escribe esto como una hoja nueva llamada Resultados Q3." | sheet_write |
| "Añade una columna Ingresos que sea Unidades por Precio Unitario, guárdala como CSV junto al original." | sheet_add_column |
| "Convierte este xlsx a JSON." | sheet_convert |
| "¿Estoy en el plan gratuito o en Pro?" | license_status |
| "Aquí está mi clave de licencia, actívala." | license_activate |
Ejemplo práctico
Desde docs/USER_VALUE_R2.md, un archivo de prueba de 400 filas con una fila de título y una fila en blanco encima del encabezado real
(fila 3), hojas Sales / Reps / Notes, precios almacenados como cadenas como "1,516.16". Una llamada, verdad
terreno confirmada contra el generador: Turing 650, Hopper 567, Linus T 551, Lovelace 486, Liskov 290.
You: Which rep sold the most units in the North region? Top 5 with totals.
sheet_query {
path: "/Users/you/sales.xlsx", sheet: "Sales",
where: "[Region] = \"North\"",
group_by: ["Rep"],
aggregate: [{ col: "Units", fn: "sum", as: "total_units" }],
sort: { col: "total_units", dir: "desc" },
limit: 5
}
Assistant: Query: where [Region] = "North"; group by Rep; sum Units as total_units;
sort total_units desc; limit 5
5 groups from 102 of 400 rows, showing 5
Alan Turing 650
Grace Hopper 567
Linus T 551
Ada Lovelace 486
Barbara Liskov 290
La respuesta ahora repite la consulta exacta que ejecutó (la línea Query:) antes de los números, de modo que un filtro que
no pediste (un AND [Status] = "Closed" accidental, por ejemplo) es visible en lugar de reducir
silenciosamente la respuesta.
Un segundo ejemplo, añadiendo una columna y guardando sin tocar la fuente:
You: Add a Revenue column and save it as a CSV next to the original.
sheet_add_column {
path: "/Users/you/sales.xlsx", sheet: "Sales",
name: "Revenue", formula: "[Units] * [Unit Price]",
out_path: "/Users/you/sales.csv"
}
Assistant: Wrote 400 rows (401 lines with header) to sales.csv.
Revenue = Units * Unit Price on every row, total 10,142,542.04.
Source file untouched.
El lenguaje where y formula
Un pequeño lenguaje de expresiones, analizado y evaluado directamente. No hay eval ni ejecución de código: una palabra suelta siempre es un nombre de columna, nunca un valor de JavaScript.
- Columnas:
[Unit Price]para nombres con espacios,Qtyen caso contrario. La búsqueda no distingue mayúsculas. - Comparaciones:
=!=>>=<<=containsstartswithendswith - Lógica:
ANDORNOTy paréntesis.ANDse une con más fuerza queOR. - Aritmética en fórmulas:
+-*%/con la precedencia habitual. - Cadenas: comillas
'single'o"double"; duplica una comilla para escaparla.
[Qty] >= 5 AND ([Status] = "open" OR [Region] contains "north")
[Amount] > 1000 AND NOT [Customer] startswith 'Test'
Ejemplo de fórmula para sheet_add_column: [Qty] * [Unit Price]. Cuando cada columna que la fórmula lee tiene como máximo 2 decimales, el resultado se redondea a 2 decimales, de modo que [Amount] * 1.23 sobre dinero da 40.79 en lugar de 40.7868. Pasa decimals (0-10) para elegir la precisión tú mismo.
Los números escritos como texto en un CSV se convierten por patrón, no por longitud: 1250.00, 12.00 y 1,250.00 se convierten todos en números en la salida xlsx, de modo que el propio SUM de Excel los cuenta. Los valores con forma de identificador y los ambiguos permanecen como texto: 007 conserva sus ceros iniciales y 1.250,00 se deja como está en lugar de adivinarse.
Las comparaciones de texto ignoran mayúsculas y espacios circundantes. Valores como $1,250.00, 1 250 y 12% se comparan como números, de modo que [Amount] > 1000 funciona en una columna que tu hoja de cálculo almacenó como texto.
Gratis vs Pro
| Gratis | Pro | |
|---|---|---|
Cada herramienta que lee un archivo (sheet_info, sheet_read, sheet_query, sheet_stats, sheet_find, sheet_add_column, sheet_convert) | Archivos de hasta 5 MB y 5,000 filas | Sin límite (hasta el tope de archivo de 50 MB) |
sheet_write, sheet_add_column, sheet_convert | Hasta 500 filas escritas por archivo; por encima de eso no se escribe nada y la herramienta lo dice | Sin límite |
| Hojas, formatos, lenguaje de expresiones | Todo | Todo |
Por encima de un límite de lectura gratuito, la herramienta aún hace el trabajo y devuelve la parte que se le permite devolver (las primeras 5,000 filas), con una nota que dice lo que se omitió. Por encima del límite de escritura gratuito no se escribe nada en absoluto: un archivo parcial que parece completo es peor que ningún archivo, por lo que la herramienta se niega, te dice el recuento de filas y el tope, y sugiere una solución gratuita (filtra las filas primero o escribe en lotes de 500 filas). Nada falla en silencio.
Obtén Pro
$19 de pago único para este servidor, $39 para cada servidor, de por vida: https://mcp.zovo.one/buy/spreadsheet
Cómo almacena datos
Este servidor no mantiene ninguna base de datos propia: lee y escribe los archivos de hoja de cálculo a los que lo apuntas,
directamente en tu disco, y nada más. Cada escritura (sheet_write, sheet_add_column, sheet_convert
en modo overwrite) va primero a un archivo temporal en el mismo directorio y luego se renombra en su lugar, de modo que
una escritura interrumpida deja el original intacto o el archivo nuevo completo, nunca uno truncado.
Como no hay archivo de estado compartido, no hay bloqueo de asesoramiento que tomar: dos llamadas que escriben en dos rutas de salida
diferentes no pueden colisionar, y una llamada a overwrite el mismo archivo dos veces seguidas es simplemente
dos escrituras en secuencia. Para respaldar tus datos, respalda los propios archivos de hoja de cálculo: no hay
nada más que copiar.
Límites y advertencias honestas
- Las lecturas gratuitas tienen un tope de 5,000 filas y 5 MB; las escrituras gratuitas tienen un tope de 500 filas por archivo y se niegan en lugar de truncar: recibes un error que nombra el recuento de filas y el tope, nunca un archivo más corto que parezca completo.
- El tope duro es de 50 MB independientemente del nivel; un archivo que supere eso se rechaza directamente con un mensaje claro en lugar de arriesgar el agotamiento de memoria.
- El lenguaje
where/formulaes intencionalmente pequeño: sin expresiones regulares, sin funciones personalizadas, sin referencias entre hojas en una sola fórmula. Cubre comparaciones, lógica booleana y aritmética, nada más. - Escribir un xlsx reemplaza una hoja, no el libro.
sheet_writeconappendooverwritelee todo el libro, intercambia la hoja que nombraste y escribe todas las demás hojas de vuelta, de modo queSheet2y sus datos sobreviven a una adición aSheet1. Lo que no se conserva es la hoja que se está escribiendo: se reconstruye a partir de valores, por lo que fórmulas, formato de celdas, formato condicional, gráficos, validación de datos y celdas combinadas en esa única hoja se convierten en valores simples. Las otras hojas conservan sus celdas tal como se leyeron. Haz una copia primero si la hoja de destino tiene formato que no puedas recrear. - Los números escritos como texto se leen con reglas sensibles a la configuración regional.
1,250.00,1 250.00,$1,250.00,12,99,1.234,56yEUR 1 250,00se leen todos como números; una coma decimal solo se acepta en la forma inequívoca (una coma con exactamente dos dígitos al final, puntos o espacios agrupando). Cualquier cosa que mezcle separadores de otra manera (1,2500.00) permanece como texto en lugar de adivinarse. Valores con ceros iniciales (007) y enteros demasiado grandes para aritmética exacta (más de 9,007,199,254,740,991) permanecen como texto para que nunca se alteren silenciosamente. - Las fechas conservan su tipo de celda. Una celda de fecha leída de un xlsx sigue siendo una fecha a través de consultas y
a través de una conversión de vuelta a xlsx. En salida de texto, CSV y JSON se representa como ISO:
2026-09-04para una fecha,2026-09-03T15:30:00cuando la celda lleva una hora. - La suposición de fila de encabezado de
sheet_infoes una heurística (busca la primera fila con menor vacío y mayor densidad de texto que las filas de arriba). Maneja una fila de título y una fila en blanco encima del encabezado; no es a prueba de todos los diseños, y siempre puedes confirmar lo que eligió antes de consultar.
Solución de problemas
npxse cuelga o no encuentra el paquete: la publicación npm de este paquete está pendiente. Usa el paquete.mcpbo la ruta de clonar y compilar indicada arriba hasta que esté disponible.- Usando el paquete
.mcpb: se instala directamente en Claude Desktop; no hay un paso de configuración separado. - Usando la ruta de clonación: el binario del servidor es
servers/spreadsheet/dist/index.jsdespués denpm run build. Apunta elcommandde tu cliente anodecon esa ruta absoluta como único argumento. - Versión de Node: requiere Node >= 18. Verifica con
node -v. - "La ruta no existe": el mensaje incluye la ruta absoluta resuelta (con
~expandido) -- compruébala contra dónde está realmente el archivo, especialmente dentro de un cliente en sandbox o contenedor. - Una escritura se rechaza con un mensaje de recuento de filas: alcanzaste el límite gratuito de escritura de 500 filas. Filtra los datos
con
sheet_queryprimero, escribe en lotes o activa Pro. - No aparece nada / fallos silenciosos: los registros van solo a stderr, nunca a stdout. En Claude Desktop revisa
Configuración -> Desarrollador -> el archivo de registro del servidor; en Claude Code revisa la terminal o
--mcp-debug.
Seguridad
- Las rutas que no existen se rechazan con la ruta resuelta en el mensaje;
~se expande. - Los archivos de más de 50 MB se rechazan con un mensaje claro en lugar de agotar la memoria.
sheet_add_columnysheet_convertescriben en un archivo nuevo y se niegan a sobrescribir uno existente a menos que pasesout_pathtú mismo.sheet_writeconmode: "new_file"se niega a sobrescribir un archivo existente. Solomode: "overwrite"reemplaza el contenido de un archivo.- Los archivos de salida se escriben con un nombre temporal y se renombran en su lugar, por lo que una escritura interrumpida no puede truncar un archivo.
Privacidad
Todos los datos permanecen locales. Los archivos se leen y escriben en tu propio disco, las claves de licencia se verifican sin conexión con una clave pública integrada, y el servidor no realiza ninguna solicitud de red.
Se combina con
- mcp-time-tracker -- exporta un CSV con
export_csv, luego consúltalo y dale forma aquí. - mcp-invoice -- extrae líneas de artículos de una hoja de cálculo antes de convertirlas en una factura.
- mcp-price-tracker -- analiza el historial de precios exportado como una hoja.
- office-suite -- los cuatro servidores en una sola instalación, una entrada de configuración.
- Guía: Haz preguntas sobre un archivo Excel o CSV desde Cursor o Claude
Preguntas frecuentes
¿Maneja una hoja de cálculo con una fila de título encima de los encabezados?
Sí. sheet_info adivina la fila de encabezados e informa qué fila eligió, por lo que una exportación con una línea de título
y una línea en blanco encima de los encabezados reales se abre correctamente sin que especifiques nada.
¿Puede agrupar y sumar, o solo filtrar?
Agrupa. sheet_query toma group_by más aggregate con suma, conteo, promedio, mínimo o máximo, y puede ordenar
por un alias agregado, por lo que las preguntas de top-N-por-categoría son una sola llamada.
¿Sobrescribirá mi archivo original?
No, a menos que pases explícitamente una ruta de salida que apunte al origen. sheet_add_column y
sheet_convert escriben un archivo nuevo junto al original por defecto.
¿Qué sucede en el plan gratuito con un archivo más grande que el límite? Las lecturas devuelven las primeras 5,000 filas con una nota que indica lo que se omitió. Las escrituras de más de 500 filas se rechazan directamente en lugar de producir un archivo truncado, y el mensaje te indica el recuento de filas, el límite y una forma gratuita de evitarlo.
¿Se envía mi dato a algún lugar? No. El servidor se ejecuta localmente en tu máquina y lee tus archivos directamente. No realiza solicitudes de red, y no almacena nada propio más allá de los archivos que le pides que escriba.
Creado por theluckystrike. Soporte: support@zovo.one