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 +1 -1
- package/dist/server.js +104 -41
- package/dist/server.js.map +2 -2
- package/dist/taskpane-app.js +31 -1
- package/dist/taskpane-app.js.map +2 -2
- package/manifest.xml +1 -1
- package/package.json +1 -1
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 (
|
|
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
|
|
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
|
|
20291
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
}
|