mcp-word-bridge 4.0.3 → 4.0.5
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 +3 -1
- package/dist/server.js +146 -48
- package/dist/server.js.map +3 -3
- package/dist/taskpane-app.js +396 -298
- package/dist/taskpane-app.js.map +3 -3
- package/manifest.xml +1 -1
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# MCP Word Bridge
|
|
2
2
|
|
|
3
|
+
[](https://github.com/likelion/mcp-word-bridge/actions/workflows/tests.yml)
|
|
4
|
+
[](https://codecov.io/gh/likelion/mcp-word-bridge)
|
|
5
|
+
|
|
3
6
|
MCP server for live Word document editing via Office Add-in. Enables programmatic editing of Word documents through the Word JavaScript API, with changes appearing as user edits in co-authoring sessions.
|
|
4
7
|
|
|
5
8
|
## Quick Start
|
|
@@ -67,7 +70,6 @@ Single process. The MCP client spawns the server, which starts both the HTTPS br
|
|
|
67
70
|
| `word_set_document_properties` | Set metadata fields |
|
|
68
71
|
| `word_save` | Save document to disk |
|
|
69
72
|
| `word_clear` | Clear all document body content |
|
|
70
|
-
| `word_create_document` | Create and open a new blank document in a new Word window |
|
|
71
73
|
| `word_get_word_count` | Get word, character, and paragraph counts |
|
|
72
74
|
| `word_get_styles` | List available styles |
|
|
73
75
|
| `word_get_coauthors` | Get co-authoring status and active authors |
|
package/dist/server.js
CHANGED
|
@@ -18722,7 +18722,7 @@ var Bridge = class {
|
|
|
18722
18722
|
|
|
18723
18723
|
// src/server/mcp.ts
|
|
18724
18724
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
18725
|
-
var
|
|
18725
|
+
var import_types7 = require("@modelcontextprotocol/sdk/types.js");
|
|
18726
18726
|
|
|
18727
18727
|
// src/server/tools/helpers.ts
|
|
18728
18728
|
function jsonResult(data) {
|
|
@@ -18784,16 +18784,6 @@ var clear = forwardTool(
|
|
|
18784
18784
|
{ properties: {} },
|
|
18785
18785
|
"clearDocument"
|
|
18786
18786
|
);
|
|
18787
|
-
var createDocument = forwardTool(
|
|
18788
|
-
"word_create_document",
|
|
18789
|
-
"[Document] Create and open a new blank document in a new Word window. Optionally provide base64-encoded .docx as template.",
|
|
18790
|
-
{
|
|
18791
|
-
properties: {
|
|
18792
|
-
base64: { type: "string", description: "Optional base64-encoded .docx file to use as template" }
|
|
18793
|
-
}
|
|
18794
|
-
},
|
|
18795
|
-
"createNewDocument"
|
|
18796
|
-
);
|
|
18797
18787
|
var getWordCount = forwardTool(
|
|
18798
18788
|
"word_get_word_count",
|
|
18799
18789
|
"[Document] Get word, character, and paragraph counts.",
|
|
@@ -18857,7 +18847,6 @@ var documentTools = [
|
|
|
18857
18847
|
setDocumentProperties,
|
|
18858
18848
|
save,
|
|
18859
18849
|
clear,
|
|
18860
|
-
createDocument,
|
|
18861
18850
|
getWordCount,
|
|
18862
18851
|
getStyles,
|
|
18863
18852
|
getCoauthors,
|
|
@@ -18874,9 +18863,23 @@ var ToolError = class extends Error {
|
|
|
18874
18863
|
};
|
|
18875
18864
|
|
|
18876
18865
|
// src/server/validation.ts
|
|
18866
|
+
var WORD_SPECIAL_CODES = /\^(p|w|t|l|m|b|n|s|d|a|e|f|g|v|~|\^|\-|13|11|14|12|07|09|30|31|32|34|36|37|38|39|40|41|42|43|44|45|46|47|92|94|127|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255)/;
|
|
18867
|
+
function checkNoSpecialCodes(text2, paramName) {
|
|
18868
|
+
const match = text2.match(WORD_SPECIAL_CODES);
|
|
18869
|
+
if (match) {
|
|
18870
|
+
throw new ToolError(
|
|
18871
|
+
`${paramName} contains Word special code "${match[0]}" which can corrupt document structure. Use literal text only. Common special codes: ^p (paragraph mark), ^t (tab), ^w (whitespace), ^13 (paragraph mark).`
|
|
18872
|
+
);
|
|
18873
|
+
}
|
|
18874
|
+
}
|
|
18875
|
+
function checkNonEmpty(value, name) {
|
|
18876
|
+
if (!value || typeof value !== "string" || value.trim() === "") {
|
|
18877
|
+
throw new ToolError(`${name} must be a non-empty string.`);
|
|
18878
|
+
}
|
|
18879
|
+
}
|
|
18877
18880
|
function checkNonNegative(value, name) {
|
|
18878
|
-
if (typeof value !== "number" || value < 0) {
|
|
18879
|
-
throw new ToolError(`${name} must be non-negative.`);
|
|
18881
|
+
if (typeof value !== "number" || value < 0 || !Number.isInteger(value)) {
|
|
18882
|
+
throw new ToolError(`${name} must be a non-negative integer.`);
|
|
18880
18883
|
}
|
|
18881
18884
|
}
|
|
18882
18885
|
function checkBounds(index, count, name) {
|
|
@@ -18898,6 +18901,22 @@ function checkOccurrence(occurrence, count) {
|
|
|
18898
18901
|
}
|
|
18899
18902
|
return idx;
|
|
18900
18903
|
}
|
|
18904
|
+
var MAX_SPACING_POINTS = 1584;
|
|
18905
|
+
var MAX_CUSTOM_PROPERTY_KEY_LENGTH = 255;
|
|
18906
|
+
function checkSpacingBounds(value, name) {
|
|
18907
|
+
if (value > MAX_SPACING_POINTS) {
|
|
18908
|
+
throw new ToolError(
|
|
18909
|
+
`${name} value ${value} exceeds maximum (${MAX_SPACING_POINTS} points = 22 inches). Use a value between 0 and ${MAX_SPACING_POINTS}.`
|
|
18910
|
+
);
|
|
18911
|
+
}
|
|
18912
|
+
}
|
|
18913
|
+
function checkPropertyKeyLength(key) {
|
|
18914
|
+
if (key.length > MAX_CUSTOM_PROPERTY_KEY_LENGTH) {
|
|
18915
|
+
throw new ToolError(
|
|
18916
|
+
`key must be ${MAX_CUSTOM_PROPERTY_KEY_LENGTH} characters or fewer (got ${key.length}).`
|
|
18917
|
+
);
|
|
18918
|
+
}
|
|
18919
|
+
}
|
|
18901
18920
|
|
|
18902
18921
|
// src/server/tools/paragraphs.ts
|
|
18903
18922
|
var getParagraphs = forwardTool(
|
|
@@ -18987,10 +19006,10 @@ var setParagraphStyle = forwardTool(
|
|
|
18987
19006
|
},
|
|
18988
19007
|
"setParagraphStyle"
|
|
18989
19008
|
);
|
|
18990
|
-
var setParagraphSpacing =
|
|
18991
|
-
"word_set_paragraph_spacing",
|
|
18992
|
-
"[Paragraphs] Set line spacing, before/after spacing, and indentation on a paragraph by index.",
|
|
18993
|
-
{
|
|
19009
|
+
var setParagraphSpacing = {
|
|
19010
|
+
name: "word_set_paragraph_spacing",
|
|
19011
|
+
description: "[Paragraphs] Set line spacing, before/after spacing, and indentation on a paragraph by index.",
|
|
19012
|
+
schema: {
|
|
18994
19013
|
properties: {
|
|
18995
19014
|
index: { type: "number", description: "Paragraph index (0-based)" },
|
|
18996
19015
|
lineSpacing: { type: "number", description: "Line spacing in points" },
|
|
@@ -19002,8 +19021,26 @@ var setParagraphSpacing = forwardTool(
|
|
|
19002
19021
|
},
|
|
19003
19022
|
required: ["index"]
|
|
19004
19023
|
},
|
|
19005
|
-
|
|
19006
|
-
|
|
19024
|
+
async handler(args, bridge2) {
|
|
19025
|
+
const index = args.index;
|
|
19026
|
+
checkNonNegative(index, "index");
|
|
19027
|
+
const spacingFields = [
|
|
19028
|
+
["lineSpacing", args.lineSpacing],
|
|
19029
|
+
["spaceBefore", args.spaceBefore],
|
|
19030
|
+
["spaceAfter", args.spaceAfter],
|
|
19031
|
+
["firstLineIndent", args.firstLineIndent],
|
|
19032
|
+
["leftIndent", args.leftIndent],
|
|
19033
|
+
["rightIndent", args.rightIndent]
|
|
19034
|
+
];
|
|
19035
|
+
for (const [name, value] of spacingFields) {
|
|
19036
|
+
if (value !== void 0 && typeof value === "number") {
|
|
19037
|
+
checkSpacingBounds(value, name);
|
|
19038
|
+
}
|
|
19039
|
+
}
|
|
19040
|
+
const result = await bridge2.send("setParagraphSpacing", args);
|
|
19041
|
+
return jsonResult(result);
|
|
19042
|
+
}
|
|
19043
|
+
};
|
|
19007
19044
|
var moveParagraph = {
|
|
19008
19045
|
name: "word_move_paragraph",
|
|
19009
19046
|
description: "[Paragraphs] Move paragraph(s) to another position. Preserves all rich content including footnotes, hyperlinks, formatting, images, and comments.",
|
|
@@ -19023,6 +19060,7 @@ var moveParagraph = {
|
|
|
19023
19060
|
const location = args.location ?? "After";
|
|
19024
19061
|
checkNonNegative(fromIndex, "fromIndex");
|
|
19025
19062
|
checkNonNegative(toIndex, "toIndex");
|
|
19063
|
+
if (!Number.isInteger(count)) throw new ToolError("count must be an integer.");
|
|
19026
19064
|
if (count < 1) throw new ToolError("count must be at least 1");
|
|
19027
19065
|
if (fromIndex === toIndex && count === 1) throw new ToolError("fromIndex and toIndex must be different");
|
|
19028
19066
|
if (toIndex >= fromIndex && toIndex < fromIndex + count) {
|
|
@@ -19033,12 +19071,23 @@ var moveParagraph = {
|
|
|
19033
19071
|
checkBounds(fromIndex, total, "fromIndex");
|
|
19034
19072
|
if (fromIndex + count - 1 >= total) throw new ToolError(`fromIndex + count (${fromIndex + count}) exceeds paragraph count (${total}).`);
|
|
19035
19073
|
checkBounds(toIndex, total, "toIndex");
|
|
19074
|
+
for (const para of paraCount.paragraphs) {
|
|
19075
|
+
if (para.index >= fromIndex && para.index < fromIndex + count && para.inTable) {
|
|
19076
|
+
throw new ToolError(`Paragraph ${para.index} is inside a table cell. Use table-specific tools to modify table content.`);
|
|
19077
|
+
}
|
|
19078
|
+
}
|
|
19079
|
+
const adjustedTo = fromIndex < toIndex ? toIndex - count : toIndex;
|
|
19080
|
+
if (toIndex === fromIndex + count && location === "After") {
|
|
19081
|
+
return jsonResult({ success: true, warning: "No move performed \u2014 destination is equivalent to source position.", moved: null });
|
|
19082
|
+
}
|
|
19083
|
+
if (adjustedTo === fromIndex && location === "After") {
|
|
19084
|
+
return jsonResult({ success: true, warning: "No move performed \u2014 destination is equivalent to source position.", moved: null });
|
|
19085
|
+
}
|
|
19036
19086
|
const ooxmlResult = await bridge2.send("getParaOoxml", { index: fromIndex, count });
|
|
19037
19087
|
const savedOoxml = ooxmlResult.ooxml;
|
|
19038
19088
|
for (let i = count - 1; i >= 0; i--) {
|
|
19039
19089
|
await bridge2.send("deleteParagraph", { index: fromIndex + i });
|
|
19040
19090
|
}
|
|
19041
|
-
const adjustedTo = fromIndex < toIndex ? toIndex - count : toIndex;
|
|
19042
19091
|
try {
|
|
19043
19092
|
await bridge2.send("insertOoxmlAtIndex", { ooxml: savedOoxml, index: adjustedTo, location });
|
|
19044
19093
|
} catch (insertErr) {
|
|
@@ -19071,14 +19120,22 @@ var copyParagraph = {
|
|
|
19071
19120
|
const location = args.location ?? "After";
|
|
19072
19121
|
checkNonNegative(fromIndex, "fromIndex");
|
|
19073
19122
|
checkNonNegative(toIndex, "toIndex");
|
|
19123
|
+
if (!Number.isInteger(count)) throw new ToolError("count must be an integer.");
|
|
19074
19124
|
if (count < 1) throw new ToolError("count must be at least 1");
|
|
19075
19125
|
const paraCount = await bridge2.send("getParagraphs", {});
|
|
19076
19126
|
const total = paraCount.count;
|
|
19077
19127
|
checkBounds(fromIndex, total, "fromIndex");
|
|
19078
19128
|
if (fromIndex + count - 1 >= total) throw new ToolError(`fromIndex + count (${fromIndex + count}) exceeds paragraph count (${total}).`);
|
|
19079
19129
|
checkBounds(toIndex, total, "toIndex");
|
|
19130
|
+
for (const para of paraCount.paragraphs) {
|
|
19131
|
+
if (para.index >= fromIndex && para.index < fromIndex + count && para.inTable) {
|
|
19132
|
+
throw new ToolError(`Paragraph ${para.index} is inside a table cell. Use table-specific tools to modify table content.`);
|
|
19133
|
+
}
|
|
19134
|
+
}
|
|
19080
19135
|
const ooxmlResult = await bridge2.send("getParaOoxml", { index: fromIndex, count });
|
|
19081
|
-
|
|
19136
|
+
const effectiveToIndex = toIndex >= fromIndex && toIndex < fromIndex + count ? fromIndex + count - 1 : toIndex;
|
|
19137
|
+
const effectiveLocation = toIndex >= fromIndex && toIndex < fromIndex + count ? "After" : location;
|
|
19138
|
+
await bridge2.send("insertOoxmlAtIndex", { ooxml: ooxmlResult.ooxml, index: effectiveToIndex, location: effectiveLocation });
|
|
19082
19139
|
return jsonResult({ success: true, copied: { from: fromIndex, count, to: toIndex, location } });
|
|
19083
19140
|
}
|
|
19084
19141
|
};
|
|
@@ -19098,7 +19155,7 @@ var paragraphTools = [
|
|
|
19098
19155
|
// src/server/tools/search.ts
|
|
19099
19156
|
var search = forwardTool(
|
|
19100
19157
|
"word_search",
|
|
19101
|
-
|
|
19158
|
+
'[Search] Find text in the document. Returns match count and up to 30 matches. Query must be \u2264255 chars. Note: Word search codes (^p = paragraph mark, ^t = tab) are interpreted. To search for literal "^", use "^^".',
|
|
19102
19159
|
{
|
|
19103
19160
|
properties: {
|
|
19104
19161
|
query: { type: "string" },
|
|
@@ -19109,10 +19166,10 @@ var search = forwardTool(
|
|
|
19109
19166
|
},
|
|
19110
19167
|
"search"
|
|
19111
19168
|
);
|
|
19112
|
-
var searchAndReplace =
|
|
19113
|
-
"word_search_and_replace",
|
|
19114
|
-
"[Search] Find and replace ALL occurrences. For single-paragraph edits, prefer word_replace_paragraph_text.",
|
|
19115
|
-
{
|
|
19169
|
+
var searchAndReplace = {
|
|
19170
|
+
name: "word_search_and_replace",
|
|
19171
|
+
description: "[Search] Find and replace ALL occurrences. For single-paragraph edits, prefer word_replace_paragraph_text.",
|
|
19172
|
+
schema: {
|
|
19116
19173
|
properties: {
|
|
19117
19174
|
find: { type: "string" },
|
|
19118
19175
|
replace: { type: "string" },
|
|
@@ -19121,8 +19178,18 @@ var searchAndReplace = forwardTool(
|
|
|
19121
19178
|
},
|
|
19122
19179
|
required: ["find", "replace"]
|
|
19123
19180
|
},
|
|
19124
|
-
|
|
19125
|
-
|
|
19181
|
+
async handler(args, bridge2) {
|
|
19182
|
+
const find = args.find;
|
|
19183
|
+
const replace = args.replace;
|
|
19184
|
+
if (!find || typeof find !== "string" || find.trim() === "") {
|
|
19185
|
+
throw new ToolError("find string cannot be empty.");
|
|
19186
|
+
}
|
|
19187
|
+
checkNoSpecialCodes(find, "find");
|
|
19188
|
+
checkNoSpecialCodes(replace, "replace");
|
|
19189
|
+
const result = await bridge2.send("searchAndReplace", args);
|
|
19190
|
+
return jsonResult(result);
|
|
19191
|
+
}
|
|
19192
|
+
};
|
|
19126
19193
|
var insertTextAtMatch = forwardTool(
|
|
19127
19194
|
"word_insert_text_at_match",
|
|
19128
19195
|
'[Search] Insert text before or after a search match. Provide "after" OR "before" as the anchor text. Use occurrence for Nth match.',
|
|
@@ -19496,7 +19563,7 @@ var commentTools = [
|
|
|
19496
19563
|
// src/server/tools/footnotes.ts
|
|
19497
19564
|
var insertFootnote = forwardTool(
|
|
19498
19565
|
"word_insert_footnote",
|
|
19499
|
-
"[Footnotes] Insert a footnote anchored to a text match.",
|
|
19566
|
+
"[Footnotes] Insert a footnote anchored to a text match. Note: multiple footnotes on the same anchor appear in reverse insertion order (most recent first). Use word_insert_footnote_at_index for explicit placement.",
|
|
19500
19567
|
{
|
|
19501
19568
|
properties: {
|
|
19502
19569
|
anchorText: { type: "string", description: "Text to search for as anchor point" },
|
|
@@ -19703,10 +19770,10 @@ var insertContentControl = forwardTool(
|
|
|
19703
19770
|
},
|
|
19704
19771
|
"insertContentControl"
|
|
19705
19772
|
);
|
|
19706
|
-
var setContentControlText =
|
|
19707
|
-
"word_set_content_control_text",
|
|
19708
|
-
"[Content Controls] Set text in a content control identified by ID or tag. Does NOT work on CheckBox controls.",
|
|
19709
|
-
{
|
|
19773
|
+
var setContentControlText = {
|
|
19774
|
+
name: "word_set_content_control_text",
|
|
19775
|
+
description: "[Content Controls] Set text in a content control identified by ID or tag. Does NOT work on CheckBox controls.",
|
|
19776
|
+
schema: {
|
|
19710
19777
|
properties: {
|
|
19711
19778
|
id: { type: "number", description: "Content control ID" },
|
|
19712
19779
|
tag: { type: "string", description: "Content control tag (alternative to ID)" },
|
|
@@ -19714,8 +19781,25 @@ var setContentControlText = forwardTool(
|
|
|
19714
19781
|
},
|
|
19715
19782
|
required: ["text"]
|
|
19716
19783
|
},
|
|
19717
|
-
|
|
19718
|
-
|
|
19784
|
+
async handler(args, bridge2) {
|
|
19785
|
+
const tag = args.tag;
|
|
19786
|
+
const id = args.id;
|
|
19787
|
+
if (!tag && id === void 0) {
|
|
19788
|
+
throw new ToolError('Provide "id" or "tag" to identify the content control. Use word_get_content_controls to list available controls.');
|
|
19789
|
+
}
|
|
19790
|
+
if (tag) {
|
|
19791
|
+
const ccResult = await bridge2.send("getContentControls", {});
|
|
19792
|
+
const matches = ccResult.controls.filter((c) => c.tag === tag);
|
|
19793
|
+
if (matches.length > 1) {
|
|
19794
|
+
throw new ToolError(
|
|
19795
|
+
`Multiple content controls (${matches.length}) share tag "${tag}". Use "id" instead to target a specific control. Matching IDs: ${matches.map((m) => m.id).join(", ")}.`
|
|
19796
|
+
);
|
|
19797
|
+
}
|
|
19798
|
+
}
|
|
19799
|
+
const result = await bridge2.send("setContentControlText", args);
|
|
19800
|
+
return jsonResult(result);
|
|
19801
|
+
}
|
|
19802
|
+
};
|
|
19719
19803
|
var contentControlTools = [
|
|
19720
19804
|
getContentControls,
|
|
19721
19805
|
insertContentControl,
|
|
@@ -19930,18 +20014,24 @@ var getCustomProperties = forwardTool(
|
|
|
19930
20014
|
{ properties: {} },
|
|
19931
20015
|
"getCustomProperties"
|
|
19932
20016
|
);
|
|
19933
|
-
var setCustomProperty =
|
|
19934
|
-
"word_set_custom_property",
|
|
19935
|
-
"[Properties] Set a custom document property. Creates or updates the key-value pair.",
|
|
19936
|
-
{
|
|
20017
|
+
var setCustomProperty = {
|
|
20018
|
+
name: "word_set_custom_property",
|
|
20019
|
+
description: "[Properties] Set a custom document property. Creates or updates the key-value pair.",
|
|
20020
|
+
schema: {
|
|
19937
20021
|
properties: {
|
|
19938
20022
|
key: { type: "string" },
|
|
19939
20023
|
value: { type: "string" }
|
|
19940
20024
|
},
|
|
19941
20025
|
required: ["key", "value"]
|
|
19942
20026
|
},
|
|
19943
|
-
|
|
19944
|
-
|
|
20027
|
+
async handler(args, bridge2) {
|
|
20028
|
+
const key = args.key;
|
|
20029
|
+
checkNonEmpty(key, "key");
|
|
20030
|
+
checkPropertyKeyLength(key);
|
|
20031
|
+
const result = await bridge2.send("setCustomProperty", args);
|
|
20032
|
+
return jsonResult(result);
|
|
20033
|
+
}
|
|
20034
|
+
};
|
|
19945
20035
|
var deleteCustomProperty = forwardTool(
|
|
19946
20036
|
"word_delete_custom_property",
|
|
19947
20037
|
"[Properties] Delete a custom document property by key.",
|
|
@@ -20310,7 +20400,7 @@ After inserting a Table of Contents, heading text appears twice (in TOC and body
|
|
|
20310
20400
|
// package.json
|
|
20311
20401
|
var package_default = {
|
|
20312
20402
|
name: "mcp-word-bridge",
|
|
20313
|
-
version: "4.0.
|
|
20403
|
+
version: "4.0.5",
|
|
20314
20404
|
description: "MCP server for live Word document editing via Office Add-in",
|
|
20315
20405
|
main: "dist/server.js",
|
|
20316
20406
|
bin: {
|
|
@@ -20328,7 +20418,14 @@ var package_default = {
|
|
|
20328
20418
|
typecheck: "tsc --noEmit",
|
|
20329
20419
|
prepublishOnly: "npm run build"
|
|
20330
20420
|
},
|
|
20331
|
-
keywords: [
|
|
20421
|
+
keywords: [
|
|
20422
|
+
"mcp",
|
|
20423
|
+
"word",
|
|
20424
|
+
"office",
|
|
20425
|
+
"add-in",
|
|
20426
|
+
"document",
|
|
20427
|
+
"editing"
|
|
20428
|
+
],
|
|
20332
20429
|
repository: {
|
|
20333
20430
|
type: "git",
|
|
20334
20431
|
url: "https://github.com/likelion/mcp-word-bridge.git"
|
|
@@ -20344,6 +20441,7 @@ var package_default = {
|
|
|
20344
20441
|
devDependencies: {
|
|
20345
20442
|
"@types/node": "^22.0.0",
|
|
20346
20443
|
"@types/ws": "^8.5.10",
|
|
20444
|
+
"@vitest/coverage-v8": "^3.2.6",
|
|
20347
20445
|
esbuild: "^0.25.0",
|
|
20348
20446
|
eslint: "^10.4.1",
|
|
20349
20447
|
typescript: "^5.7.0",
|
|
@@ -20366,7 +20464,7 @@ function createMcpServer(bridge2) {
|
|
|
20366
20464
|
{ capabilities: { tools: {}, resources: {} } }
|
|
20367
20465
|
);
|
|
20368
20466
|
const { tools, handlers } = buildToolRegistry();
|
|
20369
|
-
server.setRequestHandler(
|
|
20467
|
+
server.setRequestHandler(import_types7.ListToolsRequestSchema, async () => ({
|
|
20370
20468
|
tools: tools.map((t) => ({
|
|
20371
20469
|
name: t.name,
|
|
20372
20470
|
description: t.description,
|
|
@@ -20377,7 +20475,7 @@ function createMcpServer(bridge2) {
|
|
|
20377
20475
|
}
|
|
20378
20476
|
}))
|
|
20379
20477
|
}));
|
|
20380
|
-
server.setRequestHandler(
|
|
20478
|
+
server.setRequestHandler(import_types7.CallToolRequestSchema, async (request) => {
|
|
20381
20479
|
const { name, arguments: args } = request.params;
|
|
20382
20480
|
const handler = handlers.get(name);
|
|
20383
20481
|
if (!handler) {
|
|
@@ -20391,7 +20489,7 @@ function createMcpServer(bridge2) {
|
|
|
20391
20489
|
return { content: [{ type: "text", text: msg }], isError: true };
|
|
20392
20490
|
}
|
|
20393
20491
|
});
|
|
20394
|
-
server.setRequestHandler(
|
|
20492
|
+
server.setRequestHandler(import_types7.ListResourcesRequestSchema, async () => ({
|
|
20395
20493
|
resources: [{
|
|
20396
20494
|
uri: "word-bridge://usage-guide",
|
|
20397
20495
|
name: "Word Bridge Usage Guide",
|
|
@@ -20399,7 +20497,7 @@ function createMcpServer(bridge2) {
|
|
|
20399
20497
|
mimeType: "text/markdown"
|
|
20400
20498
|
}]
|
|
20401
20499
|
}));
|
|
20402
|
-
server.setRequestHandler(
|
|
20500
|
+
server.setRequestHandler(import_types7.ReadResourceRequestSchema, async (request) => {
|
|
20403
20501
|
if (request.params.uri === "word-bridge://usage-guide") {
|
|
20404
20502
|
return { contents: [{ uri: request.params.uri, mimeType: "text/markdown", text: usageGuide }] };
|
|
20405
20503
|
}
|