@tiwater/office-mcp 0.16.6 → 0.16.7

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.
@@ -2,7 +2,7 @@
2
2
  "schema": "tiwater.office-provider-contract-manifest/v1",
3
3
  "provider": {
4
4
  "id": "@tiwater/office-mcp",
5
- "version": "0.16.6"
5
+ "version": "0.16.7"
6
6
  },
7
7
  "tools": [
8
8
  {
package/office/index.mjs CHANGED
@@ -136,19 +136,63 @@ function artifactOutput(tool) {
136
136
  return z.object({ tool: z.literal(tool), runtime: runtimeIdentity, source: artifact, artifact }).strict();
137
137
  }
138
138
 
139
+ const docxRevision = z.object({
140
+ id: z.string().regex(/^docx-rev-v1-[0-9a-f]{64}$/),
141
+ inputSha256: z.string().regex(/^[A-F0-9]{64}$/),
142
+ provider: z.literal('tiwater.docx.cli'),
143
+ toolVersion: z.string(),
144
+ }).strict();
145
+
146
+ const docxTableIndexEntry = z.object({
147
+ ref: z.string().regex(/^dox1_[0-9a-f]{64}$/),
148
+ tableIndex: z.number().int().nonnegative(),
149
+ containmentPath: z.array(z.string()),
150
+ parentCellAddress: z.string().nullable(),
151
+ storyKind: z.string(),
152
+ rowCount: z.number().int().nonnegative(),
153
+ columnCount: z.number().int().nonnegative(),
154
+ textPreview: z.string(),
155
+ textLength: z.number().int().nonnegative(),
156
+ }).strict();
157
+
158
+ function docxInspectionOutput(tool) {
159
+ return artifactOutput(tool).extend({
160
+ revision: docxRevision,
161
+ tables: z.array(docxTableIndexEntry),
162
+ }).strict();
163
+ }
164
+
165
+ const docxObjectIdentity = z.object({
166
+ ref: z.string().regex(/^dox1_[0-9a-f]{64}$/),
167
+ parentRef: z.string().regex(/^dox1_[0-9a-f]{64}$/).nullable(),
168
+ kind: z.string(),
169
+ storyPart: z.string(),
170
+ nativePath: z.string(),
171
+ localName: z.string(),
172
+ textPreview: z.string().nullable(),
173
+ textLength: z.number().int().nonnegative().nullable(),
174
+ childCount: z.number().int().nonnegative(),
175
+ }).strict();
176
+
177
+ const docxReadObjectOutput = artifactOutput('docx_read_object').extend({
178
+ revision: docxRevision,
179
+ object: docxObjectIdentity,
180
+ descendants: z.array(docxObjectIdentity),
181
+ }).strict();
182
+
139
183
  const tools = [
140
184
  {
141
185
  name: 'docx_inspect',
142
- description: 'Write the default single full-document DOCX observation containing body content, structure, placeholders, comments, anchors, tables, fields, flow, fonts, and formatting metrics. Its tables section includes the current revision and native refs for every observed table, row, cell, paragraph, and run; use those refs directly for mutation instead of listing the same descendants again. Do not also call docx_export_json for the same observation.',
186
+ description: 'Inspect one current DOCX. The response returns its revision and a bounded table identity index for the next selection; the complete observation remains in the evidence artifact.',
143
187
  inputSchema: inputContract('docx_inspect'),
144
- outputSchema: artifactOutput('docx_inspect'),
188
+ outputSchema: docxInspectionOutput('docx_inspect'),
145
189
  handler: docxInspect,
146
190
  },
147
191
  {
148
192
  name: 'docx_inspect_tables',
149
- description: 'Inspect current DOCX tables, cells, merges, paragraphs, runs, and formatting, returning the current revision and native refs for every observed table, row, cell, paragraph, and run. Use those refs directly for mutation instead of listing the same descendants again.',
193
+ description: 'Inspect current DOCX tables. The response returns the revision and a bounded table identity index; the complete table observation remains in the evidence artifact.',
150
194
  inputSchema: inputContract('docx_inspect_tables'),
151
- outputSchema: artifactOutput('docx_inspect_tables'),
195
+ outputSchema: docxInspectionOutput('docx_inspect_tables'),
152
196
  annotations: { readOnlyHint: true, idempotentHint: true },
153
197
  handler: docxInspectTables,
154
198
  },
@@ -168,9 +212,9 @@ const tools = [
168
212
  },
169
213
  {
170
214
  name: 'docx_read_object',
171
- description: 'Write one selected revision-bound native DOCX object, its Open XML, and every descendant object ref to a new JSON artifact. One table read provides all row, cell, paragraph, run, text, and drawing refs needed for mutation; do not enumerate those descendants with repeated list calls.',
215
+ description: 'Read one selected native DOCX object. The response returns that object and every descendant identity for the next operation; full Open XML remains in the evidence artifact.',
172
216
  inputSchema: inputContract('docx_read_object'),
173
- outputSchema: artifactOutput('docx_read_object'),
217
+ outputSchema: docxReadObjectOutput,
174
218
  annotations: { readOnlyHint: true, idempotentHint: true },
175
219
  handler: docxReadObject,
176
220
  },
@@ -367,6 +411,32 @@ function buildServer() {
367
411
  return server;
368
412
  }
369
413
 
414
+ function compactDocxTableIndex(report) {
415
+ if (!report?.Revision || !Array.isArray(report.Tables)
416
+ || (report.StoryTables !== null && !Array.isArray(report.StoryTables))) {
417
+ throw new Error('docx-table-inspection-result-invalid');
418
+ }
419
+ const tables = [...report.Tables, ...(report.StoryTables ?? [])].map(table => {
420
+ const text = table.Rows.flatMap(row => row.Cells.map(cell => cell.Text))
421
+ .filter(value => typeof value === 'string' && value.length > 0)
422
+ .join(' ')
423
+ .replace(/\s+/gu, ' ')
424
+ .trim();
425
+ return {
426
+ ref: table.Ref,
427
+ tableIndex: table.TableIndex,
428
+ containmentPath: table.ContainmentPath,
429
+ parentCellAddress: table.ParentCellAddress ?? null,
430
+ storyKind: table.Story.Kind,
431
+ rowCount: table.RowCount,
432
+ columnCount: table.ColumnCount,
433
+ textPreview: text.length <= 160 ? text : `${text.slice(0, 160)}...`,
434
+ textLength: text.length,
435
+ };
436
+ });
437
+ return { revision: report.Revision, tables };
438
+ }
439
+
370
440
  async function docxInspect(args) {
371
441
  const input = path.resolve(requireString(args.input, 'input'));
372
442
  const result = await runJsonCandidateChain(docxCandidates, ['inspect', input, '--json']);
@@ -375,13 +445,20 @@ async function docxInspect(args) {
375
445
  runtime: commandRuntime(result),
376
446
  source: await fileArtifact(input),
377
447
  artifact: await writeJsonArtifact(requireString(args.output, 'output'), result.json),
448
+ ...compactDocxTableIndex(result.json.tables),
378
449
  };
379
450
  }
380
451
 
381
452
  async function docxInspectTables(args) {
382
453
  const input = path.resolve(requireString(args.input, 'input'));
383
454
  const result = await runJsonCandidateChain(docxCandidates, ['inspect-tables', input, '--json']);
384
- return { tool: 'docx_inspect_tables', runtime: commandRuntime(result), source: await fileArtifact(input), artifact: await writeJsonArtifact(requireString(args.output, 'output'), result.json) };
455
+ return {
456
+ tool: 'docx_inspect_tables',
457
+ runtime: commandRuntime(result),
458
+ source: await fileArtifact(input),
459
+ artifact: await writeJsonArtifact(requireString(args.output, 'output'), result.json),
460
+ ...compactDocxTableIndex(result.json),
461
+ };
385
462
  }
386
463
 
387
464
  async function docxObservation(tool, args) {
@@ -402,6 +479,9 @@ async function docxReadObject(args) {
402
479
  runtime: commandRuntime(result),
403
480
  source: await fileArtifact(input),
404
481
  artifact: await writeJsonArtifact(output, result.json),
482
+ revision: result.json.receipt.revision,
483
+ object: result.json.observation.object,
484
+ descendants: result.json.observation.descendants,
405
485
  };
406
486
  });
407
487
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiwater/office-mcp",
3
- "version": "0.16.6",
3
+ "version": "0.16.7",
4
4
  "description": "Published MCP server for Tiwater Office document capabilities",
5
5
  "type": "module",
6
6
  "license": "MIT",