Skip to main content

search-excel-mcp

Local MCP server that lets any MCP client (Claude Code, Cursor, Claude Desktop, Cline, …) query complex Excel files (heavy merged cells, large size, multi-language text including CJK) via SQL and substring search — no API keys, no embeddings, no GPU.

Built with FastMCP + DuckDB + openpyxl + pyarrow.


Why this exists

Documentation-style Excel files (external design docs, report specs, requirements sheets) typically have thousands of merged cells per sheet, 20–100 MB per file, and multi-language text where most FTS tokenizers fail.

Standard RAG (embeddings + vector store) needs an LLM or embedding model that you can't always run locally. Your MCP client is the reasoning layer; this server just gives it accurate structured access to cells via DuckDB.

Install

pip install search-excel-mcp
# or run without install:
uvx search-excel-mcp

Configure your MCP client

Add to the client's MCP config file. Common locations:

Client Config path
Claude Code ~/.claude/mcp.json (global) or <project>/.mcp.json (project-local)
Cursor ~/.cursor/mcp.json (global) or <project>/.cursor/mcp.json (project-local)
Claude Desktop (macOS) ~/Library/Application Support/Claude/claude_desktop_config.json
Cline / other see your client's docs

Config entry (same JSON shape for all):

{
  "mcpServers": {
    "search-excel": {
      "command": "uvx",
      "args": ["search-excel-mcp"],
      "env": {
        "SEARCH_EXCEL_DATA_DIR": "/absolute/path/to/your/excel/folder"
      }
    }
  }
}

Only SEARCH_EXCEL_DATA_DIR is required. The DuckDB cache is placed under your OS-standard app data folder (e.g. ~/Library/Application Support/search-excel-mcp/data.duckdb on macOS) — override with SEARCH_EXCEL_DB if you want it elsewhere.

Restart your MCP client → the search-excel server appears.

Use

Drop .xlsx files into your data folder, then ask your agent:

"ingest all the files in the data folder" "find rows that mention '保存ボタン' in any file" "list all sheets in report-2024.xlsx" "show me sheet 5"

The agent routes to the right MCP tool. DuckDB is built incrementally — already-ingested files are skipped unless you re-ingest with reset=true.

CLI (optional)

The same package installs CLI tools for batch use:

# Ingest everything under $SEARCH_EXCEL_DATA_DIR
search-excel-ingest

# Ingest a single file or folder
search-excel-ingest --input /path/to/file.xlsx
search-excel-ingest --input /path/to/folder

# Filter / reset
search-excel-ingest --only "report"
search-excel-ingest --reset

# Validate ingest accuracy (samples random cells against the source xlsx)
search-excel-validate --samples 20

Environment variables

Variable Default Purpose
SEARCH_EXCEL_DATA_DIR ./data (cwd-relative) Where your .xlsx files live — set this for MCP usage
SEARCH_EXCEL_DB OS user data dir DuckDB cache file
SEARCH_EXCEL_REPORTS_DIR OS user data dir / reports Ingest/validation log output
SEARCH_EXCEL_WORKERS min(4, cpu_count) Parallel ingest worker count

<OS user data dir> resolves per platform via platformdirs:

  • macOS: ~/Library/Application Support/search-excel-mcp/
  • Linux: ~/.local/share/search-excel-mcp/ (or $XDG_DATA_HOME)
  • Windows: %LOCALAPPDATA%\search-excel-mcp\

MCP tools

Tool Purpose
ingest_file(path, reset?) Ingest a single .xlsx file
ingest_folder(path?, reset?) Ingest every .xlsx under a folder (recursive)
list_files() All ingested files
list_sheets(file?) Sheets, optionally filtered
search_text(keyword, file?, sheet?, limit?) Substring search across cells (CJK-friendly)
search_sheets(keyword, limit?) Which sheets discuss a topic, ranked by hit count
get_sheet_cells(sheet_id, row/col range, ...) Read a slice of a sheet
get_sheet_text(sheet_id, max_chars?) Deduplicated text overview of a sheet
query_sql(sql, limit?) Read-only SELECT against DuckDB
delete_file(file_id) Remove one file's data
clear_db(confirm) Wipe all data (preview unless confirm=true)
db_stats() Counts and overall stats

Accuracy notes

  • No LLM in the pipeline → deterministic.
  • Cell formatting (font color, bold, fill) is not extracted — only text values. Files that mark changes with red font lose that signal here.
  • Read-only MCP for queries; ingest tools mutate DuckDB only.
  • search-excel-validate samples cells from the source xlsx and checks them against the DB.
  • search_text uses ILIKE (substring) instead of DuckDB FTS so CJK works reliably.

License

MIT

Metadata

Release files for search-excel-mcp 0.1.0

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

Source distribution (sdist)

Source distribution for search-excel-mcp 0.1.0
File Size Uploaded Provenance
search_excel_mcp-0.1.0.tar.gz 14.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for search-excel-mcp 0.1.0
File Interpreter ABI Platform
search_excel_mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 33.8 kB

Release files / search_excel_mcp-0.1.0.tar.gz

Download URL search_excel_mcp-0.1.0.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2a9f35d4b0c3a45086dd9ee8866399cb128d35892b27523e2dd2398e912f6e2d
BLAKE2b-256 checksum
How to use checksums
58f2931463a9617b09b3d0df56d386659d0fd7b9086e1cf24da0cd42a36dfaf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / search_excel_mcp-0.1.0-py3-none-any.whl

Download URL search_excel_mcp-0.1.0-py3-none-any.whl
Size 19.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
156a74f29e9f416859e395315a155a1079d98e198b6a5cdad567c503d14bfa24
BLAKE2b-256 checksum
How to use checksums
2425d8680f331d7938e37c53c6c5202668885878daa8a8993c2e2825ce4d43db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Security for search-excel-mcp 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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