@hiai-gg/docsmint 1.0.1 → 1.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.
package/README.md CHANGED
@@ -80,18 +80,17 @@ is a separate listing.
80
80
  - **Choose how you run it.** Use [managed DocsMint](https://docsmint.com) or
81
81
  self-host the application, database, search, queues, and files.
82
82
 
83
- ## What's new in 1.0.1?
84
-
85
- - Apply one action to up to 25 explicitly selected documents with
86
- `batch_documents`, receiving a success or error for each ID. The API checks
87
- workspace and category permissions on every operation; partial success is
88
- reported and permanent purge is excluded.
89
- - Read a visible folder, category, or tag by UUID with `get_workspace_item`.
90
- The compact 0.10.0 catalog and its 31 original operations remain available.
91
- - Keep the Cloud Connector and self-hosted stdio bridge distinct. Hosted MCP
92
- clients need the matching Cloud deployment for these new tools.
93
-
94
- No database migration is required. See the [release notes](https://github.com/HiAi-gg/docsmint/releases/tag/v1.0.1)
83
+ ## What's new in 1.0.2?
84
+
85
+ - Make MCP tool selection clearer: use a single-document tool for one document
86
+ and `batch_documents` when multiple explicit IDs need the same action.
87
+ - Keep the 22-tool catalog, all 31 underlying operations, input schemas,
88
+ authorization, and stdio behavior unchanged. The LobeHub tool descriptions
89
+ match the released MCP catalog.
90
+ - DocsMint Cloud remains a separate hosted Connector. Cloud descriptions
91
+ change only when the hosted service adopts this package version.
92
+
93
+ No database migration is required. See the [release notes](https://github.com/HiAi-gg/docsmint/releases/tag/v1.0.2)
95
94
  and [changelog](https://github.com/HiAi-gg/docsmint/blob/main/CHANGELOG.md).
96
95
 
97
96
  ## Install with an AI agent
@@ -144,7 +143,7 @@ docker pull vgalibov/docsmint:web-latest
144
143
  docker pull vgalibov/docsmint:caddy-latest
145
144
  ```
146
145
 
147
- Use versioned tags `api-v1.0.1`, `web-v1.0.1`, and `caddy-v1.0.1` for
146
+ Use versioned tags `api-v1.0.2`, `web-v1.0.2`, and `caddy-v1.0.2` for
148
147
  reproducible deploys. Caddy is the supporting reverse proxy with rate limiting;
149
148
  it is separate from the API and web application. The quickstart still builds the Compose stack from this repository so PostgreSQL,
150
149
  Redis, and SeaweedFS start together with the application.
@@ -238460,7 +238460,7 @@ var swaggerConfig = {
238460
238460
  },
238461
238461
  info: {
238462
238462
  title: "DocsMint API",
238463
- version: "1.0.1",
238463
+ version: "1.0.2",
238464
238464
  description: "Self-hosted AI-native knowledge workspace and installable PWA with hybrid search, GraphRAG, REST, SDK, CLI, and MCP access for people and AI agents.",
238465
238465
  contact: { name: "HiAi-gg", url: "https://github.com/HiAi-gg/docsmint" },
238466
238466
  license: {
package/dist/mcp-cli.js CHANGED
@@ -1035,7 +1035,7 @@ function registerBatchAndWorkspaceCapabilities(server, client2, wrap) {
1035
1035
  return { action: input.action, total: input.documentIds.length, succeeded, failed: results.filter((result) => result.status === "error").length, aborted, results };
1036
1036
  }
1037
1037
  server.registerTool("batch_documents", {
1038
- description: "Apply one action to 1\u201325 explicitly selected document IDs. Supports move, set_category, add_tag, remove_tag, trash, restore, or refresh_index. Processes sequentially through the existing API so each document keeps its own workspace and category permission check. Returns per-ID success or error; partial success is possible. Stops after authentication or rate-limit failure. Permanent purge and version restore are intentionally separate tools.",
1038
+ 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
1039
  inputSchema: batchInput,
1040
1040
  outputSchema: toolOutputSchemas.batch_documents,
1041
1041
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }
@@ -1088,7 +1088,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1088
1088
  return { operation: "markdown", result: await client2.exportDocument(input.id) };
1089
1089
  return { operation: "versions", result: await client2.getVersionHistory(input.id, input.onlySnapshots) };
1090
1090
  });
1091
- register("save_document", "Create a new document or update an existing document. action=create requires write access; action=update requires edit access for content, and placement changes may require write access. Content or placement changes queue normal indexing.", z3.discriminatedUnion("action", [
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
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
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)
1094
1094
  ]), destructive, async (input) => {
@@ -1099,7 +1099,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1099
1099
  const { action: _action, id, ...data } = input;
1100
1100
  return { operation: "update", result: await client2.updateDocument(id, data) };
1101
1101
  });
1102
- register("delete_document", "Move a writable document to trash without purging content or versions. Use only on an explicit delete request; permanently_delete_document is a separate irreversible action.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
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 }) => {
1103
1103
  await required2(client2.deleteDocument, "delete_document")(id);
1104
1104
  return { id, deleted: true };
1105
1105
  });
@@ -1155,7 +1155,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1155
1155
  await required2(client2.deleteTag, "delete_tag")(id);
1156
1156
  return { id, deleted: true };
1157
1157
  });
1158
- register("set_document_tag", "Add or remove one existing tag assignment on a readable document. Requires edit access to that 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 }) => {
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 }) => {
1159
1159
  if (action === "add") {
1160
1160
  await required2(client2.addTagToDocument, "add_tag_to_document")(documentId, tagId);
1161
1161
  return { operation: "add", result: { documentId, tagId, assigned: true } };
@@ -1170,9 +1170,9 @@ function registerCompactCapabilities(server, client2, wrap) {
1170
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.") })
1171
1171
  ]), read, async (input) => input.mode === "neighbors" ? { operation: "neighbors", result: await client2.getRelatedDocuments(input.documentId, input.limit) } : { operation: "search", result: await client2.searchGraph(input) });
1172
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. Routine content and placement changes already schedule indexing; check get_document_index_status first.", z3.strictObject({ documentId: uuid2 }), write, async ({ documentId }) => client2.refreshDocumentIndex(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
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 soft-deleted document to the active library. 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));
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
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 }) => {
1177
1177
  await required2(client2.permanentlyDeleteDocument, "permanently_delete_document")(id);
1178
1178
  return { id, deleted: true };
@@ -1300,7 +1300,7 @@ function registerDocsmintMcpCapabilities(server, client2) {
1300
1300
  registerPromptsAndResources(server, client2);
1301
1301
  }
1302
1302
  function createDocsmintMcpServer(options = {}) {
1303
- const server = new McpServer({ name: "docsmint", version: "1.0.1" });
1303
+ const server = new McpServer({ name: "docsmint", version: "1.0.2" });
1304
1304
  const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
1305
1305
  registerDocsmintMcpCapabilities(server, client2);
1306
1306
  return server;
@@ -1030,7 +1030,7 @@ function registerBatchAndWorkspaceCapabilities(server, client2, wrap) {
1030
1030
  return { action: input.action, total: input.documentIds.length, succeeded, failed: results.filter((result) => result.status === "error").length, aborted, results };
1031
1031
  }
1032
1032
  server.registerTool("batch_documents", {
1033
- description: "Apply one action to 1\u201325 explicitly selected document IDs. Supports move, set_category, add_tag, remove_tag, trash, restore, or refresh_index. Processes sequentially through the existing API so each document keeps its own workspace and category permission check. Returns per-ID success or error; partial success is possible. Stops after authentication or rate-limit failure. Permanent purge and version restore are intentionally separate tools.",
1033
+ 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.",
1034
1034
  inputSchema: batchInput,
1035
1035
  outputSchema: toolOutputSchemas.batch_documents,
1036
1036
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }
@@ -1083,7 +1083,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1083
1083
  return { operation: "markdown", result: await client2.exportDocument(input.id) };
1084
1084
  return { operation: "versions", result: await client2.getVersionHistory(input.id, input.onlySnapshots) };
1085
1085
  });
1086
- register("save_document", "Create a new document or update an existing document. action=create requires write access; action=update requires edit access for content, and placement changes may require write access. Content or placement changes queue normal indexing.", z3.discriminatedUnion("action", [
1086
+ 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", [
1087
1087
  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.") }),
1088
1088
  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)
1089
1089
  ]), destructive, async (input) => {
@@ -1094,7 +1094,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1094
1094
  const { action: _action, id, ...data } = input;
1095
1095
  return { operation: "update", result: await client2.updateDocument(id, data) };
1096
1096
  });
1097
- register("delete_document", "Move a writable document to trash without purging content or versions. Use only on an explicit delete request; permanently_delete_document is a separate irreversible action.", z3.strictObject({ id: uuid2 }), destructive, async ({ id }) => {
1097
+ 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 }) => {
1098
1098
  await required2(client2.deleteDocument, "delete_document")(id);
1099
1099
  return { id, deleted: true };
1100
1100
  });
@@ -1150,7 +1150,7 @@ function registerCompactCapabilities(server, client2, wrap) {
1150
1150
  await required2(client2.deleteTag, "delete_tag")(id);
1151
1151
  return { id, deleted: true };
1152
1152
  });
1153
- register("set_document_tag", "Add or remove one existing tag assignment on a readable document. Requires edit access to that 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 }) => {
1153
+ 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 }) => {
1154
1154
  if (action === "add") {
1155
1155
  await required2(client2.addTagToDocument, "add_tag_to_document")(documentId, tagId);
1156
1156
  return { operation: "add", result: { documentId, tagId, assigned: true } };
@@ -1165,9 +1165,9 @@ function registerCompactCapabilities(server, client2, wrap) {
1165
1165
  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.") })
1166
1166
  ]), read, async (input) => input.mode === "neighbors" ? { operation: "neighbors", result: await client2.getRelatedDocuments(input.documentId, input.limit) } : { operation: "search", result: await client2.searchGraph(input) });
1167
1167
  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));
1168
- register("refresh_document_index", "Queue an explicit asynchronous reindex for one document. Routine content and placement changes already schedule indexing; check get_document_index_status first.", z3.strictObject({ documentId: uuid2 }), write, async ({ documentId }) => client2.refreshDocumentIndex(documentId));
1168
+ 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));
1169
1169
  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")());
1170
- register("restore_trashed_document", "Return one soft-deleted document to the active library. 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));
1170
+ 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));
1171
1171
  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 }) => {
1172
1172
  await required2(client2.permanentlyDeleteDocument, "permanently_delete_document")(id);
1173
1173
  return { id, deleted: true };
@@ -1329,7 +1329,7 @@ function registerDocsmintMcpCapabilities(server, client2) {
1329
1329
  registerPromptsAndResources(server, client2);
1330
1330
  }
1331
1331
  function createDocsmintMcpServer(options = {}) {
1332
- const server = new McpServer({ name: "docsmint", version: "1.0.1" });
1332
+ const server = new McpServer({ name: "docsmint", version: "1.0.2" });
1333
1333
  const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
1334
1334
  registerDocsmintMcpCapabilities(server, client2);
1335
1335
  return server;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hiai-gg/docsmint",
3
3
  "mcpName": "io.github.HiAi-gg/docsmint",
4
- "version": "1.0.1",
4
+ "version": "1.0.2",
5
5
  "type": "module",
6
6
  "browser": {
7
7
  "./dist/backend-launcher.js": false,
@@ -25,7 +25,7 @@ import { registerSearch } from './commands/search.js';
25
25
  import { registerSnapshot } from './commands/snapshot.js';
26
26
  import { registerUpdate } from './commands/update.js';
27
27
 
28
- const VERSION = '1.0.1';
28
+ const VERSION = '1.0.2';
29
29
 
30
30
  const program = new Command();
31
31
  program.name('docsmint').description('CLI for the DocsMint knowledge workspace').version(VERSION);
package/server.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "id": "1249550690",
11
11
  "subfolder": "packages/mcp-server"
12
12
  },
13
- "version": "1.0.1",
13
+ "version": "1.0.2",
14
14
  "icons": [
15
15
  {
16
16
  "src": "https://raw.githubusercontent.com/HiAi-gg/docsmint/main/frontend/static/logo-dark.png",
@@ -34,7 +34,7 @@
34
34
  "registryType": "npm",
35
35
  "registryBaseUrl": "https://registry.npmjs.org",
36
36
  "identifier": "@hiai-gg/docsmint",
37
- "version": "1.0.1",
37
+ "version": "1.0.2",
38
38
  "runtimeHint": "npx",
39
39
  "transport": {
40
40
  "type": "stdio"