@tiwater/office-mcp 0.16.6 → 0.16.8

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.
@@ -12,12 +12,9 @@ export function createToolResult(payload, { isError = false } = {}) {
12
12
  return {
13
13
  ...(isError ? { isError: true } : {}),
14
14
  structuredContent: payload,
15
- content: [
16
- {
17
- type: 'text',
18
- text: JSON.stringify(payload, null, 2),
19
- },
20
- ],
15
+ content: isError
16
+ ? [{ type: 'text', text: JSON.stringify(payload) }]
17
+ : [],
21
18
  };
22
19
  }
23
20
 
@@ -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.8"
6
6
  },
7
7
  "tools": [
8
8
  {
package/office/index.mjs CHANGED
@@ -136,19 +136,58 @@ 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
+ textPreview: z.string().nullable(),
170
+ }).strict();
171
+
172
+ const docxReadObjectOutput = artifactOutput('docx_read_object').extend({
173
+ revision: docxRevision,
174
+ object: docxObjectIdentity,
175
+ descendants: z.array(docxObjectIdentity),
176
+ }).strict();
177
+
139
178
  const tools = [
140
179
  {
141
180
  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.',
181
+ 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
182
  inputSchema: inputContract('docx_inspect'),
144
- outputSchema: artifactOutput('docx_inspect'),
183
+ outputSchema: docxInspectionOutput('docx_inspect'),
145
184
  handler: docxInspect,
146
185
  },
147
186
  {
148
187
  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.',
188
+ 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
189
  inputSchema: inputContract('docx_inspect_tables'),
151
- outputSchema: artifactOutput('docx_inspect_tables'),
190
+ outputSchema: docxInspectionOutput('docx_inspect_tables'),
152
191
  annotations: { readOnlyHint: true, idempotentHint: true },
153
192
  handler: docxInspectTables,
154
193
  },
@@ -168,9 +207,9 @@ const tools = [
168
207
  },
169
208
  {
170
209
  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.',
210
+ 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
211
  inputSchema: inputContract('docx_read_object'),
173
- outputSchema: artifactOutput('docx_read_object'),
212
+ outputSchema: docxReadObjectOutput,
174
213
  annotations: { readOnlyHint: true, idempotentHint: true },
175
214
  handler: docxReadObject,
176
215
  },
@@ -367,6 +406,41 @@ function buildServer() {
367
406
  return server;
368
407
  }
369
408
 
409
+ function compactDocxTableIndex(report) {
410
+ if (!report?.Revision || !Array.isArray(report.Tables)
411
+ || (report.StoryTables !== null && !Array.isArray(report.StoryTables))) {
412
+ throw new Error('docx-table-inspection-result-invalid');
413
+ }
414
+ const tables = [...report.Tables, ...(report.StoryTables ?? [])].map(table => {
415
+ const text = table.Rows.flatMap(row => row.Cells.map(cell => cell.Text))
416
+ .filter(value => typeof value === 'string' && value.length > 0)
417
+ .join(' ')
418
+ .replace(/\s+/gu, ' ')
419
+ .trim();
420
+ return {
421
+ ref: table.Ref,
422
+ tableIndex: table.TableIndex,
423
+ containmentPath: table.ContainmentPath,
424
+ parentCellAddress: table.ParentCellAddress ?? null,
425
+ storyKind: table.Story.Kind,
426
+ rowCount: table.RowCount,
427
+ columnCount: table.ColumnCount,
428
+ textPreview: text.length <= 160 ? text : `${text.slice(0, 160)}...`,
429
+ textLength: text.length,
430
+ };
431
+ });
432
+ return { revision: report.Revision, tables };
433
+ }
434
+
435
+ function compactDocxObjectIdentity(object) {
436
+ return {
437
+ ref: object.ref,
438
+ parentRef: object.parentRef,
439
+ kind: object.kind,
440
+ textPreview: object.textPreview,
441
+ };
442
+ }
443
+
370
444
  async function docxInspect(args) {
371
445
  const input = path.resolve(requireString(args.input, 'input'));
372
446
  const result = await runJsonCandidateChain(docxCandidates, ['inspect', input, '--json']);
@@ -375,13 +449,20 @@ async function docxInspect(args) {
375
449
  runtime: commandRuntime(result),
376
450
  source: await fileArtifact(input),
377
451
  artifact: await writeJsonArtifact(requireString(args.output, 'output'), result.json),
452
+ ...compactDocxTableIndex(result.json.tables),
378
453
  };
379
454
  }
380
455
 
381
456
  async function docxInspectTables(args) {
382
457
  const input = path.resolve(requireString(args.input, 'input'));
383
458
  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) };
459
+ return {
460
+ tool: 'docx_inspect_tables',
461
+ runtime: commandRuntime(result),
462
+ source: await fileArtifact(input),
463
+ artifact: await writeJsonArtifact(requireString(args.output, 'output'), result.json),
464
+ ...compactDocxTableIndex(result.json),
465
+ };
385
466
  }
386
467
 
387
468
  async function docxObservation(tool, args) {
@@ -402,6 +483,9 @@ async function docxReadObject(args) {
402
483
  runtime: commandRuntime(result),
403
484
  source: await fileArtifact(input),
404
485
  artifact: await writeJsonArtifact(output, result.json),
486
+ revision: result.json.receipt.revision,
487
+ object: compactDocxObjectIdentity(result.json.observation.object),
488
+ descendants: result.json.observation.descendants.map(compactDocxObjectIdentity),
405
489
  };
406
490
  });
407
491
  }
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.8",
4
4
  "description": "Published MCP server for Tiwater Office document capabilities",
5
5
  "type": "module",
6
6
  "license": "MIT",