@hiai-gg/docsmint 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -4
- package/dist/backend/index.js +753 -125
- package/dist/backend-account-runtime-cleanup.js +17 -0
- package/dist/backend-api-key-facade.js +17 -0
- package/dist/backend-pipeline-cancellation.js +17 -0
- package/dist/client.d.ts +4 -1
- package/dist/client.js +9 -0
- package/dist/lifecycle-runtime.js +16 -0
- package/dist/types.d.ts +26 -0
- package/package.json +12 -2
- package/packages/cli/src/index.ts +1 -1
- package/packages/db/src/index.ts +16 -7
- package/packages/db/src/schema.ts +34 -0
- package/packages/mcp-server/src/capabilities.ts +189 -0
- package/packages/mcp-server/src/client.ts +191 -138
- package/packages/mcp-server/src/index.ts +4 -105
- package/packages/mcp-server/src/server.ts +87 -0
- package/packages/mcp-server/src/tools/create-document.ts +19 -17
- package/packages/mcp-server/src/tools/create-folder.ts +18 -11
- package/packages/mcp-server/src/tools/create-snapshot.ts +15 -18
- package/packages/mcp-server/src/tools/export-document.ts +12 -12
- package/packages/mcp-server/src/tools/get-document.ts +12 -10
- package/packages/mcp-server/src/tools/list-documents.ts +15 -23
- package/packages/mcp-server/src/tools/list-folders.ts +12 -11
- package/packages/mcp-server/src/tools/search.ts +20 -23
- package/packages/mcp-server/src/tools/update-document.ts +22 -14
- package/packages/mcp-server/src/tools/version-history.ts +13 -18
- package/server.json +55 -0
- package/skills/docsmint-document-manager/SKILL.md +33 -0
|
@@ -14,159 +14,212 @@ import type { ExportResponse } from "./types.js";
|
|
|
14
14
|
const DEFAULT_BASE_URL = "http://localhost:50700";
|
|
15
15
|
|
|
16
16
|
function readConfig() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const baseUrl = (process.env.HIAI_DOCS_URL ?? DEFAULT_BASE_URL).replace(
|
|
18
|
+
/\/+$/,
|
|
19
|
+
"",
|
|
20
|
+
);
|
|
21
|
+
const apiKey = process.env.HIAI_DOCS_API_KEY ?? "";
|
|
22
|
+
return { baseUrl, apiKey };
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export class HiaiDocsError extends Error {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
constructor(
|
|
27
|
+
message: string,
|
|
28
|
+
readonly status: number,
|
|
29
|
+
readonly body: unknown,
|
|
30
|
+
) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "HiaiDocsError";
|
|
33
|
+
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
type QueryValue = string | number | boolean | string[] | undefined;
|
|
37
37
|
|
|
38
38
|
async function request<T>(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
method: string,
|
|
40
|
+
path: string,
|
|
41
|
+
options: { query?: Record<string, QueryValue>; body?: unknown } = {},
|
|
42
42
|
): Promise<T> {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
43
|
+
const { baseUrl, apiKey } = readConfig();
|
|
44
|
+
|
|
45
|
+
const url = new URL(path.startsWith("/") ? path : `/${path}`, `${baseUrl}/`);
|
|
46
|
+
if (options.query) {
|
|
47
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
48
|
+
if (value === undefined) continue;
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
if (value.length > 0) url.searchParams.set(key, value.join(","));
|
|
51
|
+
} else {
|
|
52
|
+
url.searchParams.set(key, String(value));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const headers: Record<string, string> = {
|
|
58
|
+
Accept: "application/json",
|
|
59
|
+
};
|
|
60
|
+
if (apiKey) {
|
|
61
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let body: BodyInit | undefined;
|
|
65
|
+
if (options.body !== undefined) {
|
|
66
|
+
headers["Content-Type"] = "application/json";
|
|
67
|
+
body = JSON.stringify(options.body);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const response = await fetch(url, { method, headers, body });
|
|
71
|
+
|
|
72
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
73
|
+
const isJson = contentType.includes("application/json");
|
|
74
|
+
const payload: unknown = isJson
|
|
75
|
+
? await response.json().catch(() => null)
|
|
76
|
+
: await response.text().catch(() => null);
|
|
77
|
+
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const message =
|
|
80
|
+
(isJson && payload && typeof payload === "object" && "error" in payload
|
|
81
|
+
? String((payload as { error: unknown }).error)
|
|
82
|
+
: typeof payload === "string" && payload.length > 0
|
|
83
|
+
? payload
|
|
84
|
+
: `HTTP ${response.status} ${response.statusText}`) ||
|
|
85
|
+
`HTTP ${response.status}`;
|
|
86
|
+
throw new HiaiDocsError(message, response.status, payload);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return payload as T;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function joinId(...segments: string[]): string {
|
|
93
|
-
|
|
94
|
-
.map((s) => encodeURIComponent(s))
|
|
95
|
-
.join("/");
|
|
93
|
+
return segments.map((s) => encodeURIComponent(s)).join("/");
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
export const client = {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
97
|
+
search(params: {
|
|
98
|
+
query: string;
|
|
99
|
+
folder?: string;
|
|
100
|
+
tags?: string[];
|
|
101
|
+
limit?: number;
|
|
102
|
+
}) {
|
|
103
|
+
return request("GET", "/api/search", {
|
|
104
|
+
query: {
|
|
105
|
+
q: params.query,
|
|
106
|
+
folder: params.folder,
|
|
107
|
+
tags: params.tags,
|
|
108
|
+
limit: params.limit,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
getDocument(id: string) {
|
|
114
|
+
return request("GET", `/api/${joinId("documents", id)}`);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
createDocument(input: {
|
|
118
|
+
title: string;
|
|
119
|
+
content?: string;
|
|
120
|
+
folderId?: string | null;
|
|
121
|
+
categoryId?: string | null;
|
|
122
|
+
}) {
|
|
123
|
+
return request("POST", "/api/documents", { body: input });
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
updateDocument(
|
|
127
|
+
id: string,
|
|
128
|
+
input: {
|
|
129
|
+
title?: string;
|
|
130
|
+
content?: string;
|
|
131
|
+
folderId?: string | null;
|
|
132
|
+
categoryId?: string | null;
|
|
133
|
+
},
|
|
134
|
+
) {
|
|
135
|
+
return request("PATCH", `/api/${joinId("documents", id)}`, { body: input });
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
listDocuments(params: {
|
|
139
|
+
folderId?: string;
|
|
140
|
+
tag?: string;
|
|
141
|
+
page?: number;
|
|
142
|
+
limit?: number;
|
|
143
|
+
}) {
|
|
144
|
+
return request("GET", "/api/documents", { query: params });
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
listFolders(params: { parentId?: string }) {
|
|
148
|
+
return request("GET", "/api/folders", {
|
|
149
|
+
query: { parentId: params.parentId },
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
createFolder(input: {
|
|
154
|
+
name: string;
|
|
155
|
+
parentId?: string;
|
|
156
|
+
categoryId?: string;
|
|
157
|
+
}) {
|
|
158
|
+
return request("POST", "/api/folders", { body: input });
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
listCategories() {
|
|
162
|
+
return request("GET", "/api/categories");
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
createCategory(input: { name: string; description?: string }) {
|
|
166
|
+
return request("POST", "/api/categories", { body: input });
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
listTags() {
|
|
170
|
+
return request("GET", "/api/tags");
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
getRelatedDocuments(documentId: string, limit?: number) {
|
|
174
|
+
return request("GET", `/api/${joinId("graph", "related", documentId)}`, {
|
|
175
|
+
query: { limit },
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
searchGraph(input: { query: string; docIds: string[]; limit?: number }) {
|
|
180
|
+
return request("POST", "/api/graph/search", { body: input });
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
getDocumentIndexStatus(documentId: string) {
|
|
184
|
+
return request(
|
|
185
|
+
"GET",
|
|
186
|
+
`/api/${joinId("documents", documentId, "index-status")}`,
|
|
187
|
+
);
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
refreshDocumentIndex(documentId: string) {
|
|
191
|
+
return request(
|
|
192
|
+
"POST",
|
|
193
|
+
`/api/${joinId("documents", documentId, "index", "refresh")}`,
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
createSnapshot(
|
|
198
|
+
documentId: string,
|
|
199
|
+
input: { label: string; description?: string },
|
|
200
|
+
) {
|
|
201
|
+
return request(
|
|
202
|
+
"POST",
|
|
203
|
+
`/api/${joinId("documents", documentId, "versions")}`,
|
|
204
|
+
{ body: input },
|
|
205
|
+
);
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
getVersionHistory(documentId: string, onlySnapshots?: boolean) {
|
|
209
|
+
return request(
|
|
210
|
+
"GET",
|
|
211
|
+
`/api/${joinId("documents", documentId, "versions")}`,
|
|
212
|
+
{ query: { onlySnapshots } },
|
|
213
|
+
);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
async exportDocument(id: string): Promise<ExportResponse> {
|
|
217
|
+
const markdown = await request<string>(
|
|
218
|
+
"GET",
|
|
219
|
+
`/api/${joinId("documents", id, "export")}`,
|
|
220
|
+
);
|
|
221
|
+
return { markdown };
|
|
222
|
+
},
|
|
170
223
|
};
|
|
171
224
|
|
|
172
225
|
export type HiaiDocsClient = typeof client;
|
|
@@ -1,109 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* hiai-docs MCP Server
|
|
4
|
-
*
|
|
5
|
-
* Exposes hiai-docs operations as MCP tools via the stdio transport.
|
|
6
|
-
*
|
|
7
|
-
* Environment:
|
|
8
|
-
* HIAI_DOCS_URL — base URL of the hiai-docs API
|
|
9
|
-
* (default: http://localhost:50700)
|
|
10
|
-
* HIAI_DOCS_API_KEY — bearer token used for Authorization header
|
|
11
|
-
*/
|
|
2
|
+
/** DocsMint MCP stdio entry point. */
|
|
12
3
|
|
|
13
|
-
import {
|
|
14
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
15
|
-
import { HiaiDocsError } from "./client.js";
|
|
16
|
-
import type { ZodRawShape } from "zod";
|
|
4
|
+
import { serveStdio } from '@modelcontextprotocol/server/stdio';
|
|
17
5
|
|
|
18
|
-
import
|
|
19
|
-
import * as getDocument from "./tools/get-document.js";
|
|
20
|
-
import * as createDocument from "./tools/create-document.js";
|
|
21
|
-
import * as updateDocument from "./tools/update-document.js";
|
|
22
|
-
import * as listDocuments from "./tools/list-documents.js";
|
|
23
|
-
import * as listFolders from "./tools/list-folders.js";
|
|
24
|
-
import * as createFolder from "./tools/create-folder.js";
|
|
25
|
-
import * as createSnapshot from "./tools/create-snapshot.js";
|
|
26
|
-
import * as versionHistory from "./tools/version-history.js";
|
|
27
|
-
import * as exportDocument from "./tools/export-document.js";
|
|
6
|
+
import { createDocsmintMcpServer } from './server.js';
|
|
28
7
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
interface McpToolResult {
|
|
32
|
-
content: Array<{ type: "text"; text: string }>;
|
|
33
|
-
isError?: boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const server = new McpServer({
|
|
37
|
-
name: "hiai-docs",
|
|
38
|
-
version: "0.6.0",
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Wraps a tool handler to convert errors into MCP-formatted responses.
|
|
43
|
-
* The SDK's tool callback returns CallToolResult; we return either success
|
|
44
|
-
* with JSON-stringified content or an error with `isError: true`.
|
|
45
|
-
*/
|
|
46
|
-
function wrapHandler(
|
|
47
|
-
name: string,
|
|
48
|
-
handler: ToolHandler,
|
|
49
|
-
): (args: Record<string, unknown>) => Promise<McpToolResult> {
|
|
50
|
-
return async (args) => {
|
|
51
|
-
try {
|
|
52
|
-
const result = await handler(args);
|
|
53
|
-
return {
|
|
54
|
-
content: [
|
|
55
|
-
{
|
|
56
|
-
type: "text" as const,
|
|
57
|
-
text: JSON.stringify(result, null, 2),
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
};
|
|
61
|
-
} catch (err) {
|
|
62
|
-
if (err instanceof HiaiDocsError) {
|
|
63
|
-
return {
|
|
64
|
-
isError: true,
|
|
65
|
-
content: [
|
|
66
|
-
{
|
|
67
|
-
type: "text" as const,
|
|
68
|
-
text: `hiai-docs API error (${err.status}): ${err.message}`,
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
74
|
-
return {
|
|
75
|
-
isError: true,
|
|
76
|
-
content: [
|
|
77
|
-
{
|
|
78
|
-
type: "text" as const,
|
|
79
|
-
text: `Tool '${name}' failed: ${message}`,
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function register<Args>(
|
|
88
|
-
name: string,
|
|
89
|
-
description: string,
|
|
90
|
-
inputSchema: ZodRawShape,
|
|
91
|
-
handler: (args: Args) => Promise<unknown>,
|
|
92
|
-
): void {
|
|
93
|
-
server.tool(name, description, inputSchema as never, wrapHandler(name, handler as ToolHandler) as never);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
register(search.definition.name, search.definition.description, search.definition.inputSchema as ZodRawShape, search.handler);
|
|
97
|
-
register(getDocument.definition.name, getDocument.definition.description, getDocument.definition.inputSchema as ZodRawShape, getDocument.handler);
|
|
98
|
-
register(createDocument.definition.name, createDocument.definition.description, createDocument.definition.inputSchema as ZodRawShape, createDocument.handler);
|
|
99
|
-
register(updateDocument.definition.name, updateDocument.definition.description, updateDocument.definition.inputSchema as ZodRawShape, updateDocument.handler);
|
|
100
|
-
register(listDocuments.definition.name, listDocuments.definition.description, listDocuments.definition.inputSchema as ZodRawShape, listDocuments.handler);
|
|
101
|
-
register(listFolders.definition.name, listFolders.definition.description, listFolders.definition.inputSchema as ZodRawShape, listFolders.handler);
|
|
102
|
-
register(createFolder.definition.name, createFolder.definition.description, createFolder.definition.inputSchema as ZodRawShape, createFolder.handler);
|
|
103
|
-
register(createSnapshot.definition.name, createSnapshot.definition.description, createSnapshot.definition.inputSchema as ZodRawShape, createSnapshot.handler);
|
|
104
|
-
register(versionHistory.definition.name, versionHistory.definition.description, versionHistory.definition.inputSchema as ZodRawShape, versionHistory.handler);
|
|
105
|
-
register(exportDocument.definition.name, exportDocument.definition.description, exportDocument.definition.inputSchema as ZodRawShape, exportDocument.handler);
|
|
106
|
-
|
|
107
|
-
const transport = new StdioServerTransport();
|
|
108
|
-
|
|
109
|
-
await server.connect(transport);
|
|
8
|
+
serveStdio(() => createDocsmintMcpServer());
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
+
import { z, type ZodRawShape } from 'zod';
|
|
3
|
+
|
|
4
|
+
import { registerExtendedCapabilities } from './capabilities.js';
|
|
5
|
+
import { client as defaultClient, HiaiDocsError, type HiaiDocsClient } from './client.js';
|
|
6
|
+
import * as createDocument from './tools/create-document.js';
|
|
7
|
+
import * as createFolder from './tools/create-folder.js';
|
|
8
|
+
import * as createSnapshot from './tools/create-snapshot.js';
|
|
9
|
+
import * as exportDocument from './tools/export-document.js';
|
|
10
|
+
import * as getDocument from './tools/get-document.js';
|
|
11
|
+
import * as listDocuments from './tools/list-documents.js';
|
|
12
|
+
import * as listFolders from './tools/list-folders.js';
|
|
13
|
+
import * as search from './tools/search.js';
|
|
14
|
+
import * as updateDocument from './tools/update-document.js';
|
|
15
|
+
import * as versionHistory from './tools/version-history.js';
|
|
16
|
+
|
|
17
|
+
type ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;
|
|
18
|
+
interface McpToolResult {
|
|
19
|
+
content: Array<{ type: 'text'; text: string }>;
|
|
20
|
+
isError?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function wrapHandler(
|
|
24
|
+
name: string,
|
|
25
|
+
handler: ToolHandler
|
|
26
|
+
): (args: Record<string, unknown>) => Promise<McpToolResult> {
|
|
27
|
+
return async (args) => {
|
|
28
|
+
try {
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: 'text', text: JSON.stringify(await handler(args), null, 2) }],
|
|
31
|
+
};
|
|
32
|
+
} catch (error) {
|
|
33
|
+
const message =
|
|
34
|
+
error instanceof HiaiDocsError
|
|
35
|
+
? `DocsMint API error (${error.status}): ${error.message}`
|
|
36
|
+
: `Tool '${name}' failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
37
|
+
return { isError: true, content: [{ type: 'text', text: message }] };
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function registerDocsmintMcpCapabilities(server: McpServer, client: HiaiDocsClient): void {
|
|
43
|
+
const register = <Args>(
|
|
44
|
+
name: string,
|
|
45
|
+
description: string,
|
|
46
|
+
inputSchema: ZodRawShape,
|
|
47
|
+
handler: (args: Args) => Promise<unknown>
|
|
48
|
+
): void => {
|
|
49
|
+
server.registerTool(
|
|
50
|
+
name,
|
|
51
|
+
{ description, inputSchema: z.object(inputSchema) },
|
|
52
|
+
wrapHandler(name, handler as ToolHandler) as never
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const tools = [
|
|
57
|
+
search,
|
|
58
|
+
getDocument,
|
|
59
|
+
createDocument,
|
|
60
|
+
updateDocument,
|
|
61
|
+
listDocuments,
|
|
62
|
+
listFolders,
|
|
63
|
+
createFolder,
|
|
64
|
+
createSnapshot,
|
|
65
|
+
versionHistory,
|
|
66
|
+
exportDocument,
|
|
67
|
+
] as const;
|
|
68
|
+
for (const tool of tools) {
|
|
69
|
+
register(
|
|
70
|
+
tool.definition.name,
|
|
71
|
+
tool.definition.description,
|
|
72
|
+
tool.definition.inputSchema as ZodRawShape,
|
|
73
|
+
tool.createHandler(client) as ToolHandler
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
registerExtendedCapabilities(server, client);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface CreateDocsmintMcpServerOptions {
|
|
80
|
+
client?: HiaiDocsClient;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function createDocsmintMcpServer(options: CreateDocsmintMcpServerOptions = {}): McpServer {
|
|
84
|
+
const server = new McpServer({ name: 'docsmint', version: '0.6.2' });
|
|
85
|
+
registerDocsmintMcpCapabilities(server, options.client ?? defaultClient);
|
|
86
|
+
return server;
|
|
87
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { client } from
|
|
3
|
-
import type { DocumentDetail } from
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { client, type HiaiDocsClient } from '../client.js';
|
|
3
|
+
import type { DocumentDetail } from '../types.js';
|
|
4
4
|
|
|
5
5
|
export const definition = {
|
|
6
|
-
name:
|
|
6
|
+
name: 'create_document',
|
|
7
7
|
description:
|
|
8
|
-
|
|
8
|
+
'Create a new document. Optionally provide initial markdown content and a folder ID.',
|
|
9
9
|
inputSchema: {
|
|
10
|
-
title: z.string().describe(
|
|
11
|
-
content: z
|
|
10
|
+
title: z.string().describe('Document title.'),
|
|
11
|
+
content: z.string().optional().describe('Initial markdown content for the document.'),
|
|
12
|
+
folderId: z.string().optional().describe('Optional folder ID to place the document in.'),
|
|
13
|
+
categoryId: z
|
|
12
14
|
.string()
|
|
13
15
|
.optional()
|
|
14
|
-
.describe(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.optional()
|
|
18
|
-
.describe("Optional folder ID to place the document in."),
|
|
16
|
+
.describe(
|
|
17
|
+
'Optional category ID. Category keys are always rebound to their configured category.'
|
|
18
|
+
),
|
|
19
19
|
},
|
|
20
20
|
} as const;
|
|
21
21
|
|
|
@@ -23,10 +23,12 @@ export interface CreateDocumentArgs {
|
|
|
23
23
|
title: string;
|
|
24
24
|
content?: string;
|
|
25
25
|
folderId?: string;
|
|
26
|
+
categoryId?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
export
|
|
29
|
-
args: CreateDocumentArgs
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
export const createHandler = (api: HiaiDocsClient) =>
|
|
30
|
+
async function createDocument(args: CreateDocumentArgs): Promise<DocumentDetail> {
|
|
31
|
+
return (await api.createDocument(args)) as DocumentDetail;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const handler = createHandler(client);
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { client } from
|
|
3
|
-
import type { Folder } from
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { client, type HiaiDocsClient } from '../client.js';
|
|
3
|
+
import type { Folder } from '../types.js';
|
|
4
4
|
|
|
5
5
|
export const definition = {
|
|
6
|
-
name:
|
|
7
|
-
description:
|
|
6
|
+
name: 'create_folder',
|
|
7
|
+
description: 'Create a new folder, optionally nested under a parent folder.',
|
|
8
8
|
inputSchema: {
|
|
9
|
-
name: z.string().describe(
|
|
10
|
-
parentId: z
|
|
9
|
+
name: z.string().describe('Folder name.'),
|
|
10
|
+
parentId: z.string().optional().describe('Optional parent folder ID for nesting.'),
|
|
11
|
+
categoryId: z
|
|
11
12
|
.string()
|
|
12
13
|
.optional()
|
|
13
|
-
.describe(
|
|
14
|
+
.describe(
|
|
15
|
+
'Optional category ID. Category keys are always rebound to their configured category.'
|
|
16
|
+
),
|
|
14
17
|
},
|
|
15
18
|
} as const;
|
|
16
19
|
|
|
17
20
|
export interface CreateFolderArgs {
|
|
18
21
|
name: string;
|
|
19
22
|
parentId?: string;
|
|
23
|
+
categoryId?: string;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
export const createHandler = (api: HiaiDocsClient) =>
|
|
27
|
+
async function createFolder(args: CreateFolderArgs): Promise<Folder> {
|
|
28
|
+
return (await api.createFolder(args)) as Folder;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const handler = createHandler(client);
|