xlsx-for-ai 2.1.0 → 2.2.0

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.
Files changed (2) hide show
  1. package/mcp.js +82 -1
  2. package/package.json +1 -1
package/mcp.js CHANGED
@@ -4,7 +4,7 @@
4
4
  /**
5
5
  * xlsx-for-ai MCP stdio server (2.0)
6
6
  *
7
- * Registers 16 tools and relays each tools/call to the hosted API.
7
+ * Registers 18 tools and relays each tools/call to the hosted API.
8
8
  * xlsx_read falls back to local engine if API is unreachable (5xx / timeout).
9
9
  * All other tools fail with a clear "needs API connectivity" error.
10
10
  */
@@ -393,6 +393,65 @@ const TOOLS = [
393
393
  },
394
394
  },
395
395
 
396
+ {
397
+ name: 'xlsx_eval',
398
+ description:
399
+ 'xlsx-for-ai — read, write, diff, redact, supervise .xlsx files locally.\n' +
400
+ 'This tool: evaluate Excel formulas against a LOCAL .xlsx file via HyperFormula. xlwings-style.\n' +
401
+ 'Two modes: pass `formulas` (array of "=SUM(A1:A10)" expressions to compute against the workbook) or `cells` (array of "Sheet1!A1" cell refs to fresh-evaluate). Replaces pandas\' "trust the cached value" behavior with a real eval — if the cache is stale or missing, this still produces the right answer.\n\n' +
402
+ 'USE WHEN: the user wants the live computed value of a formula, not the cached one. Or when a workbook has formulas that depend on external data the cache might be stale on. ' +
403
+ 'Engine omits INDIRECT/HYPERLINK/WEBSERVICE/RTD/DDE by design — no I/O risk.\n\n' +
404
+ 'DO NOT USE WHEN: the workbook has no formulas (use xlsx_read). Or for upload/attached files.',
405
+ inputSchema: {
406
+ type: 'object',
407
+ properties: {
408
+ file_path: { type: 'string', description: 'Absolute path to the .xlsx file.' },
409
+ formulas: {
410
+ type: 'array',
411
+ items: { type: 'string' },
412
+ description: 'Freeform formula expressions to evaluate against the workbook. Each ~"=A1+B1" or "=SUM(Sheet1!A:A)".',
413
+ },
414
+ cells: {
415
+ type: 'array',
416
+ items: { type: 'string' },
417
+ description: 'Cell refs to fresh-evaluate, e.g. ["Sheet1!A1", "Calc!B5"].',
418
+ },
419
+ sheet: { type: 'string', description: 'Default sheet for unqualified cell refs.' },
420
+ },
421
+ required: ['file_path'],
422
+ },
423
+ },
424
+
425
+ {
426
+ name: 'xlsx_convert',
427
+ description:
428
+ 'xlsx-for-ai — read, write, diff, redact, supervise .xlsx files locally.\n' +
429
+ 'This tool: universal spreadsheet format converter. Reads ANY of 25+ input formats (xlsx, xlsb, xlsm, xls, ods, fods, numbers, csv, tsv, dbf, lotus 1-2-3, quattro pro, sylk, dif, html, rtf, etc.) and emits ANY supported output format (xlsx, csv, json, md, html, etc.).\n' +
430
+ 'No other tool in the MCP space ingests legacy formats — pandas.read_excel only reads xlsx/xls; openpyxl is xlsx-only. xlsx_convert is the only "any-spreadsheet → LLM-readable" hosted endpoint.\n\n' +
431
+ 'USE WHEN: the user has a .xls / .xlsb / .ods / Numbers / .csv / Lotus / Quattro / dBASE file they want to read or convert. ' +
432
+ 'Output to text formats (csv/json/md/html) renders into the response body for the agent to read directly. Output to binary formats (xlsx/xlsb/etc.) returns bytes in `_meta.file_b64` for the npm client to save.\n\n' +
433
+ 'DO NOT USE WHEN: the input is already xlsx and you want to read it (use xlsx_read). Or for upload/attached files.',
434
+ inputSchema: {
435
+ type: 'object',
436
+ properties: {
437
+ file_path: { type: 'string', description: 'Absolute path to the source spreadsheet file (any supported format).' },
438
+ to: {
439
+ type: 'string',
440
+ enum: [
441
+ 'xlsx', 'xlsb', 'xlsm', 'xls', 'ods', 'fods', 'dbf',
442
+ 'csv', 'tsv', 'txt', 'html', 'md', 'json',
443
+ 'dif', 'sylk', 'eth', 'prn', 'rtf',
444
+ ],
445
+ description: 'Target format. Binary formats land bytes in _meta.file_b64; text formats render in body.',
446
+ },
447
+ sheet: { type: 'string', description: 'Render only this sheet (text outputs).' },
448
+ sheets: { type: 'string', enum: ['all', 'first'], description: 'For text outputs: render every sheet (default) or only the first.' },
449
+ out_path: { type: 'string', description: 'Optional save path for binary outputs (xlsx/xlsb/etc.).' },
450
+ },
451
+ required: ['file_path', 'to'],
452
+ },
453
+ },
454
+
396
455
  {
397
456
  name: 'xlsx_validate',
398
457
  description:
@@ -595,6 +654,28 @@ async function dispatchTool(name, args) {
595
654
  return callTool('xlsx_pivot', body);
596
655
  }
597
656
 
657
+ if (name === 'xlsx_eval') {
658
+ const body = {
659
+ file_b64: fileToB64(args.file_path),
660
+ options: { sheet: args.sheet },
661
+ };
662
+ if (args.formulas) body.formulas = args.formulas;
663
+ if (args.cells) body.cells = args.cells;
664
+ return callTool('xlsx_eval', body);
665
+ }
666
+
667
+ if (name === 'xlsx_convert') {
668
+ const body = {
669
+ file_b64: fileToB64(args.file_path),
670
+ to: args.to,
671
+ options: { sheet: args.sheet, sheets: args.sheets },
672
+ };
673
+ const result = await callTool('xlsx_convert', body);
674
+ // Binary outputs land bytes in _meta.file_b64 — apply the save helper
675
+ // if the user passed out_path.
676
+ return applyFileB64(result, args.out_path);
677
+ }
678
+
598
679
  if (name === 'xlsx_validate') {
599
680
  return callTool('xlsx_validate', {
600
681
  file_b64: fileToB64(args.file_path),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "xlsx-for-ai",
3
3
  "mcpName": "io.github.senoff/xlsx-for-ai",
4
- "version": "2.1.0",
4
+ "version": "2.2.0",
5
5
  "description": "The MCP server that makes LLMs reliable on real-world Excel spreadsheets. Thin npm client over a hosted API — read, write, diff, redact, and supervise .xlsx files from any MCP-aware agent.",
6
6
  "main": "index.js",
7
7
  "bin": {