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 +176 -297
- package/index.js +65 -2108
- package/lib/client.js +82 -0
- package/lib/config.js +95 -0
- package/lib/fallback-read.js +54 -0
- package/lib/register.js +37 -0
- package/mcp.js +314 -0
- package/package.json +18 -24
- package/WHY.md +0 -97
- package/cursor-rule-template/read-xlsx.mdc +0 -139
- package/lib/bugReport.js +0 -235
- package/lib/engine.js +0 -65
- package/lib/redactWorkbook.js +0 -326
- package/lib/telemetry-config.js +0 -115
- package/lib/telemetry-hooks.js +0 -138
- package/lib/telemetry-sanitize.js +0 -180
package/README.md
CHANGED
|
@@ -1,401 +1,280 @@
|
|
|
1
1
|
# xlsx-for-ai
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The missing reliability layer that makes spreadsheet reasoning production-grade for LLMs.**
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
-
npx xlsx-for-ai budget.xlsx
|
|
46
|
-
```
|
|
13
|
+
---
|
|
47
14
|
|
|
48
|
-
##
|
|
15
|
+
## MCP configuration
|
|
49
16
|
|
|
50
|
-
|
|
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
|
-
|
|
55
|
-
npx xlsx-for-ai data.xlsx "Sheet1"
|
|
19
|
+
### Claude Desktop
|
|
56
20
|
|
|
57
|
-
|
|
58
|
-
npx xlsx-for-ai data.xlsx --list-sheets
|
|
21
|
+
Config file: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
59
22
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"xlsx-for-ai": {
|
|
27
|
+
"command": "xlsx-for-ai-mcp"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
65
32
|
|
|
66
|
-
|
|
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
|
-
|
|
70
|
-
npx xlsx-for-ai data.xlsx --stdout --compact
|
|
35
|
+
### Cursor
|
|
71
36
|
|
|
72
|
-
|
|
73
|
-
npx xlsx-for-ai data.xlsx --json --stdout > out.json
|
|
37
|
+
Config file: `~/.cursor/mcp.json`
|
|
74
38
|
|
|
75
|
-
|
|
76
|
-
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"xlsx-for-ai": {
|
|
43
|
+
"command": "xlsx-for-ai-mcp"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
77
47
|
```
|
|
78
48
|
|
|
79
|
-
|
|
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
|
-
|
|
51
|
+
### Continue
|
|
91
52
|
|
|
92
|
-
|
|
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
|
-
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": [
|
|
58
|
+
{
|
|
59
|
+
"name": "xlsx-for-ai",
|
|
60
|
+
"command": "xlsx-for-ai-mcp"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
102
65
|
|
|
103
|
-
|
|
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
|
-
|
|
68
|
+
### Codex CLI
|
|
112
69
|
|
|
113
|
-
|
|
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
|
-
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"xlsx-for-ai": {
|
|
76
|
+
"command": "xlsx-for-ai-mcp"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
120
81
|
|
|
121
|
-
|
|
82
|
+
Verify: run `codex --list-tools` and confirm the six xlsx tools are listed.
|
|
122
83
|
|
|
123
|
-
|
|
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
|
-
|
|
86
|
+
Config file: `~/.config/zed/settings.json`
|
|
131
87
|
|
|
132
88
|
```json
|
|
133
89
|
{
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
148
|
-
{
|
|
149
|
-
"
|
|
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
|
-
|
|
117
|
+
Verify: open Windsurf → Cascade → settings, confirm `xlsx-for-ai` is listed as an active MCP server.
|
|
168
118
|
|
|
169
|
-
|
|
119
|
+
### Custom agents / API
|
|
170
120
|
|
|
171
|
-
|
|
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
|
-
|
|
123
|
+
---
|
|
174
124
|
|
|
175
|
-
|
|
125
|
+
## What it does
|
|
176
126
|
|
|
177
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
189
|
-
The path(s) are printed to stdout so your agent knows where to read.
|
|
140
|
+
---
|
|
190
141
|
|
|
191
|
-
##
|
|
142
|
+
## FP&A workflows
|
|
192
143
|
|
|
193
|
-
|
|
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
|
-
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
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
|
-
|
|
173
|
+
---
|
|
298
174
|
|
|
299
|
-
|
|
175
|
+
## Reliability features
|
|
300
176
|
|
|
301
|
-
**
|
|
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
|
-
|
|
183
|
+
---
|
|
304
184
|
|
|
305
|
-
|
|
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
|
-
|
|
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
|
-
|
|
189
|
+
See [PRIVACY.md](PRIVACY.md) for the full data-handling policy.
|
|
319
190
|
|
|
320
|
-
|
|
191
|
+
---
|
|
321
192
|
|
|
322
|
-
|
|
193
|
+
## Pricing
|
|
323
194
|
|
|
324
|
-
|
|
325
|
-
|
|
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
|
-
|
|
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
|
-
|
|
204
|
+
---
|
|
330
205
|
|
|
331
|
-
|
|
206
|
+
## License
|
|
332
207
|
|
|
333
|
-
|
|
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
|
-
|
|
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
|
-
|
|
340
|
-
xlsx-for-ai --disable-telemetry
|
|
212
|
+
## Architecture
|
|
341
213
|
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
228
|
+
**Requirements:** Node.js 22+. 1.5.x line stays maintained on `main` for users who cannot upgrade.
|
|
359
229
|
|
|
360
|
-
|
|
230
|
+
---
|
|
361
231
|
|
|
362
|
-
|
|
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
|
-
|
|
234
|
+
Stored at `~/.xlsx-for-ai/config.json`. Created automatically on first run.
|
|
368
235
|
|
|
369
|
-
|
|
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
|
-
|
|
246
|
+
Telemetry is opt-in:
|
|
372
247
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
254
|
+
Delete the config to reset your client ID and API key:
|
|
382
255
|
|
|
383
|
-
|
|
256
|
+
```bash
|
|
257
|
+
rm ~/.xlsx-for-ai/config.json
|
|
258
|
+
```
|
|
384
259
|
|
|
385
|
-
|
|
260
|
+
---
|
|
386
261
|
|
|
387
|
-
##
|
|
262
|
+
## Migration from 1.5.x
|
|
388
263
|
|
|
389
|
-
|
|
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
|
-
|
|
274
|
+
The config file at `~/.xlsx-for-ai/config.json` is extended in-place — existing telemetry consent is preserved.
|
|
392
275
|
|
|
393
|
-
|
|
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
|
-
##
|
|
278
|
+
## Security
|
|
400
279
|
|
|
401
|
-
|
|
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.
|