@components-kit/open-workbook 0.1.1 → 0.1.3

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.
@@ -64,12 +64,15 @@ Cleaning writes must stay within the requested sheet, range, table, or registere
64
64
  ## Update Tables, Filters, Or Sorts
65
65
 
66
66
  1. Inspect with `excel.table.get_info` and `excel.filter.get_filters`.
67
- 2. Use `excel.table.append_rows` or `excel.table.update_rows` for data.
68
- 3. Use `excel.table.resize` only when structure must change.
69
- 4. Preserve or reapply filters with `excel.filter.apply`, `excel.filter.preserve_from_template`, or `excel.table.preserve_filters`.
70
- 5. Validate with `excel.validate.tables` and `excel.validate.filters`.
67
+ 2. Use projected `excel.table.read` options when only some columns or rows are needed.
68
+ 3. Use `excel.table.reorder_columns` for column order changes.
69
+ 4. Use `excel.table.append_rows` or `excel.table.update_rows` for data.
70
+ 5. Use `excel.table.resize` only when structure must change.
71
+ 6. Preserve or reapply filters with `excel.filter.apply`, `excel.filter.preserve_from_template`, or `excel.table.preserve_filters`.
72
+ 7. Validate with `excel.validate.tables` and `excel.validate.filters`.
71
73
 
72
74
  Avoid raw range writes inside table bodies when table tools can express the intent.
75
+ Avoid full-table rewrites for layout changes such as column reorder; they are slow on large tables and can break table identity or dependent objects.
73
76
 
74
77
  ## Create Or Update Pivots And Charts
75
78
 
@@ -45,9 +45,10 @@ const STYLE_COPY_TOOL_DIMENSIONS = {
45
45
  "excel.style.copy_hidden_rows_columns": "hiddenRowsColumns"
46
46
  };
47
47
  const runtime = await createRuntimeFacade();
48
+ const runtimeVersion = process.env.OPEN_WORKBOOK_VERSION ?? "0.1.3";
48
49
  const server = new McpServer({
49
50
  name: "open-workbook",
50
- version: "0.1.1"
51
+ version: runtimeVersion
51
52
  });
52
53
  registerRuntimeTools(server);
53
54
  registerWorkbookTools(server);
@@ -974,14 +975,14 @@ function registerRangeTools(mcp) {
974
975
  ]) {
975
976
  registerMcpTool(mcp, name, {
976
977
  title: name.replace(/^excel\./, "").replace(/\./g, " "),
977
- description: "Read a range facet using the full range snapshot path.",
978
+ description: "Read one range facet without loading unrelated cell payloads.",
978
979
  inputSchema: readSchema,
979
980
  annotations: {
980
981
  readOnlyHint: true,
981
982
  destructiveHint: false,
982
983
  openWorldHint: false
983
984
  }
984
- }, async ({ workbookId, sheetName, address }) => jsonResult(await readRangeSnapshot(workbookId, sheetName, address)));
985
+ }, async ({ workbookId, sheetName, address }) => jsonResult(await readRangeSnapshot(workbookId, sheetName, address, rangeReadFacets(name))));
985
986
  }
986
987
  for (const [name, method] of [
987
988
  ["excel.range.read_hyperlinks", "range.read_hyperlinks"],
@@ -1951,10 +1952,19 @@ function registerTableTools(mcp) {
1951
1952
  }, async (args) => jsonResult(await runtime.getTableInfo(tableSelector(args))));
1952
1953
  registerMcpTool(mcp, "excel.table.read", {
1953
1954
  title: "Read Excel table",
1954
- description: "Read table headers, values, formulas, text, number formats, and metadata.",
1955
- inputSchema: tableSelectorSchema(),
1955
+ description: "Read table headers, selected data facets, optional columns, optional row page, and metadata.",
1956
+ inputSchema: {
1957
+ ...tableSelectorSchema(),
1958
+ includeValues: z.boolean().optional(),
1959
+ includeFormulas: z.boolean().optional(),
1960
+ includeText: z.boolean().optional(),
1961
+ includeNumberFormats: z.boolean().optional(),
1962
+ columns: z.array(z.union([z.string(), z.number().int().min(0)])).optional(),
1963
+ rowOffset: z.number().int().min(0).optional(),
1964
+ rowLimit: z.number().int().min(0).optional()
1965
+ },
1956
1966
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
1957
- }, async (args) => jsonResult(await runtime.readTable(tableSelector(args))));
1967
+ }, async (args) => jsonResult(await runtime.readTable(tableReadRequest(args))));
1958
1968
  registerMcpTool(mcp, "excel.table.create", {
1959
1969
  title: "Create Excel table",
1960
1970
  description: "Create a structured table from a range, optionally writing values first.",
@@ -1976,6 +1986,18 @@ function registerTableTools(mcp) {
1976
1986
  inputSchema: { ...tableSelectorSchema(), address: z.string() },
1977
1987
  annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
1978
1988
  }, async (args) => jsonResult(await runtime.resizeTable({ ...tableSelector(args), address: args.address })));
1989
+ registerMcpTool(mcp, "excel.table.reorder_columns", {
1990
+ title: "Reorder Excel table columns",
1991
+ description: "Reorder columns in an existing structured table without clearing or recreating the table.",
1992
+ inputSchema: {
1993
+ ...tableSelectorSchema(),
1994
+ columnOrder: z.array(z.union([z.string(), z.number().int().min(0)]))
1995
+ },
1996
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
1997
+ }, async (args) => jsonResult(await runtime.reorderTableColumns({
1998
+ ...tableSelector(args),
1999
+ columnOrder: args.columnOrder
2000
+ })));
1979
2001
  registerMcpTool(mcp, "excel.table.append_rows", {
1980
2002
  title: "Append Excel table rows",
1981
2003
  description: "Append one or more rows to a structured table.",
@@ -3251,7 +3273,23 @@ function registerEventTools(mcp) {
3251
3273
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
3252
3274
  }, async ({ debounceMs }) => jsonResult(runtime.setEventDebounce(debounceMs)));
3253
3275
  }
3254
- async function readRangeSnapshot(workbookId, sheetName, address) {
3276
+ function rangeReadFacets(toolName) {
3277
+ switch (toolName) {
3278
+ case "excel.range.read_values":
3279
+ return ["values"];
3280
+ case "excel.range.read_formulas":
3281
+ return ["formulas"];
3282
+ case "excel.range.read_number_formats":
3283
+ return ["numberFormat"];
3284
+ case "excel.range.read_display_text":
3285
+ return ["text"];
3286
+ case "excel.range.read_styles":
3287
+ return ["style"];
3288
+ default:
3289
+ return ["values", "formulas", "numberFormat", "text", "style"];
3290
+ }
3291
+ }
3292
+ async function readRangeSnapshot(workbookId, sheetName, address, facets) {
3255
3293
  const operation = {
3256
3294
  kind: "range.read_full",
3257
3295
  operationId: makeId("op"),
@@ -3264,6 +3302,9 @@ async function readRangeSnapshot(workbookId, sheetName, address) {
3264
3302
  address
3265
3303
  }
3266
3304
  };
3305
+ if (facets !== undefined) {
3306
+ operation.facets = facets;
3307
+ }
3267
3308
  return runtime.applyBatch({
3268
3309
  workbookId: workbookId,
3269
3310
  mode: "apply",
@@ -3290,6 +3331,31 @@ function tableSelector(args) {
3290
3331
  tableName: args.tableName
3291
3332
  };
3292
3333
  }
3334
+ function tableReadRequest(args) {
3335
+ const request = tableSelector(args);
3336
+ if (args.includeValues !== undefined) {
3337
+ request.includeValues = args.includeValues;
3338
+ }
3339
+ if (args.includeFormulas !== undefined) {
3340
+ request.includeFormulas = args.includeFormulas;
3341
+ }
3342
+ if (args.includeText !== undefined) {
3343
+ request.includeText = args.includeText;
3344
+ }
3345
+ if (args.includeNumberFormats !== undefined) {
3346
+ request.includeNumberFormats = args.includeNumberFormats;
3347
+ }
3348
+ if (args.columns !== undefined) {
3349
+ request.columns = args.columns;
3350
+ }
3351
+ if (args.rowOffset !== undefined) {
3352
+ request.rowOffset = args.rowOffset;
3353
+ }
3354
+ if (args.rowLimit !== undefined) {
3355
+ request.rowLimit = args.rowLimit;
3356
+ }
3357
+ return request;
3358
+ }
3293
3359
  function tableCreateRequest(args) {
3294
3360
  const request = {
3295
3361
  workbookId: args.workbookId,