Home · Guides

Ask questions about an Excel or CSV file from Cursor or Claude

The usual way an assistant reads a spreadsheet is to write a throwaway pandas script, run it, and read the output. That works until the file has a title row above the headers, or prices stored as text, or 40,000 rows you do not want printed into the context window. The MCP Spreadsheet server gives the model four purpose-built tools instead: describe the file, query it, add a computed column, convert it. It opens xlsx, xlsm, xlsb, ods, csv and tsv.

Install

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

Cursor, in ~/.cursor/mcp.json:

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

Start with sheet_info

"Open sales.xlsx and tell me what is in it" runs sheet_info: sheet names, row and column counts, the guessed header row, a type per column, sample values and empty counts. This is the step that handles the export nobody designed for a machine. In the audit the test file carried a title line and a blank line above the real headers; sheet_info reported headerRow=2, three sheets and 400 rows, with correct types and ranges. Delimiters in csv files are sniffed rather than assumed, so a semicolon-separated European export opens without an argument.

Query with a filter and a group by

"Which rep sold the most units in the North region? Top 5 with totals" is one call:

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

The where string is a small safe expression language, not eval: comparisons = != > >= < <=, plus contains, startswith and endswith, combined with AND, OR, NOT and parentheses. Column names with spaces go in brackets. Aggregate functions are sum, count, avg, min and max, and sort can name an aggregate alias. Numbers written as text, such as "$1,250.00", are read as numbers. Grouping was added after the audit measured the same ranking taking five tool calls and 71 seconds, because the model had to fall back to python; it is now one call.

Add a column, convert the file

"Add a Revenue column that is Units times Unit Price and save it as CSV next to the original" runs sheet_add_column with the formula [Units] * [Unit Price]. The source file is never overwritten unless you pass an output path that points at it. sheet_convert moves between csv, xlsx and json the same way. sheet_stats gives count, empties, distinct, min, max, sum, mean and median per column, and sheet_find searches every cell and returns cell addresses with a preview of the row.

The free write cap refuses rather than truncating

The audit caught a bad failure here and it was fixed. Adding a column to a 400 row sheet on the free tier used to write 200 rows and report success, leaving a file that looked complete and was not. The write cap now refuses: nothing is written, the tool tells you the row count and the cap, and it suggests a way through on the free tier, such as filtering with sheet_query first and writing only the rows you need. A partial file that looks whole is worse than no file.

Limits

Free reads files up to 5 MB and 5,000 rows, with every tool available, and writes up to 500 rows per file. Over a read limit the tool still returns the first 5,000 rows with a note saying what was left out. Pro ($19 once) removes both, up to a 50 MB file ceiling. See MCP Spreadsheet and free versus Pro.

Questions

Does it handle a spreadsheet with a title row above the headers?

Yes. sheet_info guesses the header row and reports which row it picked, so an export with a title line and a blank line above the real headers opens correctly without you specifying anything.

Can it group and sum, or does it only filter?

It groups. sheet_query takes group_by plus aggregate with sum, count, avg, min or max, and can sort by an aggregate alias, so top-N-by-category questions are a single call.

Will it overwrite my original file?

No, not unless you explicitly pass an output path that points at the source. sheet_add_column and sheet_convert write a new file next to the original by default.

What happens on the free tier with a file bigger than the limit?

Reads return the first 5,000 rows with a note naming what was omitted. Writes over 500 rows are refused outright rather than producing a truncated file, and the message tells you the row count, the cap and a free way round.

Is my data sent anywhere?

No. The server runs locally on your machine and reads your files directly. It makes no network requests, and it stores nothing of its own beyond the files you ask it to write.

Related

All MCP servers and prices · All guides