MCP server that exposes Excel files as SQL-queryable tables via DuckDB
Project description
mcp-server-excel-sql
MCP server exposing Excel files as SQL-queryable DuckDB views.
Features
- SQL queries on Excel via DuckDB in-memory views
- RAW (all_varchar) or ASSISTED (sheet_overrides) modes
- Multi-row headers, type hints, unpivot, column renames
- Auto-refresh on file changes (--watch)
- Thread-safe timeout enforcement via conn.interrupt()
Installation
pipx install mcp-server-excel-sql
Usage
mcp-excel --path /data/excel --watch --overrides config.yaml
MCP Tools
tool_load_dir - Load Excel directory into views tool_query - Execute SELECT (read-only, timeout/limit enforced) tool_list_tables - List views with metadata tool_get_schema - DESCRIBE table tool_refresh - Rescan filesystem (incremental or full)
Table Naming
Format: <alias>.<filepath>.<sheet> (dot-separated, lowercase, sanitized)
Sanitization:
- Spaces →
_ - Special chars → removed
- Allowed:
[a-z0-9_$]
Alias: Auto-generated from directory name
Examples:
/data/sales/Q1-2024.xlsx → "sales.q12024.summary"
/reports/P&L (Final).xlsx → "reports.plfinal.sheet1"
IMPORTANT: Dots require quoted identifiers in SQL:
SELECT * FROM "sales.q12024.summary" -- correct
SELECT * FROM sales.q12024.summary -- fails (Catalog Error)
System Views
<alias>.__files - File metadata (path, sheet_count, total_rows, mtime)
<alias>.__tables - Table metadata (table_name, file, sheet, mode, est_rows)
Query: SELECT * FROM "sales.__files"
Modes
RAW: read_xlsx(..., all_varchar=true, header=false)
ASSISTED: Apply per-sheet overrides
sales.xlsx:
sheet_overrides:
Summary:
skip_rows: 3
skip_footer: 2
header_rows: 2
drop_regex: "^Total:"
column_renames:
"col_0": "region"
type_hints:
amount: "DECIMAL(10,2)"
date: "DATE"
unpivot:
id_vars: ["Region"]
value_vars: ["Jan", "Feb"]
var_name: "Month"
value_name: "Sales"
Security
- Read-only: BEGIN TRANSACTION READ ONLY (DuckDB-enforced, blocks all write operations)
- Path-confined: Root path validation, no traversal
- Timeout: threading.Timer → conn.interrupt()
- Row limit: fetchmany(max_rows + 1)
Development
pip install -e ".[dev]"
pytest --cov=mcp_excel tests/
python -m build
Coverage: 78% (567 statements, 126 missed) Tests: 53 passing
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_server_excel_sql-0.1.1.tar.gz.
File metadata
- Download URL: mcp_server_excel_sql-0.1.1.tar.gz
- Upload date:
- Size: 37.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a55f223728036e1f94f6b3db5d604bfa8072c7291aaa13f28ea7e7444f0621e6
|
|
| MD5 |
7f02590e07c6975baece0c0627fcc684
|
|
| BLAKE2b-256 |
2c64a9caea799bebff9fb67d38d1adb5e19549e06b2dd80f9ace347560a733e4
|
File details
Details for the file mcp_server_excel_sql-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mcp_server_excel_sql-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3dfabf06e5ef6023d5c28d4bb1c36643809ddc131fadfeaac785c8afab273589
|
|
| MD5 |
21ad2bdb5b737eb1ea5045f44cc51e8d
|
|
| BLAKE2b-256 |
1038e763da056c006c0122ba627ba2a585aabdc3a79b09cf416138716e1f64ee
|