spreadsheet-qa-kit MCP server
Allows querying Google Sheets data using natural language, with read-only tools for schema inspection, sampling, and executing computed queries.
Enables asking spreadsheet questions via Telegram messages, receiving answers with computation traces and optional charts.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@spreadsheet-qa-kit MCP serverWhat was total revenue in Q3 for the West region?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
spreadsheet-qa-kit
Ask your spreadsheet a question in plain words. Get the answer - and the exact steps used to compute it.
Point it at a CSV (or an exported Google Sheet) and ask the kind of thing you'd otherwise build a pivot table for:
"What was total revenue in Q3 for the West region?"
…and the kit answers it, shows its work (which rows it filtered, which column it summed, how), and draws a simple chart when the answer breaks down by category. It reads your data - it does not edit it.
The trick: Claude never computes the number. Claude only translates your question into a concrete plan (filter region = West and quarter = Q3, then sum revenue). A small, auditable Node engine runs that plan over your real rows. So the math is plain code you can read, not model output you have to trust.
This is a real, runnable, MIT-licensed kit. No paywall, no neutered features. Run it on your own machine.
Quickstart
git clone https://github.com/0xJRP/spreadsheet-qa-kit.git
cd spreadsheet-qa-kit
npm install
npm run setup # friendly wizard: Claude API key + path to your CSV
npm run dryrun # answers a sample question from the bundled data and SENDS NOTHINGnpm run dryrun loads the bundled sample spreadsheet, calls Claude to plan a sample question, runs that plan over the data, prints the answer with its work shown, renders a printable HTML report into out/, and shows exactly what an emailed report would contain - then sends nothing. It's the safest way to see the whole pipeline end to end. (It needs ANTHROPIC_API_KEY set, since it actually calls Claude.)
When you're ready to ask your own questions:
npm run ask -- "What was total revenue in Q3 for the West region?"
npm run ask -- "How many units did each rep sell? Show me a chart."
echo "total revenue by quarter" | xargs -0 -I{} npm run ask -- "{}"Open the rendered report in out/ and print to PDF (Cmd/Ctrl-P → Save as PDF) to get a PDF.
Related MCP server: querywise-mcp
What it does
Question Claude brain Your output
┌──────────┐ ───▶ ┌────────────────┐ ───▶ ┌──────────────────┐
│ "Q3 sales│ │ a QUERY PLAN: │ │ the answer + │
│ in the │ │ filter + group │ │ the steps used │
│ West?" │ │ + aggregate │ │ + a simple chart │
└──────────┘ └────────────────┘ └──────────────────┘
Telegram / CLI / MCP (NOT the answer) engine runs the plan
over YOUR real rows locally, shows its workA question. Type it on the CLI, or text it to a Telegram bot (
npm start). Plain English, the way you'd ask a coworker.A brain. Claude reads the question and the spreadsheet's schema (column names, which are numeric, a few sample values) and returns a structured query plan - which rows to filter, whether to group, what to aggregate. Claude is told the exact column names and may only use those.
A deterministic engine.
src/sheet.jsvalidates that plan against the real columns and runs it over your rows in plain Node code: filter, group, sum/average/min/max/count. It builds a step-by-step trace as it goes. This is where the number comes from - not the model.The answer, with its work. You get the headline answer, the steps ("Filtered 30 rows → 4 where region eq West AND quarter eq Q3. Computed sum of revenue over 4 rows = 18753."), an optional ASCII bar chart for grouped answers, and any assumptions Claude made (e.g. how it read "Q3"). All rendered to a clean HTML report you can print to PDF.
Your data is yours, and read-only
data/sample-sales.csv ships so the dry run works out of the box. Point DATA_PATH at your own CSV (or set GOOGLE_SHEET_CSV_URL to a published Google Sheets CSV link and pass --remote). The kit only reads that file. There is no write-back path anywhere in the code: it can answer questions about your data, never change it.
The spreadsheet as an MCP tool
The sheet is also exposed as an MCP server (npm run mcp, built on the official @modelcontextprotocol/sdk). It offers three read-only tools - sheet_schema, sheet_sample, sheet_query - so any MCP-aware client (Claude Desktop, an agent) can inspect and query your spreadsheet as a tool. sheet_query takes the same structured plan and returns the value plus the computation trace, so even an external agent gets the math from the engine, not from a guess.
The safety model - read-only / draft-first
This kit is read-only by design, with a draft-first email path. That's the whole point, and it's Rabbithole's trust differentiator.
Your spreadsheet is never edited. There is no write-back code. The kit loads the file, computes from it, and leaves it byte-for-byte unchanged.
The answer is auditable. Claude proposes the plan; the kit runs it and prints every step. You can check the filter and the arithmetic yourself - the engine is a few hundred lines of plain code.
The model can't invent a column or a number. Every column the plan references is validated against your real header row before anything runs. A bad column name is rejected with a clear error, not silently guessed.
Two locks guard the one optional send. Emailing a report happens only when (1)
DRY_RUN=falsein your.envand (2) you typeyesto the confirmation.DRY_RUNdefaults totrueon a fresh checkout - a hard kill switch that makes every send path a no-op until you deliberately turn it off.Money is never moved. There is no payment code of any kind.
Path | What guards it |
Answer a question (Claude call + engine) | Local; reads your data, writes nothing to it |
Render an HTML report | Local file write to |
Draw a chart | Local, in-memory text |
Email a report |
|
Edit / write back to the spreadsheet | Not implemented - by design |
Charge a card / take payment | Not implemented - by design |
CI / demos stay safe automatically: with DRY_RUN=true (the default), npm run dryrun runs the whole pipeline and provably sends nothing.
Configuration
Run npm run setup, or copy .env.example to .env and fill it in. Every value can also be supplied as a real environment variable, so npm run dryrun works non-interactively in CI:
ANTHROPIC_API_KEY=sk-ant-... npm run dryrunKey settings (see .env.example for all of them, with comments):
Variable | What it's for |
| Your Claude API key (from console.anthropic.com) |
| Defaults to |
| Path to your spreadsheet (CSV). Read-only |
| Optional public Google Sheets CSV-export URL (use with |
| Draw a simple text chart for grouped answers ( |
| Email creds - only needed to actually email a finished report |
| Optional phone channel - ask questions by text |
| Global kill switch. |
Which model?
The default is claude-opus-4-8 - the most capable Opus-tier model, great while you're dialing in the kinds of questions you ask. Once it's reliable and you're running high volume, set ANTHROPIC_MODEL=claude-haiku-4-5 for a cheaper, faster option. Turning a question into a filter/aggregate plan is a clean structured task, so Haiku handles it well.
Want an actual PDF (not just print-to-PDF)?
The kit renders self-contained HTML so there's no headless-browser binary to install. If you want a real .pdf generated automatically, add Puppeteer (npm i puppeteer) and render the HTML report to PDF - about ten lines. Print-to-PDF from any browser works today with zero extra setup.
How it's built
Runtime: Node.js, ES modules.
Brain: the official Anthropic SDK (
@anthropic-ai/sdk) with structured outputs (messages.parse+zodOutputFormat) so the query plan comes back as a typed object. Model defaults toclaude-opus-4-8.Engine: plain Node - filter, group, aggregate, with a step-by-step trace. The model never produces the final number.
Tools: the official MCP SDK (
@modelcontextprotocol/sdk) exposes the spreadsheet as read-only tools.Email:
nodemailer(only used when you turn sending on).Inbound: Telegram long-polling over
fetch- no extra dependency.
src/
config.js # loads .env (and real env vars) into typed config
sheet.js # load a CSV (or fetched Google Sheet) + run a query plan (the engine)
query-engine.js # the Claude brain - turns a question into a structured query plan
render.js # answer → printable HTML report + ASCII chart + a "show your work" text
mailer.js # the only send path; gated behind DRY_RUN + confirmation
pipeline.js # question → plan → computed answer → rendered report (sends nothing)
cli.js # dryrun / ask commands (confirm-before-send on --email)
setup.js # the first-run wizard (writes .env, points at your data)
mcp-server.js # MCP server exposing the spreadsheet as read-only tools
server.js # Telegram inbound - replies to YOU with the answer + its work
data/
sample-sales.csv # sample spreadsheet the dry run uses (point DATA_PATH at yours)
sample-questions.txt # example questionsDIY, or have us run it
You just got a complete, working spreadsheet-question-answering tool for free. Run it yourself - that's the whole idea.
When you're ready for the production version, that's where we come in. Rabbithole wires this to your real tools and runs it for your team: your live Google Sheets and databases (not just CSVs), richer charts, scheduled reports, multi-sheet joins, role-based access, and guardrails tuned to how your team actually asks questions of its data.
You can run this yourself - or we'll build the production version for your whole team. → rabbithole.consulting
License
MIT © 2026 Rabbithole Consulting. See LICENSE. Use it, fork it, ship it.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/0xJRP/spreadsheet-qa-kit'
If you have feedback or need assistance with the MCP directory API, please join our Discord server