@hiai-gg/docsmint 0.8.5 → 0.8.7
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 +27 -17
- package/dist/backend/index.js +119 -95
- package/dist/mcp-cli.js +113 -68
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.js +113 -68
- package/package.json +1 -1
- package/packages/cli/src/index.ts +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -10,15 +10,22 @@ agents access to the same documents through MCP, REST, the SDK, or CLI.
|
|
|
10
10
|
operating the stack, or **[self-host with Docker](#quickstart)** to run the
|
|
11
11
|
Apache-2.0 application on your own infrastructure.
|
|
12
12
|
|
|
13
|
-
[](
|
|
13
|
+
[](LICENSE)
|
|
14
14
|
[](https://github.com/hiai-gg/docsmint/releases)
|
|
15
15
|
[](https://www.npmjs.com/package/@hiai-gg/docsmint)
|
|
16
|
+
[](https://hub.docker.com/r/vgalibov/docsmint)
|
|
17
|
+
[](https://github.com/hiai-gg/docsmint/stargazers)
|
|
16
18
|
[](https://github.com/hiai-gg/docsmint/actions/workflows/ci.yml)
|
|
17
|
-
|
|
18
|
-
[
|
|
19
|
-
[
|
|
20
|
-
[
|
|
21
|
-
[
|
|
19
|
+
[](https://bun.sh)
|
|
20
|
+
[](https://www.typescriptlang.org)
|
|
21
|
+
[](https://svelte.dev)
|
|
22
|
+
[](https://elysiajs.com)
|
|
23
|
+
[](https://tailwindcss.com)
|
|
24
|
+
[](https://orm.drizzle.team)
|
|
25
|
+
[](CONTRIBUTING.md)
|
|
26
|
+
[](https://lobehub.com/mcp/hiai-gg-docsmint)
|
|
27
|
+
[](https://docsmint.com/mcp/connect?source=github_mcp)
|
|
28
|
+
[](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.HiAi-gg%2Fdocsmint/versions/latest)
|
|
22
29
|
|
|
23
30
|
<img width="1920" height="974" alt="DocsMint installable document workspace" src="https://github.com/user-attachments/assets/94701d01-a361-4ca1-b16d-de2a0c64d684" />
|
|
24
31
|
|
|
@@ -63,18 +70,21 @@ bridge to your running deployment, not a server installer. See the
|
|
|
63
70
|
- **Choose how you run it.** Use [managed DocsMint](https://docsmint.com) or
|
|
64
71
|
self-host the application, database, search, queues, and files.
|
|
65
72
|
|
|
66
|
-
## What's new in 0.8.
|
|
73
|
+
## What's new in 0.8.7?
|
|
74
|
+
|
|
75
|
+
Agents can now complete more document workflows without leaving MCP:
|
|
67
76
|
|
|
68
|
-
|
|
77
|
+
- Move documents to trash, remove folders or categories, and restore saved versions.
|
|
78
|
+
- Keep changes within workspace/category permissions; version restoration requires edit access.
|
|
79
|
+
- Discover clearer tool descriptions, parameter guidance, and destructive-operation annotations.
|
|
80
|
+
- Apply GraphRAG query text and related-document result limits consistently.
|
|
69
81
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- Consistent release notes and package documentation, with links that also work on npm.
|
|
82
|
+
The MCP surface grows additively from 17 to 21 tools. Existing tool names remain
|
|
83
|
+
available. No database migration is required. Hosted clients receive these tools
|
|
84
|
+
when their DocsMint host adopts this release.
|
|
74
85
|
|
|
75
|
-
|
|
76
|
-
[
|
|
77
|
-
[changelog](https://github.com/HiAi-gg/docsmint/blob/main/CHANGELOG.md), or [roadmap](https://github.com/HiAi-gg/docsmint/blob/main/docs/ROADMAP.md).
|
|
86
|
+
Read the [release notes](https://github.com/HiAi-gg/docsmint/releases/tag/v0.8.7)
|
|
87
|
+
and [changelog](https://github.com/HiAi-gg/docsmint/blob/main/CHANGELOG.md).
|
|
78
88
|
|
|
79
89
|
## Install with an AI agent
|
|
80
90
|
|
|
@@ -126,7 +136,7 @@ docker pull vgalibov/docsmint:web-latest
|
|
|
126
136
|
docker pull vgalibov/docsmint:caddy-latest
|
|
127
137
|
```
|
|
128
138
|
|
|
129
|
-
Use versioned tags `api-v0.8.
|
|
139
|
+
Use versioned tags `api-v0.8.7`, `web-v0.8.7`, and `caddy-v0.8.7` for
|
|
130
140
|
reproducible deploys. Caddy is the supporting reverse proxy with rate limiting;
|
|
131
141
|
it is separate from the API and web application. The quickstart still builds the Compose stack from this repository so PostgreSQL,
|
|
132
142
|
Redis, and SeaweedFS start together with the application.
|
|
@@ -211,7 +221,7 @@ command and configuration precedence.
|
|
|
211
221
|
## Connect an MCP client
|
|
212
222
|
|
|
213
223
|
Give agents a secure path to search, read, and maintain your knowledge without
|
|
214
|
-
database or filesystem access. DocsMint publishes
|
|
224
|
+
database or filesystem access. DocsMint publishes 21 tools plus ready-made
|
|
215
225
|
research prompts, scoped resources, and a document-manager skill.
|
|
216
226
|
|
|
217
227
|
### Hosted DocsMint
|
package/dist/backend/index.js
CHANGED
|
@@ -231613,6 +231613,106 @@ function stripQuotes(value) {
|
|
|
231613
231613
|
return trimmed;
|
|
231614
231614
|
}
|
|
231615
231615
|
|
|
231616
|
+
// ../../backend/src/lib/graph/search-query.ts
|
|
231617
|
+
init_drizzle_orm();
|
|
231618
|
+
|
|
231619
|
+
// ../../backend/src/search/query-analyzer.ts
|
|
231620
|
+
var CYRILLIC_LETTER = /\p{Script=Cyrillic}/u;
|
|
231621
|
+
var LATIN_LETTER = /\p{Script=Latin}/u;
|
|
231622
|
+
var LETTER2 = /\p{L}/u;
|
|
231623
|
+
function normalizeQuery(query) {
|
|
231624
|
+
const normalized = query.normalize("NFC");
|
|
231625
|
+
let result = "";
|
|
231626
|
+
let inQuotedPhrase = false;
|
|
231627
|
+
let escaped = false;
|
|
231628
|
+
let pendingWhitespace = false;
|
|
231629
|
+
for (const character of normalized) {
|
|
231630
|
+
if (inQuotedPhrase) {
|
|
231631
|
+
result += character;
|
|
231632
|
+
if (escaped) {
|
|
231633
|
+
escaped = false;
|
|
231634
|
+
} else if (character === "\\") {
|
|
231635
|
+
escaped = true;
|
|
231636
|
+
} else if (character === '"') {
|
|
231637
|
+
inQuotedPhrase = false;
|
|
231638
|
+
}
|
|
231639
|
+
continue;
|
|
231640
|
+
}
|
|
231641
|
+
if (character === '"') {
|
|
231642
|
+
if (pendingWhitespace && result.length > 0)
|
|
231643
|
+
result += " ";
|
|
231644
|
+
pendingWhitespace = false;
|
|
231645
|
+
result += character;
|
|
231646
|
+
inQuotedPhrase = true;
|
|
231647
|
+
continue;
|
|
231648
|
+
}
|
|
231649
|
+
if (/\s/u.test(character)) {
|
|
231650
|
+
pendingWhitespace = true;
|
|
231651
|
+
continue;
|
|
231652
|
+
}
|
|
231653
|
+
if (pendingWhitespace && result.length > 0)
|
|
231654
|
+
result += " ";
|
|
231655
|
+
pendingWhitespace = false;
|
|
231656
|
+
result += character;
|
|
231657
|
+
}
|
|
231658
|
+
return result;
|
|
231659
|
+
}
|
|
231660
|
+
function detectLanguage(query) {
|
|
231661
|
+
const normalized = normalizeQuery(query);
|
|
231662
|
+
let cyrillic = 0;
|
|
231663
|
+
let latin = 0;
|
|
231664
|
+
for (const token of normalized.split(" ")) {
|
|
231665
|
+
if (token.includes("/"))
|
|
231666
|
+
continue;
|
|
231667
|
+
for (const character of token) {
|
|
231668
|
+
if (!LETTER2.test(character))
|
|
231669
|
+
continue;
|
|
231670
|
+
if (CYRILLIC_LETTER.test(character))
|
|
231671
|
+
cyrillic += 1;
|
|
231672
|
+
else if (LATIN_LETTER.test(character))
|
|
231673
|
+
latin += 1;
|
|
231674
|
+
}
|
|
231675
|
+
}
|
|
231676
|
+
if (cyrillic > 0 && latin > 0)
|
|
231677
|
+
return "mixed";
|
|
231678
|
+
if (cyrillic > 0)
|
|
231679
|
+
return "ru";
|
|
231680
|
+
if (latin > 0)
|
|
231681
|
+
return "en";
|
|
231682
|
+
return "und";
|
|
231683
|
+
}
|
|
231684
|
+
function analyzeQuery(query) {
|
|
231685
|
+
return {
|
|
231686
|
+
original: query,
|
|
231687
|
+
normalized: normalizeQuery(query),
|
|
231688
|
+
detectedLanguage: detectLanguage(query),
|
|
231689
|
+
translations: [],
|
|
231690
|
+
synonyms: [],
|
|
231691
|
+
concepts: [],
|
|
231692
|
+
namedEntities: []
|
|
231693
|
+
};
|
|
231694
|
+
}
|
|
231695
|
+
|
|
231696
|
+
// ../../backend/src/lib/graph/search-query.ts
|
|
231697
|
+
function graphSearchDocumentQuery(ctx, documentIds, query) {
|
|
231698
|
+
const normalized = normalizeQuery(query ?? "");
|
|
231699
|
+
const english = sql`websearch_to_tsquery('english', ${normalized})`;
|
|
231700
|
+
const simple = sql`websearch_to_tsquery('simple', ${normalized})`;
|
|
231701
|
+
const exact = sql`lower(trim(d.title)) = lower(${normalized})`;
|
|
231702
|
+
const match2 = normalized ? sql`AND (${exact} OR d.search_vector @@ ${english} OR d.search_vector_simple @@ ${simple})` : sql``;
|
|
231703
|
+
const order = normalized ? sql`${exact} DESC, GREATEST(ts_rank(d.search_vector, ${english}), ts_rank(d.search_vector_simple, ${simple})) DESC,` : sql``;
|
|
231704
|
+
const allowed2 = documentIds.length ? sql`d.id IN (${sql.join(documentIds.map((id3) => sql`${id3}`), sql`, `)})` : sql`false`;
|
|
231705
|
+
return sql`
|
|
231706
|
+
SELECT d.id, d.title, d.content
|
|
231707
|
+
FROM documents d
|
|
231708
|
+
WHERE ${tenantOwnerSql("d", ctx)}
|
|
231709
|
+
AND d.deleted_at IS NULL
|
|
231710
|
+
AND ${allowed2}
|
|
231711
|
+
${match2}
|
|
231712
|
+
ORDER BY ${order} d.id ASC
|
|
231713
|
+
`;
|
|
231714
|
+
}
|
|
231715
|
+
|
|
231616
231716
|
// ../../backend/src/api/routes/graph.ts
|
|
231617
231717
|
init_logger3();
|
|
231618
231718
|
var entitiesQuerySchema = exports_external2.object({
|
|
@@ -231621,8 +231721,11 @@ var entitiesQuerySchema = exports_external2.object({
|
|
|
231621
231721
|
var relatedParamsSchema = exports_external2.object({
|
|
231622
231722
|
docId: exports_external2.string().min(1)
|
|
231623
231723
|
});
|
|
231724
|
+
var relatedQuerySchema = exports_external2.object({
|
|
231725
|
+
limit: exports_external2.coerce.number().int().min(1).max(100).default(20)
|
|
231726
|
+
});
|
|
231624
231727
|
var graphSearchBodySchema = exports_external2.object({
|
|
231625
|
-
query: exports_external2.string().optional(),
|
|
231728
|
+
query: exports_external2.string().max(2000).optional(),
|
|
231626
231729
|
docIds: exports_external2.array(exports_external2.string().min(1)).min(1).max(50),
|
|
231627
231730
|
maxResults: exports_external2.number().int().min(1).max(100).optional()
|
|
231628
231731
|
});
|
|
@@ -231668,7 +231771,7 @@ var graphRoutes = new Elysia({ prefix: "/api/graph" }).get("/entities", async ({
|
|
|
231668
231771
|
tags: ["Graph"],
|
|
231669
231772
|
summary: "List entities linked to a document"
|
|
231670
231773
|
}
|
|
231671
|
-
}).get("/related/:docId", async ({ params: params2, set: set2, request }) => {
|
|
231774
|
+
}).get("/related/:docId", async ({ params: params2, query, set: set2, request }) => {
|
|
231672
231775
|
const rl = await applyRateLimit(request, set2);
|
|
231673
231776
|
if (!rl.ok)
|
|
231674
231777
|
return rl.response;
|
|
@@ -231687,6 +231790,11 @@ var graphRoutes = new Elysia({ prefix: "/api/graph" }).get("/entities", async ({
|
|
|
231687
231790
|
set2.status = 400;
|
|
231688
231791
|
return { error: "Invalid params", details: parsed.error.flatten() };
|
|
231689
231792
|
}
|
|
231793
|
+
const parsedQuery = relatedQuerySchema.safeParse(query);
|
|
231794
|
+
if (!parsedQuery.success) {
|
|
231795
|
+
set2.status = 400;
|
|
231796
|
+
return { error: "Invalid query", details: parsedQuery.error.flatten() };
|
|
231797
|
+
}
|
|
231690
231798
|
try {
|
|
231691
231799
|
const seedIds = await allowedGraphDocumentIds(access, [
|
|
231692
231800
|
parsed.data.docId
|
|
@@ -231698,7 +231806,7 @@ var graphRoutes = new Elysia({ prefix: "/api/graph" }).get("/entities", async ({
|
|
|
231698
231806
|
if (!config3.GRAPH_SEARCH_ENABLED)
|
|
231699
231807
|
return { related: [] };
|
|
231700
231808
|
const related = await fetchRelatedDocuments(ctx, parsed.data.docId, access);
|
|
231701
|
-
return { related };
|
|
231809
|
+
return { related: related.slice(0, parsedQuery.data.limit) };
|
|
231702
231810
|
} catch (err) {
|
|
231703
231811
|
logger3.warn({ err, docId: parsed.data.docId }, "Graph related lookup failed \u2014 returning empty");
|
|
231704
231812
|
return { related: [] };
|
|
@@ -231737,7 +231845,7 @@ var graphRoutes = new Elysia({ prefix: "/api/graph" }).get("/entities", async ({
|
|
|
231737
231845
|
if (!config3.GRAPH_SEARCH_ENABLED) {
|
|
231738
231846
|
return { query, entities: [], relatedDocs: [] };
|
|
231739
231847
|
}
|
|
231740
|
-
const result = await graphRagLookup(ctx, docIds, maxResults, access);
|
|
231848
|
+
const result = await graphRagLookup(ctx, docIds, maxResults, access, query);
|
|
231741
231849
|
return { query, ...result };
|
|
231742
231850
|
} catch (err) {
|
|
231743
231851
|
logger3.warn({ err, docIds: docIds.length }, "Graph RAG search failed \u2014 returning empty");
|
|
@@ -231805,7 +231913,7 @@ async function fetchRelatedDocuments(ctx, docId, access) {
|
|
|
231805
231913
|
const allowedIds = access ? await allowedGraphDocumentIds(access, neighborIds) : await filterToOwnedDocuments(ctx, neighborIds);
|
|
231806
231914
|
return current.filter((neighbor) => allowedIds.has(neighbor.docId));
|
|
231807
231915
|
}
|
|
231808
|
-
async function graphRagLookup(ctx, docIds, maxResults, access) {
|
|
231916
|
+
async function graphRagLookup(ctx, docIds, maxResults, access, query) {
|
|
231809
231917
|
const sql6 = await getGraphDb();
|
|
231810
231918
|
if (!sql6)
|
|
231811
231919
|
return { entities: [], relatedDocs: [] };
|
|
@@ -231838,12 +231946,13 @@ async function graphRagLookup(ctx, docIds, maxResults, access) {
|
|
|
231838
231946
|
if (ownedNeighborIds.length === 0) {
|
|
231839
231947
|
return { entities: Array.from(entityMap.values()), relatedDocs: [] };
|
|
231840
231948
|
}
|
|
231841
|
-
const rows = await loadDocumentSummaries(ctx, ownedNeighborIds);
|
|
231949
|
+
const rows = await loadDocumentSummaries(ctx, ownedNeighborIds, query);
|
|
231842
231950
|
const byId = new Map;
|
|
231843
231951
|
for (const r4 of rows)
|
|
231844
231952
|
byId.set(r4.id, r4);
|
|
231845
231953
|
const relatedDocs = [];
|
|
231846
|
-
|
|
231954
|
+
const rankedIds = query?.trim() ? rows.map((row) => row.id) : ownedNeighborIds;
|
|
231955
|
+
for (const id3 of rankedIds) {
|
|
231847
231956
|
const meta3 = neighborMap.get(id3);
|
|
231848
231957
|
const row = byId.get(id3);
|
|
231849
231958
|
if (!meta3 || !row)
|
|
@@ -231919,19 +232028,11 @@ function currentGraphNeighbors(expansion, activeGenerations) {
|
|
|
231919
232028
|
}
|
|
231920
232029
|
return [...current.values()].sort((left, right) => left.hopDistance - right.hopDistance || left.docId.localeCompare(right.docId));
|
|
231921
232030
|
}
|
|
231922
|
-
async function loadDocumentSummaries(ctx, docIds) {
|
|
232031
|
+
async function loadDocumentSummaries(ctx, docIds, query) {
|
|
231923
232032
|
if (docIds.length === 0)
|
|
231924
232033
|
return [];
|
|
231925
232034
|
return withTenant(ctx, async (tx) => {
|
|
231926
|
-
return tx.
|
|
231927
|
-
id: documents.id,
|
|
231928
|
-
title: documents.title,
|
|
231929
|
-
content: documents.content,
|
|
231930
|
-
folderId: documents.folderId,
|
|
231931
|
-
folderName: folders.name,
|
|
231932
|
-
createdAt: documents.createdAt,
|
|
231933
|
-
updatedAt: documents.updatedAt
|
|
231934
|
-
}).from(documents).leftJoin(folders, eq(folders.id, documents.folderId)).where(and(tenantOwnerCondition(documents.ownerId, documents.workspaceId, ctx), inArray(documents.id, docIds), isNull(documents.deletedAt)));
|
|
232035
|
+
return await tx.execute(graphSearchDocumentQuery(ctx, docIds, query));
|
|
231935
232036
|
});
|
|
231936
232037
|
}
|
|
231937
232038
|
function cypherDocReplace(cypher, docId) {
|
|
@@ -232493,83 +232594,6 @@ function evaluateConfidence(results, _plan, thresholds = { vectorMinSimilarity:
|
|
|
232493
232594
|
return { confident: reasons.length === 0, reasons };
|
|
232494
232595
|
}
|
|
232495
232596
|
|
|
232496
|
-
// ../../backend/src/search/query-analyzer.ts
|
|
232497
|
-
var CYRILLIC_LETTER = /\p{Script=Cyrillic}/u;
|
|
232498
|
-
var LATIN_LETTER = /\p{Script=Latin}/u;
|
|
232499
|
-
var LETTER2 = /\p{L}/u;
|
|
232500
|
-
function normalizeQuery(query) {
|
|
232501
|
-
const normalized = query.normalize("NFC");
|
|
232502
|
-
let result = "";
|
|
232503
|
-
let inQuotedPhrase = false;
|
|
232504
|
-
let escaped = false;
|
|
232505
|
-
let pendingWhitespace = false;
|
|
232506
|
-
for (const character of normalized) {
|
|
232507
|
-
if (inQuotedPhrase) {
|
|
232508
|
-
result += character;
|
|
232509
|
-
if (escaped) {
|
|
232510
|
-
escaped = false;
|
|
232511
|
-
} else if (character === "\\") {
|
|
232512
|
-
escaped = true;
|
|
232513
|
-
} else if (character === '"') {
|
|
232514
|
-
inQuotedPhrase = false;
|
|
232515
|
-
}
|
|
232516
|
-
continue;
|
|
232517
|
-
}
|
|
232518
|
-
if (character === '"') {
|
|
232519
|
-
if (pendingWhitespace && result.length > 0)
|
|
232520
|
-
result += " ";
|
|
232521
|
-
pendingWhitespace = false;
|
|
232522
|
-
result += character;
|
|
232523
|
-
inQuotedPhrase = true;
|
|
232524
|
-
continue;
|
|
232525
|
-
}
|
|
232526
|
-
if (/\s/u.test(character)) {
|
|
232527
|
-
pendingWhitespace = true;
|
|
232528
|
-
continue;
|
|
232529
|
-
}
|
|
232530
|
-
if (pendingWhitespace && result.length > 0)
|
|
232531
|
-
result += " ";
|
|
232532
|
-
pendingWhitespace = false;
|
|
232533
|
-
result += character;
|
|
232534
|
-
}
|
|
232535
|
-
return result;
|
|
232536
|
-
}
|
|
232537
|
-
function detectLanguage(query) {
|
|
232538
|
-
const normalized = normalizeQuery(query);
|
|
232539
|
-
let cyrillic = 0;
|
|
232540
|
-
let latin = 0;
|
|
232541
|
-
for (const token of normalized.split(" ")) {
|
|
232542
|
-
if (token.includes("/"))
|
|
232543
|
-
continue;
|
|
232544
|
-
for (const character of token) {
|
|
232545
|
-
if (!LETTER2.test(character))
|
|
232546
|
-
continue;
|
|
232547
|
-
if (CYRILLIC_LETTER.test(character))
|
|
232548
|
-
cyrillic += 1;
|
|
232549
|
-
else if (LATIN_LETTER.test(character))
|
|
232550
|
-
latin += 1;
|
|
232551
|
-
}
|
|
232552
|
-
}
|
|
232553
|
-
if (cyrillic > 0 && latin > 0)
|
|
232554
|
-
return "mixed";
|
|
232555
|
-
if (cyrillic > 0)
|
|
232556
|
-
return "ru";
|
|
232557
|
-
if (latin > 0)
|
|
232558
|
-
return "en";
|
|
232559
|
-
return "und";
|
|
232560
|
-
}
|
|
232561
|
-
function analyzeQuery(query) {
|
|
232562
|
-
return {
|
|
232563
|
-
original: query,
|
|
232564
|
-
normalized: normalizeQuery(query),
|
|
232565
|
-
detectedLanguage: detectLanguage(query),
|
|
232566
|
-
translations: [],
|
|
232567
|
-
synonyms: [],
|
|
232568
|
-
concepts: [],
|
|
232569
|
-
namedEntities: []
|
|
232570
|
-
};
|
|
232571
|
-
}
|
|
232572
|
-
|
|
232573
232597
|
// ../../backend/src/search/query-expander.ts
|
|
232574
232598
|
init_zod();
|
|
232575
232599
|
init_config();
|
|
@@ -238398,7 +238422,7 @@ var swaggerConfig = {
|
|
|
238398
238422
|
},
|
|
238399
238423
|
info: {
|
|
238400
238424
|
title: "DocsMint API",
|
|
238401
|
-
version: "0.8.
|
|
238425
|
+
version: "0.8.7",
|
|
238402
238426
|
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.",
|
|
238403
238427
|
contact: { name: "HiAi-gg", url: "https://github.com/HiAi-gg/docsmint" },
|
|
238404
238428
|
license: {
|
package/dist/mcp-cli.js
CHANGED
|
@@ -20,7 +20,7 @@ import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
|
20
20
|
|
|
21
21
|
// ../mcp-server/src/server.ts
|
|
22
22
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
23
|
-
import { z as
|
|
23
|
+
import { z as z13 } from "zod";
|
|
24
24
|
|
|
25
25
|
// dist/client.js
|
|
26
26
|
var docsApiErrorBrand = Symbol.for("io.github.hiai-gg.docsmint.DocsApiError");
|
|
@@ -581,52 +581,87 @@ var RESOURCE_PERMISSIONS = new Set([
|
|
|
581
581
|
"edit",
|
|
582
582
|
"write"
|
|
583
583
|
]);
|
|
584
|
-
// ../mcp-server/src/
|
|
584
|
+
// ../mcp-server/src/lifecycle.ts
|
|
585
585
|
import { z } from "zod";
|
|
586
|
+
function unsupported(name) {
|
|
587
|
+
throw new Error(`The injected legacy MCP client does not support ${name}; use a public DocsClient.`);
|
|
588
|
+
}
|
|
589
|
+
var annotations = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
|
|
590
|
+
function registerLifecycleCapabilities(server, client, wrap) {
|
|
591
|
+
const deletions = [
|
|
592
|
+
{ name: "delete_document", description: "Move a document to trash. Requires write access to the document; category keys are limited to their category. Does not permanently purge content. Returns the document ID and deleted=true. Use only when the user intends deletion.", action: (id) => client.deleteDocument ? client.deleteDocument(id) : unsupported("delete_document"), idDescription: "UUID of the document to move to trash; obtain it from search_documents, list_documents, or get_document." },
|
|
593
|
+
{ name: "delete_folder", 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 permitted workspace or category. Returns the folder ID and deleted=true.", action: (id) => client.deleteFolder ? client.deleteFolder(id) : unsupported("delete_folder"), idDescription: "UUID of the folder to delete; obtain it from list_folders. This does not delete the documents inside it." },
|
|
594
|
+
{ name: "delete_category", description: "Delete a category and detach its folders and documents without deleting their content. Requires full workspace write access; category-scoped keys cannot delete any category, including their own. Returns the category ID and deleted=true.", action: (id) => client.deleteCategory ? client.deleteCategory(id) : unsupported("delete_category"), idDescription: "UUID of the category to delete; obtain it from list_categories using a workspace key." }
|
|
595
|
+
];
|
|
596
|
+
for (const tool of deletions) {
|
|
597
|
+
server.registerTool(tool.name, { description: tool.description, annotations, inputSchema: z.object({ id: z.string().uuid().describe(tool.idDescription) }) }, wrap(async ({ id }) => {
|
|
598
|
+
await tool.action(id);
|
|
599
|
+
return { id, deleted: true };
|
|
600
|
+
}));
|
|
601
|
+
}
|
|
602
|
+
server.registerTool("restore_document_version", {
|
|
603
|
+
description: "Restore document content from a version or named snapshot returned by get_version_history. Requires edit access to that document. The server backs up the current content, records the restoration, and queues document reindexing. Returns the updated document. Does not restore a document from trash or restore folder/category placement.",
|
|
604
|
+
annotations,
|
|
605
|
+
inputSchema: z.object({
|
|
606
|
+
documentId: z.string().uuid().describe("UUID of the document whose content should be restored; it must be visible in the active workspace or category."),
|
|
607
|
+
versionId: z.string().uuid().describe("UUID of a version belonging to this document, from get_version_history. Use the version ID, not a snapshot label.")
|
|
608
|
+
})
|
|
609
|
+
}, wrap(async ({ documentId, versionId }) => client.restoreDocumentVersion ? client.restoreDocumentVersion(documentId, versionId) : unsupported("restore_document_version")));
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// ../mcp-server/src/capabilities.ts
|
|
613
|
+
import { z as z2 } from "zod";
|
|
586
614
|
function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
587
615
|
server.registerTool("list_categories", {
|
|
616
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
588
617
|
description: "List categories visible to the API key. Category keys receive only their bound category.",
|
|
589
|
-
inputSchema:
|
|
618
|
+
inputSchema: z2.object({})
|
|
590
619
|
}, wrapHandler(async () => client.listCategories()));
|
|
591
620
|
server.registerTool("create_category", {
|
|
621
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
592
622
|
description: "Create a category. Requires a workspace key with write access; category keys cannot mutate categories.",
|
|
593
|
-
inputSchema:
|
|
594
|
-
name:
|
|
595
|
-
description:
|
|
623
|
+
inputSchema: z2.object({
|
|
624
|
+
name: z2.string().min(1).describe("Non-empty display name for the new category, for example Project notes."),
|
|
625
|
+
description: z2.string().optional().describe("Optional plain-text explanation of the category purpose; omit if not needed.")
|
|
596
626
|
})
|
|
597
627
|
}, wrapHandler(async (input) => client.createCategory(input)));
|
|
598
628
|
server.registerTool("list_tags", {
|
|
629
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
599
630
|
description: "List tags visible in the workspace or bound category.",
|
|
600
|
-
inputSchema:
|
|
631
|
+
inputSchema: z2.object({})
|
|
601
632
|
}, wrapHandler(async () => client.listTags()));
|
|
602
633
|
server.registerTool("get_related_documents", {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
634
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
635
|
+
description: "Find graph-related documents from one readable document, without a text query. Returns related documents and relation metadata. Use search_knowledge_graph to filter graph neighbors by text, or search_documents for normal retrieval. Results stay within the active scope and may be empty when graph data is unavailable.",
|
|
636
|
+
inputSchema: z2.object({
|
|
637
|
+
documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope."),
|
|
638
|
+
limit: z2.number().int().min(1).max(50).optional().describe("Maximum related documents to return, from 1 to 50. Omit to use the server default.")
|
|
607
639
|
})
|
|
608
640
|
}, wrapHandler(async ({ documentId, limit }) => client.getRelatedDocuments(documentId, limit)));
|
|
609
641
|
server.registerTool("search_knowledge_graph", {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
642
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
643
|
+
description: "Retrieve graph context from one or more readable seed documents and filter/rank related documents by query text. Returns seed entities and relatedDocs; use search_documents first to obtain seed IDs. Returned documents stay within the active category. Graph data may be empty when unavailable.",
|
|
644
|
+
inputSchema: z2.object({
|
|
645
|
+
query: z2.string().min(1).max(1000).describe("Search text used to filter and rank graph-related documents. Preserve the original query language."),
|
|
646
|
+
docIds: z2.array(z2.string().min(1)).min(1).max(50).describe("Between 1 and 50 authorized document UUIDs from search_documents or list_documents to use as graph traversal seeds."),
|
|
647
|
+
limit: z2.number().int().min(1).max(50).optional().describe("Maximum related documents to return, from 1 to 50. Omit to use the server default.")
|
|
615
648
|
})
|
|
616
649
|
}, wrapHandler(async (input) => client.searchGraph(input)));
|
|
617
650
|
server.registerTool("get_document_index_status", {
|
|
618
|
-
|
|
619
|
-
|
|
651
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
652
|
+
description: "Read a document indexing and knowledge-pipeline status without starting any work. Use after a save or refresh_document_index to inspect progress and failures. Requires read access to the document.",
|
|
653
|
+
inputSchema: z2.object({ documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope.") })
|
|
620
654
|
}, wrapHandler(async ({ documentId }) => client.getDocumentIndexStatus(documentId)));
|
|
621
655
|
server.registerTool("refresh_document_index", {
|
|
622
|
-
|
|
623
|
-
|
|
656
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
657
|
+
description: "Queue document reindexing and return the server acknowledgment; processing completes asynchronously. Requires write access. Normal saves already schedule indexing; use this for an explicit refresh and inspect progress with get_document_index_status.",
|
|
658
|
+
inputSchema: z2.object({ documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope.") })
|
|
624
659
|
}, wrapHandler(async ({ documentId }) => client.refreshDocumentIndex(documentId)));
|
|
625
660
|
server.registerPrompt("organize_workspace", {
|
|
626
661
|
description: "Plan safe document organization using DocsMint categories and folders.",
|
|
627
|
-
argsSchema:
|
|
628
|
-
objective:
|
|
629
|
-
language:
|
|
662
|
+
argsSchema: z2.object({
|
|
663
|
+
objective: z2.string(),
|
|
664
|
+
language: z2.string().optional()
|
|
630
665
|
})
|
|
631
666
|
}, ({ objective, language }) => ({
|
|
632
667
|
messages: [
|
|
@@ -641,9 +676,9 @@ function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
|
641
676
|
}));
|
|
642
677
|
server.registerPrompt("research_workspace", {
|
|
643
678
|
description: "Research a question with hybrid search and GraphRAG while citing DocsMint document IDs.",
|
|
644
|
-
argsSchema:
|
|
645
|
-
question:
|
|
646
|
-
language:
|
|
679
|
+
argsSchema: z2.object({
|
|
680
|
+
question: z2.string(),
|
|
681
|
+
language: z2.string().optional()
|
|
647
682
|
})
|
|
648
683
|
}, ({ question, language }) => ({
|
|
649
684
|
messages: [
|
|
@@ -734,6 +769,10 @@ function sanitizeMcpRequestContext(context) {
|
|
|
734
769
|
function createMcpDocsClient(docsClient, requestContext) {
|
|
735
770
|
const context = sanitizeMcpRequestContext(requestContext);
|
|
736
771
|
return {
|
|
772
|
+
deleteDocument: (id) => docsClient.deleteDoc(id, context),
|
|
773
|
+
deleteFolder: (id) => docsClient.deleteFolder(id, context),
|
|
774
|
+
deleteCategory: (id) => docsClient.deleteCategory(id, context),
|
|
775
|
+
restoreDocumentVersion: (documentId, versionId) => docsClient.restoreVersion(documentId, versionId, context),
|
|
737
776
|
search: (params) => docsClient.search(params.query, {
|
|
738
777
|
folder: params.folder,
|
|
739
778
|
tags: params.tags?.join(","),
|
|
@@ -780,15 +819,15 @@ __export(exports_create_document, {
|
|
|
780
819
|
definition: () => definition,
|
|
781
820
|
handler: () => handler
|
|
782
821
|
});
|
|
783
|
-
import { z as
|
|
822
|
+
import { z as z3 } from "zod";
|
|
784
823
|
var definition = {
|
|
785
824
|
name: "create_document",
|
|
786
825
|
description: "Create a new document. Optionally provide initial markdown content and a folder ID.",
|
|
787
826
|
inputSchema: {
|
|
788
|
-
title:
|
|
789
|
-
content:
|
|
790
|
-
folderId:
|
|
791
|
-
categoryId:
|
|
827
|
+
title: z3.string().describe("Document title."),
|
|
828
|
+
content: z3.string().optional().describe("Initial markdown content for the document."),
|
|
829
|
+
folderId: z3.string().optional().describe("Optional folder ID to place the document in."),
|
|
830
|
+
categoryId: z3.string().optional().describe("Optional category ID. Category keys are always rebound to their configured category.")
|
|
792
831
|
}
|
|
793
832
|
};
|
|
794
833
|
var createHandler = (api) => async function createDocument(args) {
|
|
@@ -803,14 +842,14 @@ __export(exports_create_folder, {
|
|
|
803
842
|
definition: () => definition2,
|
|
804
843
|
handler: () => handler2
|
|
805
844
|
});
|
|
806
|
-
import { z as
|
|
845
|
+
import { z as z4 } from "zod";
|
|
807
846
|
var definition2 = {
|
|
808
847
|
name: "create_folder",
|
|
809
848
|
description: "Create a new folder, optionally nested under a parent folder.",
|
|
810
849
|
inputSchema: {
|
|
811
|
-
name:
|
|
812
|
-
parentId:
|
|
813
|
-
categoryId:
|
|
850
|
+
name: z4.string().describe("Folder name."),
|
|
851
|
+
parentId: z4.string().optional().describe("Optional parent folder ID for nesting."),
|
|
852
|
+
categoryId: z4.string().optional().describe("Optional category ID. Category keys are always rebound to their configured category.")
|
|
814
853
|
}
|
|
815
854
|
};
|
|
816
855
|
var createHandler2 = (api) => async function createFolder(args) {
|
|
@@ -825,14 +864,14 @@ __export(exports_create_snapshot, {
|
|
|
825
864
|
definition: () => definition3,
|
|
826
865
|
handler: () => handler3
|
|
827
866
|
});
|
|
828
|
-
import { z as
|
|
867
|
+
import { z as z5 } from "zod";
|
|
829
868
|
var definition3 = {
|
|
830
869
|
name: "create_snapshot",
|
|
831
870
|
description: "Create a named snapshot (labelled version) of a document from its current content.",
|
|
832
871
|
inputSchema: {
|
|
833
|
-
documentId:
|
|
834
|
-
label:
|
|
835
|
-
description:
|
|
872
|
+
documentId: z5.string().describe("Document ID to snapshot."),
|
|
873
|
+
label: z5.string().describe("Short label for the snapshot (e.g. 'v1.0-release')."),
|
|
874
|
+
description: z5.string().optional().describe("Optional longer description of the snapshot.")
|
|
836
875
|
}
|
|
837
876
|
};
|
|
838
877
|
var createHandler3 = (api) => async function createSnapshot(args) {
|
|
@@ -848,12 +887,12 @@ __export(exports_export_document, {
|
|
|
848
887
|
definition: () => definition4,
|
|
849
888
|
handler: () => handler4
|
|
850
889
|
});
|
|
851
|
-
import { z as
|
|
890
|
+
import { z as z6 } from "zod";
|
|
852
891
|
var definition4 = {
|
|
853
892
|
name: "export_document",
|
|
854
|
-
description: "
|
|
893
|
+
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.",
|
|
855
894
|
inputSchema: {
|
|
856
|
-
id:
|
|
895
|
+
id: z6.string().describe("Document ID to export.")
|
|
857
896
|
}
|
|
858
897
|
};
|
|
859
898
|
var createHandler4 = (api) => async function exportDocument(args) {
|
|
@@ -868,12 +907,12 @@ __export(exports_get_document, {
|
|
|
868
907
|
definition: () => definition5,
|
|
869
908
|
handler: () => handler5
|
|
870
909
|
});
|
|
871
|
-
import { z as
|
|
910
|
+
import { z as z7 } from "zod";
|
|
872
911
|
var definition5 = {
|
|
873
912
|
name: "get_document",
|
|
874
|
-
description: "
|
|
913
|
+
description: "Read one document with its content, metadata, and tags before editing or citing it. Requires read access. Use export_document when you only need portable Markdown.",
|
|
875
914
|
inputSchema: {
|
|
876
|
-
id:
|
|
915
|
+
id: z7.string().describe("Document ID.")
|
|
877
916
|
}
|
|
878
917
|
};
|
|
879
918
|
var createHandler5 = (api) => async function getDocument(args) {
|
|
@@ -888,15 +927,15 @@ __export(exports_list_documents, {
|
|
|
888
927
|
definition: () => definition6,
|
|
889
928
|
handler: () => handler6
|
|
890
929
|
});
|
|
891
|
-
import { z as
|
|
930
|
+
import { z as z8 } from "zod";
|
|
892
931
|
var definition6 = {
|
|
893
932
|
name: "list_documents",
|
|
894
933
|
description: "List documents with pagination, optionally filtered by folder or tag.",
|
|
895
934
|
inputSchema: {
|
|
896
|
-
folderId:
|
|
897
|
-
tag:
|
|
898
|
-
page:
|
|
899
|
-
limit:
|
|
935
|
+
folderId: z8.string().optional().describe("Optional folder ID to filter by."),
|
|
936
|
+
tag: z8.string().optional().describe("Optional tag ID to filter by."),
|
|
937
|
+
page: z8.number().int().positive().optional().describe("Page number (1-indexed, default 1)."),
|
|
938
|
+
limit: z8.number().int().positive().max(100).optional().describe("Items per page (default 20, max 100).")
|
|
900
939
|
}
|
|
901
940
|
};
|
|
902
941
|
var createHandler6 = (api) => async function listDocuments(args) {
|
|
@@ -911,12 +950,12 @@ __export(exports_list_folders, {
|
|
|
911
950
|
definition: () => definition7,
|
|
912
951
|
handler: () => handler7
|
|
913
952
|
});
|
|
914
|
-
import { z as
|
|
953
|
+
import { z as z9 } from "zod";
|
|
915
954
|
var definition7 = {
|
|
916
955
|
name: "list_folders",
|
|
917
956
|
description: "List folders, optionally scoped to a parent folder. Returns a flat list of immediate children.",
|
|
918
957
|
inputSchema: {
|
|
919
|
-
parentId:
|
|
958
|
+
parentId: z9.string().optional().describe("Optional parent folder ID. Omit to list top-level (root) folders.")
|
|
920
959
|
}
|
|
921
960
|
};
|
|
922
961
|
var createHandler7 = (api) => async function listFolders(args) {
|
|
@@ -931,15 +970,15 @@ __export(exports_search, {
|
|
|
931
970
|
definition: () => definition8,
|
|
932
971
|
handler: () => handler8
|
|
933
972
|
});
|
|
934
|
-
import { z as
|
|
973
|
+
import { z as z10 } from "zod";
|
|
935
974
|
var definition8 = {
|
|
936
975
|
name: "search_documents",
|
|
937
976
|
description: "Hybrid search across documents (full-text + semantic). Supports filtering by folder and tags.",
|
|
938
977
|
inputSchema: {
|
|
939
|
-
query:
|
|
940
|
-
folder:
|
|
941
|
-
tags:
|
|
942
|
-
limit:
|
|
978
|
+
query: z10.string().describe("Search query string."),
|
|
979
|
+
folder: z10.string().optional().describe("Optional folder ID to scope the search to."),
|
|
980
|
+
tags: z10.array(z10.string()).optional().describe("Optional tag IDs to filter by."),
|
|
981
|
+
limit: z10.number().int().positive().optional().describe("Maximum number of results to return (default 20).")
|
|
943
982
|
}
|
|
944
983
|
};
|
|
945
984
|
var createHandler8 = (api) => async function searchDocuments(args) {
|
|
@@ -959,16 +998,16 @@ __export(exports_update_document, {
|
|
|
959
998
|
definition: () => definition9,
|
|
960
999
|
handler: () => handler9
|
|
961
1000
|
});
|
|
962
|
-
import { z as
|
|
1001
|
+
import { z as z11 } from "zod";
|
|
963
1002
|
var definition9 = {
|
|
964
1003
|
name: "update_document",
|
|
965
1004
|
description: "Update an existing document's title and/or content. The server creates a new version on each update.",
|
|
966
1005
|
inputSchema: {
|
|
967
|
-
id:
|
|
968
|
-
title:
|
|
969
|
-
content:
|
|
970
|
-
folderId:
|
|
971
|
-
categoryId:
|
|
1006
|
+
id: z11.string().describe("Document ID to update."),
|
|
1007
|
+
title: z11.string().optional().describe("New title for the document."),
|
|
1008
|
+
content: z11.string().optional().describe("New markdown content for the document."),
|
|
1009
|
+
folderId: z11.string().nullable().optional().describe("Move the document to a folder."),
|
|
1010
|
+
categoryId: z11.string().nullable().optional().describe("Move the document to a category. Category keys cannot escape their configured category.")
|
|
972
1011
|
}
|
|
973
1012
|
};
|
|
974
1013
|
var createHandler9 = (api) => async function updateDocument(args) {
|
|
@@ -984,13 +1023,13 @@ __export(exports_version_history, {
|
|
|
984
1023
|
definition: () => definition10,
|
|
985
1024
|
handler: () => handler10
|
|
986
1025
|
});
|
|
987
|
-
import { z as
|
|
1026
|
+
import { z as z12 } from "zod";
|
|
988
1027
|
var definition10 = {
|
|
989
1028
|
name: "get_version_history",
|
|
990
1029
|
description: "List the version history for a document. Optionally restrict to named snapshots.",
|
|
991
1030
|
inputSchema: {
|
|
992
|
-
documentId:
|
|
993
|
-
onlySnapshots:
|
|
1031
|
+
documentId: z12.string().describe("Document ID whose versions should be listed."),
|
|
1032
|
+
onlySnapshots: z12.boolean().optional().describe("When true, only return named snapshots (skip auto-saved revisions).")
|
|
994
1033
|
}
|
|
995
1034
|
};
|
|
996
1035
|
var createHandler10 = (api) => async function getVersionHistory(args) {
|
|
@@ -1032,7 +1071,12 @@ function wrapHandler(name, handler11) {
|
|
|
1032
1071
|
}
|
|
1033
1072
|
function registerDocsmintMcpCapabilities(server, client2) {
|
|
1034
1073
|
const register = (name, description, inputSchema, handler11) => {
|
|
1035
|
-
server.registerTool(name, { description, inputSchema:
|
|
1074
|
+
server.registerTool(name, { description, inputSchema: z13.object(inputSchema), annotations: {
|
|
1075
|
+
readOnlyHint: !["create_document", "update_document", "create_folder", "create_snapshot"].includes(name),
|
|
1076
|
+
destructiveHint: name === "update_document",
|
|
1077
|
+
idempotentHint: !["create_document", "update_document", "create_folder", "create_snapshot"].includes(name),
|
|
1078
|
+
openWorldHint: false
|
|
1079
|
+
} }, wrapHandler(name, handler11));
|
|
1036
1080
|
};
|
|
1037
1081
|
const tools = [
|
|
1038
1082
|
exports_search,
|
|
@@ -1050,9 +1094,10 @@ function registerDocsmintMcpCapabilities(server, client2) {
|
|
|
1050
1094
|
register(tool.definition.name, tool.definition.description, tool.definition.inputSchema, tool.createHandler(client2));
|
|
1051
1095
|
}
|
|
1052
1096
|
registerExtendedCapabilities(server, client2, (handler11) => wrapHandler("extended", handler11));
|
|
1097
|
+
registerLifecycleCapabilities(server, client2, (handler11) => wrapHandler("lifecycle", handler11));
|
|
1053
1098
|
}
|
|
1054
1099
|
function createDocsmintMcpServer(options = {}) {
|
|
1055
|
-
const server = new McpServer({ name: "docsmint", version: "0.8.
|
|
1100
|
+
const server = new McpServer({ name: "docsmint", version: "0.8.7" });
|
|
1056
1101
|
const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
|
|
1057
1102
|
registerDocsmintMcpCapabilities(server, client2);
|
|
1058
1103
|
return server;
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { McpServer } from "@modelcontextprotocol/server";
|
|
|
3
3
|
import type { DocsClient, DocsRequestContext } from "./index.js";
|
|
4
4
|
|
|
5
5
|
export interface HiaiDocsClient {
|
|
6
|
+
deleteDocument?(id: string): Promise<void>;
|
|
7
|
+
deleteFolder?(id: string): Promise<void>;
|
|
8
|
+
deleteCategory?(id: string): Promise<void>;
|
|
9
|
+
restoreDocumentVersion?(documentId: string, versionId: string): Promise<unknown>;
|
|
6
10
|
search(params: { query: string; folder?: string; tags?: string[]; limit?: number }): Promise<unknown>;
|
|
7
11
|
getDocument(id: string): Promise<unknown>;
|
|
8
12
|
createDocument(input: { title: string; content?: string; folderId?: string | null; categoryId?: string | null }): Promise<unknown>;
|
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 z13 } from "zod";
|
|
20
20
|
|
|
21
21
|
// dist/client.js
|
|
22
22
|
var docsApiErrorBrand = Symbol.for("io.github.hiai-gg.docsmint.DocsApiError");
|
|
@@ -577,52 +577,87 @@ var RESOURCE_PERMISSIONS = new Set([
|
|
|
577
577
|
"edit",
|
|
578
578
|
"write"
|
|
579
579
|
]);
|
|
580
|
-
// ../mcp-server/src/
|
|
580
|
+
// ../mcp-server/src/lifecycle.ts
|
|
581
581
|
import { z } from "zod";
|
|
582
|
+
function unsupported(name) {
|
|
583
|
+
throw new Error(`The injected legacy MCP client does not support ${name}; use a public DocsClient.`);
|
|
584
|
+
}
|
|
585
|
+
var annotations = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
|
|
586
|
+
function registerLifecycleCapabilities(server, client, wrap) {
|
|
587
|
+
const deletions = [
|
|
588
|
+
{ name: "delete_document", description: "Move a document to trash. Requires write access to the document; category keys are limited to their category. Does not permanently purge content. Returns the document ID and deleted=true. Use only when the user intends deletion.", action: (id) => client.deleteDocument ? client.deleteDocument(id) : unsupported("delete_document"), idDescription: "UUID of the document to move to trash; obtain it from search_documents, list_documents, or get_document." },
|
|
589
|
+
{ name: "delete_folder", 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 permitted workspace or category. Returns the folder ID and deleted=true.", action: (id) => client.deleteFolder ? client.deleteFolder(id) : unsupported("delete_folder"), idDescription: "UUID of the folder to delete; obtain it from list_folders. This does not delete the documents inside it." },
|
|
590
|
+
{ name: "delete_category", description: "Delete a category and detach its folders and documents without deleting their content. Requires full workspace write access; category-scoped keys cannot delete any category, including their own. Returns the category ID and deleted=true.", action: (id) => client.deleteCategory ? client.deleteCategory(id) : unsupported("delete_category"), idDescription: "UUID of the category to delete; obtain it from list_categories using a workspace key." }
|
|
591
|
+
];
|
|
592
|
+
for (const tool of deletions) {
|
|
593
|
+
server.registerTool(tool.name, { description: tool.description, annotations, inputSchema: z.object({ id: z.string().uuid().describe(tool.idDescription) }) }, wrap(async ({ id }) => {
|
|
594
|
+
await tool.action(id);
|
|
595
|
+
return { id, deleted: true };
|
|
596
|
+
}));
|
|
597
|
+
}
|
|
598
|
+
server.registerTool("restore_document_version", {
|
|
599
|
+
description: "Restore document content from a version or named snapshot returned by get_version_history. Requires edit access to that document. The server backs up the current content, records the restoration, and queues document reindexing. Returns the updated document. Does not restore a document from trash or restore folder/category placement.",
|
|
600
|
+
annotations,
|
|
601
|
+
inputSchema: z.object({
|
|
602
|
+
documentId: z.string().uuid().describe("UUID of the document whose content should be restored; it must be visible in the active workspace or category."),
|
|
603
|
+
versionId: z.string().uuid().describe("UUID of a version belonging to this document, from get_version_history. Use the version ID, not a snapshot label.")
|
|
604
|
+
})
|
|
605
|
+
}, wrap(async ({ documentId, versionId }) => client.restoreDocumentVersion ? client.restoreDocumentVersion(documentId, versionId) : unsupported("restore_document_version")));
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// ../mcp-server/src/capabilities.ts
|
|
609
|
+
import { z as z2 } from "zod";
|
|
582
610
|
function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
583
611
|
server.registerTool("list_categories", {
|
|
612
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
584
613
|
description: "List categories visible to the API key. Category keys receive only their bound category.",
|
|
585
|
-
inputSchema:
|
|
614
|
+
inputSchema: z2.object({})
|
|
586
615
|
}, wrapHandler(async () => client.listCategories()));
|
|
587
616
|
server.registerTool("create_category", {
|
|
617
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
588
618
|
description: "Create a category. Requires a workspace key with write access; category keys cannot mutate categories.",
|
|
589
|
-
inputSchema:
|
|
590
|
-
name:
|
|
591
|
-
description:
|
|
619
|
+
inputSchema: z2.object({
|
|
620
|
+
name: z2.string().min(1).describe("Non-empty display name for the new category, for example Project notes."),
|
|
621
|
+
description: z2.string().optional().describe("Optional plain-text explanation of the category purpose; omit if not needed.")
|
|
592
622
|
})
|
|
593
623
|
}, wrapHandler(async (input) => client.createCategory(input)));
|
|
594
624
|
server.registerTool("list_tags", {
|
|
625
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
595
626
|
description: "List tags visible in the workspace or bound category.",
|
|
596
|
-
inputSchema:
|
|
627
|
+
inputSchema: z2.object({})
|
|
597
628
|
}, wrapHandler(async () => client.listTags()));
|
|
598
629
|
server.registerTool("get_related_documents", {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
630
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
631
|
+
description: "Find graph-related documents from one readable document, without a text query. Returns related documents and relation metadata. Use search_knowledge_graph to filter graph neighbors by text, or search_documents for normal retrieval. Results stay within the active scope and may be empty when graph data is unavailable.",
|
|
632
|
+
inputSchema: z2.object({
|
|
633
|
+
documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope."),
|
|
634
|
+
limit: z2.number().int().min(1).max(50).optional().describe("Maximum related documents to return, from 1 to 50. Omit to use the server default.")
|
|
603
635
|
})
|
|
604
636
|
}, wrapHandler(async ({ documentId, limit }) => client.getRelatedDocuments(documentId, limit)));
|
|
605
637
|
server.registerTool("search_knowledge_graph", {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
638
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
639
|
+
description: "Retrieve graph context from one or more readable seed documents and filter/rank related documents by query text. Returns seed entities and relatedDocs; use search_documents first to obtain seed IDs. Returned documents stay within the active category. Graph data may be empty when unavailable.",
|
|
640
|
+
inputSchema: z2.object({
|
|
641
|
+
query: z2.string().min(1).max(1000).describe("Search text used to filter and rank graph-related documents. Preserve the original query language."),
|
|
642
|
+
docIds: z2.array(z2.string().min(1)).min(1).max(50).describe("Between 1 and 50 authorized document UUIDs from search_documents or list_documents to use as graph traversal seeds."),
|
|
643
|
+
limit: z2.number().int().min(1).max(50).optional().describe("Maximum related documents to return, from 1 to 50. Omit to use the server default.")
|
|
611
644
|
})
|
|
612
645
|
}, wrapHandler(async (input) => client.searchGraph(input)));
|
|
613
646
|
server.registerTool("get_document_index_status", {
|
|
614
|
-
|
|
615
|
-
|
|
647
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
648
|
+
description: "Read a document indexing and knowledge-pipeline status without starting any work. Use after a save or refresh_document_index to inspect progress and failures. Requires read access to the document.",
|
|
649
|
+
inputSchema: z2.object({ documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope.") })
|
|
616
650
|
}, wrapHandler(async ({ documentId }) => client.getDocumentIndexStatus(documentId)));
|
|
617
651
|
server.registerTool("refresh_document_index", {
|
|
618
|
-
|
|
619
|
-
|
|
652
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
653
|
+
description: "Queue document reindexing and return the server acknowledgment; processing completes asynchronously. Requires write access. Normal saves already schedule indexing; use this for an explicit refresh and inspect progress with get_document_index_status.",
|
|
654
|
+
inputSchema: z2.object({ documentId: z2.string().min(1).describe("Document UUID returned by search_documents or list_documents; must be readable in the active scope.") })
|
|
620
655
|
}, wrapHandler(async ({ documentId }) => client.refreshDocumentIndex(documentId)));
|
|
621
656
|
server.registerPrompt("organize_workspace", {
|
|
622
657
|
description: "Plan safe document organization using DocsMint categories and folders.",
|
|
623
|
-
argsSchema:
|
|
624
|
-
objective:
|
|
625
|
-
language:
|
|
658
|
+
argsSchema: z2.object({
|
|
659
|
+
objective: z2.string(),
|
|
660
|
+
language: z2.string().optional()
|
|
626
661
|
})
|
|
627
662
|
}, ({ objective, language }) => ({
|
|
628
663
|
messages: [
|
|
@@ -637,9 +672,9 @@ function registerExtendedCapabilities(server, client, wrapHandler) {
|
|
|
637
672
|
}));
|
|
638
673
|
server.registerPrompt("research_workspace", {
|
|
639
674
|
description: "Research a question with hybrid search and GraphRAG while citing DocsMint document IDs.",
|
|
640
|
-
argsSchema:
|
|
641
|
-
question:
|
|
642
|
-
language:
|
|
675
|
+
argsSchema: z2.object({
|
|
676
|
+
question: z2.string(),
|
|
677
|
+
language: z2.string().optional()
|
|
643
678
|
})
|
|
644
679
|
}, ({ question, language }) => ({
|
|
645
680
|
messages: [
|
|
@@ -730,6 +765,10 @@ function sanitizeMcpRequestContext(context) {
|
|
|
730
765
|
function createMcpDocsClient(docsClient, requestContext) {
|
|
731
766
|
const context = sanitizeMcpRequestContext(requestContext);
|
|
732
767
|
return {
|
|
768
|
+
deleteDocument: (id) => docsClient.deleteDoc(id, context),
|
|
769
|
+
deleteFolder: (id) => docsClient.deleteFolder(id, context),
|
|
770
|
+
deleteCategory: (id) => docsClient.deleteCategory(id, context),
|
|
771
|
+
restoreDocumentVersion: (documentId, versionId) => docsClient.restoreVersion(documentId, versionId, context),
|
|
733
772
|
search: (params) => docsClient.search(params.query, {
|
|
734
773
|
folder: params.folder,
|
|
735
774
|
tags: params.tags?.join(","),
|
|
@@ -776,15 +815,15 @@ __export(exports_create_document, {
|
|
|
776
815
|
definition: () => definition,
|
|
777
816
|
handler: () => handler
|
|
778
817
|
});
|
|
779
|
-
import { z as
|
|
818
|
+
import { z as z3 } from "zod";
|
|
780
819
|
var definition = {
|
|
781
820
|
name: "create_document",
|
|
782
821
|
description: "Create a new document. Optionally provide initial markdown content and a folder ID.",
|
|
783
822
|
inputSchema: {
|
|
784
|
-
title:
|
|
785
|
-
content:
|
|
786
|
-
folderId:
|
|
787
|
-
categoryId:
|
|
823
|
+
title: z3.string().describe("Document title."),
|
|
824
|
+
content: z3.string().optional().describe("Initial markdown content for the document."),
|
|
825
|
+
folderId: z3.string().optional().describe("Optional folder ID to place the document in."),
|
|
826
|
+
categoryId: z3.string().optional().describe("Optional category ID. Category keys are always rebound to their configured category.")
|
|
788
827
|
}
|
|
789
828
|
};
|
|
790
829
|
var createHandler = (api) => async function createDocument(args) {
|
|
@@ -799,14 +838,14 @@ __export(exports_create_folder, {
|
|
|
799
838
|
definition: () => definition2,
|
|
800
839
|
handler: () => handler2
|
|
801
840
|
});
|
|
802
|
-
import { z as
|
|
841
|
+
import { z as z4 } from "zod";
|
|
803
842
|
var definition2 = {
|
|
804
843
|
name: "create_folder",
|
|
805
844
|
description: "Create a new folder, optionally nested under a parent folder.",
|
|
806
845
|
inputSchema: {
|
|
807
|
-
name:
|
|
808
|
-
parentId:
|
|
809
|
-
categoryId:
|
|
846
|
+
name: z4.string().describe("Folder name."),
|
|
847
|
+
parentId: z4.string().optional().describe("Optional parent folder ID for nesting."),
|
|
848
|
+
categoryId: z4.string().optional().describe("Optional category ID. Category keys are always rebound to their configured category.")
|
|
810
849
|
}
|
|
811
850
|
};
|
|
812
851
|
var createHandler2 = (api) => async function createFolder(args) {
|
|
@@ -821,14 +860,14 @@ __export(exports_create_snapshot, {
|
|
|
821
860
|
definition: () => definition3,
|
|
822
861
|
handler: () => handler3
|
|
823
862
|
});
|
|
824
|
-
import { z as
|
|
863
|
+
import { z as z5 } from "zod";
|
|
825
864
|
var definition3 = {
|
|
826
865
|
name: "create_snapshot",
|
|
827
866
|
description: "Create a named snapshot (labelled version) of a document from its current content.",
|
|
828
867
|
inputSchema: {
|
|
829
|
-
documentId:
|
|
830
|
-
label:
|
|
831
|
-
description:
|
|
868
|
+
documentId: z5.string().describe("Document ID to snapshot."),
|
|
869
|
+
label: z5.string().describe("Short label for the snapshot (e.g. 'v1.0-release')."),
|
|
870
|
+
description: z5.string().optional().describe("Optional longer description of the snapshot.")
|
|
832
871
|
}
|
|
833
872
|
};
|
|
834
873
|
var createHandler3 = (api) => async function createSnapshot(args) {
|
|
@@ -844,12 +883,12 @@ __export(exports_export_document, {
|
|
|
844
883
|
definition: () => definition4,
|
|
845
884
|
handler: () => handler4
|
|
846
885
|
});
|
|
847
|
-
import { z as
|
|
886
|
+
import { z as z6 } from "zod";
|
|
848
887
|
var definition4 = {
|
|
849
888
|
name: "export_document",
|
|
850
|
-
description: "
|
|
889
|
+
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.",
|
|
851
890
|
inputSchema: {
|
|
852
|
-
id:
|
|
891
|
+
id: z6.string().describe("Document ID to export.")
|
|
853
892
|
}
|
|
854
893
|
};
|
|
855
894
|
var createHandler4 = (api) => async function exportDocument(args) {
|
|
@@ -864,12 +903,12 @@ __export(exports_get_document, {
|
|
|
864
903
|
definition: () => definition5,
|
|
865
904
|
handler: () => handler5
|
|
866
905
|
});
|
|
867
|
-
import { z as
|
|
906
|
+
import { z as z7 } from "zod";
|
|
868
907
|
var definition5 = {
|
|
869
908
|
name: "get_document",
|
|
870
|
-
description: "
|
|
909
|
+
description: "Read one document with its content, metadata, and tags before editing or citing it. Requires read access. Use export_document when you only need portable Markdown.",
|
|
871
910
|
inputSchema: {
|
|
872
|
-
id:
|
|
911
|
+
id: z7.string().describe("Document ID.")
|
|
873
912
|
}
|
|
874
913
|
};
|
|
875
914
|
var createHandler5 = (api) => async function getDocument(args) {
|
|
@@ -884,15 +923,15 @@ __export(exports_list_documents, {
|
|
|
884
923
|
definition: () => definition6,
|
|
885
924
|
handler: () => handler6
|
|
886
925
|
});
|
|
887
|
-
import { z as
|
|
926
|
+
import { z as z8 } from "zod";
|
|
888
927
|
var definition6 = {
|
|
889
928
|
name: "list_documents",
|
|
890
929
|
description: "List documents with pagination, optionally filtered by folder or tag.",
|
|
891
930
|
inputSchema: {
|
|
892
|
-
folderId:
|
|
893
|
-
tag:
|
|
894
|
-
page:
|
|
895
|
-
limit:
|
|
931
|
+
folderId: z8.string().optional().describe("Optional folder ID to filter by."),
|
|
932
|
+
tag: z8.string().optional().describe("Optional tag ID to filter by."),
|
|
933
|
+
page: z8.number().int().positive().optional().describe("Page number (1-indexed, default 1)."),
|
|
934
|
+
limit: z8.number().int().positive().max(100).optional().describe("Items per page (default 20, max 100).")
|
|
896
935
|
}
|
|
897
936
|
};
|
|
898
937
|
var createHandler6 = (api) => async function listDocuments(args) {
|
|
@@ -907,12 +946,12 @@ __export(exports_list_folders, {
|
|
|
907
946
|
definition: () => definition7,
|
|
908
947
|
handler: () => handler7
|
|
909
948
|
});
|
|
910
|
-
import { z as
|
|
949
|
+
import { z as z9 } from "zod";
|
|
911
950
|
var definition7 = {
|
|
912
951
|
name: "list_folders",
|
|
913
952
|
description: "List folders, optionally scoped to a parent folder. Returns a flat list of immediate children.",
|
|
914
953
|
inputSchema: {
|
|
915
|
-
parentId:
|
|
954
|
+
parentId: z9.string().optional().describe("Optional parent folder ID. Omit to list top-level (root) folders.")
|
|
916
955
|
}
|
|
917
956
|
};
|
|
918
957
|
var createHandler7 = (api) => async function listFolders(args) {
|
|
@@ -927,15 +966,15 @@ __export(exports_search, {
|
|
|
927
966
|
definition: () => definition8,
|
|
928
967
|
handler: () => handler8
|
|
929
968
|
});
|
|
930
|
-
import { z as
|
|
969
|
+
import { z as z10 } from "zod";
|
|
931
970
|
var definition8 = {
|
|
932
971
|
name: "search_documents",
|
|
933
972
|
description: "Hybrid search across documents (full-text + semantic). Supports filtering by folder and tags.",
|
|
934
973
|
inputSchema: {
|
|
935
|
-
query:
|
|
936
|
-
folder:
|
|
937
|
-
tags:
|
|
938
|
-
limit:
|
|
974
|
+
query: z10.string().describe("Search query string."),
|
|
975
|
+
folder: z10.string().optional().describe("Optional folder ID to scope the search to."),
|
|
976
|
+
tags: z10.array(z10.string()).optional().describe("Optional tag IDs to filter by."),
|
|
977
|
+
limit: z10.number().int().positive().optional().describe("Maximum number of results to return (default 20).")
|
|
939
978
|
}
|
|
940
979
|
};
|
|
941
980
|
var createHandler8 = (api) => async function searchDocuments(args) {
|
|
@@ -955,16 +994,16 @@ __export(exports_update_document, {
|
|
|
955
994
|
definition: () => definition9,
|
|
956
995
|
handler: () => handler9
|
|
957
996
|
});
|
|
958
|
-
import { z as
|
|
997
|
+
import { z as z11 } from "zod";
|
|
959
998
|
var definition9 = {
|
|
960
999
|
name: "update_document",
|
|
961
1000
|
description: "Update an existing document's title and/or content. The server creates a new version on each update.",
|
|
962
1001
|
inputSchema: {
|
|
963
|
-
id:
|
|
964
|
-
title:
|
|
965
|
-
content:
|
|
966
|
-
folderId:
|
|
967
|
-
categoryId:
|
|
1002
|
+
id: z11.string().describe("Document ID to update."),
|
|
1003
|
+
title: z11.string().optional().describe("New title for the document."),
|
|
1004
|
+
content: z11.string().optional().describe("New markdown content for the document."),
|
|
1005
|
+
folderId: z11.string().nullable().optional().describe("Move the document to a folder."),
|
|
1006
|
+
categoryId: z11.string().nullable().optional().describe("Move the document to a category. Category keys cannot escape their configured category.")
|
|
968
1007
|
}
|
|
969
1008
|
};
|
|
970
1009
|
var createHandler9 = (api) => async function updateDocument(args) {
|
|
@@ -980,13 +1019,13 @@ __export(exports_version_history, {
|
|
|
980
1019
|
definition: () => definition10,
|
|
981
1020
|
handler: () => handler10
|
|
982
1021
|
});
|
|
983
|
-
import { z as
|
|
1022
|
+
import { z as z12 } from "zod";
|
|
984
1023
|
var definition10 = {
|
|
985
1024
|
name: "get_version_history",
|
|
986
1025
|
description: "List the version history for a document. Optionally restrict to named snapshots.",
|
|
987
1026
|
inputSchema: {
|
|
988
|
-
documentId:
|
|
989
|
-
onlySnapshots:
|
|
1027
|
+
documentId: z12.string().describe("Document ID whose versions should be listed."),
|
|
1028
|
+
onlySnapshots: z12.boolean().optional().describe("When true, only return named snapshots (skip auto-saved revisions).")
|
|
990
1029
|
}
|
|
991
1030
|
};
|
|
992
1031
|
var createHandler10 = (api) => async function getVersionHistory(args) {
|
|
@@ -1028,7 +1067,12 @@ function wrapHandler(name, handler11) {
|
|
|
1028
1067
|
}
|
|
1029
1068
|
function registerDocsmintMcpCapabilities(server, client2) {
|
|
1030
1069
|
const register = (name, description, inputSchema, handler11) => {
|
|
1031
|
-
server.registerTool(name, { description, inputSchema:
|
|
1070
|
+
server.registerTool(name, { description, inputSchema: z13.object(inputSchema), annotations: {
|
|
1071
|
+
readOnlyHint: !["create_document", "update_document", "create_folder", "create_snapshot"].includes(name),
|
|
1072
|
+
destructiveHint: name === "update_document",
|
|
1073
|
+
idempotentHint: !["create_document", "update_document", "create_folder", "create_snapshot"].includes(name),
|
|
1074
|
+
openWorldHint: false
|
|
1075
|
+
} }, wrapHandler(name, handler11));
|
|
1032
1076
|
};
|
|
1033
1077
|
const tools = [
|
|
1034
1078
|
exports_search,
|
|
@@ -1046,9 +1090,10 @@ function registerDocsmintMcpCapabilities(server, client2) {
|
|
|
1046
1090
|
register(tool.definition.name, tool.definition.description, tool.definition.inputSchema, tool.createHandler(client2));
|
|
1047
1091
|
}
|
|
1048
1092
|
registerExtendedCapabilities(server, client2, (handler11) => wrapHandler("extended", handler11));
|
|
1093
|
+
registerLifecycleCapabilities(server, client2, (handler11) => wrapHandler("lifecycle", handler11));
|
|
1049
1094
|
}
|
|
1050
1095
|
function createDocsmintMcpServer(options = {}) {
|
|
1051
|
-
const server = new McpServer({ name: "docsmint", version: "0.8.
|
|
1096
|
+
const server = new McpServer({ name: "docsmint", version: "0.8.7" });
|
|
1052
1097
|
const client2 = options.docsClient ? createMcpDocsClient(options.docsClient, options.requestContext) : options.client ?? createMcpDocsClient(createDefaultDocsClient(), options.requestContext);
|
|
1053
1098
|
registerDocsmintMcpCapabilities(server, client2);
|
|
1054
1099
|
return server;
|
package/package.json
CHANGED
|
@@ -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 = '0.8.
|
|
28
|
+
const VERSION = '0.8.7';
|
|
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": "0.8.
|
|
13
|
+
"version": "0.8.7",
|
|
14
14
|
"icons": [
|
|
15
15
|
{
|
|
16
16
|
"src": "https://raw.githubusercontent.com/HiAi-gg/docsmint/main/frontend/static/logo-dark.png",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"registryType": "npm",
|
|
31
31
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
32
32
|
"identifier": "@hiai-gg/docsmint",
|
|
33
|
-
"version": "0.8.
|
|
33
|
+
"version": "0.8.7",
|
|
34
34
|
"runtimeHint": "npx",
|
|
35
35
|
"transport": {
|
|
36
36
|
"type": "stdio"
|