document-mcp 3.0.3 → 4.0.0

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 CHANGED
@@ -213,7 +213,7 @@ Every tool that takes or produces document bytes goes through the same two hybri
213
213
  | `docx_extras` | Reads a docx's own comments, footnotes, header/footer parts, and numbering definitions — data the `ContentDocument` pivot cannot carry, so no other tool sees it. |
214
214
  | `pdf_inspect` | Parses a PDF and reports a summary (page count, per-page size and item-kind histogram, metadata, embedded image formats), or with `full: true` the entire parsed `LayoutDocument` as plain JSON — no `$schema` stamp, since that family moved to `pdf-codec` at `document-schema.js` 4.0.0 and lost its schema-stamped envelope. |
215
215
  | `odm_to_pdf` | Converts a `.odm` (ODF master document) to PDF. A `.odm` never carries its chapters' content inline, so each chapter resolves via a caller-supplied `chapters` href-to-document map and/or a `chaptersDir` searched by basename. |
216
- | `from_package` | Rebuilds real document bytes in a target format from a `DocumentPackage` previously serialised to JSON (e.g. by a conversion tool's own `onDocument`/package-dump step). Only a package genuinely written by a current dump round-trips: the `$schema` URI it carries pins the `document-schema.js` release that wrote it, and a pre-4.0.0 dump (the flat `{ formatVersion, content, pages }` envelope) is rejected with an error naming the pinned release, the flat-to-tree change, and the remedy — a layout-document dump gets its own pointer, naming the move to `pdf-codec`. |
216
+ | `from_package` | Rebuilds real document bytes in a target format from a `DocumentTree` previously serialised to JSON (e.g. by a conversion tool's own `onDocument`/package-dump step). Only a package genuinely written by a current dump round-trips: the `$schema` URI it carries pins the `document-schema.js` release that wrote it, and a pre-4.0.0 dump (the flat `{ formatVersion, content, pages }` envelope) is rejected with an error naming the pinned release, the flat-to-tree change, and the remedy — a layout-document dump gets its own pointer, naming the move to `pdf-codec`. |
217
217
  | `outline_document` | Projects a document's own table of contents as structured JSON: groups (`{ text, level, children }`) for headings, list items, slides, sheets, and draw pages, leaves (`{ kind, text }`) for the content between them. The outline is over the source's own content — read through `documents.js`'s `DocumentConverter` port and built by `document-outline.js`'s `buildOutline`. |
218
218
  | `odb_tables` | Lists every table an embedded `.odb` database declares — column names, types, and row data — across every storage tier `documents.js` supports (HSQLDB TEXT/CACHED/BINARY, Firebird gbak backups). |
219
219
  | `odb_forms` | Lists every form an `.odb` database declares, with each form's own data source and field-bound controls. |
@@ -226,7 +226,7 @@ Every tool that takes or produces document bytes goes through the same two hybri
226
226
  ## References
227
227
 
228
228
  - [documents.js](https://github.com/ExaDev/documents.js) — the library this server exposes.
229
- - [document-outline.js](../document-outline.js/README.md) — the artefact-utilities package over document-schema.js's tree-form `DocumentPackage` whose `buildOutline` powers `outline_document`.
229
+ - [document-outline.js](../document-outline.js/README.md) — the artefact-utilities package over document-schema.js's tree-form `DocumentTree` whose `buildOutline` powers `outline_document`.
230
230
  - [document-cli](../document-cli/README.md) — the sibling CLI/TUI over the same library, whose toolchain this repository's scaffold mirrors.
231
231
  - [Model Context Protocol](https://modelcontextprotocol.io) — the protocol this server implements, via [`@modelcontextprotocol/server`](https://www.npmjs.com/package/@modelcontextprotocol/server).
232
232
 
package/dist/bin.js CHANGED
@@ -8,7 +8,7 @@ import { existsSync, readFileSync } from "node:fs";
8
8
  import { basename, join } from "node:path";
9
9
  import { buildOutline, isOutlineNode, outlineLeafText } from "document-outline.js";
10
10
  //#region package.json
11
- var version = "3.0.3";
11
+ var version = "4.0.0";
12
12
  //#endregion
13
13
  //#region src/io/document-input.ts
14
14
  const EXTENSION_TO_FORMAT = {
@@ -326,10 +326,10 @@ function isNamedError(error, name) {
326
326
  function registerFromPackageTools(server) {
327
327
  server.registerTool("from_package", {
328
328
  title: "Build document from package",
329
- description: "Rebuilds real document bytes in a target format from a DocumentPackage previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentPackage round trip a conversion's onDocument callback produces.",
329
+ description: "Rebuilds real document bytes in a target format from a DocumentTree previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentTree round trip a conversion's onDocument callback produces.",
330
330
  inputSchema: z.object({
331
- source: DocumentInputSchema.describe("The DocumentPackage JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentPackage, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
332
- targetFormat: DocumentFormatSchema.describe("The document format to build from the DocumentPackage."),
331
+ source: DocumentInputSchema.describe("The DocumentTree JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentTree, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
332
+ targetFormat: DocumentFormatSchema.describe("The document format to build from the DocumentTree."),
333
333
  output: DocumentOutputSchema.optional().describe("Where to write the resulting document. Omit entirely (or omit outputPath within it) to receive the bytes inline instead.")
334
334
  })
335
335
  }, async ({ source, targetFormat, output }) => {
@@ -343,7 +343,7 @@ function registerFromPackageTools(server) {
343
343
  return errorResult(`'source' is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
344
344
  }
345
345
  const result = documentFromJson(parsed);
346
- if (result.kind !== "DocumentPackage") return errorResult(`'source' is a ${result.kind}, not a DocumentPackage -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
346
+ if (result.kind !== "DocumentTree") return errorResult(`'source' is a ${result.kind}, not a DocumentTree -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
347
347
  const resolvedOutput = await resolveDocumentOutput(buildDocumentBytes(result.value, targetFormat), output ?? {});
348
348
  return {
349
349
  content: [{
@@ -353,9 +353,10 @@ function registerFromPackageTools(server) {
353
353
  structuredContent: resolvedOutput
354
354
  };
355
355
  } catch (error) {
356
- if (error instanceof UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
356
+ if (error instanceof UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
357
357
  if (isNamedError(error, "SchemaVersionMismatchError")) return errorResult(error.message);
358
358
  if (isNamedError(error, "LayoutSchemaDemotedError")) return errorResult(error.message);
359
+ if (isNamedError(error, "DocumentPackageRenamedError")) return errorResult(error.message);
359
360
  if (error instanceof z.ZodError) return errorResult(`'source' failed ${documentSchemaKindOf(parsed) ?? "document schema"} validation: ${error.message}`);
360
361
  return errorResult(error instanceof Error ? error.message : String(error));
361
362
  }
@@ -808,7 +809,7 @@ function registerOutlineTools(server) {
808
809
  const converter = createLocalDocumentConverter();
809
810
  server.registerTool("outline_document", {
810
811
  title: "Outline document",
811
- description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentPackage the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
812
+ description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentTree the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
812
813
  inputSchema: z.object({ source: DocumentInputSchema.describe("The document to outline.") })
813
814
  }, async ({ source }, ctx) => {
814
815
  const { signal } = ctx.mcpReq;
@@ -821,7 +822,7 @@ function registerOutlineTools(server) {
821
822
  },
822
823
  targetFormat
823
824
  }, { signal })).package;
824
- if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentPackage, so there is no tree to outline`);
825
+ if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentTree, so there is no tree to outline`);
825
826
  const structuredContent = {
826
827
  sourceFormat: format,
827
828
  kind: pkg.kind,
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ let node_fs = require("node:fs");
7
7
  let node_path = require("node:path");
8
8
  let document_outline_js = require("document-outline.js");
9
9
  //#region package.json
10
- var version = "3.0.3";
10
+ var version = "4.0.0";
11
11
  //#endregion
12
12
  //#region src/io/document-input.ts
13
13
  const EXTENSION_TO_FORMAT = {
@@ -325,10 +325,10 @@ function isNamedError(error, name) {
325
325
  function registerFromPackageTools(server) {
326
326
  server.registerTool("from_package", {
327
327
  title: "Build document from package",
328
- description: "Rebuilds real document bytes in a target format from a DocumentPackage previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentPackage round trip a conversion's onDocument callback produces.",
328
+ description: "Rebuilds real document bytes in a target format from a DocumentTree previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentTree round trip a conversion's onDocument callback produces.",
329
329
  inputSchema: zod.z.object({
330
- source: DocumentInputSchema.describe("The DocumentPackage JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentPackage, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
331
- targetFormat: documents_js.DocumentFormatSchema.describe("The document format to build from the DocumentPackage."),
330
+ source: DocumentInputSchema.describe("The DocumentTree JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentTree, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
331
+ targetFormat: documents_js.DocumentFormatSchema.describe("The document format to build from the DocumentTree."),
332
332
  output: DocumentOutputSchema.optional().describe("Where to write the resulting document. Omit entirely (or omit outputPath within it) to receive the bytes inline instead.")
333
333
  })
334
334
  }, async ({ source, targetFormat, output }) => {
@@ -342,7 +342,7 @@ function registerFromPackageTools(server) {
342
342
  return errorResult(`'source' is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
343
343
  }
344
344
  const result = (0, documents_js.documentFromJson)(parsed);
345
- if (result.kind !== "DocumentPackage") return errorResult(`'source' is a ${result.kind}, not a DocumentPackage -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
345
+ if (result.kind !== "DocumentTree") return errorResult(`'source' is a ${result.kind}, not a DocumentTree -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
346
346
  const resolvedOutput = await resolveDocumentOutput((0, documents_js.buildDocumentBytes)(result.value, targetFormat), output ?? {});
347
347
  return {
348
348
  content: [{
@@ -352,9 +352,10 @@ function registerFromPackageTools(server) {
352
352
  structuredContent: resolvedOutput
353
353
  };
354
354
  } catch (error) {
355
- if (error instanceof documents_js.UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
355
+ if (error instanceof documents_js.UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
356
356
  if (isNamedError(error, "SchemaVersionMismatchError")) return errorResult(error.message);
357
357
  if (isNamedError(error, "LayoutSchemaDemotedError")) return errorResult(error.message);
358
+ if (isNamedError(error, "DocumentPackageRenamedError")) return errorResult(error.message);
358
359
  if (error instanceof zod.z.ZodError) return errorResult(`'source' failed ${(0, documents_js.documentSchemaKindOf)(parsed) ?? "document schema"} validation: ${error.message}`);
359
360
  return errorResult(error instanceof Error ? error.message : String(error));
360
361
  }
@@ -807,7 +808,7 @@ function registerOutlineTools(server) {
807
808
  const converter = (0, documents_js.createLocalDocumentConverter)();
808
809
  server.registerTool("outline_document", {
809
810
  title: "Outline document",
810
- description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentPackage the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
811
+ description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentTree the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
811
812
  inputSchema: zod.z.object({ source: DocumentInputSchema.describe("The document to outline.") })
812
813
  }, async ({ source }, ctx) => {
813
814
  const { signal } = ctx.mcpReq;
@@ -820,7 +821,7 @@ function registerOutlineTools(server) {
820
821
  },
821
822
  targetFormat
822
823
  }, { signal })).package;
823
- if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentPackage, so there is no tree to outline`);
824
+ if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentTree, so there is no tree to outline`);
824
825
  const structuredContent = {
825
826
  sourceFormat: format,
826
827
  kind: pkg.kind,
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { existsSync, readFileSync } from "node:fs";
6
6
  import { basename, join } from "node:path";
7
7
  import { buildOutline, isOutlineNode, outlineLeafText } from "document-outline.js";
8
8
  //#region package.json
9
- var version = "3.0.3";
9
+ var version = "4.0.0";
10
10
  //#endregion
11
11
  //#region src/io/document-input.ts
12
12
  const EXTENSION_TO_FORMAT = {
@@ -324,10 +324,10 @@ function isNamedError(error, name) {
324
324
  function registerFromPackageTools(server) {
325
325
  server.registerTool("from_package", {
326
326
  title: "Build document from package",
327
- description: "Rebuilds real document bytes in a target format from a DocumentPackage previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentPackage round trip a conversion's onDocument callback produces.",
327
+ description: "Rebuilds real document bytes in a target format from a DocumentTree previously serialised to JSON (e.g. by a caller's own --dump-package-equivalent step) -- the read side of the DocumentTree round trip a conversion's onDocument callback produces.",
328
328
  inputSchema: z.object({
329
- source: DocumentInputSchema.describe("The DocumentPackage JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentPackage, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
330
- targetFormat: DocumentFormatSchema.describe("The document format to build from the DocumentPackage."),
329
+ source: DocumentInputSchema.describe("The DocumentTree JSON to read. 'path' points at a JSON file on disk -- its extension is never used to infer a document format, since the file holds a DocumentTree, not a document. 'bytesBase64' carries the JSON inline; its 'format' field is required by the shared hybrid input shape but unused by this tool."),
330
+ targetFormat: DocumentFormatSchema.describe("The document format to build from the DocumentTree."),
331
331
  output: DocumentOutputSchema.optional().describe("Where to write the resulting document. Omit entirely (or omit outputPath within it) to receive the bytes inline instead.")
332
332
  })
333
333
  }, async ({ source, targetFormat, output }) => {
@@ -341,7 +341,7 @@ function registerFromPackageTools(server) {
341
341
  return errorResult(`'source' is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
342
342
  }
343
343
  const result = documentFromJson(parsed);
344
- if (result.kind !== "DocumentPackage") return errorResult(`'source' is a ${result.kind}, not a DocumentPackage -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
344
+ if (result.kind !== "DocumentTree") return errorResult(`'source' is a ${result.kind}, not a DocumentTree -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool`);
345
345
  const resolvedOutput = await resolveDocumentOutput(buildDocumentBytes(result.value, targetFormat), output ?? {});
346
346
  return {
347
347
  content: [{
@@ -351,9 +351,10 @@ function registerFromPackageTools(server) {
351
351
  structuredContent: resolvedOutput
352
352
  };
353
353
  } catch (error) {
354
- if (error instanceof UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentPackage (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
354
+ if (error instanceof UnrecognizedDocumentSchemaError) return errorResult("'source' has no recognised $schema -- only a file carrying a real DocumentTree (e.g. written by a caller's own --dump-package-equivalent step) can be read back by this tool");
355
355
  if (isNamedError(error, "SchemaVersionMismatchError")) return errorResult(error.message);
356
356
  if (isNamedError(error, "LayoutSchemaDemotedError")) return errorResult(error.message);
357
+ if (isNamedError(error, "DocumentPackageRenamedError")) return errorResult(error.message);
357
358
  if (error instanceof z.ZodError) return errorResult(`'source' failed ${documentSchemaKindOf(parsed) ?? "document schema"} validation: ${error.message}`);
358
359
  return errorResult(error instanceof Error ? error.message : String(error));
359
360
  }
@@ -806,7 +807,7 @@ function registerOutlineTools(server) {
806
807
  const converter = createLocalDocumentConverter();
807
808
  server.registerTool("outline_document", {
808
809
  title: "Outline document",
809
- description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentPackage the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
810
+ description: "Projects a document's table of contents as a structured outline: reads the source through documents.js's DocumentConverter port, takes the tree-form DocumentTree the conversion reports, and runs document-outline.js's buildOutline over it. Groups carry { text, level, children } (a heading's, list item's, slide's, sheet's, or page's own label plus nested children); leaves carry { kind, text }. The outline is over the source's own content -- the internal conversion target preserves it and is pdf only for odf (the one format that only converts to pdf) and odg (whose alternative, svg, cannot represent more than one page).",
810
811
  inputSchema: z.object({ source: DocumentInputSchema.describe("The document to outline.") })
811
812
  }, async ({ source }, ctx) => {
812
813
  const { signal } = ctx.mcpReq;
@@ -819,7 +820,7 @@ function registerOutlineTools(server) {
819
820
  },
820
821
  targetFormat
821
822
  }, { signal })).package;
822
- if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentPackage, so there is no tree to outline`);
823
+ if (pkg === void 0) throw new Error(`the ${format}-to-${targetFormat} conversion reported no DocumentTree, so there is no tree to outline`);
823
824
  const structuredContent = {
824
825
  sourceFormat: format,
825
826
  kind: pkg.kind,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document-mcp",
3
- "version": "3.0.3",
3
+ "version": "4.0.0",
4
4
  "description": "MCP (Model Context Protocol) server exposing documents.js's document-conversion, .odb, metadata, and font tooling as MCP tools.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -87,8 +87,8 @@
87
87
  "packageManager": "pnpm@11.6.0",
88
88
  "dependencies": {
89
89
  "@modelcontextprotocol/server": "^2.0.0",
90
- "document-outline.js": "^2.1.2",
91
- "documents.js": "^5.0.2",
90
+ "document-outline.js": "^3.0.0",
91
+ "documents.js": "^6.0.0",
92
92
  "zod": "^4.2.0"
93
93
  },
94
94
  "devDependencies": {
@@ -107,8 +107,8 @@
107
107
  "globals": "^17.8.0",
108
108
  "husky": "^9.1.7",
109
109
  "lint-staged": "^17.3.0",
110
- "odf.js": "^5.5.2",
111
- "pdf-codec": "^3.4.2",
110
+ "odf.js": "^6.0.0",
111
+ "pdf-codec": "^3.4.4",
112
112
  "publint": "^0.3.22",
113
113
  "semantic-release": "^25.0.8",
114
114
  "tsdown": "^0.22.14",