Install
$ agentstack add mcp-knowledgestack-excel-parser ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
📊 Make XLSX LLM Ready 🤖
ks-xlsx-parser — the open-source Python library that parses Excel (.xlsx) files into citation-ready JSON for LLMs, RAG pipelines, and AI agents (LangChain, LangGraph, CrewAI, OpenAI Agents SDK, Claude, MCP).
> [!TIP] > .xlsx → structured, typed, citation-ready JSON that an LLM can actually reason about. > Cells, formulas, merged regions, tables, charts, conditional formatting, > dependency graphs, and RAG-ready chunks — deterministic, fully tested, MIT.
Raw workbook on the left (financial_model.xlsx) → parser output on the right: 4 chunks, each tied back to an exact sheet!range, ready to cite in an LLM response.
Spreadsheets are still the #1 unstructured data source in the enterprise. Feeding a .xlsx directly to an LLM loses structure (rows, formulas, merges), loses provenance (which cell said what), and blows through context windows. ks-xlsx-parser turns an Excel workbook into a token-counted, source-addressable graph that drops straight into LangChain, LangGraph, CrewAI, the OpenAI Agents SDK, or any MCP-aware client (Claude Desktop, Cursor, Windsurf, Zed, …).
🏁 Benchmark — ks-xlsx-parser vs Docling on SpreadsheetBench
Apples-to-apples on SpreadsheetBench v0.1: 912 real-world task instances curated from ExcelHome / Mr.Excel / r/excel. For each instance we parse the input .xlsx, embed every chunk with BAAI/bge-small-en-v1.5, then check whether the chunk containing the ground-truth answer is in the top-k by similarity to the question.
Metric 🟢 ks-xlsx-parser ⚪ Docling 2.93 Δ
📊 Parse success5,458-file corpus 5,461 ok · 3 timeouts · 0 errors not run at scale —
🎯 Recall@1text-match
🎯 Recall@3text-match
🎯 Recall@5text-match
📍 Geometric Recall@5chunk's sheet!A1:Z99 overlaps the ground-truth range
⚡ Mean parse timeper file
🧱 Parser errorsacross 912 instances
—
💡 What the numbers mean
ks-xlsx-parserties at recall@1 and wins recall@3 (+2.7 pp) and recall@5 (+1.8 pp). Text-match recall is parser-agnostic — it asks whether any parser surfaced a chunk containing the answer string, after normalising commas, percent signs, ISO dates, and booleans on both sides.ks-xlsx-parserwins citation-grade (geometric) recall outright (0.369 vs 0.000). Docling produces markdown without per-chunksheet!rangeanchors, so it can't render a citation that points at the exact source cells. This is the difference between "the answer is somewhere in the workbook" and "the answer is inRevenue!C7."Markeris excluded by design. Its xlsx → HTML → PDF → layout-recognition pipeline clocks >30 min per workbook on CPU. The benchmark framework supports adding a Marker adapter when GPU is available — see [tests/benchmarks/adapters/docling_adapter.py](tests/benchmarks/adapters/docling_adapter.py) as a template.
🔁 Reproduce
make corpus-download # one-time, ~100 MB; gitignored under data/corpora/
make bench # robustness + retrieval, ~50 min on M-series CPU
open tests/benchmarks/reports/COMPARISON.md
Full methodology, capability matrix, error breakdown, and caveats live in [tests/benchmarks/reports/COMPARISON.md](tests/benchmarks/reports/COMPARISON.md). Adapter design notes in [tests/benchmarks/README.md](tests/benchmarks/README.md).
✨ What you get, at a glance
🧾Typed cell graphvalues, formulas, styles, coords 🧭Citation URIsfile.xlsx#Sheet!A1:F18 🧮Dependency graphupstream · downstream · cycles 🧩RAG-ready chunksHTML + text + token count
📊All 7 chart typesbar · line · pie · scatter · area · radar · bubble 🎨Conditional formattingevery Excel rule type 📋Tables & mergesListObjects + master/slave 🔐Safe by defaultno macros · no external links · ZIP-bomb guard
⚡Fast1054 workbooks / 70s in CI 🧬Deterministicxxhash64 content addressing 🧰Framework-agnosticLangChain · LangGraph · CrewAI · MCP 📜MIT licenseduse it, fork it, ship it
⭐ If this helps you
This project is free, open source (MIT), and part of the Knowledge Stack ecosystem — document intelligence for agents. Stars, contributions, and honest feedback are all first-class ways to keep the lights on.
Jump into the community:
- 💬 Discord — real-time help, roadmap conversations, show off what you're building. Drop in, say hi.
- 🗣 GitHub Discussions — async Q&A, RFCs, and long-form ideas.
- 🐞 Issues — report a bug, request a feature, or file a parser edge case.
- 🎯 Show & Tell — tell us about your production use.
- 🔐 Security — private vulnerability disclosure.
- 🙌 [Contribute](CONTRIBUTING.md) — every PR is reviewed;
good-first-issuelabels live on Issues. - 🧰 Knowledge Stack org — see the rest of the ecosystem (ks-cookbook, ks-xlsx-parser, more on the way).
Not sure where to start? Run make bench-robust on SpreadsheetBench, find a file that breaks, open a Parser edge case. That's the fastest path to a merged PR.
🚀 30-second demo
pip install ks-xlsx-parser
from ks_xlsx_parser import parse_workbook
result = parse_workbook(path="q4_forecast.xlsx")
# LLM-ready chunks with citation URIs
for chunk in result.chunks:
print(chunk.source_uri) # q4_forecast.xlsx#Revenue!A1:F18
print(chunk.token_count) # 412
print(chunk.render_text[:200]) # Pipe-delimited Markdown-ish text
print(chunk.render_html[:200]) # HTML with proper colspan/rowspan
# Or dump the whole workbook graph
import json
json.dump(result.to_json(), open("workbook.json", "w"), default=str)
That's it. Every chunk has:
source_uri— cite back to exact cellsrender_text/render_html— LLM-consumable bodiestoken_count— cap your context window properlydependency_summary— upstream/downstream formulas- content hash — dedupe across versions
🗺️ Table of Contents
- [🏁 Benchmark — vs Docling on SpreadsheetBench](#-benchmark--ks-xlsx-parser-vs-docling-on-spreadsheetbench)
- [🤔 Why a dedicated XLSX parser for LLMs?](#-why-a-dedicated-xlsx-parser-for-llms)
- [🏗️ Architecture](#️-architecture)
- [📦 Installation](#-installation)
- [📚 Documentation](#-documentation)
- [⚔️ How it compares](#️-how-it-compares)
- [🎯 Who this is for](#-who-this-is-for)
- [📊 Benchmarks](#-benchmarks)
- [🚧 Limitations](#-limitations)
- [🧰 Knowledge Stack ecosystem](#-knowledge-stack-ecosystem)
- [📡 Stay in touch](#-stay-in-touch)
- [🙌 Contributing](#-contributing)
- [❓ FAQ](#-faq)
- [📜 License](#-license)
🤔 Why a dedicated XLSX parser for LLMs?
Most Excel libraries answer one of two questions well: "read a rectangle of values" (pandas, openpyxl) or "run Excel headless" (xlwings, LibreOffice). ks-xlsx-parser answers a third one: "give me a structured, inspectable, loss-minimising graph that an LLM or auditor can reason about."
| Output | Why an LLM cares | |--------|------------------| | Typed cell graph (values, formulas, styles, coordinates) | Round-trips to JSON/DB/vector store without losing formulas or data types | | Formula AST + directed dependency graph | Answer "what drives Q4 revenue?" via upstream traversal | | Detected tables, merged regions, layout blocks | Multi-table sheets no longer collapse into one giant CSV | | Chart extractions (bar / line / pie / scatter / area / radar / bubble) | Text summaries the model can read | | Token-counted render chunks (HTML + pipe-text) | Plug straight into an embedding pipeline without blowing context | | Citation-ready source URIs (sheet!A1:B10) | The LLM can cite the exact cell it's talking about | | Deterministic content hashes (xxhash64) | Dedupe across versions, detect change between uploads |
Everything is deterministic, everything is tested on a 1054-workbook stress corpus, and everything is open source.
🏗️ Architecture
The pipeline runs 8 deterministic stages: parse → analyse → annotate → segment → render → serialise → verify → compare/export. Full diagram, stage-by-stage breakdown, and module map in [docs/wiki/Architecture.md](docs/wiki/Architecture.md). Stage internals in [Pipeline Internals](docs/wiki/Pipeline-Internals.md).
> [!NOTE] > The importable module is xlsx_parser; ks_xlsx_parser is a re-export > matching the PyPI package name. The package is fully type-annotated > (py.typed is shipped).
📦 Installation
Requires Python 3.10+.
pip install ks-xlsx-parser # core library
pip install "ks-xlsx-parser[api]" # + FastAPI web server
pip install "ks-xlsx-parser[dev]" # + test tooling
From source:
git clone https://github.com/knowledgestack/ks-xlsx-parser.git
cd ks-xlsx-parser
make install # pip install -e ".[dev,api]"
make test # default suite
make corpus-download # fetch SpreadsheetBench (5,458 real-world xlsx)
make bench-robust # parse-success + structural counts vs Docling
make bench-retrieval # retrieval recall@k vs Docling
Runtime deps: openpyxl, pydantic, lxml, xxhash, tiktoken.
📚 Documentation
All implementation detail lives under [docs/wiki/](docs/wiki/) (mirrored to the GitHub Wiki on each release) so this README stays scannable:
- 🚀 [Quick Start](docs/wiki/Quick-Start.md) — parse, iterate chunks, walk the dep graph, serialise, parse from bytes. Five short snippets, ~90 % of real usage.
- 📖 [API Reference](docs/wiki/API-Reference.md) — full signatures for
parse_workbook,compare_workbooks,export_importer,StageVerifier. - 🌐 [Web API](docs/wiki/Web-API.md) — the bundled FastAPI server, Python + TypeScript clients, deployment notes.
- 📦 [Data Models](docs/wiki/Data-Models.md) — every Pydantic DTO field by field.
- 🛠 [Pipeline Internals](docs/wiki/Pipeline-Internals.md) — where to hook in if you want to extend the parser.
- 📜 [Workbook Graph Spec](docs/WORKBOOKGRAPHSPEC.md) — canonical schema for the output.
- 🐛 [Known Issues](docs/PARSERKNOWNISSUES.md) — documented edge cases.
- 📝 [CHANGELOG](CHANGELOG.md) — release history.
⚔️ How it compares
This is the structural capability matrix. For head-to-head retrieval numbers (recall@k, geometric, latency) on a 912-instance real-world corpus, see [🏁 Benchmark — ks-xlsx-parser vs Docling on SpreadsheetBench](#-benchmark--ks-xlsx-parser-vs-docling-on-spreadsheetbench) up top.
| | pandas / openpyxl | Docling | ks-xlsx-parser | |---|:---:|:---:|:---:| | Reads values | ✅ | ✅ | ✅ | | Keeps formulas | ⚠️ raw string | ❌ | ✅ parsed + dependency graph | | Preserves merges | ⚠️ coords only | ⚠️ partial | ✅ master/slave with colspan/rowspan | | Extracts charts | ❌ | ❌ | ✅ all 7 chart types + text summary | | Conditional formatting | ❌ | ❌ | ✅ cell/color-scale/icon/data-bar/formula | | Data validation (dropdowns) | ❌ | ❌ | ✅ all types incl. cross-sheet lists | | Multi-table sheet layout | ❌ | ⚠️ | ✅ adaptive-gap segmentation | | Per-chunk source URI (citation) | ❌ | ⚠️ | ✅ file.xlsx#Sheet!A1:F18 | | Token counts per chunk | ❌ | ❌ | ✅ via tiktoken | | Dependency graph traversal | ❌ | ❌ | ✅ upstream / downstream, cycle detection | | Deterministic content hashes | ❌ | ❌ | ✅ xxhash64 per cell / block / chunk | | Streaming .xlsx > 100 MB | ⚠️ | ❌ | ✅ (chunked parse) |
Most tools give you a dataframe. ks-xlsx-parser gives you a graph an LLM can cite.
> Looking for a tiny, edge-runtime I/O library with write support? See > hucre by > @productdevbook. For an unbiased > head-to-head on the SpreadsheetBench corpus — perf numbers, > extraction-count parity, where each side wins — see the wiki: > [ks-xlsx-parser vs hucre](docs/wiki/Benchmark-vs-hucre.md).
🎯 Who this is for
Teams shipping agents, RAG pipelines, or auditing tools that ingest Excel.
🏦Banking & FinanceKPI extraction, formula lineage, regulator-ready citations ⚖️Legal & Contractsschedules, fee tables, covenant matrices without flattening merges 🏥Healthcare & Insurancenormalise claims, pricing, and actuarial sheets into auditable JSON 🏗️Real Estate & Constructionquantity takeoffs and cost models that still live in XLSX 📈Sales Ops / HR / Engineering"source of truth is a spreadsheet" → structured events, in minutes
> [!IMPORTANT] > Not a fit if you need to execute Excel (recalculate, run VBA, pivot-refresh). > Use xlwings or a headless Excel for that. ks-xlsx-parser reads; it doesn't run.
📊 Benchmarks
We benchmark against SpreadsheetBench v0.1 — 912 instruction × xlsx tasks (5,458 unique workbooks) covering financial models, project trackers, HR records, scientific data, and a long tail of small business spreadsheets.
| Benchmark | What it measures | Cost | |---|---|---| | make bench-robust | Parse-success rate + structural counts vs Docling | ~20 min | | make bench-retrieval | Top-k retrieval recall + table fragmentation rate vs Docling | ~40 min |
Headline numbers and methodology live in [tests/benchmarks/reports/COMPARISON.md](tests/benchmarks/reports/COMPARISON.md). The corpus is downloaded on demand (make corpus-download) and gitignored — nothing is committed to the repo.
🚧 Limitations
.xlsnot supported — only.xlsxand.xlsm(OOXML). Convert legacy files externally.- Pivot tables — detected but not fully parsed.
- Sparklines — not extracted.
- VBA macros — flagged but never executed or analysed.
- External links — recorded but not resolved.
- Threaded comments — only legacy comments are supported (openpyxl limitation).
- Embedded OLE objects — detected but not extracted.
- Locale-dependent number formats — not interpreted.
Full list in [docs/PARSER_KNOWN_ISSUES.md](docs/PARSERKNOWNISSUES.md).
🧰 Knowledge Stack ecosystem
ks-xlsx-parser is one piece of the Knowledge Stack open-source family — document intelligence for agents, built so that engineering teams can focus on agents and we handle the messy parts of enterprise data.
| Repo | What it does | |------|--------------| | ks-cookbook | 32 production-style flagship agents + recipes for LangChain, LangGraph, CrewAI, Temporal, the OpenAI Agents SDK, and any MCP client. | | ks-xlsx-parser (this repo) | Turn .xlsx into LLM-ready JSON with citations and dependency graphs. | | @knowledgestack | Follow the org for upcoming repos — parsers, extractors, and MCP servers for PDF, DOCX, PPTX, HTML, and more. |
Building on top of the stack? Tell us about it in [Show & Tell](https://github.com/knowledgestack/ks-xlsx-parser/discussions/new?category=sh
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: knowledgestack
- Source: knowledgestack/excel-parser
- License: MIT
- Homepage: https://knowledgestack.github.io/excel-parser/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.