@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.
- package/README.md +36 -4
- package/dist/backend/index.js +753 -125
- package/dist/backend-account-runtime-cleanup.js +17 -0
- package/dist/backend-api-key-facade.js +17 -0
- package/dist/backend-pipeline-cancellation.js +17 -0
- package/dist/client.d.ts +4 -1
- package/dist/client.js +9 -0
- package/dist/lifecycle-runtime.js +16 -0
- package/dist/types.d.ts +26 -0
- package/package.json +12 -2
- package/packages/cli/src/index.ts +1 -1
- package/packages/db/src/index.ts +16 -7
- package/packages/db/src/schema.ts +34 -0
- package/packages/mcp-server/src/capabilities.ts +189 -0
- package/packages/mcp-server/src/client.ts +191 -138
- package/packages/mcp-server/src/index.ts +4 -105
- package/packages/mcp-server/src/server.ts +87 -0
- package/packages/mcp-server/src/tools/create-document.ts +19 -17
- package/packages/mcp-server/src/tools/create-folder.ts +18 -11
- package/packages/mcp-server/src/tools/create-snapshot.ts +15 -18
- package/packages/mcp-server/src/tools/export-document.ts +12 -12
- package/packages/mcp-server/src/tools/get-document.ts +12 -10
- package/packages/mcp-server/src/tools/list-documents.ts +15 -23
- package/packages/mcp-server/src/tools/list-folders.ts +12 -11
- package/packages/mcp-server/src/tools/search.ts +20 -23
- package/packages/mcp-server/src/tools/update-document.ts +22 -14
- package/packages/mcp-server/src/tools/version-history.ts +13 -18
- package/server.json +55 -0
- package/skills/docsmint-document-manager/SKILL.md +33 -0
|
@@ -46,6 +46,7 @@ __export(exports_schema, {
|
|
|
46
46
|
documentRelations: () => documentRelations,
|
|
47
47
|
documentPipelineRuns: () => documentPipelineRuns,
|
|
48
48
|
documentPipelineBatches: () => documentPipelineBatches,
|
|
49
|
+
documentKnowledgeSummaries: () => documentKnowledgeSummaries,
|
|
49
50
|
documentEmbeddings: () => documentEmbeddings,
|
|
50
51
|
documentEmbeddingRelations: () => documentEmbeddingRelations,
|
|
51
52
|
documentCreateOperations: () => documentCreateOperations,
|
|
@@ -310,6 +311,22 @@ var documentPipelineBatches = pgTable("document_pipeline_batches", {
|
|
|
310
311
|
index("document_pipeline_batches_stage_status_available_idx").on(table.stage, table.status, table.availableAt),
|
|
311
312
|
index("document_pipeline_batches_document_id_idx").on(table.documentId)
|
|
312
313
|
]);
|
|
314
|
+
var documentKnowledgeSummaries = pgTable("document_knowledge_summaries", {
|
|
315
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
316
|
+
document_id: uuid().notNull().references(() => documents.id, { onDelete: "cascade" }),
|
|
317
|
+
owner_id: uuid().notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
318
|
+
workspace_id: text(),
|
|
319
|
+
generation_id: uuid().notNull(),
|
|
320
|
+
revision: text().notNull(),
|
|
321
|
+
language: text().notNull(),
|
|
322
|
+
description: text().notNull(),
|
|
323
|
+
keywords: text().array().notNull().default(sql`ARRAY[]::text[]`),
|
|
324
|
+
created_at: timestamp().defaultNow().notNull(),
|
|
325
|
+
updated_at: timestamp().defaultNow().notNull()
|
|
326
|
+
}, (table) => [
|
|
327
|
+
uniqueIndex("document_knowledge_summaries_document_generation_idx").on(table.document_id, table.generation_id),
|
|
328
|
+
index("document_knowledge_summaries_owner_document_idx").on(table.owner_id, table.document_id)
|
|
329
|
+
]);
|
|
313
330
|
var tags = pgTable("tags", {
|
|
314
331
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
315
332
|
ownerId: uuid("owner_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -46,6 +46,7 @@ __export(exports_schema, {
|
|
|
46
46
|
documentRelations: () => documentRelations,
|
|
47
47
|
documentPipelineRuns: () => documentPipelineRuns,
|
|
48
48
|
documentPipelineBatches: () => documentPipelineBatches,
|
|
49
|
+
documentKnowledgeSummaries: () => documentKnowledgeSummaries,
|
|
49
50
|
documentEmbeddings: () => documentEmbeddings,
|
|
50
51
|
documentEmbeddingRelations: () => documentEmbeddingRelations,
|
|
51
52
|
documentCreateOperations: () => documentCreateOperations,
|
|
@@ -310,6 +311,22 @@ var documentPipelineBatches = pgTable("document_pipeline_batches", {
|
|
|
310
311
|
index("document_pipeline_batches_stage_status_available_idx").on(table.stage, table.status, table.availableAt),
|
|
311
312
|
index("document_pipeline_batches_document_id_idx").on(table.documentId)
|
|
312
313
|
]);
|
|
314
|
+
var documentKnowledgeSummaries = pgTable("document_knowledge_summaries", {
|
|
315
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
316
|
+
document_id: uuid().notNull().references(() => documents.id, { onDelete: "cascade" }),
|
|
317
|
+
owner_id: uuid().notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
318
|
+
workspace_id: text(),
|
|
319
|
+
generation_id: uuid().notNull(),
|
|
320
|
+
revision: text().notNull(),
|
|
321
|
+
language: text().notNull(),
|
|
322
|
+
description: text().notNull(),
|
|
323
|
+
keywords: text().array().notNull().default(sql`ARRAY[]::text[]`),
|
|
324
|
+
created_at: timestamp().defaultNow().notNull(),
|
|
325
|
+
updated_at: timestamp().defaultNow().notNull()
|
|
326
|
+
}, (table) => [
|
|
327
|
+
uniqueIndex("document_knowledge_summaries_document_generation_idx").on(table.document_id, table.generation_id),
|
|
328
|
+
index("document_knowledge_summaries_owner_document_idx").on(table.owner_id, table.document_id)
|
|
329
|
+
]);
|
|
313
330
|
var tags = pgTable("tags", {
|
|
314
331
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
315
332
|
ownerId: uuid("owner_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
@@ -46,6 +46,7 @@ __export(exports_schema, {
|
|
|
46
46
|
documentRelations: () => documentRelations,
|
|
47
47
|
documentPipelineRuns: () => documentPipelineRuns,
|
|
48
48
|
documentPipelineBatches: () => documentPipelineBatches,
|
|
49
|
+
documentKnowledgeSummaries: () => documentKnowledgeSummaries,
|
|
49
50
|
documentEmbeddings: () => documentEmbeddings,
|
|
50
51
|
documentEmbeddingRelations: () => documentEmbeddingRelations,
|
|
51
52
|
documentCreateOperations: () => documentCreateOperations,
|
|
@@ -310,6 +311,22 @@ var documentPipelineBatches = pgTable("document_pipeline_batches", {
|
|
|
310
311
|
index("document_pipeline_batches_stage_status_available_idx").on(table.stage, table.status, table.availableAt),
|
|
311
312
|
index("document_pipeline_batches_document_id_idx").on(table.documentId)
|
|
312
313
|
]);
|
|
314
|
+
var documentKnowledgeSummaries = pgTable("document_knowledge_summaries", {
|
|
315
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
316
|
+
document_id: uuid().notNull().references(() => documents.id, { onDelete: "cascade" }),
|
|
317
|
+
owner_id: uuid().notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
318
|
+
workspace_id: text(),
|
|
319
|
+
generation_id: uuid().notNull(),
|
|
320
|
+
revision: text().notNull(),
|
|
321
|
+
language: text().notNull(),
|
|
322
|
+
description: text().notNull(),
|
|
323
|
+
keywords: text().array().notNull().default(sql`ARRAY[]::text[]`),
|
|
324
|
+
created_at: timestamp().defaultNow().notNull(),
|
|
325
|
+
updated_at: timestamp().defaultNow().notNull()
|
|
326
|
+
}, (table) => [
|
|
327
|
+
uniqueIndex("document_knowledge_summaries_document_generation_idx").on(table.document_id, table.generation_id),
|
|
328
|
+
index("document_knowledge_summaries_owner_document_idx").on(table.owner_id, table.document_id)
|
|
329
|
+
]);
|
|
313
330
|
var tags = pgTable("tags", {
|
|
314
331
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
315
332
|
ownerId: uuid("owner_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
package/dist/client.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* failures (502 / 503 / 504 / timeout / network reset) are retried
|
|
8
8
|
* with exponential backoff up to `config.retries` attempts.
|
|
9
9
|
*/
|
|
10
|
-
import type { DocsApiKeyCreated, DocsApiKeyListResponse, DocsAttachment, DocsAttachmentConfirmInput, DocsAttachmentListResponse, DocsAttachmentPresignInput, DocsAttachmentPresignResponse, DocsCategory, DocsCategoryInput, DocsCategoryUpdate, DocsDocument, DocsDocumentCreateInput, DocsDocumentCursorPage, DocsDocumentListResponse, DocsDocumentPipeline, DocsDocumentUpdateInput, DocsFolder, DocsFolderCreateInput, DocsFolderUpdateInput, DocsGraphEntitiesResponse, DocsGraphRelatedResponse, DocsGraphSearchResponse, DocsHealthResponse, DocsRequestContext, DocsSearchOptions, DocsSearchResponse, DocsSearchSuggestItem, DocsSharedContent, DocsShareLink, DocsShareListResponse, DocsShareRole, DocsTag, DocsVersion, DocsVersionDiff } from "./types.js";
|
|
10
|
+
import type { DocsApiKeyCreated, DocsApiKeyListResponse, DocsAttachment, DocsAttachmentConfirmInput, DocsAttachmentListResponse, DocsAttachmentPresignInput, DocsAttachmentPresignResponse, DocsCategory, DocsCategoryInput, DocsCategoryUpdate, DocsDocument, DocsDocumentCreateInput, DocsDocumentCursorPage, DocsDocumentIndexRefresh, DocsDocumentIndexStatus, DocsDocumentKnowledgeSummary, DocsDocumentListResponse, DocsDocumentPipeline, DocsDocumentUpdateInput, DocsFolder, DocsFolderCreateInput, DocsFolderUpdateInput, DocsGraphEntitiesResponse, DocsGraphRelatedResponse, DocsGraphSearchResponse, DocsHealthResponse, DocsRequestContext, DocsSearchOptions, DocsSearchResponse, DocsSearchSuggestItem, DocsSharedContent, DocsShareLink, DocsShareListResponse, DocsShareRole, DocsTag, DocsVersion, DocsVersionDiff } from "./types.js";
|
|
11
11
|
export interface DocsClientConfig {
|
|
12
12
|
/** Base URL of the hiai-docs API, e.g. `http://localhost:50700`. */
|
|
13
13
|
baseUrl: string;
|
|
@@ -81,6 +81,9 @@ export declare class DocsClient {
|
|
|
81
81
|
}, context?: DocsRequestContext): Promise<DocsDocumentCursorPage>;
|
|
82
82
|
duplicateDoc(id: string, context?: DocsRequestContext): Promise<DocsDocument>;
|
|
83
83
|
getDocumentPipeline(id: string, context?: DocsRequestContext): Promise<DocsDocumentPipeline>;
|
|
84
|
+
getDocumentKnowledgeSummary(id: string, context?: DocsRequestContext): Promise<DocsDocumentKnowledgeSummary>;
|
|
85
|
+
getDocumentIndexStatus(id: string, context?: DocsRequestContext): Promise<DocsDocumentIndexStatus>;
|
|
86
|
+
refreshDocumentIndex(id: string, context?: DocsRequestContext): Promise<DocsDocumentIndexRefresh>;
|
|
84
87
|
publishDoc(id: string, context?: DocsRequestContext): Promise<DocsDocument>;
|
|
85
88
|
unpublishDoc(id: string, context?: DocsRequestContext): Promise<DocsDocument>;
|
|
86
89
|
/**
|
package/dist/client.js
CHANGED
|
@@ -123,6 +123,15 @@ export class DocsClient {
|
|
|
123
123
|
async getDocumentPipeline(id, context) {
|
|
124
124
|
return this.request("GET", `/api/documents/${encodeURIComponent(id)}/pipeline`, undefined, context);
|
|
125
125
|
}
|
|
126
|
+
async getDocumentKnowledgeSummary(id, context) {
|
|
127
|
+
return this.request("GET", `/api/documents/${encodeURIComponent(id)}/knowledge-summary`, undefined, context);
|
|
128
|
+
}
|
|
129
|
+
async getDocumentIndexStatus(id, context) {
|
|
130
|
+
return this.request("GET", `/api/documents/${encodeURIComponent(id)}/index-status`, undefined, context);
|
|
131
|
+
}
|
|
132
|
+
async refreshDocumentIndex(id, context) {
|
|
133
|
+
return this.request("POST", `/api/documents/${encodeURIComponent(id)}/index/refresh`, undefined, context);
|
|
134
|
+
}
|
|
126
135
|
async publishDoc(id, context) {
|
|
127
136
|
return this.request("POST", `/api/documents/${encodeURIComponent(id)}/publish`, undefined, context);
|
|
128
137
|
}
|
|
@@ -252,6 +252,22 @@ var documentPipelineBatches = pgTable("document_pipeline_batches", {
|
|
|
252
252
|
index("document_pipeline_batches_stage_status_available_idx").on(table.stage, table.status, table.availableAt),
|
|
253
253
|
index("document_pipeline_batches_document_id_idx").on(table.documentId)
|
|
254
254
|
]);
|
|
255
|
+
var documentKnowledgeSummaries = pgTable("document_knowledge_summaries", {
|
|
256
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
257
|
+
document_id: uuid().notNull().references(() => documents.id, { onDelete: "cascade" }),
|
|
258
|
+
owner_id: uuid().notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
259
|
+
workspace_id: text(),
|
|
260
|
+
generation_id: uuid().notNull(),
|
|
261
|
+
revision: text().notNull(),
|
|
262
|
+
language: text().notNull(),
|
|
263
|
+
description: text().notNull(),
|
|
264
|
+
keywords: text().array().notNull().default(sql`ARRAY[]::text[]`),
|
|
265
|
+
created_at: timestamp().defaultNow().notNull(),
|
|
266
|
+
updated_at: timestamp().defaultNow().notNull()
|
|
267
|
+
}, (table) => [
|
|
268
|
+
uniqueIndex("document_knowledge_summaries_document_generation_idx").on(table.document_id, table.generation_id),
|
|
269
|
+
index("document_knowledge_summaries_owner_document_idx").on(table.owner_id, table.document_id)
|
|
270
|
+
]);
|
|
255
271
|
var tags = pgTable("tags", {
|
|
256
272
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
257
273
|
ownerId: uuid("owner_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
package/dist/types.d.ts
CHANGED
|
@@ -356,6 +356,32 @@ export interface DocsDocumentPipeline {
|
|
|
356
356
|
};
|
|
357
357
|
updatedAt: string;
|
|
358
358
|
}
|
|
359
|
+
export interface DocsDocumentKnowledgeSummary {
|
|
360
|
+
documentId: string;
|
|
361
|
+
generationId: string;
|
|
362
|
+
revision: string;
|
|
363
|
+
language: string;
|
|
364
|
+
description: string;
|
|
365
|
+
keywords: string[];
|
|
366
|
+
createdAt: string;
|
|
367
|
+
updatedAt: string;
|
|
368
|
+
}
|
|
369
|
+
export interface DocsDocumentIndexStatus {
|
|
370
|
+
documentId: string;
|
|
371
|
+
embeddingStatus: "pending" | "processing" | "ready" | "failed" | "stale";
|
|
372
|
+
activeGenerationId: string | null;
|
|
373
|
+
pendingGenerationId: string | null;
|
|
374
|
+
embeddingProfile: string | null;
|
|
375
|
+
embeddingErrorCode: string | null;
|
|
376
|
+
embeddingUpdatedAt: string | null;
|
|
377
|
+
searchable: boolean;
|
|
378
|
+
pipeline: DocsDocumentPipeline | null;
|
|
379
|
+
}
|
|
380
|
+
export interface DocsDocumentIndexRefresh {
|
|
381
|
+
documentId: string;
|
|
382
|
+
generationId: string;
|
|
383
|
+
deduplicated: boolean;
|
|
384
|
+
}
|
|
359
385
|
export interface DocsVersion {
|
|
360
386
|
id: string;
|
|
361
387
|
documentId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hiai-gg/docsmint",
|
|
3
|
-
"
|
|
3
|
+
"mcpName": "io.github.hiai-gg/docsmint",
|
|
4
|
+
"version": "0.6.2",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"browser": {
|
|
6
7
|
"./dist/backend-launcher.js": false,
|
|
@@ -57,6 +58,10 @@
|
|
|
57
58
|
"import": "./dist/index.js",
|
|
58
59
|
"types": "./dist/index.d.ts"
|
|
59
60
|
},
|
|
61
|
+
"./mcp": {
|
|
62
|
+
"import": "./packages/mcp-server/src/server.ts",
|
|
63
|
+
"types": "./packages/mcp-server/src/server.ts"
|
|
64
|
+
},
|
|
60
65
|
"./lifecycle": {
|
|
61
66
|
"browser": "./dist/server-only-browser-entry.js",
|
|
62
67
|
"import": "./dist/lifecycle.js",
|
|
@@ -349,8 +354,12 @@
|
|
|
349
354
|
"packages/cli/src/format.ts",
|
|
350
355
|
"packages/cli/src/commands",
|
|
351
356
|
"packages/mcp-server/src/client.ts",
|
|
357
|
+
"packages/mcp-server/src/index.ts",
|
|
358
|
+
"packages/mcp-server/src/server.ts",
|
|
359
|
+
"packages/mcp-server/src/capabilities.ts",
|
|
352
360
|
"packages/mcp-server/src/types.ts",
|
|
353
361
|
"packages/mcp-server/src/tools",
|
|
362
|
+
"skills",
|
|
354
363
|
"backend/src/lib/redis-factory.ts",
|
|
355
364
|
"backend/src/lib/storage-factory.ts",
|
|
356
365
|
"backend/src/lib/logger.ts",
|
|
@@ -358,6 +367,7 @@
|
|
|
358
367
|
"backend/src/lib/api-keys.ts",
|
|
359
368
|
"backend/src/lib/api-key-encryption.ts",
|
|
360
369
|
"backend/src/lib/lifecycle-service.ts",
|
|
370
|
+
"server.json",
|
|
361
371
|
"README.md",
|
|
362
372
|
"LICENSE"
|
|
363
373
|
],
|
|
@@ -376,7 +386,7 @@
|
|
|
376
386
|
"prepublishOnly": "cd packages/sdk && bun run build"
|
|
377
387
|
},
|
|
378
388
|
"dependencies": {
|
|
379
|
-
"@modelcontextprotocol/
|
|
389
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
380
390
|
"bullmq": "^5.80.2",
|
|
381
391
|
"commander": "^13.1.0",
|
|
382
392
|
"ioredis": "^5.11.1",
|
|
@@ -24,7 +24,7 @@ import { registerSearch } from "./commands/search.js";
|
|
|
24
24
|
import { registerSnapshot } from "./commands/snapshot.js";
|
|
25
25
|
import { registerUpdate } from "./commands/update.js";
|
|
26
26
|
|
|
27
|
-
const VERSION = "0.6.
|
|
27
|
+
const VERSION = "0.6.2";
|
|
28
28
|
|
|
29
29
|
const program = new Command();
|
|
30
30
|
program
|
package/packages/db/src/index.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
export * from "./schema";
|
|
2
|
-
export { db, client } from "./client";
|
|
3
1
|
export type { Database } from "./client";
|
|
2
|
+
export { client, db } from "./client";
|
|
3
|
+
export type {
|
|
4
|
+
CreateDocumentWithVersionInput,
|
|
5
|
+
UpdateDocumentWithVersionInput,
|
|
6
|
+
} from "./document-writer";
|
|
4
7
|
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
createDocumentWithVersion,
|
|
9
|
+
trashDocuments,
|
|
10
|
+
updateDocumentWithVersion,
|
|
11
|
+
} from "./document-writer";
|
|
12
|
+
export * from "./schema";
|
|
10
13
|
export type {
|
|
11
14
|
ActorScopedTransactionExecutor,
|
|
12
15
|
TenantContext,
|
|
13
16
|
TenantTransaction,
|
|
14
17
|
} from "./with-tenant";
|
|
18
|
+
export {
|
|
19
|
+
adminTenantContext,
|
|
20
|
+
createActorScopedTransactionExecutor,
|
|
21
|
+
shareGuestTenantContext,
|
|
22
|
+
withTenant,
|
|
23
|
+
} from "./with-tenant";
|
|
@@ -354,6 +354,40 @@ export const documentPipelineBatches = pgTable(
|
|
|
354
354
|
],
|
|
355
355
|
);
|
|
356
356
|
|
|
357
|
+
// ============================================
|
|
358
|
+
// document_knowledge_summaries — generation-scoped retrieval metadata
|
|
359
|
+
// ============================================
|
|
360
|
+
export const documentKnowledgeSummaries = pgTable(
|
|
361
|
+
"document_knowledge_summaries",
|
|
362
|
+
{
|
|
363
|
+
id: uuid().primaryKey().defaultRandom(),
|
|
364
|
+
document_id: uuid()
|
|
365
|
+
.notNull()
|
|
366
|
+
.references(() => documents.id, { onDelete: "cascade" }),
|
|
367
|
+
owner_id: uuid()
|
|
368
|
+
.notNull()
|
|
369
|
+
.references(() => users.id, { onDelete: "cascade" }),
|
|
370
|
+
workspace_id: text(),
|
|
371
|
+
generation_id: uuid().notNull(),
|
|
372
|
+
revision: text().notNull(),
|
|
373
|
+
language: text().notNull(),
|
|
374
|
+
description: text().notNull(),
|
|
375
|
+
keywords: text().array().notNull().default(sql`ARRAY[]::text[]`),
|
|
376
|
+
created_at: timestamp().defaultNow().notNull(),
|
|
377
|
+
updated_at: timestamp().defaultNow().notNull(),
|
|
378
|
+
},
|
|
379
|
+
(table) => [
|
|
380
|
+
uniqueIndex("document_knowledge_summaries_document_generation_idx").on(
|
|
381
|
+
table.document_id,
|
|
382
|
+
table.generation_id,
|
|
383
|
+
),
|
|
384
|
+
index("document_knowledge_summaries_owner_document_idx").on(
|
|
385
|
+
table.owner_id,
|
|
386
|
+
table.document_id,
|
|
387
|
+
),
|
|
388
|
+
],
|
|
389
|
+
);
|
|
390
|
+
|
|
357
391
|
// ============================================
|
|
358
392
|
// tags — document tags
|
|
359
393
|
// ============================================
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
import type { HiaiDocsClient } from './client.js';
|
|
5
|
+
|
|
6
|
+
export const capabilityCatalog = {
|
|
7
|
+
tools: [
|
|
8
|
+
'search_documents',
|
|
9
|
+
'get_document',
|
|
10
|
+
'create_document',
|
|
11
|
+
'update_document',
|
|
12
|
+
'list_documents',
|
|
13
|
+
'list_folders',
|
|
14
|
+
'create_folder',
|
|
15
|
+
'create_snapshot',
|
|
16
|
+
'get_version_history',
|
|
17
|
+
'export_document',
|
|
18
|
+
'list_categories',
|
|
19
|
+
'create_category',
|
|
20
|
+
'list_tags',
|
|
21
|
+
'get_related_documents',
|
|
22
|
+
'search_knowledge_graph',
|
|
23
|
+
'get_document_index_status',
|
|
24
|
+
'refresh_document_index',
|
|
25
|
+
] as const,
|
|
26
|
+
prompts: ['organize_workspace', 'research_workspace'] as const,
|
|
27
|
+
resources: [
|
|
28
|
+
'docsmint://guide/editor',
|
|
29
|
+
'docsmint://guide/search',
|
|
30
|
+
'docsmint://workspace/catalog',
|
|
31
|
+
] as const,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type TextResult = { content: Array<{ type: 'text'; text: string }> };
|
|
35
|
+
|
|
36
|
+
function jsonResult(value: unknown): TextResult {
|
|
37
|
+
return { content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function registerExtendedCapabilities(server: McpServer, client: HiaiDocsClient): void {
|
|
41
|
+
server.registerTool(
|
|
42
|
+
'list_categories',
|
|
43
|
+
{
|
|
44
|
+
description:
|
|
45
|
+
'List categories visible to the API key. Category keys receive only their bound category.',
|
|
46
|
+
inputSchema: z.object({}),
|
|
47
|
+
},
|
|
48
|
+
async () => jsonResult(await client.listCategories())
|
|
49
|
+
);
|
|
50
|
+
server.registerTool(
|
|
51
|
+
'create_category',
|
|
52
|
+
{
|
|
53
|
+
description:
|
|
54
|
+
'Create a category. Requires a workspace key with write access; category keys cannot mutate categories.',
|
|
55
|
+
inputSchema: z.object({
|
|
56
|
+
name: z.string().min(1),
|
|
57
|
+
description: z.string().optional(),
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
async (input) => jsonResult(await client.createCategory(input))
|
|
61
|
+
);
|
|
62
|
+
server.registerTool(
|
|
63
|
+
'list_tags',
|
|
64
|
+
{
|
|
65
|
+
description: 'List tags visible in the workspace or bound category.',
|
|
66
|
+
inputSchema: z.object({}),
|
|
67
|
+
},
|
|
68
|
+
async () => jsonResult(await client.listTags())
|
|
69
|
+
);
|
|
70
|
+
server.registerTool(
|
|
71
|
+
'get_related_documents',
|
|
72
|
+
{
|
|
73
|
+
description: 'Traverse the knowledge graph from one authorized document.',
|
|
74
|
+
inputSchema: z.object({
|
|
75
|
+
documentId: z.string().min(1),
|
|
76
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
async ({ documentId, limit }) => jsonResult(await client.getRelatedDocuments(documentId, limit))
|
|
80
|
+
);
|
|
81
|
+
server.registerTool(
|
|
82
|
+
'search_knowledge_graph',
|
|
83
|
+
{
|
|
84
|
+
description:
|
|
85
|
+
'Search connected knowledge using authorized seed documents. Category keys may use only documents in their category.',
|
|
86
|
+
inputSchema: z.object({
|
|
87
|
+
query: z.string().min(1).max(1000),
|
|
88
|
+
docIds: z.array(z.string().min(1)).min(1),
|
|
89
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
90
|
+
}),
|
|
91
|
+
},
|
|
92
|
+
async (input) => jsonResult(await client.searchGraph(input))
|
|
93
|
+
);
|
|
94
|
+
server.registerTool(
|
|
95
|
+
'get_document_index_status',
|
|
96
|
+
{
|
|
97
|
+
description: 'Read the current indexing and knowledge-pipeline status of a document.',
|
|
98
|
+
inputSchema: z.object({ documentId: z.string().min(1) }),
|
|
99
|
+
},
|
|
100
|
+
async ({ documentId }) => jsonResult(await client.getDocumentIndexStatus(documentId))
|
|
101
|
+
);
|
|
102
|
+
server.registerTool(
|
|
103
|
+
'refresh_document_index',
|
|
104
|
+
{
|
|
105
|
+
description: 'Request reindexing after a document or metadata change. Requires write access.',
|
|
106
|
+
inputSchema: z.object({ documentId: z.string().min(1) }),
|
|
107
|
+
},
|
|
108
|
+
async ({ documentId }) => jsonResult(await client.refreshDocumentIndex(documentId))
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
server.registerPrompt(
|
|
112
|
+
'organize_workspace',
|
|
113
|
+
{
|
|
114
|
+
description: 'Plan safe document organization using DocsMint categories and folders.',
|
|
115
|
+
argsSchema: z.object({
|
|
116
|
+
objective: z.string(),
|
|
117
|
+
language: z.string().optional(),
|
|
118
|
+
}),
|
|
119
|
+
},
|
|
120
|
+
({ objective, language }) => ({
|
|
121
|
+
messages: [
|
|
122
|
+
{
|
|
123
|
+
role: 'user',
|
|
124
|
+
content: {
|
|
125
|
+
type: 'text',
|
|
126
|
+
text: `Organize this DocsMint workspace for: ${objective}. Work in ${language ?? 'the document language'}. Inspect categories, folders, tags, and documents before proposing or applying changes. Preserve document content and obey the API key scope.`,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
server.registerPrompt(
|
|
133
|
+
'research_workspace',
|
|
134
|
+
{
|
|
135
|
+
description:
|
|
136
|
+
'Research a question with hybrid search and GraphRAG while citing DocsMint document IDs.',
|
|
137
|
+
argsSchema: z.object({
|
|
138
|
+
question: z.string(),
|
|
139
|
+
language: z.string().optional(),
|
|
140
|
+
}),
|
|
141
|
+
},
|
|
142
|
+
({ question, language }) => ({
|
|
143
|
+
messages: [
|
|
144
|
+
{
|
|
145
|
+
role: 'user',
|
|
146
|
+
content: {
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: `Answer this question from DocsMint: ${question}. Respond in ${language ?? 'the question language'}. Start with hybrid search, use graph traversal only from authorized result documents, and cite document IDs. Distinguish retrieved facts from inference.`,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
server.registerResource('editor-guide', 'docsmint://guide/editor', {}, async (uri) => ({
|
|
156
|
+
contents: [
|
|
157
|
+
{
|
|
158
|
+
uri: uri.href,
|
|
159
|
+
mimeType: 'text/markdown',
|
|
160
|
+
text: '# DocsMint editing rules\n\nRead a document before updating it. Preserve its language, title intent, TipTap/Markdown structure, category, folder, and tags unless the user explicitly requests a change. After content changes, verify index status and request refresh only when needed.',
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
}));
|
|
164
|
+
server.registerResource('search-guide', 'docsmint://guide/search', {}, async (uri) => ({
|
|
165
|
+
contents: [
|
|
166
|
+
{
|
|
167
|
+
uri: uri.href,
|
|
168
|
+
mimeType: 'text/markdown',
|
|
169
|
+
text: '# DocsMint retrieval rules\n\nUse search_documents for normal retrieval. Use get_related_documents or search_knowledge_graph only with document IDs already authorized by the active API key. Keep multilingual queries in their original language and cite document IDs in answers.',
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
}));
|
|
173
|
+
server.registerResource('workspace-catalog', 'docsmint://workspace/catalog', {}, async (uri) => {
|
|
174
|
+
const [categories, folders, tags] = await Promise.all([
|
|
175
|
+
client.listCategories(),
|
|
176
|
+
client.listFolders({}),
|
|
177
|
+
client.listTags(),
|
|
178
|
+
]);
|
|
179
|
+
return {
|
|
180
|
+
contents: [
|
|
181
|
+
{
|
|
182
|
+
uri: uri.href,
|
|
183
|
+
mimeType: 'application/json',
|
|
184
|
+
text: JSON.stringify({ categories, folders, tags }, null, 2),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|