Skip to main content

excel-mcp

Python MCP License

Let your AI agent read real, messy Excel files. An MCP server that handles the things LLMs choke on: multiple sheets, title rows sitting above the actual table, and merged cells.

If you paste a spreadsheet into a prompt, the model has to guess where the data starts and what the merged cells mean, and it often gets it wrong. This reads the file properly with deterministic code, so the values are exact and the model never invents cell contents.

The problem it solves

A real spreadsheet almost never starts cleanly at cell A1:

A1:  Quarterly Sales Report 2024      <- title, not data
A2:  Generated by finance             <- note, not data
A3:  (blank)
A4:  Region | Product | Units         <- the actual header
A5:  North  | Widget  | 120
...

Ask an LLM to read that and it'll often treat the title as a column. read_table auto-detects that the header is on row 4 and returns clean records. Merged cells (a value spanning several rows) get forward-filled, so rows don't lose their category.

The tools it gives an agent

Tool What it does
list_sheets(path) Every sheet in the workbook, with its size
preview_sheet(path, sheet, rows) Top rows as a grid, so the agent can see the layout
read_table(path, sheet) The actual data table as records. Reports the decisions that could be wrong: header_source (explicit / auto-detected), header_confidence, and forward_filled_columns (values inferred from merged cells, not read)
sheet_to_csv(path, sheet) The table as clean CSV text

Getting started (Claude Desktop)

The fastest way to use this is with an MCP client like Claude Desktop. Three steps:

1. Install it

pip install "excel-agent-mcp[mcp]"

2. Add it to your client's config

Claude Desktop's config lives here:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the server:

{
  "mcpServers": {
    "excel": { "command": "excel-agent-mcp" }
  }
}

3. Restart Claude Desktop. You'll see a tools icon appear, meaning the server is connected.

That's it. Now ask about any .xlsx file on your machine:

You:  What's in /Users/me/reports/sales.xlsx?

Agent (calls list_sheets, then read_table):
  The workbook has one sheet, "Q1". The table starts on row 4 (the rows above
  are a title). 3 rows: North/Widget/2400, South/Widget/3000, South/Gadget/2400.
  Total revenue 7800.

The agent reads the real file instead of guessing, so the numbers are exact.

Restricting file access: to stop the agent reading anything outside one folder, set EXCEL_MCP_ALLOWED_DIR. See SECURITY.md.

Use it with other MCP clients

The same server works in any MCP client, only the config differs. Use excel-agent-mcp as the command.

Cursor~/.cursor/mcp.json (global) or .cursor/mcp.json (per project). Same shape as Claude Desktop, and it hot-reloads (no restart):

{ "mcpServers": { "excel": { "command": "excel-agent-mcp" } } }

VS Code / GitHub Copilot.vscode/mcp.json. Note the different key (servers, not mcpServers) and the required type. Tools only run in Copilot Agent mode:

{ "servers": { "excel": { "type": "stdio", "command": "excel-agent-mcp" } } }

Windsurf~/.codeium/windsurf/mcp_config.json (create it if missing). Same shape as Claude Desktop:

{ "mcpServers": { "excel": { "command": "excel-agent-mcp" } } }

Cline — add it from the extension's MCP settings panel in VS Code (command: excel-agent-mcp).

Understanding the output

read_table doesn't just return the data, it tells you how confident it is, so you can trust a clean parse and double-check a guess:

{
  "columns": ["Region", "Product", "Revenue"],
  "rows": [ ... ],
  "header_row": 3,
  "header_source": "auto-detected",
  "header_confidence": 0.42,
  "forward_filled_columns": ["Region"]
}
  • header_source"explicit" if you told it which row is the header, "auto-detected" if it guessed.
  • header_confidence0..1 for an auto-detected header. A low value means it was a close call; if the result looks off, pass an explicit header_row.
  • looks_clean + table_warnings — a verdict on the table as a whole (flags low header confidence, unnamed columns, mostly-empty tables), separate from the per-column signals below.
  • forward_filled_columns — columns whose values came from a merged cell. Those values are inferred (copied down to fill the block), not read cell-by-cell, so treat them accordingly.

The idea: surface the decisions that could be wrong, instead of handing back tidy-looking output that hides a guess.

Also usable from plain Python

from excel_mcp import reader

reader.list_sheets("report.xlsx")
reader.read_table("report.xlsx", "Sales")     # {'columns': [...], 'header_source': ..., ...}
reader.sheet_to_csv("report.xlsx", "Sales")

Tests

python -m unittest discover -s tests     # builds its own messy xlsx, runs anywhere

License

MIT

Release files for excel-agent-mcp 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for excel-agent-mcp 0.1.3
File Size Uploaded
excel_agent_mcp-0.1.3.tar.gz 9.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for excel-agent-mcp 0.1.3
File Interpreter ABI Platform
excel_agent_mcp-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 18.9 kB

Release files / excel_agent_mcp-0.1.3.tar.gz

Download URL excel_agent_mcp-0.1.3.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
540ac58aa17996f2448b7c0c0320756e6d2a57ce3cfeaabc7c2ef862d6412c94
BLAKE2b-256 checksum
How to use checksums
4008e6d04ff7ed55141a41829d82e5b73c04fe4ae3a6295eec7ef5dffbae7780
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / excel_agent_mcp-0.1.3-py3-none-any.whl

Download URL excel_agent_mcp-0.1.3-py3-none-any.whl
Size 9.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
507d90aa59c484cf90540b7cefe0d9d15409bedcc764b9b7c45232ed4e2652d0
BLAKE2b-256 checksum
How to use checksums
21ce4b1951dfb9c3f7c4c22763bc550807a42c91ff00449eced5a9efdcd58bbd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page