excel-mcp-polars
An MCP server that lets LLMs inspect, query, and transform tabular files using Polars — the fast, Arrow-native DataFrame library.
Supports Excel (.xlsx, .xlsm, .xlsb, .xls), CSV, TSV, and Parquet files.
Quick start
With uvx (no install needed)
The fastest way — uvx downloads and runs the package on demand:
{
"mcpServers": {
"excel": {
"command": "uvx",
"args": ["excel-mcp-polars"]
}
}
}
With pip
pip install excel-mcp-polars
Then use excel-mcp as the command in your client config (see setup sections below).
Client setup
Claude Desktop
Edit the config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
With uvx (no prior install needed):
{
"mcpServers": {
"excel": {
"command": "uvx",
"args": ["excel-mcp-polars"]
}
}
}
With pip install excel-mcp-polars:
{
"mcpServers": {
"excel": {
"type": "stdio",
"command": "excel-mcp"
}
}
}
Restart Claude Desktop. You can now ask:
"Load sales.xlsx, filter to Q4, group by region, and show me total revenue."
Claude Code (CLI)
claude mcp add excel-mcp -- uvx excel-mcp-polars
GitHub Copilot / VS Code
Option A — Workspace config (.vscode/mcp.json, committed to the repo):
{
"servers": {
"excel": {
"type": "stdio",
"command": "uvx",
"args": ["excel-mcp-polars"]
}
}
}
Option B — User settings (settings.json):
{
"mcp.servers": {
"excel": {
"type": "stdio",
"command": "uvx",
"args": ["excel-mcp-polars"]
}
}
}
After saving, run MCP: Start Server from the VS Code command palette.
Note on
pip install: If you installed viapipinstead ofuvx, replace"uvx"/"args": ["excel-mcp"]with the full path to the binary (e.g./usr/local/bin/excel-mcp). Claude Desktop and VS Code launch the subprocess in a minimal environment and may not inherit your shell'sPATH. Runwhich excel-mcpto find the path.
Security: restricting file access
By default the server can access any file path and prints a warning at startup. To restrict it to specific directories, set the EXCEL_MCP_ALLOWED_DIRS environment variable:
export EXCEL_MCP_ALLOWED_DIRS="/home/alice/reports:/home/alice/exports"
In your MCP client config:
{
"mcpServers": {
"excel": {
"command": "uvx",
"args": ["excel-mcp-polars"],
"env": {
"EXCEL_MCP_ALLOWED_DIRS": "/home/alice/reports:/home/alice/exports"
}
}
}
}
Any attempt to read or write outside the listed directories will be rejected with a PermissionError.
Tools
Inspect
| Tool | Description |
|---|---|
list_sheets |
List all sheets in a workbook with row/column counts |
load_sheet |
Load a sheet into session cache with optional skip_rows for title rows above headers |
peek |
Read the first N raw rows directly from disk (bypasses cache) — use before load_sheet to inspect header layout |
get_schema |
Column names, data types, null counts, and a sample value per column |
describe |
Descriptive statistics (min, max, mean, std, percentiles) for numeric columns |
preview |
First N rows as a markdown table, with optional column filter and row offset |
find_dirty_rows |
Identify rows with nulls, type mismatches, or other data quality issues |
Transform (operations update the session cache)
| Tool | Description |
|---|---|
filter_rows |
Filter rows using a SQL WHERE expression |
select_columns |
Keep and optionally rename a subset of columns |
drop_columns |
Remove specific columns |
sort_data |
Sort by one or more columns, with per-column direction control |
drop_duplicates |
Remove duplicate rows, optionally scoped to a column subset |
cast_columns |
Change column data types (e.g. String → Int64, String → Date) |
fill_nulls |
Fill null values using a strategy (forward, mean, median, …) or a literal value |
add_column |
Add a computed column using a SQL expression (e.g. "Revenue * 0.1") |
reset_sheet |
Reload the original file from disk, discarding all in-session transformations |
Aggregate
| Tool | Description |
|---|---|
group_by_aggregate |
Group by columns and compute sum, mean, count, min, max, median, std, first, last, n_unique |
value_counts |
Frequency table for a column, with optional normalization and top-N filter |
sample_rows |
Random sample by row count or fraction |
compute_percentiles |
Compute arbitrary percentiles (e.g. p50, p90, p95, p99) for a column, optionally grouped |
Advanced
| Tool | Description |
|---|---|
join_sheets |
Join two sheets/files on key columns (inner, left, right, full, cross) |
pivot_data |
Pivot: unique values of one column become new column headers |
unpivot_data |
Melt wide-format data into long format |
concat_sheets |
Stack or side-by-side multiple sheets/files (vertical, horizontal, diagonal) |
window_function |
Apply a window/analytic function: rank, cumsum, diff, pct_change, rolling_mean, rolling_sum, … |
run_query |
Run a full SQL SELECT statement via Polars SQLContext (data is the primary table) |
save_sheet |
Write the current in-session state back to disk (Excel or CSV) |
clone_sheet |
Copy a sheet within the session under a new name |
export_data |
Export to csv, xlsx, parquet, or json |
Why stdio (local-only)
excel-mcp-polars runs as a local process on your machine, not as a hosted service. This is intentional.
The tools operate on file paths that point to your filesystem. A remote server would require uploading your files to third-party infrastructure before any query could run — spreadsheets that often contain payroll data, customer records, financial projections, or other sensitive information.
Running locally means:
- Your files never leave your machine
- No account, API key, or internet connection required
- No per-query cost or rate limits
- Works on air-gapped or restricted networks
The tradeoff is that users install the package themselves, but that is a one-time step (pip install excel-mcp-polars or uvx excel-mcp-polars) and is the right default for a tool whose entire job is reading your private data.
Transform and aggregate operations update an in-memory cache for the current server session. This lets you chain operations naturally:
load → filter rows → add column → group by → export
Each tool call operates on the result of the previous one. Call reset_sheet to discard changes and reload from disk.
SQL reference (filter_rows, run_query, add_column)
These tools use Polars SQLContext. Standard SQL syntax is supported:
-- filter_rows expression (no WHERE keyword)
"Country = 'US' AND Revenue > 1000"
"Status IN ('Active', 'Pending')"
"Name LIKE '%Corp%'"
-- run_query (full SELECT)
SELECT Region, SUM(Revenue) AS total
FROM data
GROUP BY Region
ORDER BY total DESC
LIMIT 10
-- add_column expression
"Revenue * 0.1"
"UPPER(Country)"
"Revenue - Cost"
Development
git clone https://github.com/your-org/excel-mcp-polars
cd excel-mcp-polars
pip install -e .
excel-mcp # starts the server on stdio
Test interactively with the MCP Inspector:
npx @modelcontextprotocol/inspector excel-mcp-polars
License
MIT
Metadata
Release files for excel-mcp-polars 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| excel_mcp_polars-0.1.3.tar.gz | 23.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| excel_mcp_polars-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.2 kB
Release files / excel_mcp_polars-0.1.3.tar.gz
| Download URL | excel_mcp_polars-0.1.3.tar.gz |
|---|---|
| Size | 23.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9a0c2b0354178d4d5ecfff8d7f140a642ae04f853fc5b0dee048e96dd162d531
|
|
BLAKE2b-256 checksum How to use checksums |
01ec13c05ae7d1a5312772812122624707e098a26ea4421db5861367c3a2db10
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / excel_mcp_polars-0.1.3-py3-none-any.whl
| Download URL | excel_mcp_polars-0.1.3-py3-none-any.whl |
|---|---|
| Size | 24.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a9a5cf681cf89ab43e69e999cfc44a791bbce8d3b0fdd6924586815cbedf507a
|
|
BLAKE2b-256 checksum How to use checksums |
6eae45fc61c9b9c316c6c39f050b9b36812e570c2015d6b8a37d242b5ae41ea1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|