mcp-docs-service 0.5.2 → 7.1.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 +1 -17
- package/dist/handlers/documents.js +484 -411
- package/dist/handlers/health.js +7 -7
- package/dist/index.js +298 -155
- package/dist/schemas/tools.js +0 -1
- package/package.json +5 -2
- package/dist/index.d.ts +0 -8
- package/dist/index.js.map +0 -1
package/dist/handlers/health.js
CHANGED
@@ -24,8 +24,8 @@ export class HealthCheckHandler {
|
|
24
24
|
async checkDocumentationHealth(basePath = "", options) {
|
25
25
|
try {
|
26
26
|
// Always use tolerance mode by default
|
27
|
-
const toleranceMode =
|
28
|
-
safeLog(`Checking documentation health with tolerance mode
|
27
|
+
const toleranceMode = true;
|
28
|
+
safeLog(`Checking documentation health with tolerance mode enabled by default`);
|
29
29
|
// Get the full path to the docs directory
|
30
30
|
const docsPath = path.join(this.docsDir, basePath);
|
31
31
|
// Check if the directory exists
|
@@ -231,7 +231,7 @@ ${results.issues
|
|
231
231
|
// Deduct up to 30 points based on metadata completeness
|
232
232
|
const metadataDeduction = Math.round((30 * (100 - metadataCompleteness)) / 100);
|
233
233
|
score -= toleranceMode
|
234
|
-
? Math.min(metadataDeduction,
|
234
|
+
? Math.min(metadataDeduction, 15)
|
235
235
|
: metadataDeduction;
|
236
236
|
}
|
237
237
|
// Deduct points for broken links
|
@@ -239,7 +239,7 @@ ${results.issues
|
|
239
239
|
// Deduct 2 points per broken link, up to 20 points
|
240
240
|
const brokenLinksDeduction = Math.min(results.brokenLinks * 2, 20);
|
241
241
|
score -= toleranceMode
|
242
|
-
? Math.min(brokenLinksDeduction,
|
242
|
+
? Math.min(brokenLinksDeduction, 10)
|
243
243
|
: brokenLinksDeduction;
|
244
244
|
}
|
245
245
|
// Deduct points for orphaned documents
|
@@ -258,9 +258,9 @@ ${results.issues
|
|
258
258
|
? Math.min(missingRefsDeduction, 0)
|
259
259
|
: missingRefsDeduction;
|
260
260
|
}
|
261
|
-
// In tolerance mode, ensure a minimum score of
|
262
|
-
if (toleranceMode && score <
|
263
|
-
score =
|
261
|
+
// In tolerance mode, ensure a minimum score of 70
|
262
|
+
if (toleranceMode && score < 70) {
|
263
|
+
score = 70;
|
264
264
|
}
|
265
265
|
return Math.max(0, score);
|
266
266
|
}
|
package/dist/index.js
CHANGED
@@ -16,12 +16,15 @@ import { safeLog, normalizePath } from "./utils/index.js";
|
|
16
16
|
// Import schemas
|
17
17
|
import { ReadDocumentSchema, WriteDocumentSchema, EditDocumentSchema, ListDocumentsSchema, SearchDocumentsSchema, CheckDocumentationHealthSchema, CreateFolderSchema, MoveDocumentSchema, RenameDocumentSchema, UpdateNavigationOrderSchema, CreateSectionSchema, ValidateLinksSchema, ValidateMetadataSchema, } from "./schemas/index.js";
|
18
18
|
// Import handlers
|
19
|
-
import {
|
19
|
+
import { NavigationHandler, HealthCheckHandler } from "./handlers/index.js";
|
20
|
+
// Import our document handler
|
21
|
+
import { DocumentHandler } from "./handlers/documents.js";
|
20
22
|
// Command line argument parsing
|
21
23
|
const args = process.argv.slice(2);
|
22
24
|
let docsDir = path.join(process.cwd(), "docs");
|
23
25
|
let createDir = false;
|
24
26
|
let runHealthCheck = false;
|
27
|
+
let useSingleDoc = false;
|
25
28
|
// Parse arguments
|
26
29
|
for (let i = 0; i < args.length; i++) {
|
27
30
|
if (args[i] === "--docs-dir" && i + 1 < args.length) {
|
@@ -34,12 +37,25 @@ for (let i = 0; i < args.length; i++) {
|
|
34
37
|
else if (args[i] === "--health-check") {
|
35
38
|
runHealthCheck = true;
|
36
39
|
}
|
40
|
+
else if (args[i] === "--single-doc") {
|
41
|
+
useSingleDoc = true;
|
42
|
+
}
|
37
43
|
else if (!args[i].startsWith("--")) {
|
38
44
|
docsDir = path.resolve(args[i]);
|
39
45
|
}
|
40
46
|
}
|
41
47
|
// Normalize path
|
42
48
|
docsDir = normalizePath(docsDir);
|
49
|
+
// Helper function to check if a file exists
|
50
|
+
async function fileExists(filePath) {
|
51
|
+
try {
|
52
|
+
await fs.access(filePath);
|
53
|
+
return true;
|
54
|
+
}
|
55
|
+
catch {
|
56
|
+
return false;
|
57
|
+
}
|
58
|
+
}
|
43
59
|
// Ensure docs directory exists
|
44
60
|
async function ensureDocsDirectory() {
|
45
61
|
try {
|
@@ -50,12 +66,12 @@ async function ensureDocsDirectory() {
|
|
50
66
|
}
|
51
67
|
}
|
52
68
|
catch (error) {
|
53
|
-
// Create directory if it doesn't exist
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
69
|
+
// Create directory if it doesn't exist and --create-dir is specified
|
70
|
+
if (createDir) {
|
71
|
+
try {
|
72
|
+
await fs.mkdir(docsDir, { recursive: true });
|
73
|
+
safeLog(`Created docs directory: ${docsDir}`);
|
74
|
+
// Create a sample README.md
|
59
75
|
const readmePath = path.join(docsDir, "README.md");
|
60
76
|
try {
|
61
77
|
await fs.access(readmePath);
|
@@ -74,16 +90,20 @@ This is the documentation directory for your project.
|
|
74
90
|
safeLog(`Created sample README.md in ${docsDir}`);
|
75
91
|
}
|
76
92
|
}
|
77
|
-
|
93
|
+
catch (error) {
|
94
|
+
safeLog(`Error creating docs directory: ${error}`);
|
95
|
+
process.exit(1);
|
96
|
+
}
|
78
97
|
}
|
79
|
-
|
80
|
-
safeLog(`Error
|
98
|
+
else {
|
99
|
+
safeLog(`Error: Docs directory does not exist: ${docsDir}`);
|
100
|
+
safeLog(`Use --create-dir to create it automatically`);
|
81
101
|
process.exit(1);
|
82
102
|
}
|
83
103
|
}
|
84
104
|
}
|
85
|
-
//
|
86
|
-
const documentHandler = new DocumentHandler(docsDir);
|
105
|
+
// Create handlers
|
106
|
+
const documentHandler = new DocumentHandler(docsDir, useSingleDoc);
|
87
107
|
const navigationHandler = new NavigationHandler(docsDir);
|
88
108
|
const healthCheckHandler = new HealthCheckHandler(docsDir);
|
89
109
|
// Server setup
|
@@ -97,99 +117,225 @@ const server = new Server({
|
|
97
117
|
});
|
98
118
|
// Tool handlers
|
99
119
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
120
|
+
if (useSingleDoc) {
|
121
|
+
return {
|
122
|
+
tools: [
|
123
|
+
{
|
124
|
+
name: "read_document",
|
125
|
+
description: "Read a markdown document from the docs directory. Returns the document content " +
|
126
|
+
"including frontmatter. In single-doc mode, this will always return the consolidated document.",
|
127
|
+
inputSchema: zodToJsonSchema(ReadDocumentSchema),
|
128
|
+
},
|
129
|
+
{
|
130
|
+
name: "write_document",
|
131
|
+
description: "Create a new markdown document or completely overwrite an existing document with new content. " +
|
132
|
+
"In single-doc mode, this will automatically update the consolidated document.",
|
133
|
+
inputSchema: zodToJsonSchema(WriteDocumentSchema),
|
134
|
+
},
|
135
|
+
{
|
136
|
+
name: "generate_llms_doc",
|
137
|
+
description: "Generate a single comprehensive document optimized for LLMs by compiling content from all " +
|
138
|
+
"markdown documents in the docs directory. This creates or refreshes the single_doc.md file.",
|
139
|
+
inputSchema: { type: "object", properties: {} },
|
140
|
+
},
|
141
|
+
{
|
142
|
+
name: "interactive_template",
|
143
|
+
description: "Interactively prompts the human user for information to fill in a document template. " +
|
144
|
+
"Useful for creating standardized documentation with user input.",
|
145
|
+
inputSchema: {
|
146
|
+
type: "object",
|
147
|
+
properties: {
|
148
|
+
template_type: {
|
149
|
+
type: "string",
|
150
|
+
description: "The type of template to use (feature, api, guide, etc.)",
|
151
|
+
},
|
152
|
+
output_path: {
|
153
|
+
type: "string",
|
154
|
+
description: "The path where the generated document should be saved",
|
155
|
+
},
|
156
|
+
},
|
157
|
+
required: ["template_type", "output_path"],
|
158
|
+
},
|
159
|
+
},
|
160
|
+
],
|
161
|
+
};
|
162
|
+
}
|
163
|
+
else {
|
164
|
+
return {
|
165
|
+
tools: [
|
166
|
+
{
|
167
|
+
name: "read_document",
|
168
|
+
description: "Read a markdown document from the docs directory. Returns the document content " +
|
169
|
+
"including frontmatter. Use this tool when you need to examine the contents of a " +
|
170
|
+
"single document.",
|
171
|
+
inputSchema: zodToJsonSchema(ReadDocumentSchema),
|
172
|
+
},
|
173
|
+
{
|
174
|
+
name: "write_document",
|
175
|
+
description: "Create a new markdown document or completely overwrite an existing document with new content. " +
|
176
|
+
"Use with caution as it will overwrite existing documents without warning. " +
|
177
|
+
"Can create parent directories if they don't exist.",
|
178
|
+
inputSchema: zodToJsonSchema(WriteDocumentSchema),
|
179
|
+
},
|
180
|
+
{
|
181
|
+
name: "edit_document",
|
182
|
+
description: "Make line-based edits to a markdown document. Each edit replaces exact line sequences " +
|
183
|
+
"with new content. Returns a git-style diff showing the changes made.",
|
184
|
+
inputSchema: zodToJsonSchema(EditDocumentSchema),
|
185
|
+
},
|
186
|
+
{
|
187
|
+
name: "list_documents",
|
188
|
+
description: "List all markdown documents in the docs directory or a subdirectory. " +
|
189
|
+
"Returns the relative paths to all documents.",
|
190
|
+
inputSchema: zodToJsonSchema(ListDocumentsSchema),
|
191
|
+
},
|
192
|
+
{
|
193
|
+
name: "search_documents",
|
194
|
+
description: "Search for markdown documents containing specific text in their content or frontmatter. " +
|
195
|
+
"Returns the relative paths to matching documents.",
|
196
|
+
inputSchema: zodToJsonSchema(SearchDocumentsSchema),
|
197
|
+
},
|
198
|
+
{
|
199
|
+
name: "generate_documentation_navigation",
|
200
|
+
description: "Generate a navigation structure from the markdown documents in the docs directory. " +
|
201
|
+
"Returns a JSON structure that can be used for navigation menus.",
|
202
|
+
inputSchema: zodToJsonSchema(ListDocumentsSchema),
|
203
|
+
},
|
204
|
+
{
|
205
|
+
name: "check_documentation_health",
|
206
|
+
description: "Check the health of the documentation by analyzing frontmatter, links, and navigation. " +
|
207
|
+
"Returns a report with issues and a health score.",
|
208
|
+
inputSchema: zodToJsonSchema(CheckDocumentationHealthSchema),
|
209
|
+
},
|
210
|
+
// New tools for Phase 2
|
211
|
+
{
|
212
|
+
name: "create_folder",
|
213
|
+
description: "Create a new folder in the docs directory. Optionally creates a README.md file " +
|
214
|
+
"in the new folder with basic frontmatter.",
|
215
|
+
inputSchema: zodToJsonSchema(CreateFolderSchema),
|
216
|
+
},
|
217
|
+
{
|
218
|
+
name: "move_document",
|
219
|
+
description: "Move a document from one location to another. Optionally updates references to the " +
|
220
|
+
"document in other files.",
|
221
|
+
inputSchema: zodToJsonSchema(MoveDocumentSchema),
|
222
|
+
},
|
223
|
+
{
|
224
|
+
name: "rename_document",
|
225
|
+
description: "Rename a document while preserving its location and content. Optionally updates " +
|
226
|
+
"references to the document in other files.",
|
227
|
+
inputSchema: zodToJsonSchema(RenameDocumentSchema),
|
228
|
+
},
|
229
|
+
{
|
230
|
+
name: "update_navigation_order",
|
231
|
+
description: "Update the navigation order of a document by modifying its frontmatter.",
|
232
|
+
inputSchema: zodToJsonSchema(UpdateNavigationOrderSchema),
|
233
|
+
},
|
234
|
+
{
|
235
|
+
name: "create_documentation_section",
|
236
|
+
description: "Create a new navigation section with an index.md file.",
|
237
|
+
inputSchema: zodToJsonSchema(CreateSectionSchema),
|
238
|
+
},
|
239
|
+
// New tools for Phase 3
|
240
|
+
{
|
241
|
+
name: "validate_documentation_links",
|
242
|
+
description: "Check for broken internal links in documentation files.",
|
243
|
+
inputSchema: zodToJsonSchema(ValidateLinksSchema),
|
244
|
+
},
|
245
|
+
{
|
246
|
+
name: "validate_documentation_metadata",
|
247
|
+
description: "Ensure all documents have required metadata fields.",
|
248
|
+
inputSchema: zodToJsonSchema(ValidateMetadataSchema),
|
249
|
+
},
|
250
|
+
],
|
251
|
+
};
|
252
|
+
}
|
189
253
|
});
|
190
254
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
191
255
|
try {
|
192
256
|
const { name, arguments: args } = request.params;
|
257
|
+
// Handle form responses
|
258
|
+
if (request.params._meta?.formResponse && request.params._meta?.metadata) {
|
259
|
+
const formResponse = request.params._meta.formResponse;
|
260
|
+
const metadata = request.params._meta.metadata;
|
261
|
+
if (metadata.template_type) {
|
262
|
+
const templateType = metadata.template_type;
|
263
|
+
const outputPath = metadata.output_path;
|
264
|
+
// Format tags from comma-separated string
|
265
|
+
const tags = formResponse.tags?.split(",").map((tag) => tag.trim()) || [];
|
266
|
+
// Create frontmatter
|
267
|
+
const frontmatter = {
|
268
|
+
title: formResponse.title || "Untitled",
|
269
|
+
description: formResponse.description || "",
|
270
|
+
author: formResponse.author || "Unknown",
|
271
|
+
tags,
|
272
|
+
status: formResponse.status || "draft",
|
273
|
+
date: new Date().toISOString(),
|
274
|
+
version: "1.0.0",
|
275
|
+
};
|
276
|
+
// Create document content based on template type
|
277
|
+
let content = `# ${formResponse.title || "Untitled"}\n\n${formResponse.description || ""}\n\n`;
|
278
|
+
if (templateType === "feature") {
|
279
|
+
content += `## Usage\n\nDescribe how to use this feature.\n\n`;
|
280
|
+
content += `## Examples\n\nProvide examples of how to use this feature.\n\n`;
|
281
|
+
content += `## Configuration\n\nDescribe any configuration options.\n\n`;
|
282
|
+
}
|
283
|
+
else if (templateType === "api") {
|
284
|
+
content += `## Endpoint\n\n\`\`\`\n/api/path\n\`\`\`\n\n`;
|
285
|
+
}
|
286
|
+
// Format frontmatter
|
287
|
+
const frontmatterYaml = `---\n${Object.entries(frontmatter)
|
288
|
+
.map(([key, value]) => {
|
289
|
+
if (Array.isArray(value)) {
|
290
|
+
return `${key}:\n${value
|
291
|
+
.map((item) => ` - ${item}`)
|
292
|
+
.join("\n")}`;
|
293
|
+
}
|
294
|
+
return `${key}: ${typeof value === "string" ? `"${value}"` : value}`;
|
295
|
+
})
|
296
|
+
.join("\n")}\n---\n\n`;
|
297
|
+
// Create full document
|
298
|
+
const fullContent = frontmatterYaml + content;
|
299
|
+
// Write the document
|
300
|
+
const docPath = path.join(docsDir, outputPath);
|
301
|
+
const dirPath = path.dirname(docPath);
|
302
|
+
try {
|
303
|
+
await fs.mkdir(dirPath, { recursive: true });
|
304
|
+
await fs.writeFile(docPath, fullContent, "utf-8");
|
305
|
+
// If in single-doc mode, regenerate the single doc
|
306
|
+
if (useSingleDoc) {
|
307
|
+
const singleDocPath = path.join(docsDir, "single_doc.md");
|
308
|
+
if (await fileExists(singleDocPath)) {
|
309
|
+
// Regenerate the single doc by calling refresh
|
310
|
+
await documentHandler.refreshSingleDoc();
|
311
|
+
}
|
312
|
+
}
|
313
|
+
return {
|
314
|
+
content: [
|
315
|
+
{
|
316
|
+
type: "text",
|
317
|
+
text: `Successfully created document at ${outputPath}`,
|
318
|
+
},
|
319
|
+
],
|
320
|
+
metadata: {
|
321
|
+
path: outputPath,
|
322
|
+
},
|
323
|
+
};
|
324
|
+
}
|
325
|
+
catch (error) {
|
326
|
+
return {
|
327
|
+
content: [
|
328
|
+
{
|
329
|
+
type: "text",
|
330
|
+
text: `Error creating document: ${error.message || String(error)}`,
|
331
|
+
},
|
332
|
+
],
|
333
|
+
isError: true,
|
334
|
+
};
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
// Handle regular tool calls
|
193
339
|
switch (name) {
|
194
340
|
case "read_document": {
|
195
341
|
const parsed = ReadDocumentSchema.safeParse(args);
|
@@ -238,97 +384,94 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
238
384
|
if (!parsed.success) {
|
239
385
|
throw new Error(`Invalid arguments for check_documentation_health: ${parsed.error}`);
|
240
386
|
}
|
241
|
-
return await healthCheckHandler.checkDocumentationHealth(parsed.data.basePath
|
387
|
+
return await healthCheckHandler.checkDocumentationHealth(parsed.data.basePath);
|
242
388
|
}
|
243
389
|
// New tools for Phase 2
|
244
|
-
case "
|
390
|
+
case "create_folder": {
|
245
391
|
const parsed = CreateFolderSchema.safeParse(args);
|
246
392
|
if (!parsed.success) {
|
247
393
|
throw new Error(`Invalid arguments for create_folder: ${parsed.error}`);
|
248
394
|
}
|
249
|
-
|
395
|
+
throw new Error("Method not implemented");
|
250
396
|
}
|
251
|
-
case "
|
397
|
+
case "move_document": {
|
252
398
|
const parsed = MoveDocumentSchema.safeParse(args);
|
253
399
|
if (!parsed.success) {
|
254
400
|
throw new Error(`Invalid arguments for move_document: ${parsed.error}`);
|
255
401
|
}
|
256
|
-
|
402
|
+
throw new Error("Method not implemented");
|
257
403
|
}
|
258
|
-
case "
|
404
|
+
case "rename_document": {
|
259
405
|
const parsed = RenameDocumentSchema.safeParse(args);
|
260
406
|
if (!parsed.success) {
|
261
407
|
throw new Error(`Invalid arguments for rename_document: ${parsed.error}`);
|
262
408
|
}
|
263
|
-
|
409
|
+
throw new Error("Method not implemented");
|
264
410
|
}
|
265
|
-
case "
|
411
|
+
case "update_navigation_order": {
|
266
412
|
const parsed = UpdateNavigationOrderSchema.safeParse(args);
|
267
413
|
if (!parsed.success) {
|
268
414
|
throw new Error(`Invalid arguments for update_navigation_order: ${parsed.error}`);
|
269
415
|
}
|
270
|
-
|
416
|
+
throw new Error("Method not implemented");
|
271
417
|
}
|
272
|
-
case "
|
273
|
-
|
274
|
-
|
275
|
-
throw new Error(`Invalid arguments for create_section: ${parsed.error}`);
|
276
|
-
}
|
277
|
-
return await documentHandler.createSection(parsed.data.title, parsed.data.path, parsed.data.order);
|
278
|
-
}
|
279
|
-
// New tools for Phase 3
|
280
|
-
case "validate_documentation_links": {
|
281
|
-
const parsed = ValidateLinksSchema.safeParse(args);
|
282
|
-
if (!parsed.success) {
|
283
|
-
throw new Error(`Invalid arguments for validate_links: ${parsed.error}`);
|
418
|
+
case "generate_llms_doc":
|
419
|
+
if (!useSingleDoc) {
|
420
|
+
throw new Error("Single-doc mode is not enabled");
|
284
421
|
}
|
285
|
-
return await documentHandler.
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
if (!parsed.success) {
|
290
|
-
throw new Error(`Invalid arguments for validate_metadata: ${parsed.error}`);
|
422
|
+
return await documentHandler.refreshSingleDoc();
|
423
|
+
case "interactive_template": {
|
424
|
+
if (!args) {
|
425
|
+
throw new Error(`Invalid arguments for interactive_template: args is undefined`);
|
291
426
|
}
|
292
|
-
|
427
|
+
const template_type = args.template_type;
|
428
|
+
const output_path = args.output_path;
|
429
|
+
// Build a form as text content
|
430
|
+
const formText = `# Create ${template_type.charAt(0).toUpperCase() + template_type.slice(1)} Documentation\n\n` +
|
431
|
+
`Please provide the following information to create your ${template_type} documentation at '${output_path}':\n\n` +
|
432
|
+
`- Title: [${template_type.charAt(0).toUpperCase() + template_type.slice(1)} Name]\n` +
|
433
|
+
`- Description: [Description of this ${template_type}]\n` +
|
434
|
+
`- Author: [Documentation Team]\n` +
|
435
|
+
`- Tags (comma separated): [${template_type}]\n` +
|
436
|
+
`- Status: [draft]\n\n` +
|
437
|
+
`Once you provide this information, I'll create the document for you.`;
|
438
|
+
return {
|
439
|
+
content: [{ type: "text", text: formText }],
|
440
|
+
metadata: {
|
441
|
+
template_type,
|
442
|
+
output_path,
|
443
|
+
},
|
444
|
+
};
|
293
445
|
}
|
294
446
|
default:
|
295
447
|
throw new Error(`Unknown tool: ${name}`);
|
296
448
|
}
|
297
449
|
}
|
298
450
|
catch (error) {
|
299
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
300
451
|
return {
|
301
|
-
content: [
|
452
|
+
content: [
|
453
|
+
{ type: "text", text: `Error: ${error.message || String(error)}` },
|
454
|
+
],
|
302
455
|
isError: true,
|
303
456
|
};
|
304
457
|
}
|
305
458
|
});
|
306
|
-
//
|
307
|
-
|
459
|
+
// Start server
|
460
|
+
(async () => {
|
308
461
|
try {
|
309
|
-
|
310
|
-
|
311
|
-
|
462
|
+
await ensureDocsDirectory();
|
463
|
+
const transport = new StdioServerTransport();
|
464
|
+
await server.connect(transport);
|
465
|
+
// The server will be started by the SDK
|
466
|
+
safeLog("MCP Documentation Management Service started.");
|
467
|
+
safeLog("Using docs directory:", docsDir);
|
468
|
+
if (useSingleDoc) {
|
469
|
+
safeLog("Single-doc mode enabled.");
|
470
|
+
}
|
471
|
+
safeLog("Reading from stdin, writing results to stdout...");
|
312
472
|
}
|
313
473
|
catch (error) {
|
314
|
-
safeLog(
|
474
|
+
safeLog("Fatal error running server:", error);
|
315
475
|
process.exit(1);
|
316
476
|
}
|
317
|
-
}
|
318
|
-
else {
|
319
|
-
// Start server
|
320
|
-
(async () => {
|
321
|
-
try {
|
322
|
-
await ensureDocsDirectory();
|
323
|
-
const transport = new StdioServerTransport();
|
324
|
-
await server.connect(transport);
|
325
|
-
safeLog("MCP Documentation Management Service started.");
|
326
|
-
safeLog("Using docs directory:", docsDir);
|
327
|
-
safeLog("Reading from stdin, writing results to stdout...");
|
328
|
-
}
|
329
|
-
catch (error) {
|
330
|
-
safeLog("Fatal error running server:", error);
|
331
|
-
process.exit(1);
|
332
|
-
}
|
333
|
-
})();
|
334
|
-
}
|
477
|
+
})();
|
package/dist/schemas/tools.js
CHANGED
@@ -44,7 +44,6 @@ export const SearchDocumentsSchema = ToolInputSchema.extend({
|
|
44
44
|
});
|
45
45
|
export const CheckDocumentationHealthSchema = ToolInputSchema.extend({
|
46
46
|
basePath: z.string().optional().default(""),
|
47
|
-
toleranceMode: z.boolean().optional().default(true),
|
48
47
|
});
|
49
48
|
// New schemas for Phase 2 features
|
50
49
|
export const CreateFolderSchema = ToolInputSchema.extend({
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "mcp-docs-service",
|
3
|
-
"version": "
|
3
|
+
"version": "7.1.0",
|
4
4
|
"description": "MCP Documentation Service - A Model Context Protocol implementation for documentation management",
|
5
5
|
"type": "module",
|
6
6
|
"main": "dist/index.js",
|
@@ -20,8 +20,11 @@
|
|
20
20
|
"test": "vitest run",
|
21
21
|
"test:watch": "vitest",
|
22
22
|
"test:coverage": "vitest run --coverage",
|
23
|
+
"test:integration": "node tests/integration/test-single-doc.js",
|
24
|
+
"test:clients": "node tests/clients/test-all-tools.js",
|
23
25
|
"prepublishOnly": "npm run build",
|
24
|
-
"prepare-publish": "node scripts/prepare-publish.js"
|
26
|
+
"prepare-publish": "node scripts/prepare-publish.js",
|
27
|
+
"clean": "rm -rf dist coverage temp-publish"
|
25
28
|
},
|
26
29
|
"keywords": [
|
27
30
|
"mcp",
|