mcp-word-bridge 3.5.0 → 3.5.1
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 +2 -1
- package/index.js +1 -1
- package/lib/tools.js +2 -0
- package/package.json +1 -1
- package/taskpane-app.js +49 -0
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ mcp-word-bridge/
|
|
|
80
80
|
└── README.md
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
## Tools (
|
|
83
|
+
## Tools (91)
|
|
84
84
|
|
|
85
85
|
### Document
|
|
86
86
|
| Tool | Description |
|
|
@@ -222,6 +222,7 @@ mcp-word-bridge/
|
|
|
222
222
|
| `word_get_sections` | List all sections with page setup |
|
|
223
223
|
| `word_insert_page_break` | Insert a page break after a paragraph |
|
|
224
224
|
| `word_insert_section_break` | Insert a section break after a paragraph |
|
|
225
|
+
| `word_get_page_info` | Get page count and per-page paragraphs with document indices (Desktop only) |
|
|
225
226
|
|
|
226
227
|
### Custom Properties
|
|
227
228
|
| Tool | Description |
|
package/index.js
CHANGED
package/lib/tools.js
CHANGED
|
@@ -100,6 +100,7 @@ const tools = [
|
|
|
100
100
|
{ name: 'word_get_sections', description: '[Layout] List all sections with their page setup (margins, orientation, paper size).', inputSchema: { type: 'object', properties: {} } },
|
|
101
101
|
{ name: 'word_insert_page_break', description: '[Layout] Insert a page break after a paragraph. Omit paragraphIndex to insert at end of document.', inputSchema: { type: 'object', properties: { paragraphIndex: { type: 'number', description: 'Paragraph index (0-based). Omit for end of document.' } } } },
|
|
102
102
|
{ name: 'word_insert_section_break', description: '[Layout] Insert a section break after a paragraph. Cannot be used inside table cells.', inputSchema: { type: 'object', properties: { paragraphIndex: { type: 'number', description: 'Paragraph index (0-based). Omit for end of document.' }, breakType: { type: 'string', enum: ['SectionNext', 'SectionContinuous', 'SectionEven', 'SectionOdd'], description: 'Default: SectionNext' } } } },
|
|
103
|
+
{ name: 'word_get_page_info', description: '[Layout] Get page count and per-page paragraph ranges. Returns page dimensions and the first/last document paragraph index for each page. Use with word_get_paragraphs to read specific page content.', inputSchema: { type: 'object', properties: {} } },
|
|
103
104
|
// 16. CUSTOM PROPERTIES
|
|
104
105
|
{ name: 'word_get_custom_properties', description: '[Properties] Get all custom document properties (key-value pairs with types).', inputSchema: { type: 'object', properties: {} } },
|
|
105
106
|
{ name: 'word_set_custom_property', description: '[Properties] Set a custom document property. Creates or updates the key-value pair.', inputSchema: { type: 'object', properties: { key: { type: 'string' }, value: { type: 'string' } }, required: ['key', 'value'] } },
|
|
@@ -161,6 +162,7 @@ const toolActionMap = {
|
|
|
161
162
|
word_delete_custom_property: 'deleteCustomProperty',
|
|
162
163
|
word_insert_html: 'insertHtml', word_insert_ooxml: 'insertOoxml',
|
|
163
164
|
word_insert_table_of_contents: 'insertTableOfContents', word_get_fields: 'getFields',
|
|
165
|
+
word_get_page_info: 'getPageInfo',
|
|
164
166
|
// word_insert_equation, word_batch, word_get_document_outline, word_move_paragraph
|
|
165
167
|
// are handled directly in index.js (not via taskpane action map)
|
|
166
168
|
};
|
package/package.json
CHANGED
package/taskpane-app.js
CHANGED
|
@@ -1431,6 +1431,55 @@ commands.clearFormatting = (p) => Word.run(async (ctx) => {
|
|
|
1431
1431
|
return { success: true };
|
|
1432
1432
|
});
|
|
1433
1433
|
|
|
1434
|
+
// == PAGE INFO (WordApiDesktop 1.2+) ==
|
|
1435
|
+
commands.getPageInfo = async () => {
|
|
1436
|
+
if (!Office.context.requirements.isSetSupported('WordApiDesktop', '1.2')) {
|
|
1437
|
+
throw new Error('Page API not available on this platform (requires desktop Word).');
|
|
1438
|
+
}
|
|
1439
|
+
return Word.run(async (ctx) => {
|
|
1440
|
+
const bodyRange = ctx.document.body.getRange();
|
|
1441
|
+
const pages = bodyRange.pages;
|
|
1442
|
+
pages.load('items');
|
|
1443
|
+
await ctx.sync();
|
|
1444
|
+
const pageCount = pages.items.length;
|
|
1445
|
+
// Load all body paragraphs to map page boundaries to document indices
|
|
1446
|
+
const allParas = ctx.document.body.paragraphs;
|
|
1447
|
+
allParas.load('text,style');
|
|
1448
|
+
await ctx.sync();
|
|
1449
|
+
const pageDetails = [];
|
|
1450
|
+
const usedIndices = new Set();
|
|
1451
|
+
for (let i = 0; i < pages.items.length; i++) {
|
|
1452
|
+
const page = pages.items[i];
|
|
1453
|
+
page.load('index,height,width');
|
|
1454
|
+
const paras = page.getRange().paragraphs;
|
|
1455
|
+
paras.load('text,style');
|
|
1456
|
+
await ctx.sync();
|
|
1457
|
+
let firstIdx = -1;
|
|
1458
|
+
let lastIdx = -1;
|
|
1459
|
+
for (let j = 0; j < paras.items.length; j++) {
|
|
1460
|
+
const p = paras.items[j];
|
|
1461
|
+
for (let k = 0; k < allParas.items.length; k++) {
|
|
1462
|
+
if (!usedIndices.has(k) && allParas.items[k].text === p.text && allParas.items[k].style === p.style) {
|
|
1463
|
+
usedIndices.add(k);
|
|
1464
|
+
if (firstIdx === -1) firstIdx = k;
|
|
1465
|
+
lastIdx = k;
|
|
1466
|
+
break;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
pageDetails.push({
|
|
1471
|
+
pageIndex: page.index,
|
|
1472
|
+
height: page.height,
|
|
1473
|
+
width: page.width,
|
|
1474
|
+
paragraphCount: paras.items.length,
|
|
1475
|
+
firstParagraphIndex: firstIdx,
|
|
1476
|
+
lastParagraphIndex: lastIdx
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
return { pageCount, pages: pageDetails };
|
|
1480
|
+
});
|
|
1481
|
+
};
|
|
1482
|
+
|
|
1434
1483
|
// == INSERT TOC ==
|
|
1435
1484
|
commands.insertTableOfContents = (p) => Word.run(async (ctx) => {
|
|
1436
1485
|
const body = ctx.document.body;
|