Letting an AI Assistant Read Your Excel Files Without Uploading Them (MCP)
Ask an AI assistant about a spreadsheet and the usual route is to upload it or paste it in. Both work, sort of. Uploading sends the whole file to a service. Pasting turns a grid into a wall of tab-separated text: merged header cells collapse, sheet names disappear, and dates often arrive as numbers like 45292 that the model has to guess are dates.
There's a third route. With the Model Context Protocol (MCP), the assistant calls tools that run on your own PC and asks for exactly the part of the workbook it needs. This post covers how that works with LocalSynapse's spreadsheet tool, what comes back, and — plainly — what stays private and what doesn't.
Why pasted spreadsheets go wrong
A spreadsheet carries meaning in its structure, not just its values:
- Coordinates. "The value in C14 on the Q3 sheet" is a precise reference. A pasted block loses it.
- Merged cells. A header spanning B1:E1 says "these four columns belong together". Pasted, it becomes one value followed by blanks.
- Types. Excel stores dates and currency as plain numbers and relies on formatting to display them. Without the format,
45292is just a number, and a model that guesses wrong is confidently wrong.
The model is good at reasoning over a table. It's bad at reconstructing one from a lossy copy.
How it works with MCP
LocalSynapse indexes the documents on your PC, including .xlsx workbooks, and runs an MCP server that assistants such as Claude Desktop can connect to. For spreadsheets, three tools matter:
search_filesfinds documents by what's written in them — "the vendor pricing workbook" — and returns file ids.list_indexed_fileslists what's indexed, filterable by folder and by extension, e.g..xlsx.get_spreadsheettakes a file id and returns the workbook's structure. OptionalsheetIndex(0-based) limits it to one sheet; optionalcellRangesuch asA1:Z100limits it to a block of cells.
A typical exchange: you ask "what did we budget for travel in Q3?", the assistant searches, finds the budget workbook, reads the relevant sheet with get_spreadsheet, and answers citing the cells it used.
What comes back
The response is the grid as it's stored. An illustrative, shortened example:
{
"fileId": "...",
"schemaVersion": 1,
"sheets": [
{
"index": 0,
"name": "Q3",
"cells": [
{ "coord": "A1", "type": "string", "value": "Travel budget" },
{ "coord": "A3", "type": "string", "value": "Month" },
{ "coord": "B3", "type": "string", "value": "Amount" },
{ "coord": "A4", "type": "date", "value": "2024-07-01" },
{ "coord": "B4", "type": "number", "value": 1250.5 }
],
"mergedRanges": [ { "start": "A1", "end": "B1" } ],
"truncated": false
}
]
}
What to notice:
- Every cell has its coordinate, so the assistant can cite exactly where a figure came from — and you can check it.
- Types follow what the workbook declares. A cell with a standard date format comes back as an ISO date (with a time if it has one), while some custom or locale-specific date formats come back as the raw serial number. Workbooks that use the 1904 date system (an option mostly seen in older Mac files) are not yet handled; their dates come back shifted by about four years. Numbers stay numbers, booleans stay booleans, and Excel errors are marked as errors.
- Empty cells are left out. A gap in the coordinates means the cell was empty.
- Formula cells return the value Excel last saved, not the formula.
- Merged ranges are listed separately, so headers that span columns stay recognisable.
What it deliberately doesn't do
get_spreadsheet doesn't decide which row is the header, what a column means, or which number is "the total". Those are judgements, and a tool that guesses them wrong hands the assistant a confident mistake. The tool supplies the grid as stored; your assistant does the interpreting, and you can see from the coordinates what it based its answer on.
Limits worth knowing
- .xlsx only for the structured view, up to 25 MB per workbook. CSV and .ods files are searchable and readable as text through
get_file_content, but don't get cell coordinates. Legacy .xls is not supported. - Very large sheets are capped. The structured view keeps up to 50,000 non-empty cells per sheet, and a single response returns at most 50,000 cells. When a cap is hit,
truncatedistrue— narrow the request withcellRangeto stay under the per-response cap. Cells beyond the per-sheet cap were not stored, socellRangecannot reach them. - The workbook has to be indexed first. If a search comes back empty, the assistant can call
get_pipeline_statusto see whether indexing has caught up.
What stays private — and what doesn't
This part matters more than anything above, so it's stated plainly.
LocalSynapse itself doesn't upload your files. Indexing and search run on your PC, and the MCP server runs on your PC as a process your assistant starts. LocalSynapse sends anonymous product-usage counts and technical health metrics only, and you can turn that off in the app.
But the cells your assistant reads become part of your conversation. If you use a cloud assistant such as Claude Desktop, whatever a tool returns is sent to the assistant's provider along with your messages — the same as if you had pasted it. MCP doesn't change that; what it changes is how much leaves. Instead of the whole workbook, the assistant fetches the sheet and range the question needs. Asking it to use sheetIndex and cellRange keeps it that way.
Setting it up
- Install LocalSynapse and let it index the folders that hold your spreadsheets.
- Open the app's MCP page and use the Claude Desktop register button. It adds a
localsynapseentry to Claude Desktop's config file (%APPDATA%\Claude\claude_desktop_config.json) that starts LocalSynapse with the argumentmcp. - Restart Claude Desktop so it picks up the new server.
Other MCP clients work the same way: point them at the LocalSynapse executable with the argument mcp. Our MCP file search guide covers the general setup, and Claude Desktop alone vs with local search shows the difference in practice.