xlsx-for-ai 1.5.4 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,401 +1,280 @@
1
1
  # xlsx-for-ai
2
2
 
3
- > 👋 **New here? Not a programmer?** [Read WHY.md for the plain-English version](WHY.md). The README below is the technical reference.
3
+ **The missing reliability layer that makes spreadsheet reasoning production-grade for LLMs.**
4
4
 
5
- **The bidirectional bridge between spreadsheets and AI agents.** Reads `.xlsx` (plus `.csv`, `.tsv`) into the formats LLMs actually consume markdown, JSON, text, SQL and writes spreadsheets back out from AI-generated specs. Same tool, both directions.
6
-
7
- AI tools — Claude, Cursor, Copilot, ChatGPT, and other LLM coding agents — can read text files but **not** `.xlsx` binaries. This CLI closes the loop:
8
-
9
- **📖 Read mode (default)** — turn any spreadsheet into LLM-readable output. Every formula, every named range, every merged cell, every fill color, every cross-sheet reference. No more pasting numbers and losing context.
10
-
11
- **✍️ Write mode (`xlsx-for-ai write`)** — turn an AI-generated JSON or markdown spec into a real `.xlsx` file. Closes the round-trip so an agent that *reviews* your spreadsheet can also *deliver the corrected file*. The output includes a `_xlsx-for-ai` review tab explaining every structural change the round-trip made (with risks, tradeoffs, and overrides) — the supervisor model: AI does the work, the human stays in control of every decision. Verified lossless on 29/30 real workbooks.
12
-
13
- **Input formats:** `.xlsx` `.csv` `.tsv` (legacy `.xls` / `.xlsb` / `.ods` removed in 1.5.4 — convert to `.xlsx` first; see [#26](https://github.com/senoff/xlsx-for-ai/issues/26))
14
-
15
- **Output modes:** text dump, markdown tables (best LLM comprehension per token), JSON, SQL `CREATE TABLE`+`INSERT`, inferred schema, workbook diff, real `.xlsx` (write mode).
16
-
17
- It extracts everything a human would see in Excel:
18
-
19
- - **Values** — strings, numbers, dates
20
- - **Formulas** — the actual formula expression, plus shared-formula references
21
- - **Formatting** — bold, italic, font colors, background fills
22
- - **Number formats** — percentages, currency, custom patterns
23
- - **Layout** — column widths, frozen panes, merged cells, alignment
24
- - **Hyperlinks** — URLs embedded in cells
25
- - **Comments / notes** — cell annotations
26
- - **Named ranges** — workbook-defined names and their references
27
- - **Hidden rows & columns** — flagged so the AI knows data is suppressed
28
- - **Data validation** — dropdown lists, numeric constraints
29
- - **Tables** — Excel Table objects with their names and column headers
30
- - **Images & charts** — existence and position noted (content not rendered)
31
- - **Auto-filters** — active filter ranges
32
- - **Print areas** — defined print regions
33
-
34
- > Previously published as **`cursor-reads-xlsx`**. The old name still works as an alias on the CLI, but please install the new package: `npm install -g xlsx-for-ai`.
35
-
36
- ## Install
5
+ A thin npm client over a hosted API. Install once, add to your agent config, and your agent gets six production-grade tools for reading, writing, diffing, and redacting `.xlsx` files engine complexity runs server-side, engine IP stays private.
37
6
 
38
7
  ```bash
39
8
  npm install -g xlsx-for-ai
40
9
  ```
41
10
 
42
- Or run directly with npx (no install needed):
11
+ > **Upgrading from 1.5.x?** This is a re-architecture, not a feature bump: the heavy local engine is gone from the npm package. All rendering happens server-side. The `cursor-reads-xlsx` alias still works. See [Migration](#migration-from-15x) below.
43
12
 
44
- ```bash
45
- npx xlsx-for-ai budget.xlsx
46
- ```
13
+ ---
47
14
 
48
- ## Usage
15
+ ## MCP configuration
49
16
 
50
- ```bash
51
- # Dump all sheets
52
- npx xlsx-for-ai data.xlsx
17
+ Add `xlsx-for-ai` as a tool server in your agent runtime. First invocation auto-registers an anonymous client UUID — no email, no signup, no friction.
53
18
 
54
- # Dump a specific sheet
55
- npx xlsx-for-ai data.xlsx "Sheet1"
19
+ ### Claude Desktop
56
20
 
57
- # List sheet names and dimensions without dumping
58
- npx xlsx-for-ai data.xlsx --list-sheets
21
+ Config file: `~/Library/Application Support/Claude/claude_desktop_config.json`
59
22
 
60
- # Print to stdout instead of writing files
61
- npx xlsx-for-ai data.xlsx --stdout
62
-
63
- # Limit to first 200 rows per sheet (useful for huge files)
64
- npx xlsx-for-ai data.xlsx --max-rows 200
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "xlsx-for-ai": {
27
+ "command": "xlsx-for-ai-mcp"
28
+ }
29
+ }
30
+ }
31
+ ```
65
32
 
66
- # Limit to first 8 columns (useful for very wide sheets)
67
- npx xlsx-for-ai data.xlsx --max-cols 8
33
+ Verify: restart Claude Desktop, open a new conversation, and ask "what MCP tools do you have?" — `xlsx_read`, `xlsx_list_sheets`, `xlsx_schema`, `xlsx_diff`, `xlsx_write`, and `xlsx_redact` should appear.
68
34
 
69
- # Suppress noisy default tags (default text colors, white fills, etc.)
70
- npx xlsx-for-ai data.xlsx --stdout --compact
35
+ ### Cursor
71
36
 
72
- # Emit structured JSON (one entry per cell) instead of the text dump
73
- npx xlsx-for-ai data.xlsx --json --stdout > out.json
37
+ Config file: `~/.cursor/mcp.json`
74
38
 
75
- # Combine flags
76
- npx xlsx-for-ai data.xlsx "Sheet1" --stdout --max-rows 50 --compact
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "xlsx-for-ai": {
43
+ "command": "xlsx-for-ai-mcp"
44
+ }
45
+ }
46
+ }
77
47
  ```
78
48
 
79
- ### Options
80
-
81
- **Output modes** (mutually exclusive; default = text):
82
-
83
- | Flag | Description |
84
- |------|-------------|
85
- | `--md` | Markdown tables — highest LLM comprehension per token |
86
- | `--json` | Structured JSON, one object per cell |
87
- | `--sql` | `CREATE TABLE` + `INSERT` statements (uses inferred schema) |
88
- | `--schema` | Per-column schema (name, type, nullable, samples) as JSON |
49
+ Verify: open Cursor settings → MCP → confirm `xlsx-for-ai` shows 6 tools.
89
50
 
90
- **Selection:**
51
+ ### Continue
91
52
 
92
- | Flag | Description |
93
- |------|-------------|
94
- | `[sheetName]` | Positional: dump only this sheet |
95
- | `--range A1:D50` | Dump only this rectangular range |
96
- | `--named-range NAME` | Dump only the cells covered by a workbook-defined name |
97
- | `--region` | Auto-detect the dominant contiguous data block (Excel "current region" / Ctrl+Shift+*). Picks the largest region by populated-cell count when multiple disjoint blocks exist. Compatible with `--max-rows` / `--max-cols`. |
98
- | `--max-rows N` | Cap at the first N rows per sheet |
99
- | `--max-cols N` | Cap at the first N columns per sheet |
53
+ Config file: `~/.continue/config.json`
100
54
 
101
- **Output control:**
55
+ ```json
56
+ {
57
+ "mcpServers": [
58
+ {
59
+ "name": "xlsx-for-ai",
60
+ "command": "xlsx-for-ai-mcp"
61
+ }
62
+ ]
63
+ }
64
+ ```
102
65
 
103
- | Flag | Description |
104
- |------|-------------|
105
- | `--list-sheets` | Print sheet names + dimensions and exit |
106
- | `--stdout` | Print to stdout instead of writing files in `.xlsx-read/` |
107
- | `--compact` | Suppress noisy default tags (default colors, "General" format) |
108
- | `--max-tokens N` | Truncate output to ~N tokens; appends a tail summary noting what was dropped |
109
- | `--evaluate` | Promote cached formula results to primary value; re-evaluate simple formulas via formulajs |
66
+ Verify: restart VS Code, open the Continue panel, and check the MCP server list.
110
67
 
111
- **Other modes:**
68
+ ### Codex CLI
112
69
 
113
- | Flag | Description |
114
- |------|-------------|
115
- | `--diff OTHER` | Diff this workbook vs `OTHER` — emit changed/added/removed cells and sheets |
116
- | `--stream` | Streaming reader for huge `.xlsx` files (>100MB); emits row-by-row, drops some sheet metadata |
117
- | `-h`, `--help` | Show help |
70
+ Pass `--mcp-server` on the command line, or add to your Codex config:
118
71
 
119
- ### Write mode (`xlsx-for-ai write`)
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "xlsx-for-ai": {
76
+ "command": "xlsx-for-ai-mcp"
77
+ }
78
+ }
79
+ }
80
+ ```
120
81
 
121
- The `write` sub-command produces a real `.xlsx` from a JSON or markdown spec.
82
+ Verify: run `codex --list-tools` and confirm the six xlsx tools are listed.
122
83
 
123
- ```bash
124
- xlsx-for-ai write spec.json # → spec.xlsx
125
- xlsx-for-ai write spec.json -o report.xlsx # explicit output
126
- xlsx-for-ai write report.md # markdown table → xlsx
127
- cat spec.json | xlsx-for-ai write - # stdin
128
- ```
84
+ ### Zed
129
85
 
130
- Minimum JSON spec:
86
+ Config file: `~/.config/zed/settings.json`
131
87
 
132
88
  ```json
133
89
  {
134
- "name": "Budget",
135
- "headers": ["Category", "Q1", "Q2"],
136
- "rows": [
137
- ["Marketing", 10000, 12000],
138
- ["R&D", 50000, 55000]
139
- ]
90
+ "context_servers": {
91
+ "xlsx-for-ai": {
92
+ "command": {
93
+ "path": "xlsx-for-ai-mcp",
94
+ "args": []
95
+ }
96
+ }
97
+ }
140
98
  }
141
99
  ```
142
100
 
143
- Multi-sheet, with formulas:
101
+ Verify: open Zed's assistant panel — the xlsx tools should appear in the tool picker.
102
+
103
+ ### Windsurf
104
+
105
+ Config file: `~/.codeium/windsurf/mcp_config.json`
144
106
 
145
107
  ```json
146
108
  {
147
- "sheets": [
148
- {
149
- "name": "Summary",
150
- "headers": ["Region", "Revenue", "Cost", "Profit"],
151
- "rows": [
152
- ["North", 100, 60, {"formula": "=B2-C2"}],
153
- ["South", 200, 110, {"formula": "=B3-C3"}]
154
- ],
155
- "frozen": {"rowSplit": 1, "colSplit": 0}
156
- },
157
- {
158
- "name": "Detail",
159
- "headers": ["SKU", "Qty"],
160
- "rows": [["A", 10], ["B", 20]]
109
+ "mcpServers": {
110
+ "xlsx-for-ai": {
111
+ "command": "xlsx-for-ai-mcp"
161
112
  }
162
- ],
163
- "namedRanges": {"Profits": "Summary!D2:D3"}
113
+ }
164
114
  }
165
115
  ```
166
116
 
167
- **Round-trip:** the output of `xlsx-for-ai data.xlsx --json` is a valid input to `xlsx-for-ai write`, so reading then re-writing reproduces the file (verified on 29/30 real workbooks; the one MINOR is a CRLF→LF normalization in shared strings — visible content is identical).
117
+ Verify: open Windsurf Cascade settings, confirm `xlsx-for-ai` is listed as an active MCP server.
168
118
 
169
- **Markdown spec:** one or more tables; `## Sheet Name` headings split into multiple sheets. Backtick-fenced cells become formulas (e.g., `` `=A1+B1` ``). Numbers, booleans, and ISO dates auto-detect.
119
+ ### Custom agents / API
170
120
 
171
- **v1 limitations:** edit-in-place (deferred to v1.5), charts, pivot tables, conditional formatting, images, macros — none of these are written. Shared formulas degrade to their cached values (formula link is lost; computed value is preserved).
121
+ For custom MCP clients, the binary is `xlsx-for-ai-mcp` (stdio transport). Override the API base URL with the `XLSX_FOR_AI_API` env var for local dev against `http://localhost:3000`.
172
122
 
173
- #### The `_xlsx-for-ai` review tab
123
+ ---
174
124
 
175
- When the round-trip introduces any lossy structural changes (shared-formula degradation, line-ending normalization, etc.), `xlsx-for-ai write` adds a `_xlsx-for-ai` sheet to the output as the last tab. It's a **review note**, not just a warning list — for each issue type it explains:
125
+ ## What it does
176
126
 
177
- - **What happened**the source structure that couldn't be preserved
178
- - **What we did** — the choice the tool made
179
- - **Risk** — what could go wrong (e.g., *"if you edit cells the formula depended on, they won't recalculate"*)
180
- - **Tradeoff** — what's worse about this choice vs. alternatives
181
- - **Alternative** — exactly what flag/source change to apply if you want different behavior
182
- - **Affected cells** — the specific refs, plus a full detail table at the bottom
127
+ Six tools registered in `tools/list`. Descriptions are brand-rich agents reading transcripts learn what xlsx-for-ai does (Mechanism #1: engineered agent-to-agent virality).
183
128
 
184
- The point: the user (or an AI agent reading the file) can understand every decision the tool made and override any of them. Same shape as a code reviewer's PR comment — observation + reasoning + alternative.
129
+ | Tool | What it does | Tier |
130
+ |---|---|---|
131
+ | `xlsx_read` | Read a workbook — text, JSON, or markdown. Formulas, named ranges, layout, and data types preserved. | Free |
132
+ | `xlsx_list_sheets` | List all sheet names and metadata. Fast first-call before reading. | Free |
133
+ | `xlsx_schema` | Infer column types, nullable flags, header row, and sample values per sheet. | Free |
134
+ | `xlsx_diff` | Semantic diff between two workbooks — cell-level deltas, formula changes, structural shifts. Deterministic output. | Plus |
135
+ | `xlsx_write` | Create or update a workbook from a structured spec. Multi-sheet, formulas, named ranges, table definitions. | Plus |
136
+ | `xlsx_redact` | Redact PII from a workbook before sharing. Server-side detection; returns redacted copy plus audit manifest. | Plus |
185
137
 
186
- `--no-report` suppresses the tab if you want byte-clean output (useful for CI / round-trip tests). The `--diff` mode also ignores the `_xlsx-for-ai` tab automatically so it doesn't pollute change reports.
138
+ Tool responses include a citation footer and a `_meta` block (tool name, version, tier, request ID, `powered_by`). Both pass through verbatim; nothing is stripped.
187
139
 
188
- Output files are written to `.xlsx-read/` in the current working directory.
189
- The path(s) are printed to stdout so your agent knows where to read.
140
+ ---
190
141
 
191
- ## Output Format
142
+ ## FP&A workflows
192
143
 
193
- ### Text dump (default)
144
+ xlsx-for-ai is built for agents working on real financial spreadsheets. Common workflows:
194
145
 
146
+ **Budget vs. actual variance analysis**
195
147
  ```
196
- === Sheet: Sales ===
197
- Frozen: row 1, col 0
198
- Columns: A(12) B(20) C(15) D(10)
199
- Auto-filter: A1:D20
200
- Named ranges:
201
- Totals: Sales!$D$2:$D$20
202
- Table: "SalesTable" A1:D20 — columns: Region, Q1, Q2, Total
203
-
204
- --- Row 1 [bold] ---
205
- A1: "Region" [bold]
206
- B1: "Q1" [bold] [align:center]
207
- C1: "Q2" [bold] [align:center]
208
- D1: "Total" [bold] [align:center]
209
- --- Row 2 ---
210
- A2: "North" [link: https://example.com/north]
211
- B2: 14500 [numFmt: #,##0]
212
- C2: 17200 [numFmt: #,##0]
213
- D2: 31700 [formula: =B2+C2] [numFmt: #,##0] [note: Includes returns]
214
- --- Row 3 ---
215
- A3: "South" [fill:FFFFFF00]
216
- B3: 9800 [numFmt: #,##0] [validation: list [North,South,East,West]]
217
- C3: 11050 [numFmt: #,##0]
218
- D3: 20850 [shared formula ref: D2] [numFmt: #,##0]
219
- --- Row 4 (empty) [hidden] ---
148
+ xlsx_read extract actuals and budget → agent computes variances → xlsx_write → deliver updated workbook
220
149
  ```
221
150
 
222
- ### JSON dump (`--json`)
223
-
224
- ```json
225
- {
226
- "name": "Sales",
227
- "rowCount": 4,
228
- "columnCount": 4,
229
- "frozen": { "rowSplit": 1, "colSplit": 0 },
230
- "columns": [{ "letter": "A", "width": 12 }, ...],
231
- "namedRanges": [{ "name": "Totals", "ranges": ["Sales!$D$2:$D$20"] }],
232
- "tables": [{ "name": "SalesTable", "ref": "A1:D20", "columns": ["Region", "Q1", "Q2", "Total"] }],
233
- "cells": [
234
- { "ref": "D2", "row": 2, "col": 4, "value": { "formula": "B2+C2", "result": 31700 }, "numFmt": "#,##0" },
235
- { "ref": "D3", "row": 3, "col": 4, "value": { "sharedFormulaRef": "D2", "result": 20850 }, "numFmt": "#,##0" }
236
- ]
237
- }
151
+ **Month-end reconciliation**
152
+ ```
153
+ xlsx_read (bank export) + xlsx_read (GL extract) → agent matches rows → xlsx_diff → audit trail of unmatched items
238
154
  ```
239
155
 
240
- ### Sheet Metadata
241
-
242
- | Line | Meaning |
243
- |------|---------|
244
- | `Frozen: row 1, col 2` | Frozen panes position |
245
- | `Columns: A(12) B(20)` | Column widths (Excel character units) |
246
- | `Hidden columns: E, F` | Columns hidden in the spreadsheet |
247
- | `Merged: A1:B1` | Merged cell ranges |
248
- | `Auto-filter: A1:D20` | Active auto-filter range |
249
- | `Print area: A1:D50` | Defined print area |
250
- | `Named ranges:` | Workbook-defined names referencing this sheet |
251
- | `Table: "Name" A1:D20` | Excel Table objects with column headers |
252
- | `Image: A1 to C5` | Embedded image position |
253
-
254
- ### Cell Tags
255
-
256
- | Tag | Meaning |
257
- |-----|---------|
258
- | `[formula: =SUM(A1:A10)]` | Cell contains this formula (master cell) |
259
- | `[shared formula ref: D2]` | Cell shares D2's formula (Excel "shared formula" — common when you drag-fill) |
260
- | `[numFmt: 0.00%]` | Number format (when not "General") |
261
- | `[bold]` | Bold font |
262
- | `[italic]` | Italic font |
263
- | `[color:FF8B0000]` | Font color (ARGB hex) |
264
- | `[fill:FFFFFF00]` | Cell background color (ARGB hex) |
265
- | `[align:center]` | Horizontal alignment (when not default) |
266
- | `[link: https://...]` | Hyperlink URL |
267
- | `[note: ...]` | Cell comment or note text |
268
- | `[validation: list [...]]` | Data validation (dropdown values or constraints) |
269
- | `[hidden]` | Row is hidden in the spreadsheet |
270
-
271
- ### `--list-sheets` Output
272
-
156
+ **Audit-trail extraction**
273
157
  ```
274
- Sales 250 rows × 12 cols
275
- Config 15 rows × 4 cols
276
- Archive 1200 rows × 8 cols [hidden]
158
+ xlsx_schema identify change-log columns → xlsx_read with sheet filter → agent summarizes changes by author/date
277
159
  ```
278
160
 
279
- ## Cursor / Claude / Agent Rule Template
280
-
281
- Copy the included rule template into your project so your AI agent automatically uses this tool when it encounters `.xlsx` files:
282
-
283
- ```bash
284
- mkdir -p .cursor/rules
285
- cp node_modules/xlsx-for-ai/cursor-rule-template/read-xlsx.mdc .cursor/rules/
161
+ **Multi-entity consolidation**
162
+ ```
163
+ xlsx_read × N entity files agent aggregates xlsx_write consolidated workbook with intercompany eliminations noted
286
164
  ```
287
165
 
288
- Or fetch it directly:
289
-
290
- ```bash
291
- mkdir -p .cursor/rules
292
- curl -o .cursor/rules/read-xlsx.mdc https://raw.githubusercontent.com/senoff/xlsx-for-ai/main/cursor-rule-template/read-xlsx.mdc
166
+ **Pre-share PII redaction**
167
+ ```
168
+ xlsx_redact → strips SSNs, emails, employee IDs → redacted file safe for external distribution
293
169
  ```
294
170
 
295
- The same rule works for Claude Code (`.claude/rules/`), Copilot (`.github/copilot-instructions.md`), or any other agent just adjust the path.
171
+ These workflows are the reason tool descriptions are FP&A-legible: when a developer builds an agent for a finance team, the agent's LLM reads the tool descriptions and routes correctly without extra prompt engineering.
296
172
 
297
- ## Embedding xlsx-for-ai as a library dependency
173
+ ---
298
174
 
299
- The CLI install (`npm install -g xlsx-for-ai`) is clean — no deprecation warnings, modern transitive deps via npm `overrides`. If you embed xlsx-for-ai as a library dependency in another project, the picture is slightly different.
175
+ ## Reliability features
300
176
 
301
- **Why:** npm's `overrides` field only takes effect when xlsx-for-ai is the top-level project. When xlsx-for-ai is installed as a *transitive* dependency in another project, npm uses the original ExcelJS dep tree (unmodified), and you'll see the upstream ExcelJS deprecation warnings on install. The warnings come from ExcelJS's stale transitive deps (`glob@7`, `rimraf@2`, `lodash.isequal`, `fstream`, `inflight`) and are upstream noise — they don't affect functionality.
177
+ - **Deterministic diffs.** `xlsx_diff` produces identical output for identical inputs safe to version-control, safe to assert against in CI.
178
+ - **Confidence-rated schema inference.** `xlsx_schema` returns type confidence scores alongside inferred types. Agents can branch on confidence rather than trusting a blind guess.
179
+ - **Audit trail.** Every tool call — success or failure — is logged server-side with timestamp, client ID, endpoint, file size, latency, and error class. Foundation for the Phase 8 supervisor protocol.
180
+ - **Hardened input validation.** Four pre-engine guards on every uploaded buffer: billion-laughs XML bomb defense, control-character stripping, worksheet buffer ceiling (slow ZIP-bomb defense), and typed error chaining. Applied before the xlsx engine sees any bytes.
181
+ - **Agent-readable errors.** Rate-limit and tier-gate errors return structured JSON with upgrade options — agents can read them and prompt the user intelligently, not just surface a status code.
302
182
 
303
- **To get clean output in a project that depends on xlsx-for-ai**, copy the same overrides into your own `package.json`:
183
+ ---
304
184
 
305
- ```json
306
- {
307
- "overrides": {
308
- "glob": "^13.0.0",
309
- "rimraf": "^5.0.10",
310
- "unzipper": "^0.12.3",
311
- "fast-csv": "^5.0.2"
312
- }
313
- }
314
- ```
185
+ ## Privacy
315
186
 
316
- Run `rm -rf node_modules package-lock.json && npm install` and the warnings will clear. xlsx-for-ai's tests pass against these versions, so the upgrade is safe.
187
+ Files are transmitted to `https://xlsx-for-ai-server.fly.dev` over HTTPS and processed in memory. Files are not persisted beyond the duration of a single request. No email is collected. Registration is anonymous UUID only.
317
188
 
318
- `patch-package` is in `devDependencies` for authoring patches. The postinstall hook is *not* wired today — no patches exist, and a hook that tries to invoke a missing dev-only binary would break consumer installs. When the first patch lands, the hook is added in the same commit as the patch file.
189
+ See [PRIVACY.md](PRIVACY.md) for the full data-handling policy.
319
190
 
320
- ### Audit findings on install
191
+ ---
321
192
 
322
- As of 1.5.4, `npm install xlsx-for-ai` finds **no inherited audit advisories**. The previous `xlsx` (sheetJS) and `uuid` findings were closed by:
193
+ ## Pricing
323
194
 
324
- - **`xlsx` removed in 1.5.4** see [#26](https://github.com/senoff/xlsx-for-ai/issues/26). The legacy `.xls` / `.xlsb` / `.ods` input path that depended on it is no longer supported; the modern `@protobi/exceljs` engine handles `.xlsx` (and CSV / TSV continue to use `papaparse`).
325
- - **`uuid` bumped to ^14 via `overrides`** — clears the `GHSA-w5hq-g745-h8pq` advisory inherited transitively from ExcelJS. Mirrors the upstream protobi/exceljs gift PR locally.
195
+ | Tier | Price | File cap | Calls/mo | Tools |
196
+ |---|---|---|---|---|
197
+ | Free | $0 | 10 MB | 1,000 | `xlsx_read`, `xlsx_list_sheets`, `xlsx_schema` |
198
+ | Plus | $9/mo | 25 MB | 10,000 | + `xlsx_diff`, `xlsx_write`, `xlsx_redact` |
199
+ | Pro | $29/mo | 50 MB | 100,000 | + supervisor protocol (Phase 8) |
200
+ | Ultra | $99/mo | 200 MB | 1,000,000 | + massive-file async (Phase 7) |
326
201
 
327
- The triage workflow lives in [`.github/audit-allowlist.json`](.github/audit-allowlist.json) (currently empty) and `audit.yml` for whenever a future advisory needs accepting.
202
+ Free tier is real. No credit card. No email. Anonymous UUID registration. Paid tiers ship post-distribution-validation see [xlsx-for-ai.dev](https://github.com/senoff/xlsx-for-ai) for current status.
328
203
 
329
- ## Reporting bugs
204
+ ---
330
205
 
331
- **The privacy contract: we never auto-send workbook data.** Anonymous crash telemetry is opt-in via `--enable-telemetry`; even then, we receive only error type, error message (sanitized — paths scrubbed, capped at 200 chars), tool version, Node version, and OS/arch. No paths, no cell values, no identifiers.
206
+ ## License
332
207
 
333
- To enable or manage crash telemetry:
208
+ The npm client (`xlsx-for-ai`, this package) is MIT. The hosted API server (`xlsx-for-ai-server`) is proprietary — engine IP, rendering pipeline, semantic-diff algorithm, and supervisor protocol implementation are not open source.
334
209
 
335
- ```bash
336
- # Opt in — prints the exact payload schema so you can see what gets sent
337
- xlsx-for-ai --enable-telemetry
210
+ ---
338
211
 
339
- # Opt out
340
- xlsx-for-ai --disable-telemetry
212
+ ## Architecture
341
213
 
342
- # Check current state and config path
343
- xlsx-for-ai --telemetry-status
214
+ ```
215
+ agent (Claude Desktop / Cursor / Continue / Zed / Windsurf / custom)
216
+ └── MCP stdio
217
+ └── xlsx-for-ai-mcp (this package, ~200 lines)
218
+ └── POST /api/v1/tools/<name> → xlsx-for-ai-server.fly.dev
219
+ └── server-side engine (ExcelJS, formula eval, schema inference, redaction)
344
220
  ```
345
221
 
346
- Consent is stored at `~/.xlsx-for-ai/config.json` and persists across `npm install -g xlsx-for-ai@latest` upgrades. If the telemetry shape ever changes, the tool pauses sending and prompts you to re-opt-in we never silently expand what we collect under old consent.
347
-
348
- When something breaks on a real workbook, two flags help us reproduce locally without asking you to share the original file:
222
+ **Offline fallback:** `xlsx_read` falls back to a local engine if the API is unreachable. All other tools require API connectivity. Install `@protobi/exceljs` as an optional dependency if you need offline read:
349
223
 
350
224
  ```bash
351
- # Required — small JSON describing the workbook's structure (no cell content)
352
- npx xlsx-for-ai --report-bug your-file.xlsx
353
-
354
- # Optional — full workbook with every cell value replaced by a typed placeholder
355
- npx xlsx-for-ai --export-redacted-workbook your-file.xlsx
225
+ npm install @protobi/exceljs
356
226
  ```
357
227
 
358
- ### `--report-bug`
228
+ **Requirements:** Node.js 22+. 1.5.x line stays maintained on `main` for users who cannot upgrade.
359
229
 
360
- Writes `xlsx-for-ai-bugreport-<ISO-timestamp>.json` to the current directory. The report contains:
230
+ ---
361
231
 
362
- - File size, sheet count, per-sheet shape (rows × cols), per-sheet merge counts
363
- - Feature inventory detected via OOXML part inspection — pivot tables, charts, threaded comments, sensitivity labels, linked data types, sparklines, Power Query, slicers, timelines, dynamic arrays, conditional formatting, VBA, and more
364
- - Defined-name *labels* (e.g. `Totals`) — but NOT their target ranges or formulas
365
- - Tool version, Node version, OS + arch
232
+ ## Config
366
233
 
367
- What the report **never** contains: cell values, formulas, shared strings, named-range targets, comment text, or your absolute file path. You can `cat` it before attaching to verify.
234
+ Stored at `~/.xlsx-for-ai/config.json`. Created automatically on first run.
368
235
 
369
- ### `--export-redacted-workbook`
236
+ ```json
237
+ {
238
+ "client_id": "<uuid>",
239
+ "api_key": "<opaque>",
240
+ "registered_at": "2026-05-05T00:00:00.000Z",
241
+ "telemetry": false,
242
+ "consent_version": 1
243
+ }
244
+ ```
370
245
 
371
- Writes `<input>-redacted.xlsx` next to the input. Every cell value is replaced by a typed placeholder:
246
+ Telemetry is opt-in:
372
247
 
373
- | Original cell type | Placeholder |
374
- |--------------------|-------------|
375
- | Number | `0` |
376
- | String | `"x"` |
377
- | Boolean | `false` |
378
- | ISO date | `1899-12-30`|
379
- | Error | preserved |
248
+ ```bash
249
+ xlsx-for-ai --enable-telemetry
250
+ xlsx-for-ai --disable-telemetry
251
+ xlsx-for-ai --telemetry-status
252
+ ```
380
253
 
381
- Formulas, sheet names, merges, named ranges (formulas), styles, conditional formatting, pivots, charts, queries, and macros are passed through byte-for-byte at the ZIP/XML level (no lossy ExcelJS round-trip). Shared strings and comment payloads are also rewritten to `"x"` for defense-in-depth. Open the redacted file in Excel to confirm it still triggers the bug, then attach it.
254
+ Delete the config to reset your client ID and API key:
382
255
 
383
- ### Filing the issue
256
+ ```bash
257
+ rm ~/.xlsx-for-ai/config.json
258
+ ```
384
259
 
385
- Open https://github.com/senoff/xlsx-for-ai/issues — the bug template asks you to drag-drop the JSON (and optionally the redacted workbook). That's the whole workflow. No accounts to create, no SDK to integrate, no consent screen to click through.
260
+ ---
386
261
 
387
- ## Why This Exists
262
+ ## Migration from 1.5.x
388
263
 
389
- Spreadsheets are everywhere in real projects — financial models, data exports, config files, tax estimates. AI coding agents choke on binary formats. This tool makes spreadsheets legible to AI with zero information loss, including the tricky bits like shared formulas, named ranges, and merged cells that other tools drop.
264
+ | Was | Now |
265
+ |---|---|
266
+ | All rendering local | Rendering server-side; local engine is optional fallback for `xlsx_read` only |
267
+ | `xlsx-for-ai <file>` CLI | Same — still works |
268
+ | `cursor-reads-xlsx` | Still works — back-compat alias |
269
+ | `--list-sheets`, `--schema`, `--diff`, etc. | Moved to MCP tools (`xlsx_list_sheets`, `xlsx_schema`, `xlsx_diff`) |
270
+ | `--export-redacted-workbook` | Moved to `xlsx_redact` MCP tool |
271
+ | Heavy npm install (~50 MB) | Thin install (~2 MB); engine stays server-side |
272
+ | PII detection, region scoring | Moved server-side; not exposed in the npm package |
390
273
 
391
- ## Security
274
+ The config file at `~/.xlsx-for-ai/config.json` is extended in-place — existing telemetry consent is preserved.
392
275
 
393
- `xlsx-for-ai` parses untrusted `.xlsx` files on your machine. The
394
- project's security policy, supported-versions table, and reporting inbox
395
- are in [SECURITY.md](SECURITY.md). The supply-chain hardening that goes
396
- with it lives in [docs/INTEGRITY_PINNING.md](docs/INTEGRITY_PINNING.md)
397
- and [FORK_READINESS.md](FORK_READINESS.md).
276
+ ---
398
277
 
399
- ## License
278
+ ## Security
400
279
 
401
- MIT
280
+ See [SECURITY.md](SECURITY.md). All file content is transmitted to `xlsx-for-ai-server.fly.dev` over HTTPS. Files are not retained beyond the duration of a single request on the free tier.