@hiai-gg/docsmint 0.8.7 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -21
- package/dist/backend/index.js +203 -165
- package/dist/client.d.ts +2 -2
- package/dist/mcp-cli.js +421 -114
- package/dist/mcp-server.d.ts +12 -4
- package/dist/mcp-server.js +453 -114
- package/dist/types.d.ts +5 -0
- package/package.json +2 -2
- package/packages/cli/src/index.ts +1 -1
- package/server.json +12 -8
package/dist/mcp-server.js
CHANGED
|
@@ -16,7 +16,7 @@ var __export = (target, all) => {
|
|
|
16
16
|
|
|
17
17
|
// ../mcp-server/src/server.ts
|
|
18
18
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
19
|
-
import { z as
|
|
19
|
+
import { z as z14 } from "zod";
|
|
20
20
|
|
|
21
21
|
// dist/client.js
|
|
22
22
|
var docsApiErrorBrand = Symbol.for("io.github.hiai-gg.docsmint.DocsApiError");
|
|
@@ -578,86 +578,403 @@ var RESOURCE_PERMISSIONS = new Set([
|
|
|
578
578
|
"write"
|
|
579
579
|
]);
|
|
580
580
|
// ../mcp-server/src/lifecycle.ts
|
|
581
|
+
import { z as z2 } from "zod";
|
|
582
|
+
|
|
583
|
+
// ../mcp-server/src/output-schemas.ts
|
|
581
584
|
import { z } from "zod";
|
|
585
|
+
var tagSchema = z.looseObject({
|
|
586
|
+
id: z.string(),
|
|
587
|
+
name: z.string(),
|
|
588
|
+
color: z.string().nullable(),
|
|
589
|
+
createdAt: z.string().optional(),
|
|
590
|
+
documentCount: z.number().optional()
|
|
591
|
+
});
|
|
592
|
+
var documentSchema = z.looseObject({
|
|
593
|
+
id: z.string(),
|
|
594
|
+
ownerId: z.string(),
|
|
595
|
+
folderId: z.string().nullable(),
|
|
596
|
+
categoryId: z.string().nullable(),
|
|
597
|
+
title: z.string(),
|
|
598
|
+
content: z.string(),
|
|
599
|
+
contentJson: z.unknown().optional(),
|
|
600
|
+
metadata: z.unknown().optional(),
|
|
601
|
+
visibility: z.enum(["private", "shared", "public"]),
|
|
602
|
+
createdAt: z.string(),
|
|
603
|
+
updatedAt: z.string(),
|
|
604
|
+
tags: z.array(tagSchema).optional(),
|
|
605
|
+
folderName: z.string().nullable().optional()
|
|
606
|
+
});
|
|
607
|
+
var documentListItemSchema = z.looseObject({
|
|
608
|
+
id: z.string(),
|
|
609
|
+
title: z.string(),
|
|
610
|
+
content: z.string(),
|
|
611
|
+
folderId: z.string().nullable(),
|
|
612
|
+
folderName: z.string().nullable(),
|
|
613
|
+
categoryId: z.string().nullable(),
|
|
614
|
+
categoryName: z.string().nullable(),
|
|
615
|
+
createdAt: z.string(),
|
|
616
|
+
updatedAt: z.string(),
|
|
617
|
+
tags: z.array(tagSchema)
|
|
618
|
+
});
|
|
619
|
+
var searchChunkSchema = z.looseObject({
|
|
620
|
+
chunkIndex: z.number(),
|
|
621
|
+
chunkText: z.string(),
|
|
622
|
+
charStart: z.number(),
|
|
623
|
+
charEnd: z.number(),
|
|
624
|
+
score: z.number()
|
|
625
|
+
});
|
|
626
|
+
var searchResultSchema = z.looseObject({
|
|
627
|
+
id: z.string(),
|
|
628
|
+
title: z.string(),
|
|
629
|
+
snippet: z.string(),
|
|
630
|
+
score: z.number(),
|
|
631
|
+
folder_id: z.string().nullable(),
|
|
632
|
+
folder_name: z.string().nullable(),
|
|
633
|
+
created_at: z.string(),
|
|
634
|
+
updated_at: z.string(),
|
|
635
|
+
tags: z.array(tagSchema).optional(),
|
|
636
|
+
chunks: z.array(searchChunkSchema).optional()
|
|
637
|
+
});
|
|
638
|
+
var categoryBaseSchema = z.looseObject({
|
|
639
|
+
id: z.string(),
|
|
640
|
+
name: z.string(),
|
|
641
|
+
order: z.number(),
|
|
642
|
+
createdAt: z.string(),
|
|
643
|
+
updatedAt: z.string(),
|
|
644
|
+
documentCount: z.number().optional(),
|
|
645
|
+
folderCount: z.number().optional()
|
|
646
|
+
});
|
|
647
|
+
var categorySchema = categoryBaseSchema.extend({
|
|
648
|
+
apiMode: z.enum(["unavailable", "global", "category"]),
|
|
649
|
+
apiPermissionRead: z.boolean(),
|
|
650
|
+
apiPermissionEdit: z.boolean(),
|
|
651
|
+
apiPermissionWrite: z.boolean()
|
|
652
|
+
});
|
|
653
|
+
var categoryListItemSchema = z.union([
|
|
654
|
+
categorySchema,
|
|
655
|
+
categoryBaseSchema
|
|
656
|
+
]);
|
|
657
|
+
var graphEntitySchema = z.looseObject({
|
|
658
|
+
name: z.string(),
|
|
659
|
+
type: z.string()
|
|
660
|
+
});
|
|
661
|
+
var pipelineStatusSchema = z.enum([
|
|
662
|
+
"pending",
|
|
663
|
+
"processing",
|
|
664
|
+
"ready",
|
|
665
|
+
"retrying",
|
|
666
|
+
"failed",
|
|
667
|
+
"ready_with_warnings",
|
|
668
|
+
"skipped",
|
|
669
|
+
"cancelled"
|
|
670
|
+
]);
|
|
671
|
+
var pipelineSchema = z.looseObject({
|
|
672
|
+
documentId: z.string(),
|
|
673
|
+
generationId: z.string(),
|
|
674
|
+
status: pipelineStatusSchema,
|
|
675
|
+
revision: z.string(),
|
|
676
|
+
stages: z.looseObject({
|
|
677
|
+
prepare: pipelineStatusSchema,
|
|
678
|
+
embed: pipelineStatusSchema,
|
|
679
|
+
graph: pipelineStatusSchema,
|
|
680
|
+
summarize: pipelineStatusSchema,
|
|
681
|
+
finalize: pipelineStatusSchema
|
|
682
|
+
}),
|
|
683
|
+
batches: z.looseObject({
|
|
684
|
+
total: z.number(),
|
|
685
|
+
completed: z.number(),
|
|
686
|
+
failed: z.number()
|
|
687
|
+
}),
|
|
688
|
+
warnings: z.array(z.looseObject({
|
|
689
|
+
stage: z.enum(["graph", "summarize"]),
|
|
690
|
+
code: z.string(),
|
|
691
|
+
retryable: z.boolean()
|
|
692
|
+
})),
|
|
693
|
+
updatedAt: z.string()
|
|
694
|
+
});
|
|
695
|
+
var indexStatusSchema = z.looseObject({
|
|
696
|
+
documentId: z.string(),
|
|
697
|
+
embeddingStatus: z.enum(["pending", "processing", "ready", "failed", "stale"]),
|
|
698
|
+
activeGenerationId: z.string().nullable(),
|
|
699
|
+
pendingGenerationId: z.string().nullable(),
|
|
700
|
+
embeddingProfile: z.string().nullable(),
|
|
701
|
+
embeddingErrorCode: z.string().nullable(),
|
|
702
|
+
embeddingUpdatedAt: z.string().nullable(),
|
|
703
|
+
searchable: z.boolean(),
|
|
704
|
+
pipeline: pipelineSchema.nullable()
|
|
705
|
+
});
|
|
706
|
+
var versionSchema = z.looseObject({
|
|
707
|
+
id: z.string(),
|
|
708
|
+
documentId: z.string(),
|
|
709
|
+
content: z.string(),
|
|
710
|
+
contentJson: z.unknown().optional(),
|
|
711
|
+
createdBy: z.string(),
|
|
712
|
+
createdAt: z.string(),
|
|
713
|
+
label: z.string().nullable().optional(),
|
|
714
|
+
description: z.string().nullable().optional(),
|
|
715
|
+
isSnapshot: z.boolean().optional(),
|
|
716
|
+
restoredFrom: z.string().nullable().optional()
|
|
717
|
+
});
|
|
718
|
+
var folderSchema = z.looseObject({
|
|
719
|
+
id: z.string(),
|
|
720
|
+
ownerId: z.string(),
|
|
721
|
+
parentId: z.string().nullable(),
|
|
722
|
+
name: z.string(),
|
|
723
|
+
createdAt: z.string(),
|
|
724
|
+
updatedAt: z.string(),
|
|
725
|
+
categoryId: z.string().nullable().optional(),
|
|
726
|
+
order: z.number().optional(),
|
|
727
|
+
documentCount: z.number().optional(),
|
|
728
|
+
subfolderCount: z.number().optional(),
|
|
729
|
+
children: z.array(z.lazy(() => folderSchema)).optional(),
|
|
730
|
+
documents: z.array(documentListItemSchema).optional()
|
|
731
|
+
});
|
|
732
|
+
var exportedDocumentSchema = z.looseObject({
|
|
733
|
+
markdown: z.string(),
|
|
734
|
+
filename: z.string().optional()
|
|
735
|
+
});
|
|
736
|
+
var relatedDocumentsSchema = z.looseObject({
|
|
737
|
+
related: z.array(z.looseObject({
|
|
738
|
+
docId: z.string(),
|
|
739
|
+
relationType: z.string(),
|
|
740
|
+
hopDistance: z.number()
|
|
741
|
+
}))
|
|
742
|
+
});
|
|
743
|
+
var graphSearchSchema = z.looseObject({
|
|
744
|
+
query: z.string().optional(),
|
|
745
|
+
entities: z.array(graphEntitySchema),
|
|
746
|
+
relatedDocs: z.array(z.looseObject({
|
|
747
|
+
docId: z.string(),
|
|
748
|
+
relationType: z.string(),
|
|
749
|
+
hopDistance: z.number(),
|
|
750
|
+
title: z.string(),
|
|
751
|
+
snippet: z.string()
|
|
752
|
+
}))
|
|
753
|
+
});
|
|
754
|
+
var deleteAcknowledgmentSchema = z.looseObject({
|
|
755
|
+
id: z.string().uuid(),
|
|
756
|
+
deleted: z.literal(true)
|
|
757
|
+
});
|
|
758
|
+
var toolOutputSchemas = {
|
|
759
|
+
search_documents: z.looseObject({
|
|
760
|
+
items: z.array(searchResultSchema),
|
|
761
|
+
total: z.number(),
|
|
762
|
+
page: z.number(),
|
|
763
|
+
limit: z.number(),
|
|
764
|
+
diagnostics: z.looseObject({
|
|
765
|
+
graphAttempted: z.boolean(),
|
|
766
|
+
graphFailed: z.boolean(),
|
|
767
|
+
graphContribution: z.boolean()
|
|
768
|
+
}).optional()
|
|
769
|
+
}),
|
|
770
|
+
get_document: documentSchema,
|
|
771
|
+
create_document: documentSchema,
|
|
772
|
+
update_document: documentSchema,
|
|
773
|
+
list_documents: z.looseObject({
|
|
774
|
+
items: z.array(documentListItemSchema),
|
|
775
|
+
total: z.number(),
|
|
776
|
+
page: z.number(),
|
|
777
|
+
limit: z.number()
|
|
778
|
+
}),
|
|
779
|
+
list_folders: z.array(folderSchema),
|
|
780
|
+
create_folder: folderSchema,
|
|
781
|
+
create_snapshot: versionSchema,
|
|
782
|
+
get_version_history: z.array(versionSchema),
|
|
783
|
+
export_document: exportedDocumentSchema,
|
|
784
|
+
list_categories: z.array(categoryListItemSchema),
|
|
785
|
+
create_category: categorySchema,
|
|
786
|
+
list_tags: z.array(tagSchema),
|
|
787
|
+
get_related_documents: relatedDocumentsSchema,
|
|
788
|
+
search_knowledge_graph: graphSearchSchema,
|
|
789
|
+
get_document_index_status: indexStatusSchema,
|
|
790
|
+
refresh_document_index: z.looseObject({
|
|
791
|
+
documentId: z.string(),
|
|
792
|
+
generationId: z.string(),
|
|
793
|
+
deduplicated: z.boolean()
|
|
794
|
+
}),
|
|
795
|
+
delete_document: deleteAcknowledgmentSchema,
|
|
796
|
+
delete_folder: deleteAcknowledgmentSchema,
|
|
797
|
+
delete_category: deleteAcknowledgmentSchema,
|
|
798
|
+
restore_document_version: documentSchema
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
// ../mcp-server/src/lifecycle.ts
|
|
582
802
|
function unsupported(name) {
|
|
583
803
|
throw new Error(`The injected legacy MCP client does not support ${name}; use a public DocsClient.`);
|
|
584
804
|
}
|
|
585
805
|
var annotations = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
|
|
586
806
|
function registerLifecycleCapabilities(server, client, wrap) {
|
|
587
807
|
const deletions = [
|
|
588
|
-
{
|
|
589
|
-
|
|
590
|
-
|
|
808
|
+
{
|
|
809
|
+
name: "delete_document",
|
|
810
|
+
description: "Move an existing document to trash; this is a soft delete and does not permanently purge its content or version history. Requires write access in the active workspace/category. Returns {id, deleted:true}. Use only when the user intends to delete it.",
|
|
811
|
+
action: (id) => client.deleteDocument ? client.deleteDocument(id) : unsupported("delete_document"),
|
|
812
|
+
idDescription: "UUID of the document to move to trash; obtain it from search_documents, list_documents, or get_document."
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
name: "delete_folder",
|
|
816
|
+
description: "Delete a folder while preserving its documents. Direct child folders and documents are detached according to the server folder rules, and reindexing is queued for affected documents. Requires write access in the active workspace/category. Returns {id, deleted:true}.",
|
|
817
|
+
action: (id) => client.deleteFolder ? client.deleteFolder(id) : unsupported("delete_folder"),
|
|
818
|
+
idDescription: "UUID of the folder to delete; obtain it from list_folders. This detaches, but does not delete, the documents inside it."
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
name: "delete_category",
|
|
822
|
+
description: "Delete a category and detach its folders and documents without deleting their content. Requires full workspace write access; category-scoped credentials cannot delete any category, including their configured one. Returns {id, deleted:true}.",
|
|
823
|
+
action: (id) => client.deleteCategory ? client.deleteCategory(id) : unsupported("delete_category"),
|
|
824
|
+
idDescription: "UUID of the category to delete; obtain it from list_categories using a workspace-scoped credential."
|
|
825
|
+
}
|
|
591
826
|
];
|
|
592
827
|
for (const tool of deletions) {
|
|
593
|
-
server.registerTool(tool.name, {
|
|
828
|
+
server.registerTool(tool.name, {
|
|
829
|
+
description: tool.description,
|
|
830
|
+
annotations,
|
|
831
|
+
inputSchema: z2.object({ id: z2.string().uuid().describe(tool.idDescription) }),
|
|
832
|
+
outputSchema: toolOutputSchemas[tool.name]
|
|
833
|
+
}, wrap(tool.name, async ({ id }) => {
|
|
594
834
|
await tool.action(id);
|
|
595
835
|
return { id, deleted: true };
|
|
596
836
|
}));
|
|
597
837
|
}
|
|
598
838
|
server.registerTool("restore_document_version", {
|
|
599
|
-
description: "Restore document
|
|
839
|
+
description: "Restore content for an existing document from a version or named snapshot returned by get_version_history. Requires edit access. The server saves current content in history, records the restoration, and queues indexing. Returns the updated document; it does not recover a trashed document or change folder/category placement.",
|
|
600
840
|
annotations,
|
|
601
|
-
inputSchema:
|
|
602
|
-
documentId:
|
|
603
|
-
versionId:
|
|
604
|
-
})
|
|
605
|
-
|
|
841
|
+
inputSchema: z2.object({
|
|
842
|
+
documentId: z2.string().uuid().describe("UUID of the document whose content should be restored; it must be visible in the active workspace or category."),
|
|
843
|
+
versionId: z2.string().uuid().describe("UUID of a version belonging to this document, from get_version_history. Use the version ID, not a snapshot label.")
|
|
844
|
+
}),
|
|
845
|
+
outputSchema: toolOutputSchemas.restore_document_version
|
|
846
|
+
}, wrap("restore_document_version", async ({ documentId, versionId }) => client.restoreDocumentVersion ? client.restoreDocumentVersion(documentId, versionId) : unsupported("restore_document_version")));
|
|
606
847
|
}
|
|
607
848
|
|
|
608
849
|
// ../mcp-server/src/capabilities.ts
|
|
609
|
-
import { z as
|
|
850
|
+
import { z as z3 } from "zod";
|
|
851
|
+
var capabilityCatalog = {
|
|
852
|
+
tools: [
|
|
853
|
+
"search_documents",
|
|
854
|
+
"get_document",
|
|
855
|
+
"create_document",
|
|
856
|
+
"update_document",
|
|
857
|
+
"list_documents",
|
|
858
|
+
"list_folders",
|
|
859
|
+
"create_folder",
|
|
860
|
+
"create_snapshot",
|
|
861
|
+
"get_version_history",
|
|
862
|
+
"export_document",
|
|
863
|
+
"list_categories",
|
|
864
|
+
"create_category",
|
|
865
|
+
"list_tags",
|
|
866
|
+
"get_related_documents",
|
|
867
|
+
"search_knowledge_graph",
|
|
868
|
+
"get_document_index_status",
|
|
869
|
+
"refresh_document_index",
|
|
870
|
+
"delete_document",
|
|
871
|
+
"delete_folder",
|
|
872
|
+
"delete_category",
|
|
873
|
+
"restore_document_version"
|
|
874
|
+
],
|
|
875
|
+
prompts: ["organize_workspace", "research_workspace"],
|
|
876
|
+
resources: [
|
|
877
|
+
"docsmint://guide/editor",
|
|
878
|
+
"docsmint://guide/search",
|
|
879
|
+
"docsmint://workspace/catalog"
|
|
880
|
+
]
|
|
881
|
+
};
|
|
610
882
|
function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
611
883
|
server.registerTool("list_categories", {
|
|
612
|
-
annotations: {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
884
|
+
annotations: {
|
|
885
|
+
readOnlyHint: true,
|
|
886
|
+
destructiveHint: false,
|
|
887
|
+
idempotentHint: true,
|
|
888
|
+
openWorldHint: false
|
|
889
|
+
},
|
|
890
|
+
description: "List categories visible in the active workspace or category scope. Requires read access; a category-scoped credential sees only its configured category. Use this before create_document or create_folder when you need an existing category ID.",
|
|
891
|
+
inputSchema: z3.object({}),
|
|
892
|
+
outputSchema: toolOutputSchemas.list_categories
|
|
893
|
+
}, wrapHandler("list_categories", async () => client.listCategories()));
|
|
616
894
|
server.registerTool("create_category", {
|
|
617
|
-
annotations: {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
|
|
895
|
+
annotations: {
|
|
896
|
+
readOnlyHint: false,
|
|
897
|
+
destructiveHint: false,
|
|
898
|
+
idempotentHint: false,
|
|
899
|
+
openWorldHint: false
|
|
900
|
+
},
|
|
901
|
+
description: "Create a new category for the active workspace. Requires workspace-level write access; category-scoped credentials cannot create categories. Returns the created category. Use list_categories to inspect existing categories.",
|
|
902
|
+
inputSchema: z3.object({
|
|
903
|
+
name: z3.string().trim().min(1).max(255).describe("Non-empty display name, up to 255 characters, for example Project notes.")
|
|
904
|
+
}),
|
|
905
|
+
outputSchema: toolOutputSchemas.create_category
|
|
906
|
+
}, wrapHandler("create_category", async (input) => client.createCategory(input)));
|
|
624
907
|
server.registerTool("list_tags", {
|
|
625
|
-
annotations: {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
908
|
+
annotations: {
|
|
909
|
+
readOnlyHint: true,
|
|
910
|
+
destructiveHint: false,
|
|
911
|
+
idempotentHint: true,
|
|
912
|
+
openWorldHint: false
|
|
913
|
+
},
|
|
914
|
+
description: "List tags visible in the active workspace or configured category scope. Requires read access; use returned tag IDs to filter list_documents and returned tag names to filter search_documents.",
|
|
915
|
+
inputSchema: z3.object({}),
|
|
916
|
+
outputSchema: toolOutputSchemas.list_tags
|
|
917
|
+
}, wrapHandler("list_tags", async () => client.listTags()));
|
|
629
918
|
server.registerTool("get_related_documents", {
|
|
630
|
-
annotations: {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
636
|
-
|
|
919
|
+
annotations: {
|
|
920
|
+
readOnlyHint: true,
|
|
921
|
+
destructiveHint: false,
|
|
922
|
+
idempotentHint: true,
|
|
923
|
+
openWorldHint: false
|
|
924
|
+
},
|
|
925
|
+
description: "Traverse graph relations from one readable document without a text query. Requires read access and returns related document IDs plus relation metadata. Use search_knowledge_graph to rank graph neighbors with query text, or search_documents for normal hybrid retrieval. Results stay in the active scope and may be empty when graph data is unavailable.",
|
|
926
|
+
inputSchema: z3.object({
|
|
927
|
+
documentId: z3.string().min(1).describe("Document ID returned by search_documents or list_documents; it must be readable in the active scope."),
|
|
928
|
+
limit: z3.number().int().min(1).max(100).optional().describe("Maximum related documents to return, from 1 to 100. Omit to use the server default.")
|
|
929
|
+
}),
|
|
930
|
+
outputSchema: toolOutputSchemas.get_related_documents
|
|
931
|
+
}, wrapHandler("get_related_documents", async ({ documentId, limit }) => client.getRelatedDocuments(documentId, limit)));
|
|
637
932
|
server.registerTool("search_knowledge_graph", {
|
|
638
|
-
annotations: {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
933
|
+
annotations: {
|
|
934
|
+
readOnlyHint: true,
|
|
935
|
+
destructiveHint: false,
|
|
936
|
+
idempotentHint: true,
|
|
937
|
+
openWorldHint: false
|
|
938
|
+
},
|
|
939
|
+
description: "Search graph relations from one or more readable seed documents, optionally using query text to filter and rank related documents. Requires read access and returns seed entities plus relatedDocs. Use search_documents first to obtain authorized seed IDs; use get_related_documents for one-seed neighbors without graph search. Results stay in the active scope and graph data may be empty when unavailable.",
|
|
940
|
+
inputSchema: z3.object({
|
|
941
|
+
query: z3.string().max(2000).optional().describe("Optional search text up to 2,000 characters to filter and rank graph-related documents; omit it to inspect relations without query filtering."),
|
|
942
|
+
docIds: z3.array(z3.string().min(1)).min(1).max(50).describe("Between 1 and 50 document IDs returned by search_documents or list_documents; each seed must be readable in the active scope."),
|
|
943
|
+
limit: z3.number().int().min(1).max(100).optional().describe("Maximum related documents to return, from 1 to 100. Omit to use the server default.")
|
|
944
|
+
}),
|
|
945
|
+
outputSchema: toolOutputSchemas.search_knowledge_graph
|
|
946
|
+
}, wrapHandler("search_knowledge_graph", async (input) => client.searchGraph(input)));
|
|
646
947
|
server.registerTool("get_document_index_status", {
|
|
647
|
-
annotations: {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
948
|
+
annotations: {
|
|
949
|
+
readOnlyHint: true,
|
|
950
|
+
destructiveHint: false,
|
|
951
|
+
idempotentHint: true,
|
|
952
|
+
openWorldHint: false
|
|
953
|
+
},
|
|
954
|
+
description: "Read indexing and knowledge-pipeline status for an existing document without starting work. Requires read access. Use after a save or refresh_document_index to check progress or failures.",
|
|
955
|
+
inputSchema: z3.object({
|
|
956
|
+
documentId: z3.string().uuid().describe("UUID of a document returned by search_documents or list_documents; it must be readable in the active scope.")
|
|
957
|
+
}),
|
|
958
|
+
outputSchema: toolOutputSchemas.get_document_index_status
|
|
959
|
+
}, wrapHandler("get_document_index_status", async ({ documentId }) => client.getDocumentIndexStatus(documentId)));
|
|
651
960
|
server.registerTool("refresh_document_index", {
|
|
652
|
-
annotations: {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
961
|
+
annotations: {
|
|
962
|
+
readOnlyHint: false,
|
|
963
|
+
destructiveHint: false,
|
|
964
|
+
idempotentHint: false,
|
|
965
|
+
openWorldHint: false
|
|
966
|
+
},
|
|
967
|
+
description: "Queue an explicit reindex for an existing document; processing is asynchronous and the response acknowledges the generation. Requires write access. Normal content and placement changes schedule indexing when needed, so use get_document_index_status first and refresh only when a retry is intended.",
|
|
968
|
+
inputSchema: z3.object({
|
|
969
|
+
documentId: z3.string().uuid().describe("UUID of the document to refresh, obtained from search_documents or list_documents and visible in the active scope.")
|
|
970
|
+
}),
|
|
971
|
+
outputSchema: toolOutputSchemas.refresh_document_index
|
|
972
|
+
}, wrapHandler("refresh_document_index", async ({ documentId }) => client.refreshDocumentIndex(documentId)));
|
|
656
973
|
server.registerPrompt("organize_workspace", {
|
|
657
974
|
description: "Plan safe document organization using DocsMint categories and folders.",
|
|
658
|
-
argsSchema:
|
|
659
|
-
objective:
|
|
660
|
-
language:
|
|
975
|
+
argsSchema: z3.object({
|
|
976
|
+
objective: z3.string(),
|
|
977
|
+
language: z3.string().optional()
|
|
661
978
|
})
|
|
662
979
|
}, ({ objective, language }) => ({
|
|
663
980
|
messages: [
|
|
@@ -672,9 +989,9 @@ function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
|
672
989
|
}));
|
|
673
990
|
server.registerPrompt("research_workspace", {
|
|
674
991
|
description: "Research a question with hybrid search and GraphRAG while citing DocsMint document IDs.",
|
|
675
|
-
argsSchema:
|
|
676
|
-
question:
|
|
677
|
-
language:
|
|
992
|
+
argsSchema: z3.object({
|
|
993
|
+
question: z3.string(),
|
|
994
|
+
language: z3.string().optional()
|
|
678
995
|
})
|
|
679
996
|
}, ({ question, language }) => ({
|
|
680
997
|
messages: [
|
|
@@ -815,15 +1132,15 @@ __export(exports_create_document, {
|
|
|
815
1132
|
definition: () => definition,
|
|
816
1133
|
handler: () => handler
|
|
817
1134
|
});
|
|
818
|
-
import { z as
|
|
1135
|
+
import { z as z4 } from "zod";
|
|
819
1136
|
var definition = {
|
|
820
1137
|
name: "create_document",
|
|
821
|
-
description: "Create a new document. Optionally
|
|
1138
|
+
description: "Create a new DocsMint document when no existing document should be modified. Optionally set a title, initial Markdown content, and folder or category placement; an omitted title defaults to \u201CUntitled\u201D. Requires write access in the target scope. A category-scoped credential must create inside its configured category, by selecting that category or a folder within it. Normal creation schedules indexing asynchronously and returns the created document. Use update_document for an existing document.",
|
|
822
1139
|
inputSchema: {
|
|
823
|
-
title:
|
|
824
|
-
content:
|
|
825
|
-
folderId:
|
|
826
|
-
categoryId:
|
|
1140
|
+
title: z4.string().min(1).max(500).optional().describe("Optional title from 1 to 500 characters; omit to use the API default \u201CUntitled\u201D."),
|
|
1141
|
+
content: z4.string().optional().describe("Optional initial Markdown content; omit to create an empty document."),
|
|
1142
|
+
folderId: z4.string().uuid().optional().describe("Optional folder UUID from list_folders; the folder must be writable in the active workspace or category."),
|
|
1143
|
+
categoryId: z4.string().uuid().nullable().optional().describe("Optional category UUID from list_categories; omit or pass null to leave the explicit category unset. A categorized folder still supplies the document\u2019s effective category; without one the document remains uncategorized. Category-scoped credentials stay bound to their configured category.")
|
|
827
1144
|
}
|
|
828
1145
|
};
|
|
829
1146
|
var createHandler = (api) => async function createDocument(args) {
|
|
@@ -838,14 +1155,14 @@ __export(exports_create_folder, {
|
|
|
838
1155
|
definition: () => definition2,
|
|
839
1156
|
handler: () => handler2
|
|
840
1157
|
});
|
|
841
|
-
import { z as
|
|
1158
|
+
import { z as z5 } from "zod";
|
|
842
1159
|
var definition2 = {
|
|
843
1160
|
name: "create_folder",
|
|
844
|
-
description: "Create a new folder
|
|
1161
|
+
description: "Create a new folder in the active workspace or category scope. Requires write access and returns the created folder. A nested folder inherits its parent category; for a root folder, pass categoryId when using a category-scoped credential. Category-scoped credentials cannot create outside their configured category.",
|
|
845
1162
|
inputSchema: {
|
|
846
|
-
name:
|
|
847
|
-
parentId:
|
|
848
|
-
categoryId:
|
|
1163
|
+
name: z5.string().min(1).max(255).describe("Non-empty folder name up to 255 characters."),
|
|
1164
|
+
parentId: z5.string().uuid().nullable().optional().describe("Optional parent folder UUID from list_folders; omit or pass null to create a root-level folder."),
|
|
1165
|
+
categoryId: z5.string().uuid().nullable().optional().describe("Optional category UUID from list_categories for a root-level folder. A nested folder inherits its parent category; category-scoped credentials cannot escape their configured category.")
|
|
849
1166
|
}
|
|
850
1167
|
};
|
|
851
1168
|
var createHandler2 = (api) => async function createFolder(args) {
|
|
@@ -860,14 +1177,14 @@ __export(exports_create_snapshot, {
|
|
|
860
1177
|
definition: () => definition3,
|
|
861
1178
|
handler: () => handler3
|
|
862
1179
|
});
|
|
863
|
-
import { z as
|
|
1180
|
+
import { z as z6 } from "zod";
|
|
864
1181
|
var definition3 = {
|
|
865
1182
|
name: "create_snapshot",
|
|
866
|
-
description: "
|
|
1183
|
+
description: "Save a named, retained snapshot of an existing document\u2019s current content before a planned change. Requires edit access and adds an entry to get_version_history without changing the document itself. Use restore_document_version with the returned version ID to restore its content later.",
|
|
867
1184
|
inputSchema: {
|
|
868
|
-
documentId:
|
|
869
|
-
label:
|
|
870
|
-
description:
|
|
1185
|
+
documentId: z6.string().uuid().describe("UUID of the existing document, obtained from search_documents or list_documents and visible in the active scope."),
|
|
1186
|
+
label: z6.string().min(1).max(200).describe("Non-empty snapshot label up to 200 characters, for example 'v1.0-release'."),
|
|
1187
|
+
description: z6.string().max(1000).optional().describe("Optional snapshot note up to 1,000 characters; omit if not needed.")
|
|
871
1188
|
}
|
|
872
1189
|
};
|
|
873
1190
|
var createHandler3 = (api) => async function createSnapshot(args) {
|
|
@@ -883,12 +1200,12 @@ __export(exports_export_document, {
|
|
|
883
1200
|
definition: () => definition4,
|
|
884
1201
|
handler: () => handler4
|
|
885
1202
|
});
|
|
886
|
-
import { z as
|
|
1203
|
+
import { z as z7 } from "zod";
|
|
887
1204
|
var definition4 = {
|
|
888
1205
|
name: "export_document",
|
|
889
1206
|
description: "Render one readable document as portable Markdown and return a markdown string in the response object. Does not modify the document or include its complete metadata; use get_document to inspect the editable document.",
|
|
890
1207
|
inputSchema: {
|
|
891
|
-
id:
|
|
1208
|
+
id: z7.string().uuid().describe("UUID of the readable document to export, obtained from search_documents or list_documents.")
|
|
892
1209
|
}
|
|
893
1210
|
};
|
|
894
1211
|
var createHandler4 = (api) => async function exportDocument(args) {
|
|
@@ -903,12 +1220,12 @@ __export(exports_get_document, {
|
|
|
903
1220
|
definition: () => definition5,
|
|
904
1221
|
handler: () => handler5
|
|
905
1222
|
});
|
|
906
|
-
import { z as
|
|
1223
|
+
import { z as z8 } from "zod";
|
|
907
1224
|
var definition5 = {
|
|
908
1225
|
name: "get_document",
|
|
909
|
-
description: "Read
|
|
1226
|
+
description: "Read an existing document by UUID with its content, metadata, and tags before editing or citing it. Requires read access in the active workspace/category. Use export_document when you only need the portable Markdown body.",
|
|
910
1227
|
inputSchema: {
|
|
911
|
-
id:
|
|
1228
|
+
id: z8.string().uuid().describe("UUID of the document, obtained from search_documents or list_documents, and visible in the active scope.")
|
|
912
1229
|
}
|
|
913
1230
|
};
|
|
914
1231
|
var createHandler5 = (api) => async function getDocument(args) {
|
|
@@ -923,15 +1240,15 @@ __export(exports_list_documents, {
|
|
|
923
1240
|
definition: () => definition6,
|
|
924
1241
|
handler: () => handler6
|
|
925
1242
|
});
|
|
926
|
-
import { z as
|
|
1243
|
+
import { z as z9 } from "zod";
|
|
927
1244
|
var definition6 = {
|
|
928
1245
|
name: "list_documents",
|
|
929
|
-
description: "List documents with
|
|
1246
|
+
description: "List readable documents in the active workspace or category with page-based results. Optionally filter by folder or tag; page defaults to 1 and limit to 20 (maximum 1,000). Use search_documents for text or semantic retrieval.",
|
|
930
1247
|
inputSchema: {
|
|
931
|
-
folderId:
|
|
932
|
-
tag:
|
|
933
|
-
page:
|
|
934
|
-
limit:
|
|
1248
|
+
folderId: z9.string().uuid().optional().describe("Optional folder UUID from list_folders to limit the listing."),
|
|
1249
|
+
tag: z9.string().uuid().optional().describe("Optional tag UUID from list_tags to filter the documents."),
|
|
1250
|
+
page: z9.number().int().min(1).optional().describe("1-indexed result page; defaults to 1."),
|
|
1251
|
+
limit: z9.number().int().min(1).max(1000).optional().describe("Number of documents per page, from 1 to 1,000; defaults to 20.")
|
|
935
1252
|
}
|
|
936
1253
|
};
|
|
937
1254
|
var createHandler6 = (api) => async function listDocuments(args) {
|
|
@@ -946,12 +1263,12 @@ __export(exports_list_folders, {
|
|
|
946
1263
|
definition: () => definition7,
|
|
947
1264
|
handler: () => handler7
|
|
948
1265
|
});
|
|
949
|
-
import { z as
|
|
1266
|
+
import { z as z10 } from "zod";
|
|
950
1267
|
var definition7 = {
|
|
951
1268
|
name: "list_folders",
|
|
952
|
-
description: "List folders
|
|
1269
|
+
description: "List folders readable in the active workspace/category. Omit parentId to list root folders, or supply a parent UUID to list its immediate children as a flat list. Use create_folder to add a folder.",
|
|
953
1270
|
inputSchema: {
|
|
954
|
-
parentId:
|
|
1271
|
+
parentId: z10.string().uuid().optional().describe("Optional parent folder UUID from list_folders; omit to list root folders.")
|
|
955
1272
|
}
|
|
956
1273
|
};
|
|
957
1274
|
var createHandler7 = (api) => async function listFolders(args) {
|
|
@@ -966,15 +1283,15 @@ __export(exports_search, {
|
|
|
966
1283
|
definition: () => definition8,
|
|
967
1284
|
handler: () => handler8
|
|
968
1285
|
});
|
|
969
|
-
import { z as
|
|
1286
|
+
import { z as z11 } from "zod";
|
|
970
1287
|
var definition8 = {
|
|
971
1288
|
name: "search_documents",
|
|
972
|
-
description: "
|
|
1289
|
+
description: "Search readable DocsMint documents with hybrid full-text and semantic retrieval, optionally filtered by folder and tag names. Requires read access and stays within the active workspace/category. Use search_knowledge_graph for graph relations from seed documents or get_related_documents for neighbors without a text query.",
|
|
973
1290
|
inputSchema: {
|
|
974
|
-
query:
|
|
975
|
-
folder:
|
|
976
|
-
tags:
|
|
977
|
-
limit:
|
|
1291
|
+
query: z11.string().describe("Text to search for; preserve the language and terms relevant to the user request."),
|
|
1292
|
+
folder: z11.string().optional().describe("Optional folder UUID from list_folders to scope retrieval."),
|
|
1293
|
+
tags: z11.array(z11.string()).optional().describe("Optional tag names as shown by list_tags; documents match when they have any supplied tag name."),
|
|
1294
|
+
limit: z11.number().int().positive().max(100).optional().describe("Maximum result count, from 1 to 100; defaults to 20.")
|
|
978
1295
|
}
|
|
979
1296
|
};
|
|
980
1297
|
var createHandler8 = (api) => async function searchDocuments(args) {
|
|
@@ -994,16 +1311,16 @@ __export(exports_update_document, {
|
|
|
994
1311
|
definition: () => definition9,
|
|
995
1312
|
handler: () => handler9
|
|
996
1313
|
});
|
|
997
|
-
import { z as
|
|
1314
|
+
import { z as z12 } from "zod";
|
|
998
1315
|
var definition9 = {
|
|
999
1316
|
name: "update_document",
|
|
1000
|
-
description: "
|
|
1317
|
+
description: "Modify an existing document by UUID after reading its current state. Omitted fields remain unchanged; null folderId removes folder placement and null categoryId clears the explicit category, while a categorized folder can still supply the effective category. Changing title or Markdown content requires edit access, while moving placement requires write access in the active workspace/category. The server stores the prior content in version history and queues indexing when content or placement changes. Returns the updated document. Use create_document for new content.",
|
|
1001
1318
|
inputSchema: {
|
|
1002
|
-
id:
|
|
1003
|
-
title:
|
|
1004
|
-
content:
|
|
1005
|
-
folderId:
|
|
1006
|
-
categoryId:
|
|
1319
|
+
id: z12.string().uuid().describe("UUID of the existing document, obtained from search_documents, list_documents, or get_document."),
|
|
1320
|
+
title: z12.string().min(1).max(500).optional().describe("Optional replacement title, 1 to 500 characters; omit to leave the current title unchanged."),
|
|
1321
|
+
content: z12.string().optional().describe("New markdown content for the document."),
|
|
1322
|
+
folderId: z12.string().uuid().nullable().optional().describe("Optional destination folder UUID from list_folders; omit to keep current placement or pass null to remove folder placement."),
|
|
1323
|
+
categoryId: z12.string().uuid().nullable().optional().describe("Optional destination category UUID from list_categories; omit to keep the explicit category or pass null to clear it. A categorized folder may still supply the effective category. Category-scoped credentials cannot move outside their configured category.")
|
|
1007
1324
|
}
|
|
1008
1325
|
};
|
|
1009
1326
|
var createHandler9 = (api) => async function updateDocument(args) {
|
|
@@ -1019,13 +1336,13 @@ __export(exports_version_history, {
|
|
|
1019
1336
|
definition: () => definition10,
|
|
1020
1337
|
handler: () => handler10
|
|
1021
1338
|
});
|
|
1022
|
-
import { z as
|
|
1339
|
+
import { z as z13 } from "zod";
|
|
1023
1340
|
var definition10 = {
|
|
1024
1341
|
name: "get_version_history",
|
|
1025
|
-
description: "
|
|
1342
|
+
description: "Read versions for an existing document, including saved snapshots. Requires read access and returns version IDs with content and timestamps; pass a version ID to restore_document_version when the user asks to restore content. This is read-only and does not change the document.",
|
|
1026
1343
|
inputSchema: {
|
|
1027
|
-
documentId:
|
|
1028
|
-
onlySnapshots:
|
|
1344
|
+
documentId: z13.string().uuid().describe("UUID of the readable document whose version history you need; obtain it from search_documents or list_documents."),
|
|
1345
|
+
onlySnapshots: z13.boolean().optional().describe("When true, return only named snapshots and omit auto-saved revisions; omit or use false for the full history.")
|
|
1029
1346
|
}
|
|
1030
1347
|
};
|
|
1031
1348
|
var createHandler10 = (api) => async function getVersionHistory(args) {
|
|
@@ -1034,11 +1351,17 @@ var createHandler10 = (api) => async function getVersionHistory(args) {
|
|
|
1034
1351
|
var handler10 = createHandler10(client);
|
|
1035
1352
|
|
|
1036
1353
|
// ../mcp-server/src/server.ts
|
|
1037
|
-
function wrapHandler(name, handler11) {
|
|
1354
|
+
function wrapHandler(name, handler11, outputSchema) {
|
|
1038
1355
|
return async (args) => {
|
|
1039
1356
|
try {
|
|
1357
|
+
const output = await handler11(args);
|
|
1358
|
+
const parsedOutput = outputSchema ? await outputSchema.safeParseAsync(output) : undefined;
|
|
1359
|
+
if (parsedOutput && !parsedOutput.success) {
|
|
1360
|
+
throw new Error(`Tool '${name}' returned a result outside its published output schema`);
|
|
1361
|
+
}
|
|
1040
1362
|
return {
|
|
1041
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
1363
|
+
content: [{ type: "text", text: JSON.stringify(output, null, 2) }],
|
|
1364
|
+
...parsedOutput?.success ? { structuredContent: parsedOutput.data } : {}
|
|
1042
1365
|
};
|
|
1043
1366
|
} catch (error) {
|
|
1044
1367
|
if (isDocsApiError(error) || error instanceof HiaiDocsError) {
|
|
@@ -1067,12 +1390,27 @@ function wrapHandler(name, handler11) {
|
|
|
1067
1390
|
}
|
|
1068
1391
|
function registerDocsmintMcpCapabilities(server, client2) {
|
|
1069
1392
|
const register = (name, description, inputSchema, handler11) => {
|
|
1070
|
-
server.registerTool(name, {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1393
|
+
server.registerTool(name, {
|
|
1394
|
+
description,
|
|
1395
|
+
inputSchema: z14.object(inputSchema),
|
|
1396
|
+
annotations: {
|
|
1397
|
+
readOnlyHint: ![
|
|
1398
|
+
"create_document",
|
|
1399
|
+
"update_document",
|
|
1400
|
+
"create_folder",
|
|
1401
|
+
"create_snapshot"
|
|
1402
|
+
].includes(name),
|
|
1403
|
+
destructiveHint: name === "update_document",
|
|
1404
|
+
idempotentHint: ![
|
|
1405
|
+
"create_document",
|
|
1406
|
+
"update_document",
|
|
1407
|
+
"create_folder",
|
|
1408
|
+
"create_snapshot"
|
|
1409
|
+
].includes(name),
|
|
1410
|
+
openWorldHint: false
|
|
1411
|
+
},
|
|
1412
|
+
outputSchema: toolOutputSchemas[name]
|
|
1413
|
+
}, wrapHandler(name, handler11, toolOutputSchemas[name]));
|
|
1076
1414
|
};
|
|
1077
1415
|
const tools = [
|
|
1078
1416
|
exports_search,
|
|
@@ -1089,16 +1427,17 @@ function registerDocsmintMcpCapabilities(server, client2) {
|
|
|
1089
1427
|
for (const tool of tools) {
|
|
1090
1428
|
register(tool.definition.name, tool.definition.description, tool.definition.inputSchema, tool.createHandler(client2));
|
|
1091
1429
|
}
|
|
1092
|
-
registerExtendedCapabilities(server, client2, (handler11) => wrapHandler(
|
|
1093
|
-
registerLifecycleCapabilities(server, client2, (handler11) => wrapHandler(
|
|
1430
|
+
registerExtendedCapabilities(server, client2, (name, handler11) => wrapHandler(name, handler11, toolOutputSchemas[name]));
|
|
1431
|
+
registerLifecycleCapabilities(server, client2, (name, handler11) => wrapHandler(name, handler11, toolOutputSchemas[name]));
|
|
1094
1432
|
}
|
|
1095
1433
|
function createDocsmintMcpServer(options = {}) {
|
|
1096
|
-
const server = new McpServer({ name: "docsmint", version: "0.
|
|
1434
|
+
const server = new McpServer({ name: "docsmint", version: "0.9.0" });
|
|
1097
1435
|
const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
|
|
1098
1436
|
registerDocsmintMcpCapabilities(server, client2);
|
|
1099
1437
|
return server;
|
|
1100
1438
|
}
|
|
1101
1439
|
export {
|
|
1440
|
+
capabilityCatalog,
|
|
1102
1441
|
createDocsmintMcpServer,
|
|
1103
1442
|
registerDocsmintMcpCapabilities
|
|
1104
1443
|
};
|