@hiai-gg/docsmint 0.6.0 → 0.6.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.
@@ -1,20 +1,14 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { Version } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { Version } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "create_snapshot",
7
- description:
8
- "Create a named snapshot (labelled version) of a document from its current content.",
6
+ name: 'create_snapshot',
7
+ description: 'Create a named snapshot (labelled version) of a document from its current content.',
9
8
  inputSchema: {
10
- documentId: z.string().describe("Document ID to snapshot."),
11
- label: z
12
- .string()
13
- .describe("Short label for the snapshot (e.g. 'v1.0-release')."),
14
- description: z
15
- .string()
16
- .optional()
17
- .describe("Optional longer description of the snapshot."),
9
+ documentId: z.string().describe('Document ID to snapshot.'),
10
+ label: z.string().describe("Short label for the snapshot (e.g. 'v1.0-release')."),
11
+ description: z.string().optional().describe('Optional longer description of the snapshot.'),
18
12
  },
19
13
  } as const;
20
14
 
@@ -24,7 +18,10 @@ export interface CreateSnapshotArgs {
24
18
  description?: string;
25
19
  }
26
20
 
27
- export async function handler(args: CreateSnapshotArgs): Promise<Version> {
28
- const { documentId, ...input } = args;
29
- return (await client.createSnapshot(documentId, input)) as Version;
30
- }
21
+ export const createHandler = (api: HiaiDocsClient) =>
22
+ async function createSnapshot(args: CreateSnapshotArgs): Promise<Version> {
23
+ const { documentId, ...input } = args;
24
+ return (await api.createSnapshot(documentId, input)) as Version;
25
+ };
26
+
27
+ export const handler = createHandler(client);
@@ -1,13 +1,12 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { ExportResponse } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { ExportResponse } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "export_document",
7
- description:
8
- "Export a document as markdown. Returns the rendered markdown content.",
6
+ name: 'export_document',
7
+ description: 'Export a document as markdown. Returns the rendered markdown content.',
9
8
  inputSchema: {
10
- id: z.string().describe("Document ID to export."),
9
+ id: z.string().describe('Document ID to export.'),
11
10
  },
12
11
  } as const;
13
12
 
@@ -15,8 +14,9 @@ export interface ExportDocumentArgs {
15
14
  id: string;
16
15
  }
17
16
 
18
- export async function handler(
19
- args: ExportDocumentArgs,
20
- ): Promise<ExportResponse> {
21
- return (await client.exportDocument(args.id)) as ExportResponse;
22
- }
17
+ export const createHandler = (api: HiaiDocsClient) =>
18
+ async function exportDocument(args: ExportDocumentArgs): Promise<ExportResponse> {
19
+ return (await api.exportDocument(args.id)) as ExportResponse;
20
+ };
21
+
22
+ export const handler = createHandler(client);
@@ -1,13 +1,12 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { DocumentDetail } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { DocumentDetail } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "get_document",
7
- description:
8
- "Fetch a single document by ID. Returns full content, metadata, and tags.",
6
+ name: 'get_document',
7
+ description: 'Fetch a single document by ID. Returns full content, metadata, and tags.',
9
8
  inputSchema: {
10
- id: z.string().describe("Document ID."),
9
+ id: z.string().describe('Document ID.'),
11
10
  },
12
11
  } as const;
13
12
 
@@ -15,6 +14,9 @@ export interface GetDocumentArgs {
15
14
  id: string;
16
15
  }
17
16
 
18
- export async function handler(args: GetDocumentArgs): Promise<DocumentDetail> {
19
- return (await client.getDocument(args.id)) as DocumentDetail;
20
- }
17
+ export const createHandler = (api: HiaiDocsClient) =>
18
+ async function getDocument(args: GetDocumentArgs): Promise<DocumentDetail> {
19
+ return (await api.getDocument(args.id)) as DocumentDetail;
20
+ };
21
+
22
+ export const handler = createHandler(client);
@@ -1,30 +1,21 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { ListDocumentsResponse } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { ListDocumentsResponse } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "list_documents",
7
- description:
8
- "List documents with pagination, optionally filtered by folder or tag.",
6
+ name: 'list_documents',
7
+ description: 'List documents with pagination, optionally filtered by folder or tag.',
9
8
  inputSchema: {
10
- folderId: z
11
- .string()
12
- .optional()
13
- .describe("Optional folder ID to filter by."),
14
- tag: z.string().optional().describe("Optional tag ID to filter by."),
15
- page: z
16
- .number()
17
- .int()
18
- .positive()
19
- .optional()
20
- .describe("Page number (1-indexed, default 1)."),
9
+ folderId: z.string().optional().describe('Optional folder ID to filter by.'),
10
+ tag: z.string().optional().describe('Optional tag ID to filter by.'),
11
+ page: z.number().int().positive().optional().describe('Page number (1-indexed, default 1).'),
21
12
  limit: z
22
13
  .number()
23
14
  .int()
24
15
  .positive()
25
16
  .max(100)
26
17
  .optional()
27
- .describe("Items per page (default 20, max 100)."),
18
+ .describe('Items per page (default 20, max 100).'),
28
19
  },
29
20
  } as const;
30
21
 
@@ -35,8 +26,9 @@ export interface ListDocumentsArgs {
35
26
  limit?: number;
36
27
  }
37
28
 
38
- export async function handler(
39
- args: ListDocumentsArgs,
40
- ): Promise<ListDocumentsResponse> {
41
- return (await client.listDocuments(args)) as ListDocumentsResponse;
42
- }
29
+ export const createHandler = (api: HiaiDocsClient) =>
30
+ async function listDocuments(args: ListDocumentsArgs): Promise<ListDocumentsResponse> {
31
+ return (await api.listDocuments(args)) as ListDocumentsResponse;
32
+ };
33
+
34
+ export const handler = createHandler(client);
@@ -1,18 +1,16 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { Folder } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { Folder } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "list_folders",
6
+ name: 'list_folders',
7
7
  description:
8
- "List folders, optionally scoped to a parent folder. Returns a flat list of immediate children.",
8
+ 'List folders, optionally scoped to a parent folder. Returns a flat list of immediate children.',
9
9
  inputSchema: {
10
10
  parentId: z
11
11
  .string()
12
12
  .optional()
13
- .describe(
14
- "Optional parent folder ID. Omit to list top-level (root) folders.",
15
- ),
13
+ .describe('Optional parent folder ID. Omit to list top-level (root) folders.'),
16
14
  },
17
15
  } as const;
18
16
 
@@ -20,6 +18,9 @@ export interface ListFoldersArgs {
20
18
  parentId?: string;
21
19
  }
22
20
 
23
- export async function handler(args: ListFoldersArgs): Promise<Folder[]> {
24
- return (await client.listFolders(args)) as Folder[];
25
- }
21
+ export const createHandler = (api: HiaiDocsClient) =>
22
+ async function listFolders(args: ListFoldersArgs): Promise<Folder[]> {
23
+ return (await api.listFolders(args)) as Folder[];
24
+ };
25
+
26
+ export const handler = createHandler(client);
@@ -1,27 +1,21 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { SearchResponse } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { SearchResponse } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "search_documents",
6
+ name: 'search_documents',
7
7
  description:
8
- "Hybrid search across documents (full-text + semantic). Supports filtering by folder and tags.",
8
+ 'Hybrid search across documents (full-text + semantic). Supports filtering by folder and tags.',
9
9
  inputSchema: {
10
- query: z.string().describe("Search query string."),
11
- folder: z
12
- .string()
13
- .optional()
14
- .describe("Optional folder ID to scope the search to."),
15
- tags: z
16
- .array(z.string())
17
- .optional()
18
- .describe("Optional tag IDs to filter by."),
10
+ query: z.string().describe('Search query string.'),
11
+ folder: z.string().optional().describe('Optional folder ID to scope the search to.'),
12
+ tags: z.array(z.string()).optional().describe('Optional tag IDs to filter by.'),
19
13
  limit: z
20
14
  .number()
21
15
  .int()
22
16
  .positive()
23
17
  .optional()
24
- .describe("Maximum number of results to return (default 20)."),
18
+ .describe('Maximum number of results to return (default 20).'),
25
19
  },
26
20
  } as const;
27
21
 
@@ -32,11 +26,14 @@ export type SearchArgs = {
32
26
  limit?: number;
33
27
  };
34
28
 
35
- export async function handler(args: SearchArgs): Promise<SearchResponse> {
36
- return (await client.search({
37
- query: args.query,
38
- folder: args.folder,
39
- tags: args.tags,
40
- limit: args.limit,
41
- })) as SearchResponse;
42
- }
29
+ export const createHandler = (api: HiaiDocsClient) =>
30
+ async function searchDocuments(args: SearchArgs): Promise<SearchResponse> {
31
+ return (await api.search({
32
+ query: args.query,
33
+ folder: args.folder,
34
+ tags: args.tags,
35
+ limit: args.limit,
36
+ })) as SearchResponse;
37
+ };
38
+
39
+ export const handler = createHandler(client);
@@ -1,18 +1,23 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { DocumentDetail } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { DocumentDetail } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "update_document",
6
+ name: 'update_document',
7
7
  description:
8
8
  "Update an existing document's title and/or content. The server creates a new version on each update.",
9
9
  inputSchema: {
10
- id: z.string().describe("Document ID to update."),
11
- title: z.string().optional().describe("New title for the document."),
12
- content: z
10
+ id: z.string().describe('Document ID to update.'),
11
+ title: z.string().optional().describe('New title for the document.'),
12
+ content: z.string().optional().describe('New markdown content for the document.'),
13
+ folderId: z.string().nullable().optional().describe('Move the document to a folder.'),
14
+ categoryId: z
13
15
  .string()
16
+ .nullable()
14
17
  .optional()
15
- .describe("New markdown content for the document."),
18
+ .describe(
19
+ 'Move the document to a category. Category keys cannot escape their configured category.'
20
+ ),
16
21
  },
17
22
  } as const;
18
23
 
@@ -20,11 +25,14 @@ export interface UpdateDocumentArgs {
20
25
  id: string;
21
26
  title?: string;
22
27
  content?: string;
28
+ folderId?: string | null;
29
+ categoryId?: string | null;
23
30
  }
24
31
 
25
- export async function handler(
26
- args: UpdateDocumentArgs,
27
- ): Promise<DocumentDetail> {
28
- const { id, ...patch } = args;
29
- return (await client.updateDocument(id, patch)) as DocumentDetail;
30
- }
32
+ export const createHandler = (api: HiaiDocsClient) =>
33
+ async function updateDocument(args: UpdateDocumentArgs): Promise<DocumentDetail> {
34
+ const { id, ...patch } = args;
35
+ return (await api.updateDocument(id, patch)) as DocumentDetail;
36
+ };
37
+
38
+ export const handler = createHandler(client);
@@ -1,21 +1,16 @@
1
- import { z } from "zod";
2
- import { client } from "../client.js";
3
- import type { Version } from "../types.js";
1
+ import { z } from 'zod';
2
+ import { client, type HiaiDocsClient } from '../client.js';
3
+ import type { Version } from '../types.js';
4
4
 
5
5
  export const definition = {
6
- name: "get_version_history",
7
- description:
8
- "List the version history for a document. Optionally restrict to named snapshots.",
6
+ name: 'get_version_history',
7
+ description: 'List the version history for a document. Optionally restrict to named snapshots.',
9
8
  inputSchema: {
10
- documentId: z
11
- .string()
12
- .describe("Document ID whose versions should be listed."),
9
+ documentId: z.string().describe('Document ID whose versions should be listed.'),
13
10
  onlySnapshots: z
14
11
  .boolean()
15
12
  .optional()
16
- .describe(
17
- "When true, only return named snapshots (skip auto-saved revisions).",
18
- ),
13
+ .describe('When true, only return named snapshots (skip auto-saved revisions).'),
19
14
  },
20
15
  } as const;
21
16
 
@@ -24,9 +19,9 @@ export interface VersionHistoryArgs {
24
19
  onlySnapshots?: boolean;
25
20
  }
26
21
 
27
- export async function handler(args: VersionHistoryArgs): Promise<Version[]> {
28
- return (await client.getVersionHistory(
29
- args.documentId,
30
- args.onlySnapshots,
31
- )) as Version[];
32
- }
22
+ export const createHandler = (api: HiaiDocsClient) =>
23
+ async function getVersionHistory(args: VersionHistoryArgs): Promise<Version[]> {
24
+ return (await api.getVersionHistory(args.documentId, args.onlySnapshots)) as Version[];
25
+ };
26
+
27
+ export const handler = createHandler(client);
package/server.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.hiai-gg/docsmint",
4
+ "title": "DocsMint",
5
+ "description": "Manage scoped DocsMint documents, folders, categories, search, GraphRAG, and indexing through MCP.",
6
+ "repository": {
7
+ "url": "https://github.com/HiAi-gg/docsmint",
8
+ "source": "github",
9
+ "id": "1249550690"
10
+ },
11
+ "version": "0.6.2",
12
+ "packages": [
13
+ {
14
+ "registryType": "npm",
15
+ "identifier": "@hiai-gg/docsmint",
16
+ "version": "0.6.2",
17
+ "transport": {
18
+ "type": "stdio"
19
+ },
20
+ "environmentVariables": [
21
+ {
22
+ "name": "HIAI_DOCS_URL",
23
+ "description": "Base URL of the DocsMint API.",
24
+ "default": "http://localhost:50700"
25
+ },
26
+ {
27
+ "name": "HIAI_DOCS_API_KEY",
28
+ "description": "Workspace or category scoped DocsMint API key.",
29
+ "isRequired": true,
30
+ "isSecret": true
31
+ }
32
+ ]
33
+ }
34
+ ],
35
+ "remotes": [
36
+ {
37
+ "type": "streamable-http",
38
+ "url": "https://docsmint.com/mcp",
39
+ "headers": [
40
+ {
41
+ "name": "Authorization",
42
+ "description": "Bearer DocsMint API key.",
43
+ "isRequired": true,
44
+ "isSecret": true
45
+ },
46
+ {
47
+ "name": "X-Docsmint-Workspace",
48
+ "description": "Optional workspace override for a workspace scoped key.",
49
+ "isRequired": false,
50
+ "isSecret": false
51
+ }
52
+ ]
53
+ }
54
+ ]
55
+ }
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: docsmint-document-manager
3
+ description: Manage and research DocsMint documents through its scoped MCP tools, including categories, folders, hybrid search, GraphRAG, and index refresh.
4
+ ---
5
+
6
+ # DocsMint Document Manager
7
+
8
+ Use this skill when an agent must create, organize, edit, or research documents in a DocsMint workspace.
9
+
10
+ ## Safety and access
11
+
12
+ - Treat the configured API key as the complete authority boundary.
13
+ - A workspace key may manage categories, folders, tags, and documents according to its role.
14
+ - A category key may access only its bound category, folders and documents inside that category, and explicitly granted `read`, `edit`, or `write` operations.
15
+ - Never attempt to manage API keys, members, billing, or workspace settings through document tools.
16
+ - Read a document before changing it. Preserve its language and structure unless the user asks otherwise.
17
+
18
+ ## Retrieval workflow
19
+
20
+ 1. Use `search_documents` with the user's original language.
21
+ 2. Read the most relevant documents with `get_document`.
22
+ 3. Use `get_related_documents` or `search_knowledge_graph` only with authorized document IDs returned by search.
23
+ 4. Cite document IDs and distinguish retrieved facts from inference.
24
+
25
+ ## Document management workflow
26
+
27
+ 1. Inspect `list_categories`, `list_folders`, and `list_tags` before organizing content.
28
+ 2. Create categories only with a workspace-scoped key.
29
+ 3. Create folders and documents within the active scope.
30
+ 4. After an update, inspect `get_document_index_status`; use `refresh_document_index` only when indexing is stale or failed.
31
+ 5. Use snapshots before a substantial rewrite when version history is important.
32
+
33
+ DocsMint owns chunking, embeddings, multilingual hybrid retrieval, entity extraction, and GraphRAG indexing. Agents must use the MCP tools and never write those persistence layers directly.