mcp-word-bridge 4.1.3 → 4.1.4

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
@@ -60,7 +60,7 @@ MCP Client ←stdio→ Server ←WebSocket→ Taskpane (Office Add-in) ←→ Wo
60
60
 
61
61
  Single process. The MCP client spawns the server, which starts both the HTTPS bridge (for the add-in) and the MCP protocol handler (on stdio). Everything starts and stops together.
62
62
 
63
- ## Tools (92)
63
+ ## Tools (91)
64
64
 
65
65
  ### Document
66
66
  | Tool | Description |
package/dist/server.js CHANGED
@@ -18723,7 +18723,7 @@ var Bridge = class {
18723
18723
 
18724
18724
  // src/server/mcp.ts
18725
18725
  var import_server = require("@modelcontextprotocol/sdk/server/index.js");
18726
- var import_types9 = require("@modelcontextprotocol/sdk/types.js");
18726
+ var import_types10 = require("@modelcontextprotocol/sdk/types.js");
18727
18727
 
18728
18728
  // src/server/types.ts
18729
18729
  var ToolError = class extends Error {
@@ -18781,7 +18781,15 @@ var setDocumentProperties = forwardTool(
18781
18781
  format: { type: "string" }
18782
18782
  }
18783
18783
  },
18784
- "setDocumentProperties"
18784
+ "setDocumentProperties",
18785
+ (args) => {
18786
+ const hasProperty = args.title !== void 0 || args.subject !== void 0 || args.author !== void 0 || args.keywords !== void 0 || args.comments !== void 0 || args.category !== void 0 || args.company !== void 0 || args.manager !== void 0 || args.format !== void 0;
18787
+ if (!hasProperty) {
18788
+ throw new ToolError(
18789
+ "At least one document property must be provided (title, subject, author, keywords, comments, category, company, manager, format)."
18790
+ );
18791
+ }
18792
+ }
18785
18793
  );
18786
18794
  var save = forwardTool(
18787
18795
  "word_save",
@@ -18886,18 +18894,6 @@ function checkBounds(index, count, name) {
18886
18894
  );
18887
18895
  }
18888
18896
  }
18889
- function checkOccurrence(occurrence, count) {
18890
- const idx = occurrence ?? 0;
18891
- if (idx < 0) {
18892
- throw new ToolError("occurrence must be non-negative (0-indexed).");
18893
- }
18894
- if (idx >= count) {
18895
- throw new ToolError(
18896
- `Occurrence ${idx} not found (only ${count} match${count === 1 ? "" : "es"}).`
18897
- );
18898
- }
18899
- return idx;
18900
- }
18901
18897
  var MAX_SPACING_POINTS = 1584;
18902
18898
  var MAX_CUSTOM_PROPERTY_KEY_LENGTH = 255;
18903
18899
  function checkSpacingBounds(value, name) {
@@ -19032,7 +19028,12 @@ var setParagraphStyle = forwardTool(
19032
19028
  },
19033
19029
  required: ["index"]
19034
19030
  },
19035
- "setParagraphStyle"
19031
+ "setParagraphStyle",
19032
+ (args) => {
19033
+ if (args.style === void 0 && args.alignment === void 0) {
19034
+ throw new ToolError('At least one of "style" or "alignment" must be provided.');
19035
+ }
19036
+ }
19036
19037
  );
19037
19038
  var setParagraphSpacing = {
19038
19039
  name: "word_set_paragraph_spacing",
@@ -19279,7 +19280,10 @@ var insertTextAtMatch = forwardTool(
19279
19280
  },
19280
19281
  required: ["text"]
19281
19282
  },
19282
- "insertText"
19283
+ "insertText",
19284
+ (args) => {
19285
+ checkNonEmpty(args.text, "text");
19286
+ }
19283
19287
  );
19284
19288
  var getSelectionInfo = forwardTool(
19285
19289
  "word_get_selection_info",
@@ -19386,7 +19390,10 @@ var clearFormatting = forwardTool(
19386
19390
  },
19387
19391
  required: ["text"]
19388
19392
  },
19389
- "clearFormatting"
19393
+ "clearFormatting",
19394
+ (args) => {
19395
+ checkNonEmpty(args.text, "text");
19396
+ }
19390
19397
  );
19391
19398
  var getFontInfo = forwardTool(
19392
19399
  "word_get_font_info",
@@ -19399,7 +19406,10 @@ var getFontInfo = forwardTool(
19399
19406
  },
19400
19407
  required: ["text"]
19401
19408
  },
19402
- "getFontInfo"
19409
+ "getFontInfo",
19410
+ (args) => {
19411
+ checkNonEmpty(args.text, "text");
19412
+ }
19403
19413
  );
19404
19414
  var formattingTools = [
19405
19415
  formatText,
@@ -19422,7 +19432,24 @@ var insertTable = forwardTool(
19422
19432
  },
19423
19433
  required: ["rows", "cols"]
19424
19434
  },
19425
- "insertTable"
19435
+ "insertTable",
19436
+ (args) => {
19437
+ const rows = args.rows;
19438
+ const cols = args.cols;
19439
+ if (typeof rows !== "number" || !Number.isInteger(rows) || rows <= 0) throw new ToolError("rows must be a positive integer (minimum 1).");
19440
+ if (typeof cols !== "number" || !Number.isInteger(cols) || cols <= 0) throw new ToolError("cols must be a positive integer (minimum 1).");
19441
+ if (cols > 63) throw new ToolError("cols must not exceed 63 (Word maximum column limit).");
19442
+ if (rows > 500) throw new ToolError("rows must not exceed 500 (practical limit for performance).");
19443
+ if (args.data !== void 0) {
19444
+ const data = args.data;
19445
+ if (!Array.isArray(data)) throw new ToolError("data must be an array of arrays.");
19446
+ if (data.length !== rows) throw new ToolError(`Data rows (${data.length}) do not match specified rows (${rows}). Provide exactly ${rows} row(s) in the data array.`);
19447
+ for (let i = 0; i < data.length; i++) {
19448
+ if (!Array.isArray(data[i])) throw new ToolError(`data[${i}] must be an array.`);
19449
+ if (data[i].length !== cols) throw new ToolError(`Data row ${i} has ${data[i].length} columns but expected ${cols}.`);
19450
+ }
19451
+ }
19452
+ }
19426
19453
  );
19427
19454
  var listTables = forwardTool(
19428
19455
  "word_list_tables",
@@ -19453,7 +19480,12 @@ var setTableCell = forwardTool(
19453
19480
  },
19454
19481
  required: ["tableIndex", "row", "col", "text"]
19455
19482
  },
19456
- "setTableCell"
19483
+ "setTableCell",
19484
+ (args) => {
19485
+ checkNonNegative(args.tableIndex, "tableIndex");
19486
+ checkNonNegative(args.row, "row");
19487
+ checkNonNegative(args.col, "col");
19488
+ }
19457
19489
  );
19458
19490
  var addTableRow = forwardTool(
19459
19491
  "word_add_table_row",
@@ -19478,7 +19510,11 @@ var deleteTableRow = forwardTool(
19478
19510
  },
19479
19511
  required: ["tableIndex", "rowIndex"]
19480
19512
  },
19481
- "deleteTableRow"
19513
+ "deleteTableRow",
19514
+ (args) => {
19515
+ checkNonNegative(args.tableIndex, "tableIndex");
19516
+ checkNonNegative(args.rowIndex, "rowIndex");
19517
+ }
19482
19518
  );
19483
19519
  var mergeTableCells = forwardTool(
19484
19520
  "word_merge_table_cells",
@@ -19493,7 +19529,17 @@ var mergeTableCells = forwardTool(
19493
19529
  },
19494
19530
  required: ["tableIndex", "topRow", "firstCell", "bottomRow", "lastCell"]
19495
19531
  },
19496
- "mergeTableCells"
19532
+ "mergeTableCells",
19533
+ (args) => {
19534
+ checkNonNegative(args.tableIndex, "tableIndex");
19535
+ checkNonNegative(args.topRow, "topRow");
19536
+ checkNonNegative(args.firstCell, "firstCell");
19537
+ checkNonNegative(args.bottomRow, "bottomRow");
19538
+ checkNonNegative(args.lastCell, "lastCell");
19539
+ if (args.topRow > args.bottomRow) throw new ToolError(`topRow (${args.topRow}) must be less than or equal to bottomRow (${args.bottomRow}).`);
19540
+ if (args.firstCell > args.lastCell) throw new ToolError(`firstCell (${args.firstCell}) must be less than or equal to lastCell (${args.lastCell}).`);
19541
+ if (args.topRow === args.bottomRow && args.firstCell === args.lastCell) throw new ToolError("Cannot merge a single cell with itself. Provide a range spanning at least 2 cells.");
19542
+ }
19497
19543
  );
19498
19544
  var splitTableCell = forwardTool(
19499
19545
  "word_split_table_cell",
@@ -19508,7 +19554,14 @@ var splitTableCell = forwardTool(
19508
19554
  },
19509
19555
  required: ["tableIndex", "row", "col"]
19510
19556
  },
19511
- "splitTableCell"
19557
+ "splitTableCell",
19558
+ (args) => {
19559
+ checkNonNegative(args.tableIndex, "tableIndex");
19560
+ checkNonNegative(args.row, "row");
19561
+ checkNonNegative(args.col, "col");
19562
+ if (args.rowCount !== void 0 && (typeof args.rowCount !== "number" || args.rowCount <= 0)) throw new ToolError("rowCount must be a positive integer.");
19563
+ if (args.colCount !== void 0 && (typeof args.colCount !== "number" || args.colCount <= 0)) throw new ToolError("colCount must be a positive integer.");
19564
+ }
19512
19565
  );
19513
19566
  var setTableStyle = forwardTool(
19514
19567
  "word_set_table_style",
@@ -19534,7 +19587,13 @@ var setTableCellShading = forwardTool(
19534
19587
  },
19535
19588
  required: ["tableIndex", "row", "col", "color"]
19536
19589
  },
19537
- "setTableCellShading"
19590
+ "setTableCellShading",
19591
+ (args) => {
19592
+ checkNonNegative(args.tableIndex, "tableIndex");
19593
+ checkNonNegative(args.row, "row");
19594
+ checkNonNegative(args.col, "col");
19595
+ checkHexColor(args.color, "color");
19596
+ }
19538
19597
  );
19539
19598
  var tableTools = [
19540
19599
  insertTable,
@@ -20055,7 +20114,15 @@ var setPageLayout = forwardTool(
20055
20114
  paperSize: { type: "string", description: "Letter, A4, etc." }
20056
20115
  }
20057
20116
  },
20058
- "setPageLayout"
20117
+ "setPageLayout",
20118
+ (args) => {
20119
+ const hasProperty = args.orientation !== void 0 || args.topMargin !== void 0 || args.bottomMargin !== void 0 || args.leftMargin !== void 0 || args.rightMargin !== void 0 || args.paperSize !== void 0;
20120
+ if (!hasProperty) {
20121
+ throw new ToolError(
20122
+ "At least one layout property must be provided (orientation, topMargin, bottomMargin, leftMargin, rightMargin, paperSize)."
20123
+ );
20124
+ }
20125
+ }
20059
20126
  );
20060
20127
  var getSections = forwardTool(
20061
20128
  "word_get_sections",
@@ -20193,7 +20260,10 @@ var deleteCustomProperty = forwardTool(
20193
20260
  },
20194
20261
  required: ["key"]
20195
20262
  },
20196
- "deleteCustomProperty"
20263
+ "deleteCustomProperty",
20264
+ (args) => {
20265
+ checkNonEmpty(args.key, "key");
20266
+ }
20197
20267
  );
20198
20268
  var propertyTools = [
20199
20269
  getCustomProperties,
@@ -20253,7 +20323,6 @@ async function loadEquationLib() {
20253
20323
  buildEquationOoxml2 = lib.buildEquationOoxml;
20254
20324
  }
20255
20325
  }
20256
- var MARKER = "\u200B\uFEFF\u200B";
20257
20326
  var insertEquation = {
20258
20327
  name: "word_insert_equation",
20259
20328
  description: "[Equations] Insert a LaTeX math equation as a native editable Word equation. Display mode (default) inserts a centered block. Inline mode inserts after a search match (provide anchorText) or at cursor.",
@@ -20272,6 +20341,7 @@ var insertEquation = {
20272
20341
  await loadEquationLib();
20273
20342
  const { mml2omml: mml2omml2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
20274
20343
  const latex = args.latex;
20344
+ checkNonEmpty(latex, "latex");
20275
20345
  const displayMode = args.displayMode !== false;
20276
20346
  let result;
20277
20347
  try {
@@ -20287,15 +20357,8 @@ var insertEquation = {
20287
20357
  } else if (args.anchorText) {
20288
20358
  const anchorText = args.anchorText;
20289
20359
  const matchCase = args.matchCase || false;
20290
- const searchResult = await bridge2.send("search", { query: anchorText, matchCase });
20291
- if (!searchResult || searchResult.count === 0) throw new ToolError("Anchor not found: " + anchorText);
20292
- const occurrence = checkOccurrence(args.occurrence, searchResult.count);
20293
- await bridge2.send("insertText", { text: " " + MARKER, after: anchorText, occurrence, matchCase });
20294
- try {
20295
- await bridge2.send("insertOoxmlAtSelection", { ooxml });
20296
- } finally {
20297
- await bridge2.send("searchAndReplace", { find: MARKER, replace: "" });
20298
- }
20360
+ const occurrence = args.occurrence ?? 0;
20361
+ await bridge2.send("insertOoxmlAfterMatch", { ooxml, anchorText, occurrence, matchCase });
20299
20362
  } else {
20300
20363
  await bridge2.send("insertOoxmlAtSelection", { ooxml });
20301
20364
  }
@@ -20596,7 +20659,7 @@ Output always uses canonical form: "Left", "Center", "Right", "Justified".
20596
20659
  // package.json
20597
20660
  var package_default = {
20598
20661
  name: "mcp-word-bridge",
20599
- version: "4.1.3",
20662
+ version: "4.1.4",
20600
20663
  description: "MCP server for live Word document editing via Office Add-in",
20601
20664
  main: "dist/server.js",
20602
20665
  bin: {
@@ -20661,7 +20724,7 @@ function createMcpServer(bridge2) {
20661
20724
  );
20662
20725
  const { tools, handlers } = buildToolRegistry();
20663
20726
  const toolMutex = createMutex();
20664
- server.setRequestHandler(import_types9.ListToolsRequestSchema, async () => ({
20727
+ server.setRequestHandler(import_types10.ListToolsRequestSchema, async () => ({
20665
20728
  tools: tools.map((t) => ({
20666
20729
  name: t.name,
20667
20730
  description: t.description,
@@ -20672,7 +20735,7 @@ function createMcpServer(bridge2) {
20672
20735
  }
20673
20736
  }))
20674
20737
  }));
20675
- server.setRequestHandler(import_types9.CallToolRequestSchema, async (request) => {
20738
+ server.setRequestHandler(import_types10.CallToolRequestSchema, async (request) => {
20676
20739
  return toolMutex.run(async () => {
20677
20740
  const { name, arguments: args } = request.params;
20678
20741
  const handler = handlers.get(name);
@@ -20688,7 +20751,7 @@ function createMcpServer(bridge2) {
20688
20751
  }
20689
20752
  });
20690
20753
  });
20691
- server.setRequestHandler(import_types9.ListResourcesRequestSchema, async () => ({
20754
+ server.setRequestHandler(import_types10.ListResourcesRequestSchema, async () => ({
20692
20755
  resources: [{
20693
20756
  uri: "word-bridge://usage-guide",
20694
20757
  name: "Word Bridge Usage Guide",
@@ -20696,7 +20759,7 @@ function createMcpServer(bridge2) {
20696
20759
  mimeType: "text/markdown"
20697
20760
  }]
20698
20761
  }));
20699
- server.setRequestHandler(import_types9.ReadResourceRequestSchema, async (request) => {
20762
+ server.setRequestHandler(import_types10.ReadResourceRequestSchema, async (request) => {
20700
20763
  if (request.params.uri === "word-bridge://usage-guide") {
20701
20764
  return { contents: [{ uri: request.params.uri, mimeType: "text/markdown", text: usageGuide }] };
20702
20765
  }