@holysheets/mcp
v0.8.0
Published
Drive a Holy Sheets spreadsheet from your existing Claude (Claude Code / Desktop) over MCP — no API key, on your subscription. Runs the same pure engine the browser runs, over a local .json document.
Maintainers
Readme
holysheets MCP server
Drive a holysheets spreadsheet from your existing Claude (Claude Code / Claude Desktop) over MCP — on your subscription, with no API key and no per-token spend. This is the "drive from Claude" path that leans on your plan instead of the in-app Ask-Claude panel's bring-your-own-key.
It runs the same pure engine the browser runs, over a local .json document, so a sheet round-trips
with the app: browser File → Export (.json) → Claude edits it → browser File → Import (.json)
(and back). Zero external dependencies; minimal newline-delimited JSON-RPC over stdio.
Add it to Claude Code
claude mcp add holysheets -- npx -y @holysheets/mcp sheet.jsonThe last argument is the document file (created if absent). Or set HOLYSHEETS_DOC. Then just ask
Claude things like "open the sheet, build a 3-year revenue model, and tell me what predicts EBITDA."
Working from a clone of this repo instead of npm? Point Claude at the source directly:
claude mcp add holysheets -- node /ABS/PATH/holymoly/integrations/mcp/holysheets-mcp.mjs /ABS/PATH/sheet.jsonAdd it to Claude Desktop
In claude_desktop_config.json:
{
"mcpServers": {
"holysheets": {
"command": "node",
"args": ["/ABS/PATH/holysheets/integrations/mcp/holysheets-mcp.mjs", "/ABS/PATH/model.json"]
}
}
}Tools
| tool | what it does |
|---|---|
| get_summary | used range + every non-empty cell (formula + value) + named functions — call first |
| get_cells | read a range (A1:C5) or a list of refs |
| set_cells | set literals/formulas ({"B1":"=A1*1.1"}); recomputes immediately. =LUME("…"), =FEED("manifold:slug") for live values |
| define_function | a reusable named LAMBDA, =NAME(args) anywhere |
| list_functions | the document's named functions |
| what_predicts | rank the other columns as drivers of a target column, write a live model + residual, return R² |
| export_csv | the used range as CSV |
The document is re-read from disk on every call, so edits you make in the browser (after re-importing the file) are picked up. The round-trip is the point: your Claude edits it, the browser opens it, and nothing is locked in.
Testing (how the coverage is kept rigorous)
npm run test:mcp— protocol (real stdio JSON-RPC), a tool-completeness meta-test (every listed tool must be schema-valid, error-safe, and tested — adding a tool without a test fails the build), robustness fuzz (malformed/unknown/notification inputs never crash the server), and a conformance test driven by the OFFICIAL@modelcontextprotocol/sdkclient (an independent implementation — the same "faithful oracle" bar as openpyxl for xlsx; skips cleanly if the SDK isn't installed).npm run test:mcp-parity— the differential oracle: one op-sequence run through both this MCP toolset and the browser'swindow.__sheet, diffed cell-for-cell, proving the terminal and the browser are the same driver.
Roadmap
- A live-room bridge: the MCP server and an open browser tab join the same collaboration room (the claim-log transport) and both project the same log — so you watch Claude drive your open sheet in real time, no file shuffle. Same substrate, Claude as just another peer.
