@hiai-gg/docsmint 1.0.2 → 2.0.2

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.
Files changed (147) hide show
  1. package/README.md +21 -6
  2. package/dist/backend/index.js +14356 -12995
  3. package/dist/frontend/{CategoryDialog-B6zqtwE6.js → CategoryDialog-CJeAYxcd.js} +7 -7
  4. package/dist/frontend/{ConfirmDialog-Dk7wwcj9.js → ConfirmDialog-B1MjKlVQ.js} +5 -5
  5. package/dist/frontend/{CreateSnapshotDialog-BPYjO1qN.js → CreateSnapshotDialog-BTMoPFdj.js} +4 -4
  6. package/dist/frontend/{DatePicker-SiGLx9yh.js → DatePicker-Bmjko3X7.js} +12 -12
  7. package/dist/frontend/{DeleteDialog-D1jox8h1.js → DeleteDialog-BkfIeKXO.js} +3 -3
  8. package/dist/frontend/{FolderNode-BG4l6I5C.js → FolderNode-Do8pIfyA.js} +4 -4
  9. package/dist/frontend/{FolderTreeSelector-DqO-f0nt.js → FolderTreeSelector-FyxhcHjr.js} +3 -3
  10. package/dist/frontend/{HiAiEditor-Dxqt8BUN.js → HiAiEditor-DDpfdQEg.js} +42 -42
  11. package/dist/frontend/{Icon-y7xxAIC6.js → Icon-3EYzvNyk.js} +1 -1
  12. package/dist/frontend/{SettingsDialog-DnrPV8dM.js → SettingsDialog-DzlYW50I.js} +18 -18
  13. package/dist/frontend/{ShareDialog-CmX-VoJ9.js → ShareDialog-Ddvl7xvb.js} +1 -1
  14. package/dist/frontend/{Sidebar-BI_ccYTl.js → Sidebar-rFiVen96.js} +29 -29
  15. package/dist/frontend/{TagCreateDialog-C5j3H49u.js → TagCreateDialog-DQmMJe_E.js} +5 -5
  16. package/dist/frontend/api/categories.js +1 -1
  17. package/dist/frontend/api/settings.js +1 -1
  18. package/dist/frontend/api/tags.js +1 -1
  19. package/dist/frontend/app-shell.js +6 -6
  20. package/dist/frontend/{auth-client-Dc0mkuZH.js → auth-client-CXR-7mIO.js} +11 -11
  21. package/dist/frontend/{camera-BI-BtnIm.js → camera-DtgHzfVI.js} +2 -2
  22. package/dist/frontend/{categories-Bjcc41We.js → categories-C8AAkhCR.js} +1 -1
  23. package/dist/frontend/{check-sdTlLwi9.js → check-DVx65aSv.js} +2 -2
  24. package/dist/frontend/{chevron-down-DlBnIE7Y.js → chevron-down-C2tbZ8Ol.js} +2 -2
  25. package/dist/frontend/{circle-check-hWC-HeKu.js → circle-check-BAN-D7yg.js} +2 -2
  26. package/dist/frontend/{clock-C4FHq-9q.js → clock-ByiB0SwQ.js} +2 -2
  27. package/dist/frontend/components/category-dialog.js +1 -1
  28. package/dist/frontend/components/create-snapshot-dialog.js +1 -1
  29. package/dist/frontend/components/delete-dialog.js +1 -1
  30. package/dist/frontend/components/editor/compact-editor.js +1 -1
  31. package/dist/frontend/components/editor/document-editor.js +1 -1
  32. package/dist/frontend/components/editor/extensions.js +1 -1
  33. package/dist/frontend/components/editor/markdown-toggle.js +3 -3
  34. package/dist/frontend/components/editor/markdown.js +1 -1
  35. package/dist/frontend/components/folder-node.js +1 -1
  36. package/dist/frontend/components/folder-tree-selector.js +1 -1
  37. package/dist/frontend/components/save-as-dialog.js +7 -7
  38. package/dist/frontend/components/settings.js +1 -1
  39. package/dist/frontend/components/share-dialog.js +1 -1
  40. package/dist/frontend/components/sidebar.js +1 -1
  41. package/dist/frontend/components/tag-create-dialog.js +1 -1
  42. package/dist/frontend/components/version-history.js +10 -10
  43. package/dist/frontend/{copy-4H99lwAQ.js → copy-CRzvfZGb.js} +2 -2
  44. package/dist/frontend/dashboard.js +48 -48
  45. package/dist/frontend/{db-DUOtrCBC.js → db-Dya0HRhS.js} +1 -1
  46. package/dist/frontend/{dialog-DC97Hnxo.js → dialog-a_ZcpEC5.js} +9 -9
  47. package/dist/frontend/{dist-D7zL6zdU.js → dist-CcHOStsA.js} +2 -2
  48. package/dist/frontend/dist-DcHl92QO.js +316 -0
  49. package/dist/frontend/{dndzone-BrakBHwm.js → dndzone-CDhrbpTg.js} +1 -1
  50. package/dist/frontend/{dropdown-menu-COZwS7c0.js → dropdown-menu-DrHYReIC.js} +12 -12
  51. package/dist/frontend/{editorExtensions-Cu__YKW7.js → editorExtensions-DPR-CjMu.js} +1 -1
  52. package/dist/frontend/{ellipsis-vertical-CObXWXZW.js → ellipsis-vertical-qxNgoXu-.js} +2 -2
  53. package/dist/frontend/{folder-BAX6qBYy.js → folder-D74E-Kdp.js} +3 -3
  54. package/dist/frontend/frontend.css +1 -1
  55. package/dist/frontend/{identity-D_rjww-V.js → identity-BOA7Jejv.js} +1 -1
  56. package/dist/frontend/{input-CrlYAH2S.js → input-Q_7qCfnU.js} +2 -2
  57. package/dist/frontend/{label-B0syEfns.js → label-Dj8FDEhf.js} +2 -2
  58. package/dist/frontend/{lib-DYgslUw1.js → lib-aUbBbIW2.js} +3357 -3328
  59. package/dist/frontend/{loader-circle-DnyUzAmN.js → loader-circle-D3t5NkvC.js} +2 -2
  60. package/dist/frontend/{markdown-Co8ZAKf4.js → markdown-O9YJA70S.js} +2 -2
  61. package/dist/frontend/offline/identity.js +1 -1
  62. package/dist/frontend/{popper-layer-force-mount-BAYjg6Pp.js → popper-layer-force-mount-CNtiLgbV.js} +63 -63
  63. package/dist/frontend/{rotate-ccw-DtZDfSK3.js → rotate-ccw-B1ybQ8oQ.js} +2 -2
  64. package/dist/frontend/schemas-1Na35n71.js +3988 -0
  65. package/dist/frontend/search.js +13 -13
  66. package/dist/frontend/{select-value-D9VqY5n5.js → select-value-BkI1W1bn.js} +19 -19
  67. package/dist/frontend/{settings-CW_SR-EH.js → settings-BRcYFQa_.js} +1 -1
  68. package/dist/frontend/{share-context-DooXPYKd.js → share-context-BJ4GF4yT.js} +8 -8
  69. package/dist/frontend/{tag-ChpMfbfa.js → tag-qbTBLj-g.js} +3 -3
  70. package/dist/frontend/{tags-CzPNUoFw.js → tags-CF_cqzSV.js} +1 -1
  71. package/dist/frontend/{textarea-l_gRXsrH.js → textarea-BNK0LFUK.js} +2 -2
  72. package/dist/frontend/theme.js +1 -1
  73. package/dist/frontend/{theme.svelte-gLPpG6eU.js → theme.svelte-BRdxXd-B.js} +3 -3
  74. package/dist/frontend/utils/dndzone.js +1 -1
  75. package/dist/frontend/{utils-B4LKx7VS.js → utils-BlHvR6OL.js} +1 -1
  76. package/dist/frontend/{x-B2ifxSH7.js → x-CvSSnrjl.js} +2 -2
  77. package/dist/frontend-ssr/api/settings.js +1 -1
  78. package/dist/frontend-ssr/app-shell.js +6 -6
  79. package/dist/frontend-ssr/assets/{CategoryDialog-C41IBNWG.js → CategoryDialog-DuZLLlt7.js} +7 -7
  80. package/dist/frontend-ssr/assets/{ConfirmDialog-CWO0HBaS.js → ConfirmDialog-0WVu9BCE.js} +8 -8
  81. package/dist/frontend-ssr/assets/{CreateSnapshotDialog-CECCRK0d.js → CreateSnapshotDialog-3vhDTFNu.js} +4 -4
  82. package/dist/frontend-ssr/assets/{DatePicker-CCylVH0q.js → DatePicker-t12leL2Y.js} +7 -7
  83. package/dist/frontend-ssr/assets/{DeleteDialog-BVnmzR2e.js → DeleteDialog-B0AU1fJR.js} +3 -3
  84. package/dist/frontend-ssr/assets/{FolderNode-CscMQ9sf.js → FolderNode-C-B-s8x1.js} +5 -5
  85. package/dist/frontend-ssr/assets/{FolderTreeSelector-DnrKCYtl.js → FolderTreeSelector-DdQuEcj0.js} +4 -4
  86. package/dist/frontend-ssr/assets/{HiAiEditor-D-FYXUht.js → HiAiEditor-Bj6tiE97.js} +30 -30
  87. package/dist/frontend-ssr/assets/{Icon-Clqe8D8X.js → Icon-DE_3EnuF.js} +4 -4
  88. package/dist/frontend-ssr/assets/{SettingsDialog-BaI2MU5d.js → SettingsDialog-h4SFwpUa.js} +16 -16
  89. package/dist/frontend-ssr/assets/{ShareDialog-DHPbSHZg.js → ShareDialog-CpE9zd_f.js} +1 -1
  90. package/dist/frontend-ssr/assets/{Sidebar-BpTS2uCa.js → Sidebar-BFBpsd3L.js} +26 -26
  91. package/dist/frontend-ssr/assets/{TagCreateDialog-CPg-nG0D.js → TagCreateDialog-DBHO1DPU.js} +4 -4
  92. package/dist/frontend-ssr/assets/{auth-client-Bo5Fg-sb.js → auth-client-BC4hSFKF.js} +13 -13
  93. package/dist/frontend-ssr/assets/{camera-Dwwtgvfn.js → camera-B6ldo_Js.js} +2 -2
  94. package/dist/frontend-ssr/assets/{chevron-down-C6BTPJFz.js → chevron-down-DQcr6JUc.js} +2 -2
  95. package/dist/frontend-ssr/assets/{chevron-right-CseGE1qd.js → chevron-right-9szrliZx.js} +2 -2
  96. package/dist/frontend-ssr/assets/{circle-check-BRhWPZo1.js → circle-check-BgP9MRRv.js} +2 -2
  97. package/dist/frontend-ssr/assets/{clock-DpP_Y7WP.js → clock-roNtGlT6.js} +2 -2
  98. package/dist/frontend-ssr/assets/{copy-DRMKiRZ0.js → copy-BYqYnBIQ.js} +2 -2
  99. package/dist/frontend-ssr/assets/{db-DUKz2X3Z.js → db-C3rFdTZa.js} +1 -1
  100. package/dist/frontend-ssr/assets/{dialog--tDgDGw9.js → dialog-SqCnTT43.js} +9 -9
  101. package/dist/frontend-ssr/assets/{dist-DqeAICTy.js → dist-CaZQ1FhA.js} +10 -10
  102. package/dist/frontend-ssr/assets/{dist-CshZmNmp.js → dist-CqxHwOlp.js} +3 -3
  103. package/dist/frontend-ssr/assets/{dndzone-WtNaDxoQ.js → dndzone-CnTCMhPd.js} +1 -1
  104. package/dist/frontend-ssr/assets/{dropdown-menu--acO7nXs.js → dropdown-menu-CE6U0f1b.js} +12 -12
  105. package/dist/frontend-ssr/assets/{ellipsis-vertical-BErUuhWg.js → ellipsis-vertical-Cg1MrZsl.js} +2 -2
  106. package/dist/frontend-ssr/assets/{folder-DszunwKc.js → folder-DHB-CEcQ.js} +2 -2
  107. package/dist/frontend-ssr/assets/{identity-_M3U9lqe.js → identity-DNIo1bgc.js} +1 -1
  108. package/dist/frontend-ssr/assets/{input-BlAj7LzC.js → input-DVrBVPgs.js} +2 -2
  109. package/dist/frontend-ssr/assets/{label-BRToaMg9.js → label-vtCK3pTp.js} +2 -2
  110. package/dist/frontend-ssr/assets/{loader-circle-BpRVrMZg.js → loader-circle-D3NWhCif.js} +2 -2
  111. package/dist/frontend-ssr/assets/{popper-layer-force-mount-Djnq7l7a.js → popper-layer-force-mount-C4dMMt-f.js} +71 -71
  112. package/dist/frontend-ssr/assets/{rotate-ccw-1GOD_yt_.js → rotate-ccw-DNf3nwMD.js} +2 -2
  113. package/dist/frontend-ssr/assets/{select-value-BCWSsoTd.js → select-value-Ce5c_fuA.js} +18 -18
  114. package/dist/frontend-ssr/assets/{settings-DaOQ4Gv2.js → settings-DWCpfCPj.js} +1 -1
  115. package/dist/frontend-ssr/assets/{share-context-BvXQrIIH.js → share-context-B4UpvTSw.js} +9 -9
  116. package/dist/frontend-ssr/assets/{tag-DFh6nF9R.js → tag-Cqv0fWVG.js} +3 -3
  117. package/dist/frontend-ssr/assets/{textarea-BuszTo9i.js → textarea-BdjOJJVb.js} +2 -2
  118. package/dist/frontend-ssr/assets/{theme.svelte-CGgnJc3k.js → theme.svelte-D6bbaJ9m.js} +3 -3
  119. package/dist/frontend-ssr/assets/{utils-BK35BJKQ.js → utils-D3X7I8nz.js} +1 -1
  120. package/dist/frontend-ssr/components/category-dialog.js +1 -1
  121. package/dist/frontend-ssr/components/create-snapshot-dialog.js +1 -1
  122. package/dist/frontend-ssr/components/delete-dialog.js +1 -1
  123. package/dist/frontend-ssr/components/editor/compact-editor.js +1 -1
  124. package/dist/frontend-ssr/components/editor/document-editor.js +1 -1
  125. package/dist/frontend-ssr/components/editor/markdown-toggle.js +1 -1
  126. package/dist/frontend-ssr/components/folder-node.js +1 -1
  127. package/dist/frontend-ssr/components/folder-tree-selector.js +1 -1
  128. package/dist/frontend-ssr/components/save-as-dialog.js +6 -6
  129. package/dist/frontend-ssr/components/settings.js +1 -1
  130. package/dist/frontend-ssr/components/share-dialog.js +1 -1
  131. package/dist/frontend-ssr/components/sidebar.js +1 -1
  132. package/dist/frontend-ssr/components/tag-create-dialog.js +1 -1
  133. package/dist/frontend-ssr/components/version-history.js +10 -10
  134. package/dist/frontend-ssr/dashboard.js +40 -40
  135. package/dist/frontend-ssr/offline/identity.js +1 -1
  136. package/dist/frontend-ssr/search.js +8 -8
  137. package/dist/frontend-ssr/theme.js +1 -1
  138. package/dist/frontend-ssr/utils/dndzone.js +1 -1
  139. package/dist/lifecycle-runtime.js +7129 -1986
  140. package/dist/mcp-cli.js +171 -73
  141. package/dist/mcp-server.d.ts +15 -0
  142. package/dist/mcp-server.js +175 -73
  143. package/package.json +16 -7
  144. package/packages/cli/src/index.ts +1 -1
  145. package/server.json +2 -2
  146. package/dist/frontend/dist-BLpDfrDC.js +0 -316
  147. package/dist/frontend/schemas-CdPhcuru.js +0 -3001
package/dist/mcp-cli.js CHANGED
@@ -575,9 +575,6 @@ var RESOURCE_PERMISSIONS = new Set([
575
575
  "edit",
576
576
  "write"
577
577
  ]);
578
- // ../mcp-server/src/compact.ts
579
- import { z as z3 } from "zod";
580
-
581
578
  // ../mcp-server/src/output-schemas.ts
582
579
  import { z } from "zod";
583
580
  var tagSchema = z.looseObject({
@@ -806,7 +803,7 @@ var operationOutputSchemas = {
806
803
  permanently_delete_document: deleteAcknowledgmentSchema
807
804
  };
808
805
  var variant = (operation, result) => z.object({ operation: z.literal(operation), result });
809
- var toolOutputSchemas = {
806
+ var singleToolOutputSchemas = {
810
807
  delete_document: operationOutputSchemas.delete_document,
811
808
  delete_folder: operationOutputSchemas.delete_folder,
812
809
  delete_category: operationOutputSchemas.delete_category,
@@ -832,6 +829,7 @@ var toolOutputSchemas = {
832
829
  variant("update", operationOutputSchemas.update_document)
833
830
  ]),
834
831
  list_workspace_structure: z.union([
832
+ variant("workspaces", z.array(z.object({ id: z.string().uuid(), name: z.string(), slug: z.string(), entireWorkspace: z.boolean(), categoryIds: z.array(z.string().uuid()) }))),
835
833
  variant("folders", operationOutputSchemas.list_folders),
836
834
  variant("categories", operationOutputSchemas.list_categories),
837
835
  variant("tags", operationOutputSchemas.list_tags)
@@ -874,9 +872,27 @@ var toolOutputSchemas = {
874
872
  variant("tag", tagSchema)
875
873
  ])
876
874
  };
875
+ var workspaceSchema = z.object({ id: z.string().uuid(), name: z.string(), slug: z.string() });
876
+ var scoped = (data) => z.object({
877
+ operation: z.string(),
878
+ scopedResults: z.array(z.object({ workspace: workspaceSchema, categoryId: z.string().uuid().nullable(), data }))
879
+ });
880
+ var scopedSchemas = {
881
+ find_documents: scoped(singleToolOutputSchemas.find_documents),
882
+ list_workspace_structure: scoped(singleToolOutputSchemas.list_workspace_structure),
883
+ list_trash: scoped(singleToolOutputSchemas.list_trash)
884
+ };
885
+ var toolOutputSchemas = {
886
+ ...singleToolOutputSchemas,
887
+ find_documents: z.union([...singleToolOutputSchemas.find_documents.options, scopedSchemas.find_documents]),
888
+ list_workspace_structure: z.union([...singleToolOutputSchemas.list_workspace_structure.options, scopedSchemas.list_workspace_structure]),
889
+ list_trash: z.union([singleToolOutputSchemas.list_trash, scopedSchemas.list_trash])
890
+ };
891
+ // ../mcp-server/src/compact.ts
892
+ import { z as z4 } from "zod";
877
893
 
878
894
  // ../mcp-server/src/batch-workspace.ts
879
- import { z as z2 } from "zod";
895
+ import { z as z3 } from "zod";
880
896
 
881
897
  // ../mcp-server/src/client.ts
882
898
  var DEFAULT_BASE_URL = "http://localhost:50700";
@@ -970,18 +986,82 @@ var client = new Proxy({}, {
970
986
  }
971
987
  });
972
988
 
989
+ // ../mcp-server/src/client-routing-schema.ts
990
+ import { z as z2 } from "zod";
991
+ function hoistObjectUnionClosure(schema) {
992
+ const variants = schema.oneOf;
993
+ if (!Array.isArray(variants) || !variants.every((variant2) => typeof variant2 === "object" && variant2 !== null && variant2.type === "object" && variant2.additionalProperties === false && typeof variant2.properties === "object" && variant2.properties !== null))
994
+ return schema;
995
+ const propertyVariants = new Map;
996
+ for (const variant2 of variants) {
997
+ for (const [key, property] of Object.entries(variant2.properties)) {
998
+ const values = propertyVariants.get(key) ?? [];
999
+ values.push(property);
1000
+ propertyVariants.set(key, values);
1001
+ }
1002
+ }
1003
+ return {
1004
+ ...schema,
1005
+ type: "object",
1006
+ properties: Object.fromEntries([...propertyVariants].map(([key, values]) => [
1007
+ key,
1008
+ values.length === 1 ? values[0] : { anyOf: values }
1009
+ ])),
1010
+ additionalProperties: false,
1011
+ oneOf: variants.map((variant2) => {
1012
+ const { additionalProperties: _closure, ...branch } = variant2;
1013
+ const excluded = [...propertyVariants.keys()].filter((key) => !(key in variant2.properties));
1014
+ return excluded.length === 0 ? branch : {
1015
+ ...branch,
1016
+ allOf: [
1017
+ ...Array.isArray(branch.allOf) ? branch.allOf : [],
1018
+ { not: { anyOf: excluded.map((key) => ({ required: [key] })) } }
1019
+ ]
1020
+ };
1021
+ })
1022
+ };
1023
+ }
1024
+ function withClientRoutingSchema(schema) {
1025
+ const standard = schema["~standard"];
1026
+ const selector = z2.string().uuid().optional().describe("Workspace UUID from list_workspace_structure(kind=workspaces). Required for ambiguous creates and structure changes; omit to search all granted scopes.");
1027
+ return {
1028
+ "~standard": {
1029
+ ...standard,
1030
+ validate: async (value, options) => {
1031
+ if (!value || typeof value !== "object" || Array.isArray(value))
1032
+ return standard.validate(value, options);
1033
+ const { workspaceId, ...args } = value;
1034
+ const selected = selector.safeParse(workspaceId);
1035
+ if (!selected.success)
1036
+ return { issues: selected.error.issues };
1037
+ const validated = await standard.validate(args, options);
1038
+ if (validated.issues)
1039
+ return validated;
1040
+ return { value: { ...validated.value, ...selected.data ? { workspaceId: selected.data } : {} } };
1041
+ },
1042
+ jsonSchema: {
1043
+ ...standard.jsonSchema,
1044
+ input: (options) => (() => {
1045
+ const published = hoistObjectUnionClosure(standard.jsonSchema.input(options));
1046
+ return { ...published, properties: { ...published.properties, workspaceId: z2.toJSONSchema(selector) } };
1047
+ })()
1048
+ }
1049
+ }
1050
+ };
1051
+ }
1052
+
973
1053
  // ../mcp-server/src/batch-workspace.ts
974
- var uuid = z2.string().uuid().describe("UUID of an item visible to the active API key.");
975
- var documentIds = z2.array(uuid).min(1).max(25).refine((ids) => new Set(ids).size === ids.length, "Document IDs must be unique.").describe("One to 25 distinct document UUIDs, explicitly selected by the user; no search expansion.");
1054
+ var uuid = z3.string().uuid().describe("UUID of an item visible to the active API key.");
1055
+ var documentIds = z3.array(uuid).min(1).max(25).refine((ids) => new Set(ids).size === ids.length, "Document IDs must be unique.").describe("One to 25 distinct document UUIDs, explicitly selected by the user; no search expansion.");
976
1056
  var base = { documentIds };
977
- var batchInput = z2.discriminatedUnion("action", [
978
- z2.strictObject({ ...base, action: z2.literal("move").describe("Move each document to the same folder."), folderId: uuid.nullable().describe("Destination folder UUID, or null for no folder.") }),
979
- z2.strictObject({ ...base, action: z2.literal("set_category").describe("Set one explicit category on every document."), categoryId: uuid.nullable().describe("Category UUID, or null to clear explicit category.") }),
980
- z2.strictObject({ ...base, action: z2.literal("add_tag").describe("Assign one existing tag to every document."), tagId: uuid.describe("Existing tag UUID to assign to each document.") }),
981
- z2.strictObject({ ...base, action: z2.literal("remove_tag").describe("Remove one tag assignment from every document."), tagId: uuid.describe("Existing tag UUID to unassign from each document.") }),
982
- z2.strictObject({ ...base, action: z2.literal("trash").describe("Move every document to trash without permanent deletion.") }),
983
- z2.strictObject({ ...base, action: z2.literal("restore").describe("Restore every selected document from trash.") }),
984
- z2.strictObject({ ...base, action: z2.literal("refresh_index").describe("Request explicit indexing retry for every document.") })
1057
+ var batchInput = z3.discriminatedUnion("action", [
1058
+ z3.strictObject({ ...base, action: z3.literal("move").describe("Move each document to the same folder."), folderId: uuid.nullable().describe("Destination folder UUID, or null for no folder.") }),
1059
+ z3.strictObject({ ...base, action: z3.literal("set_category").describe("Set one explicit category on every document."), categoryId: uuid.nullable().describe("Category UUID, or null to clear explicit category.") }),
1060
+ z3.strictObject({ ...base, action: z3.literal("add_tag").describe("Assign one existing tag to every document."), tagId: uuid.describe("Existing tag UUID to assign to each document.") }),
1061
+ z3.strictObject({ ...base, action: z3.literal("remove_tag").describe("Remove one tag assignment from every document."), tagId: uuid.describe("Existing tag UUID to unassign from each document.") }),
1062
+ z3.strictObject({ ...base, action: z3.literal("trash").describe("Move every document to trash without permanent deletion.") }),
1063
+ z3.strictObject({ ...base, action: z3.literal("restore").describe("Restore every selected document from trash.") }),
1064
+ z3.strictObject({ ...base, action: z3.literal("refresh_index").describe("Request explicit indexing retry for every document.") })
985
1065
  ]);
986
1066
  function required(method, name) {
987
1067
  if (!method)
@@ -1036,13 +1116,13 @@ function registerBatchAndWorkspaceCapabilities(server, client2, wrap) {
1036
1116
  }
1037
1117
  server.registerTool("batch_documents", {
1038
1118
  description: "Use for multiple explicitly selected documents that need the same action; for one document prefer the matching single-document tool. Accepts 1\u201325 IDs for automation compatibility. Supports move, set_category, add_tag, remove_tag, trash, restore, or refresh_index. Processes sequentially through the existing API with a permission check per document and a per-ID result; partial success is possible. Stops after authentication or rate-limit failure. Never expands a search result or permanently purges documents; version restore is separate.",
1039
- inputSchema: batchInput,
1119
+ inputSchema: withClientRoutingSchema(batchInput),
1040
1120
  outputSchema: toolOutputSchemas.batch_documents,
1041
1121
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }
1042
1122
  }, wrap("batch_documents", batch, toolOutputSchemas.batch_documents));
1043
1123
  server.registerTool("get_workspace_item", {
1044
1124
  description: "Read one visible folder, category, or tag by UUID. Folder uses its direct API getter; category and tag lookup uses the complete permission-filtered lists. An absent or out-of-scope ID is reported as not found. Use list_workspace_structure to discover IDs first.",
1045
- inputSchema: z2.strictObject({ kind: z2.enum(["folder", "category", "tag"]).describe("The workspace resource type to read by ID."), id: uuid }),
1125
+ inputSchema: withClientRoutingSchema(z3.strictObject({ kind: z3.enum(["folder", "category", "tag"]).describe("The workspace resource type to read by ID."), id: uuid })),
1046
1126
  outputSchema: toolOutputSchemas.get_workspace_item,
1047
1127
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
1048
1128
  }, wrap("get_workspace_item", async ({ kind, id }) => {
@@ -1057,10 +1137,10 @@ function registerBatchAndWorkspaceCapabilities(server, client2, wrap) {
1057
1137
  }
1058
1138
 
1059
1139
  // ../mcp-server/src/compact.ts
1060
- var uuid2 = z3.string().uuid().describe("UUID returned by the corresponding list or read operation.");
1061
- var text = z3.string().min(1).describe("Non-empty human-readable name or title.");
1062
- var title = z3.string().min(1).max(500).describe("Document title, from 1 to 500 characters.");
1063
- var content = z3.string().describe("Markdown document content; an empty string clears the content on update.");
1140
+ var uuid2 = z4.string().uuid().describe("UUID returned by the corresponding list or read operation.");
1141
+ var text = z4.string().min(1).describe("Non-empty human-readable name or title.");
1142
+ var title = z4.string().min(1).max(500).describe("Document title, from 1 to 500 characters.");
1143
+ var content = z4.string().describe("Markdown document content; an empty string clears the content on update.");
1064
1144
  var read = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
1065
1145
  var write = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
1066
1146
  var destructive = { ...write, destructiveHint: true };
@@ -1071,16 +1151,16 @@ function required2(value, name) {
1071
1151
  }
1072
1152
  function registerCompactCapabilities(server, client2, wrap) {
1073
1153
  function register(name, description, inputSchema, annotations, handler) {
1074
- server.registerTool(name, { description, inputSchema, outputSchema: toolOutputSchemas[name], annotations }, wrap(name, handler, toolOutputSchemas[name]));
1154
+ server.registerTool(name, { description, inputSchema: withClientRoutingSchema(inputSchema), outputSchema: toolOutputSchemas[name], annotations }, wrap(name, handler, toolOutputSchemas[name]));
1075
1155
  }
1076
- register("find_documents", "Find readable documents in the active scope. Use mode=list for paginated browsing by folder or tag UUID; use mode=search for hybrid text and semantic retrieval with tag names.", z3.discriminatedUnion("mode", [
1077
- z3.strictObject({ mode: z3.literal("list").describe("Select the list operation explicitly."), folderId: uuid2.optional(), tag: uuid2.optional(), page: z3.number().int().min(1).optional().describe("One-based page number; defaults to the API first page."), limit: z3.number().int().min(1).max(1000).optional().describe("Maximum documents per page, up to 1000.") }),
1078
- z3.strictObject({ mode: z3.literal("search").describe("Select the search operation explicitly."), query: text.describe("Text to search in the original language."), folder: z3.string().optional().describe("Optional folder UUID filter for search."), tags: z3.array(z3.string()).optional().describe("Optional tag names; all supplied names must match."), limit: z3.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") })
1156
+ register("find_documents", "Find readable documents in the active scope. Use mode=list for paginated browsing by folder or tag UUID; use mode=search for hybrid text and semantic retrieval with tag names.", z4.discriminatedUnion("mode", [
1157
+ z4.strictObject({ mode: z4.literal("list").describe("Select the list operation explicitly."), folderId: uuid2.optional(), tag: uuid2.optional(), page: z4.number().int().min(1).optional().describe("One-based page number; defaults to the API first page."), limit: z4.number().int().min(1).max(1000).optional().describe("Maximum documents per page, up to 1000.") }),
1158
+ z4.strictObject({ mode: z4.literal("search").describe("Select the search operation explicitly."), query: text.describe("Text to search in the original language."), folder: z4.string().optional().describe("Optional folder UUID filter for search."), tags: z4.array(z4.string()).optional().describe("Optional tag names; all supplied names must match."), limit: z4.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") })
1079
1159
  ]), read, async (input) => input.mode === "list" ? { operation: "list", result: await client2.listDocuments(input) } : { operation: "search", result: await client2.search(input) });
1080
- register("read_document", "Read one document by UUID. Choose detail for content and metadata, markdown for portable export, or versions for saved revisions and snapshots. All views are read-only.", z3.discriminatedUnion("view", [
1081
- z3.strictObject({ view: z3.literal("detail").describe("Select the detail operation explicitly."), id: uuid2 }),
1082
- z3.strictObject({ view: z3.literal("markdown").describe("Select the markdown operation explicitly."), id: uuid2 }),
1083
- z3.strictObject({ view: z3.literal("versions").describe("Select the versions operation explicitly."), id: uuid2, onlySnapshots: z3.boolean().optional().describe("When true, return only named snapshots.") })
1160
+ register("read_document", "Read one document by UUID. Choose detail for content and metadata, markdown for portable export, or versions for saved revisions and snapshots. All views are read-only.", z4.discriminatedUnion("view", [
1161
+ z4.strictObject({ view: z4.literal("detail").describe("Select the detail operation explicitly."), id: uuid2 }),
1162
+ z4.strictObject({ view: z4.literal("markdown").describe("Select the markdown operation explicitly."), id: uuid2 }),
1163
+ z4.strictObject({ view: z4.literal("versions").describe("Select the versions operation explicitly."), id: uuid2, onlySnapshots: z4.boolean().optional().describe("When true, return only named snapshots.") })
1084
1164
  ]), read, async (input) => {
1085
1165
  if (input.view === "detail")
1086
1166
  return { operation: "detail", result: await client2.getDocument(input.id) };
@@ -1088,9 +1168,9 @@ function registerCompactCapabilities(server, client2, wrap) {
1088
1168
  return { operation: "markdown", result: await client2.exportDocument(input.id) };
1089
1169
  return { operation: "versions", result: await client2.getVersionHistory(input.id, input.onlySnapshots) };
1090
1170
  });
1091
- register("save_document", "Create or update one document. Use action=create for a new document or action=update for an existing one; batch_documents handles the same placement change across multiple existing documents. Creation requires write access; content edits require edit access, and placement changes may require write access. Content or placement changes queue normal indexing.", z3.discriminatedUnion("action", [
1092
- z3.strictObject({ action: z3.literal("create").describe("Select the create operation explicitly."), title: title.optional(), content: content.optional(), folderId: uuid2.optional(), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }),
1093
- z3.strictObject({ action: z3.literal("update").describe("Select the update operation explicitly."), id: uuid2, title: title.optional(), content: content.optional(), folderId: uuid2.nullable().optional().describe("Optional folder UUID; null clears the placement on update."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }).refine((value) => value.title !== undefined || value.content !== undefined || value.folderId !== undefined || value.categoryId !== undefined)
1171
+ register("save_document", "Create or update one document. Use action=create for a new document or action=update for an existing one; batch_documents handles the same placement change across multiple existing documents. Creation requires write access; content edits require edit access, and placement changes may require write access. Content or placement changes queue normal indexing.", z4.discriminatedUnion("action", [
1172
+ z4.strictObject({ action: z4.literal("create").describe("Select the create operation explicitly."), title: title.optional(), content: content.optional(), folderId: uuid2.optional(), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }),
1173
+ z4.strictObject({ action: z4.literal("update").describe("Select the update operation explicitly."), id: uuid2, title: title.optional(), content: content.optional(), folderId: uuid2.nullable().optional().describe("Optional folder UUID; null clears the placement on update."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }).refine((value) => value.title !== undefined || value.content !== undefined || value.folderId !== undefined || value.categoryId !== undefined)
1094
1174
  ]), destructive, async (input) => {
1095
1175
  if (input.action === "create") {
1096
1176
  const { action: _action2, ...data2 } = input;
@@ -1099,24 +1179,27 @@ function registerCompactCapabilities(server, client2, wrap) {
1099
1179
  const { action: _action, id, ...data } = input;
1100
1180
  return { operation: "update", result: await client2.updateDocument(id, data) };
1101
1181
  });
1102
- register("delete_document", "Move one document to trash without purging content or versions. Use batch_documents(action=trash) for multiple explicit IDs. Requires write access and an explicit delete request; permanently_delete_document is a separate irreversible action.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1182
+ register("delete_document", "Move one document to trash without purging content or versions. Use batch_documents(action=trash) for multiple explicit IDs. Requires write access and an explicit delete request; permanently_delete_document is a separate irreversible action.", z4.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1103
1183
  await required2(client2.deleteDocument, "delete_document")(id);
1104
1184
  return { id, deleted: true };
1105
1185
  });
1106
- register("list_workspace_structure", "List visible folders, categories, or tags in the active workspace or category scope. Set kind=folders to inspect root folders or children of parentId.", z3.discriminatedUnion("kind", [
1107
- z3.strictObject({ kind: z3.literal("folders").describe("Select the folders operation explicitly."), parentId: uuid2.optional() }),
1108
- z3.strictObject({ kind: z3.literal("categories").describe("Select the categories operation explicitly.") }),
1109
- z3.strictObject({ kind: z3.literal("tags").describe("Select the tags operation explicitly.") })
1186
+ register("list_workspace_structure", "Discover permitted spaces with kind=workspaces, including empty spaces; use returned workspaceId for scoped operations. List folders, categories, or tags; set kind=folders for root folders or children of parentId. Unselected reads cover all granted scopes when supported by the host.", z4.discriminatedUnion("kind", [
1187
+ z4.strictObject({ kind: z4.literal("workspaces").describe("Discover every workspace granted to this connection, including empty ones.") }),
1188
+ z4.strictObject({ kind: z4.literal("folders").describe("Select the folders operation explicitly."), parentId: uuid2.optional() }),
1189
+ z4.strictObject({ kind: z4.literal("categories").describe("Select the categories operation explicitly.") }),
1190
+ z4.strictObject({ kind: z4.literal("tags").describe("Select the tags operation explicitly.") })
1110
1191
  ]), read, async (input) => {
1192
+ if (input.kind === "workspaces")
1193
+ throw new Error("Workspace routing is not configured");
1111
1194
  if (input.kind === "folders")
1112
1195
  return { operation: "folders", result: await client2.listFolders({ parentId: input.parentId }) };
1113
1196
  if (input.kind === "categories")
1114
1197
  return { operation: "categories", result: await client2.listCategories() };
1115
1198
  return { operation: "tags", result: await client2.listTags() };
1116
1199
  });
1117
- register("save_folder", "Create or update a folder. action=update can rename or move an existing folder; the API enforces category boundaries and queues affected documents for reindexing.", z3.discriminatedUnion("action", [
1118
- z3.strictObject({ action: z3.literal("create").describe("Select the create operation explicitly."), name: text.max(255), parentId: uuid2.nullable().optional().describe("Optional parent folder UUID; null selects the root."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }),
1119
- z3.strictObject({ action: z3.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(255).optional(), parentId: uuid2.nullable().optional().describe("Optional parent folder UUID; null selects the root."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category."), order: z3.number().int().nonnegative().optional().describe("New non-negative display order.") }).refine((value) => value.name !== undefined || value.parentId !== undefined || value.categoryId !== undefined || value.order !== undefined)
1200
+ register("save_folder", "Create or update a folder. action=update can rename or move an existing folder; the API enforces category boundaries and queues affected documents for reindexing.", z4.discriminatedUnion("action", [
1201
+ z4.strictObject({ action: z4.literal("create").describe("Select the create operation explicitly."), name: text.max(255), parentId: uuid2.nullable().optional().describe("Optional parent folder UUID; null selects the root."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category.") }),
1202
+ z4.strictObject({ action: z4.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(255).optional(), parentId: uuid2.nullable().optional().describe("Optional parent folder UUID; null selects the root."), categoryId: uuid2.nullable().optional().describe("Optional category UUID; null clears the explicit category."), order: z4.number().int().nonnegative().optional().describe("New non-negative display order.") }).refine((value) => value.name !== undefined || value.parentId !== undefined || value.categoryId !== undefined || value.order !== undefined)
1120
1203
  ]), destructive, async (input) => {
1121
1204
  if (input.action === "create") {
1122
1205
  const { action: _action2, ...data2 } = input;
@@ -1125,37 +1208,37 @@ function registerCompactCapabilities(server, client2, wrap) {
1125
1208
  const { action: _action, id, ...data } = input;
1126
1209
  return { operation: "update", result: await required2(client2.updateFolder, "update_folder")(id, data) };
1127
1210
  });
1128
- register("delete_folder", "Delete a folder while preserving its documents; child folders and documents are detached under the API rules. Requires write access.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1211
+ register("delete_folder", "Delete a folder while preserving its documents; child folders and documents are detached under the API rules. Requires write access.", z4.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1129
1212
  await required2(client2.deleteFolder, "delete_folder")(id);
1130
1213
  return { id, deleted: true };
1131
1214
  });
1132
- register("save_category", "Create or update a workspace category. Full workspace write access is required; category-scoped credentials cannot manage categories.", z3.discriminatedUnion("action", [
1133
- z3.strictObject({ action: z3.literal("create").describe("Select the create operation explicitly."), name: text.max(255) }),
1134
- z3.strictObject({ action: z3.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(255).optional(), order: z3.number().int().nonnegative().optional().describe("New non-negative display order.") }).refine((value) => value.name !== undefined || value.order !== undefined)
1215
+ register("save_category", "Create or update a workspace category. Full workspace write access is required; category-scoped credentials cannot manage categories.", z4.discriminatedUnion("action", [
1216
+ z4.strictObject({ action: z4.literal("create").describe("Select the create operation explicitly."), name: text.max(255) }),
1217
+ z4.strictObject({ action: z4.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(255).optional(), order: z4.number().int().nonnegative().optional().describe("New non-negative display order.") }).refine((value) => value.name !== undefined || value.order !== undefined)
1135
1218
  ]), destructive, async (input) => {
1136
1219
  if (input.action === "create")
1137
1220
  return { operation: "create", result: await client2.createCategory({ name: input.name }) };
1138
1221
  const { action: _action, id, ...data } = input;
1139
1222
  return { operation: "update", result: await required2(client2.updateCategory, "update_category")(id, data) };
1140
1223
  });
1141
- register("delete_category", "Delete a workspace category and detach its documents without deleting them. Requires full workspace write access; category-scoped credentials are denied.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1224
+ register("delete_category", "Delete a workspace category and detach its documents without deleting them. Requires full workspace write access; category-scoped credentials are denied.", z4.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1142
1225
  await required2(client2.deleteCategory, "delete_category")(id);
1143
1226
  return { id, deleted: true };
1144
1227
  });
1145
- register("save_tag", "Create or update a workspace tag. Full workspace write access is required; renaming or recoloring a tag causes affected documents to be reindexed.", z3.discriminatedUnion("action", [
1146
- z3.strictObject({ action: z3.literal("create").describe("Select the create operation explicitly."), name: text.max(100), color: z3.string().max(20).optional().describe("Optional tag color, at most 20 characters.") }),
1147
- z3.strictObject({ action: z3.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(100).optional(), color: z3.string().max(20).optional().describe("Optional tag color, at most 20 characters.") }).refine((value) => value.name !== undefined || value.color !== undefined)
1228
+ register("save_tag", "Create or update a workspace tag. Full workspace write access is required; renaming or recoloring a tag causes affected documents to be reindexed.", z4.discriminatedUnion("action", [
1229
+ z4.strictObject({ action: z4.literal("create").describe("Select the create operation explicitly."), name: text.max(100), color: z4.string().max(20).optional().describe("Optional tag color, at most 20 characters.") }),
1230
+ z4.strictObject({ action: z4.literal("update").describe("Select the update operation explicitly."), id: uuid2, name: text.max(100).optional(), color: z4.string().max(20).optional().describe("Optional tag color, at most 20 characters.") }).refine((value) => value.name !== undefined || value.color !== undefined)
1148
1231
  ]), destructive, async (input) => {
1149
1232
  if (input.action === "create")
1150
1233
  return { operation: "create", result: await required2(client2.createTag, "create_tag")({ name: input.name, color: input.color }) };
1151
1234
  const { action: _action, id, ...data } = input;
1152
1235
  return { operation: "update", result: await required2(client2.updateTag, "update_tag")(id, data) };
1153
1236
  });
1154
- register("delete_tag", "Delete a workspace tag and remove its document assignments. Full workspace write access is required; documents themselves remain.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1237
+ register("delete_tag", "Delete a workspace tag and remove its document assignments. Full workspace write access is required; documents themselves remain.", z4.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1155
1238
  await required2(client2.deleteTag, "delete_tag")(id);
1156
1239
  return { id, deleted: true };
1157
1240
  });
1158
- register("set_document_tag", "Add or remove an existing tag assignment on one document. Use batch_documents for the same tag action across multiple explicit IDs. Requires edit access to each document; action=remove preserves the tag itself.", z3.strictObject({ action: z3.enum(["add", "remove"]).describe("Add or remove exactly one tag assignment."), documentId: uuid2, tagId: uuid2 }), destructive, async ({ action, documentId, tagId }) => {
1241
+ register("set_document_tag", "Add or remove an existing tag assignment on one document. Use batch_documents for the same tag action across multiple explicit IDs. Requires edit access to each document; action=remove preserves the tag itself.", z4.strictObject({ action: z4.enum(["add", "remove"]).describe("Add or remove exactly one tag assignment."), documentId: uuid2, tagId: uuid2 }), destructive, async ({ action, documentId, tagId }) => {
1159
1242
  if (action === "add") {
1160
1243
  await required2(client2.addTagToDocument, "add_tag_to_document")(documentId, tagId);
1161
1244
  return { operation: "add", result: { documentId, tagId, assigned: true } };
@@ -1163,17 +1246,17 @@ function registerCompactCapabilities(server, client2, wrap) {
1163
1246
  await required2(client2.removeTagFromDocument, "remove_tag_from_document")(documentId, tagId);
1164
1247
  return { operation: "remove", result: { documentId, tagId, removed: true } };
1165
1248
  });
1166
- register("create_snapshot", "Save a named snapshot of an existing document before a planned change. The snapshot can later be restored with restore_document_version.", z3.strictObject({ documentId: uuid2, label: text.max(200).describe("Snapshot label, from 1 to 200 characters."), description: z3.string().max(1000).optional().describe("Optional snapshot note, at most 1000 characters.") }), write, async ({ documentId, label, description }) => client2.createSnapshot(documentId, { label, description }));
1167
- register("restore_document_version", "Restore content from a version or snapshot listed by read_document(view=versions). This changes current content and queues indexing; it does not restore a trashed document.", z3.strictObject({ documentId: uuid2, versionId: uuid2 }), destructive, async ({ documentId, versionId }) => required2(client2.restoreDocumentVersion, "restore_document_version")(documentId, versionId));
1168
- register("explore_graph", "Explore graph relations from readable seed documents. mode=neighbors traverses one document without a query; mode=search ranks relations from one or more seed IDs with optional query text.", z3.discriminatedUnion("mode", [
1169
- z3.strictObject({ mode: z3.literal("neighbors").describe("Select the neighbors operation explicitly."), documentId: uuid2, limit: z3.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") }),
1170
- z3.strictObject({ mode: z3.literal("search").describe("Select the search operation explicitly."), docIds: z3.array(uuid2).min(1).max(50).describe("One to 50 authorized seed document UUIDs."), query: z3.string().max(2000).optional().describe("Optional graph relevance query, at most 2000 characters."), limit: z3.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") })
1249
+ register("create_snapshot", "Save a named snapshot of an existing document before a planned change. The snapshot can later be restored with restore_document_version.", z4.strictObject({ documentId: uuid2, label: text.max(200).describe("Snapshot label, from 1 to 200 characters."), description: z4.string().max(1000).optional().describe("Optional snapshot note, at most 1000 characters.") }), write, async ({ documentId, label, description }) => client2.createSnapshot(documentId, { label, description }));
1250
+ register("restore_document_version", "Restore content from a version or snapshot listed by read_document(view=versions). This changes current content and queues indexing; it does not restore a trashed document.", z4.strictObject({ documentId: uuid2, versionId: uuid2 }), destructive, async ({ documentId, versionId }) => required2(client2.restoreDocumentVersion, "restore_document_version")(documentId, versionId));
1251
+ register("explore_graph", "Explore graph relations from readable seed documents. mode=neighbors traverses one document without a query; mode=search ranks relations from one or more seed IDs with optional query text.", z4.discriminatedUnion("mode", [
1252
+ z4.strictObject({ mode: z4.literal("neighbors").describe("Select the neighbors operation explicitly."), documentId: uuid2, limit: z4.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") }),
1253
+ z4.strictObject({ mode: z4.literal("search").describe("Select the search operation explicitly."), docIds: z4.array(uuid2).min(1).max(50).describe("One to 50 authorized seed document UUIDs."), query: z4.string().max(2000).optional().describe("Optional graph relevance query, at most 2000 characters."), limit: z4.number().int().min(1).max(100).optional().describe("Maximum results to return, up to 100.") })
1171
1254
  ]), read, async (input) => input.mode === "neighbors" ? { operation: "neighbors", result: await client2.getRelatedDocuments(input.documentId, input.limit) } : { operation: "search", result: await client2.searchGraph(input) });
1172
- register("get_document_index_status", "Read current indexing and pipeline status for one document without starting work. Use refresh_document_index only when an explicit retry is intended.", z3.strictObject({ documentId: uuid2 }), read, async ({ documentId }) => client2.getDocumentIndexStatus(documentId));
1173
- register("refresh_document_index", "Queue an explicit asynchronous reindex for one document; use batch_documents(action=refresh_index) for multiple explicit IDs. Routine content and placement changes already schedule indexing; check get_document_index_status first.", z3.strictObject({ documentId: uuid2 }), write, async ({ documentId }) => client2.refreshDocumentIndex(documentId));
1174
- register("list_trash", "List soft-deleted documents visible to the active workspace or category scope. Requires read access and does not restore or purge anything.", z3.strictObject({}), read, async () => required2(client2.listTrash, "list_trash")());
1175
- register("restore_trashed_document", "Return one document from trash to the active library; use batch_documents(action=restore) for multiple explicit IDs. This restores the document itself, unlike restore_document_version which changes content.", z3.strictObject({ id: uuid2 }), write, async ({ id }) => required2(client2.restoreTrashedDocument, "restore_trashed_document")(id));
1176
- register("permanently_delete_document", "Irreversibly purge a document already in trash, including its version history. Use only on an explicit user request after checking list_trash.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1255
+ register("get_document_index_status", "Read current indexing and pipeline status for one document without starting work. Use refresh_document_index only when an explicit retry is intended.", z4.strictObject({ documentId: uuid2 }), read, async ({ documentId }) => client2.getDocumentIndexStatus(documentId));
1256
+ register("refresh_document_index", "Queue an explicit asynchronous reindex for one document; use batch_documents(action=refresh_index) for multiple explicit IDs. Routine content and placement changes already schedule indexing; check get_document_index_status first.", z4.strictObject({ documentId: uuid2 }), write, async ({ documentId }) => client2.refreshDocumentIndex(documentId));
1257
+ register("list_trash", "List soft-deleted documents visible to the active workspace or category scope. Requires read access and does not restore or purge anything.", z4.strictObject({}), read, async () => required2(client2.listTrash, "list_trash")());
1258
+ register("restore_trashed_document", "Return one document from trash to the active library; use batch_documents(action=restore) for multiple explicit IDs. This restores the document itself, unlike restore_document_version which changes content.", z4.strictObject({ id: uuid2 }), write, async ({ id }) => required2(client2.restoreTrashedDocument, "restore_trashed_document")(id));
1259
+ register("permanently_delete_document", "Irreversibly purge a document already in trash, including its version history. Use only on an explicit user request after checking list_trash.", z4.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1177
1260
  await required2(client2.permanentlyDeleteDocument, "permanently_delete_document")(id);
1178
1261
  return { id, deleted: true };
1179
1262
  });
@@ -1181,13 +1264,13 @@ function registerCompactCapabilities(server, client2, wrap) {
1181
1264
  }
1182
1265
 
1183
1266
  // ../mcp-server/src/prompts-resources.ts
1184
- import { z as z4 } from "zod";
1267
+ import { z as z5 } from "zod";
1185
1268
  function registerPromptsAndResources(server, client2) {
1186
1269
  server.registerPrompt("organize_workspace", {
1187
1270
  description: "Plan safe document organization using DocsMint categories and folders.",
1188
- argsSchema: z4.object({
1189
- objective: z4.string(),
1190
- language: z4.string().optional()
1271
+ argsSchema: z5.object({
1272
+ objective: z5.string(),
1273
+ language: z5.string().optional()
1191
1274
  })
1192
1275
  }, ({ objective, language }) => ({
1193
1276
  messages: [
@@ -1202,9 +1285,9 @@ function registerPromptsAndResources(server, client2) {
1202
1285
  }));
1203
1286
  server.registerPrompt("research_workspace", {
1204
1287
  description: "Research a question with hybrid search and GraphRAG while citing DocsMint document IDs.",
1205
- argsSchema: z4.object({
1206
- question: z4.string(),
1207
- language: z4.string().optional()
1288
+ argsSchema: z5.object({
1289
+ question: z5.string(),
1290
+ language: z5.string().optional()
1208
1291
  })
1209
1292
  }, ({ question, language }) => ({
1210
1293
  messages: [
@@ -1258,10 +1341,24 @@ Use find_documents(mode=search) for normal retrieval. Use explore_graph only wit
1258
1341
  }
1259
1342
 
1260
1343
  // ../mcp-server/src/server.ts
1261
- function wrapHandler(name, handler, outputSchema) {
1344
+ function wrapHandler(name, handler, outputSchema, workspaceRouting) {
1262
1345
  return async (args) => {
1263
1346
  try {
1264
- const output = await handler(args);
1347
+ const { workspaceId, ...data } = args;
1348
+ if (workspaceId !== undefined) {
1349
+ if (!workspaceRouting)
1350
+ throw new Error("Workspace routing is not configured");
1351
+ await workspaceRouting.assertSelection(workspaceId);
1352
+ }
1353
+ let output;
1354
+ if (name === "list_workspace_structure" && data.kind === "workspaces") {
1355
+ if (!workspaceRouting)
1356
+ throw new Error("Workspace routing is not configured");
1357
+ const workspaces = await workspaceRouting.listWorkspaces();
1358
+ output = { operation: "workspaces", result: workspaceId ? workspaces.filter((item) => item.id === workspaceId) : workspaces };
1359
+ } else {
1360
+ output = await handler(data);
1361
+ }
1265
1362
  const parsedOutput = outputSchema ? await outputSchema.safeParseAsync(output) : undefined;
1266
1363
  if (parsedOutput && !parsedOutput.success) {
1267
1364
  throw new Error(`Tool '${name}' returned a result outside its published output schema`);
@@ -1295,14 +1392,15 @@ function wrapHandler(name, handler, outputSchema) {
1295
1392
  }
1296
1393
  };
1297
1394
  }
1298
- function registerDocsmintMcpCapabilities(server, client2) {
1299
- registerCompactCapabilities(server, client2, wrapHandler);
1395
+ function registerDocsmintMcpCapabilities(server, client2, workspaceRouting) {
1396
+ const wrap = (name, handler, outputSchema) => wrapHandler(name, handler, outputSchema, workspaceRouting);
1397
+ registerCompactCapabilities(server, client2, wrap);
1300
1398
  registerPromptsAndResources(server, client2);
1301
1399
  }
1302
1400
  function createDocsmintMcpServer(options = {}) {
1303
- const server = new McpServer({ name: "docsmint", version: "1.0.2" });
1401
+ const server = new McpServer({ name: "docsmint", version: "2.0.2" });
1304
1402
  const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
1305
- registerDocsmintMcpCapabilities(server, client2);
1403
+ registerDocsmintMcpCapabilities(server, client2, options.workspaceRouting);
1306
1404
  return server;
1307
1405
  }
1308
1406
 
@@ -34,9 +34,23 @@ export interface HiaiDocsClient {
34
34
  exportDocument(id: string): Promise<{ markdown: string; filename?: string }>;
35
35
  }
36
36
 
37
+ export interface McpWorkspaceDescriptor {
38
+ id: string;
39
+ name: string;
40
+ slug: string;
41
+ entireWorkspace: boolean;
42
+ categoryIds: string[];
43
+ }
44
+ export interface McpWorkspaceRouting {
45
+ listWorkspaces(): Promise<McpWorkspaceDescriptor[]>;
46
+ assertSelection(workspaceId: string): Promise<void>;
47
+ }
48
+ export declare function createMcpScopedResult(toolName: 'find_documents' | 'list_workspace_structure' | 'list_trash', input: unknown): unknown;
49
+
37
50
  export interface CreateDocsmintMcpServerOptions {
38
51
  docsClient?: DocsClient;
39
52
  requestContext?: DocsRequestContext;
53
+ workspaceRouting?: McpWorkspaceRouting;
40
54
  /** @deprecated Inject a legacy capability client only for compatibility. */
41
55
  client?: HiaiDocsClient;
42
56
  }
@@ -44,6 +58,7 @@ export interface CreateDocsmintMcpServerOptions {
44
58
  export declare function registerDocsmintMcpCapabilities(
45
59
  server: McpServer,
46
60
  client: HiaiDocsClient,
61
+ workspaceRouting?: McpWorkspaceRouting,
47
62
  ): void;
48
63
 
49
64
  export declare function createDocsmintMcpServer(