mcp-docs-service 0.3.10 → 0.4.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/dist/cli/bin.d.ts +8 -0
- package/dist/cli/bin.js +133 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/handlers/docs.d.ts +26 -0
- package/dist/handlers/docs.js +513 -0
- package/dist/handlers/docs.js.map +1 -0
- package/dist/handlers/documents.js +282 -0
- package/dist/handlers/file.d.ts +32 -0
- package/dist/handlers/file.js +222 -0
- package/dist/handlers/file.js.map +1 -0
- package/dist/handlers/health.js +196 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +8 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/navigation.js +128 -0
- package/dist/index.js +107 -549
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/tools.d.ts +164 -0
- package/dist/schemas/tools.js +47 -0
- package/dist/schemas/tools.js.map +1 -0
- package/dist/types/docs.d.ts +74 -0
- package/dist/types/docs.js +1 -0
- package/dist/types/docs.js.map +1 -0
- package/dist/types/file.d.ts +21 -0
- package/dist/types/file.js +2 -0
- package/dist/types/file.js.map +1 -0
- package/dist/types/index.d.ts +44 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/tools.d.ts +11 -0
- package/dist/types/tools.js +1 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/file.d.ts +24 -0
- package/dist/utils/file.js +94 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logging.js +27 -0
- package/dist/utils/path.d.ts +16 -0
- package/dist/utils/path.js +69 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +4 -8
- package/cursor-wrapper.cjs +0 -111
- package/npx-wrapper.cjs +0 -160
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./tools.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./tools.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,cAAc,YAAY,CAAC"}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const ToolInputSchema: z.ZodObject<{
|
3
|
+
path: z.ZodOptional<z.ZodString>;
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
5
|
+
path?: string | undefined;
|
6
|
+
}, {
|
7
|
+
path?: string | undefined;
|
8
|
+
}>;
|
9
|
+
export declare const ReadDocumentSchema: z.ZodObject<z.objectUtil.extendShape<{
|
10
|
+
path: z.ZodOptional<z.ZodString>;
|
11
|
+
}, {
|
12
|
+
path: z.ZodString;
|
13
|
+
}>, "strip", z.ZodTypeAny, {
|
14
|
+
path: string;
|
15
|
+
}, {
|
16
|
+
path: string;
|
17
|
+
}>;
|
18
|
+
export declare const ListDocumentsSchema: z.ZodObject<z.objectUtil.extendShape<{
|
19
|
+
path: z.ZodOptional<z.ZodString>;
|
20
|
+
}, {
|
21
|
+
basePath: z.ZodOptional<z.ZodString>;
|
22
|
+
}>, "strip", z.ZodTypeAny, {
|
23
|
+
path?: string | undefined;
|
24
|
+
basePath?: string | undefined;
|
25
|
+
}, {
|
26
|
+
path?: string | undefined;
|
27
|
+
basePath?: string | undefined;
|
28
|
+
}>;
|
29
|
+
export declare const GetStructureSchema: z.ZodObject<z.objectUtil.extendShape<{
|
30
|
+
path: z.ZodOptional<z.ZodString>;
|
31
|
+
}, {
|
32
|
+
basePath: z.ZodOptional<z.ZodString>;
|
33
|
+
}>, "strip", z.ZodTypeAny, {
|
34
|
+
path?: string | undefined;
|
35
|
+
basePath?: string | undefined;
|
36
|
+
}, {
|
37
|
+
path?: string | undefined;
|
38
|
+
basePath?: string | undefined;
|
39
|
+
}>;
|
40
|
+
export declare const GetNavigationSchema: z.ZodObject<z.objectUtil.extendShape<{
|
41
|
+
path: z.ZodOptional<z.ZodString>;
|
42
|
+
}, {
|
43
|
+
basePath: z.ZodOptional<z.ZodString>;
|
44
|
+
}>, "strip", z.ZodTypeAny, {
|
45
|
+
path?: string | undefined;
|
46
|
+
basePath?: string | undefined;
|
47
|
+
}, {
|
48
|
+
path?: string | undefined;
|
49
|
+
basePath?: string | undefined;
|
50
|
+
}>;
|
51
|
+
export declare const GetDocsKnowledgeBaseSchema: z.ZodObject<z.objectUtil.extendShape<{
|
52
|
+
path: z.ZodOptional<z.ZodString>;
|
53
|
+
}, {
|
54
|
+
basePath: z.ZodOptional<z.ZodString>;
|
55
|
+
includeSummaries: z.ZodOptional<z.ZodBoolean>;
|
56
|
+
maxSummaryLength: z.ZodOptional<z.ZodNumber>;
|
57
|
+
}>, "strip", z.ZodTypeAny, {
|
58
|
+
path?: string | undefined;
|
59
|
+
basePath?: string | undefined;
|
60
|
+
includeSummaries?: boolean | undefined;
|
61
|
+
maxSummaryLength?: number | undefined;
|
62
|
+
}, {
|
63
|
+
path?: string | undefined;
|
64
|
+
basePath?: string | undefined;
|
65
|
+
includeSummaries?: boolean | undefined;
|
66
|
+
maxSummaryLength?: number | undefined;
|
67
|
+
}>;
|
68
|
+
export declare const WriteDocumentSchema: z.ZodObject<z.objectUtil.extendShape<{
|
69
|
+
path: z.ZodOptional<z.ZodString>;
|
70
|
+
}, {
|
71
|
+
path: z.ZodString;
|
72
|
+
content: z.ZodString;
|
73
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
74
|
+
}>, "strip", z.ZodTypeAny, {
|
75
|
+
content: string;
|
76
|
+
path: string;
|
77
|
+
metadata?: Record<string, any> | undefined;
|
78
|
+
}, {
|
79
|
+
content: string;
|
80
|
+
path: string;
|
81
|
+
metadata?: Record<string, any> | undefined;
|
82
|
+
}>;
|
83
|
+
export declare const EditDocumentSchema: z.ZodObject<z.objectUtil.extendShape<{
|
84
|
+
path: z.ZodOptional<z.ZodString>;
|
85
|
+
}, {
|
86
|
+
path: z.ZodString;
|
87
|
+
edits: z.ZodArray<z.ZodObject<{
|
88
|
+
oldText: z.ZodString;
|
89
|
+
newText: z.ZodString;
|
90
|
+
}, "strip", z.ZodTypeAny, {
|
91
|
+
oldText: string;
|
92
|
+
newText: string;
|
93
|
+
}, {
|
94
|
+
oldText: string;
|
95
|
+
newText: string;
|
96
|
+
}>, "many">;
|
97
|
+
}>, "strip", z.ZodTypeAny, {
|
98
|
+
path: string;
|
99
|
+
edits: {
|
100
|
+
oldText: string;
|
101
|
+
newText: string;
|
102
|
+
}[];
|
103
|
+
}, {
|
104
|
+
path: string;
|
105
|
+
edits: {
|
106
|
+
oldText: string;
|
107
|
+
newText: string;
|
108
|
+
}[];
|
109
|
+
}>;
|
110
|
+
export declare const DeleteDocumentSchema: z.ZodObject<z.objectUtil.extendShape<{
|
111
|
+
path: z.ZodOptional<z.ZodString>;
|
112
|
+
}, {
|
113
|
+
path: z.ZodString;
|
114
|
+
}>, "strip", z.ZodTypeAny, {
|
115
|
+
path: string;
|
116
|
+
}, {
|
117
|
+
path: string;
|
118
|
+
}>;
|
119
|
+
export declare const SearchDocumentsSchema: z.ZodObject<z.objectUtil.extendShape<{
|
120
|
+
path: z.ZodOptional<z.ZodString>;
|
121
|
+
}, {
|
122
|
+
basePath: z.ZodOptional<z.ZodString>;
|
123
|
+
query: z.ZodOptional<z.ZodString>;
|
124
|
+
excludePatterns: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
125
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
126
|
+
status: z.ZodOptional<z.ZodString>;
|
127
|
+
}>, "strip", z.ZodTypeAny, {
|
128
|
+
tags?: string[] | undefined;
|
129
|
+
status?: string | undefined;
|
130
|
+
path?: string | undefined;
|
131
|
+
basePath?: string | undefined;
|
132
|
+
query?: string | undefined;
|
133
|
+
excludePatterns?: string[] | undefined;
|
134
|
+
}, {
|
135
|
+
tags?: string[] | undefined;
|
136
|
+
status?: string | undefined;
|
137
|
+
path?: string | undefined;
|
138
|
+
basePath?: string | undefined;
|
139
|
+
query?: string | undefined;
|
140
|
+
excludePatterns?: string[] | undefined;
|
141
|
+
}>;
|
142
|
+
export declare const CheckDocumentationHealthSchema: z.ZodObject<z.objectUtil.extendShape<{
|
143
|
+
path: z.ZodOptional<z.ZodString>;
|
144
|
+
}, {
|
145
|
+
basePath: z.ZodOptional<z.ZodString>;
|
146
|
+
checkLinks: z.ZodOptional<z.ZodBoolean>;
|
147
|
+
checkMetadata: z.ZodOptional<z.ZodBoolean>;
|
148
|
+
checkOrphans: z.ZodOptional<z.ZodBoolean>;
|
149
|
+
requiredMetadataFields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
150
|
+
}>, "strip", z.ZodTypeAny, {
|
151
|
+
path?: string | undefined;
|
152
|
+
basePath?: string | undefined;
|
153
|
+
checkLinks?: boolean | undefined;
|
154
|
+
checkMetadata?: boolean | undefined;
|
155
|
+
checkOrphans?: boolean | undefined;
|
156
|
+
requiredMetadataFields?: string[] | undefined;
|
157
|
+
}, {
|
158
|
+
path?: string | undefined;
|
159
|
+
basePath?: string | undefined;
|
160
|
+
checkLinks?: boolean | undefined;
|
161
|
+
checkMetadata?: boolean | undefined;
|
162
|
+
checkOrphans?: boolean | undefined;
|
163
|
+
requiredMetadataFields?: string[] | undefined;
|
164
|
+
}>;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
// Base schema for tool inputs
|
3
|
+
export const ToolInputSchema = z.object({
|
4
|
+
path: z.string().optional(),
|
5
|
+
});
|
6
|
+
// Documentation schemas
|
7
|
+
export const ReadDocumentSchema = ToolInputSchema.extend({
|
8
|
+
path: z.string(),
|
9
|
+
});
|
10
|
+
export const ListDocumentsSchema = ToolInputSchema.extend({
|
11
|
+
basePath: z.string().optional(),
|
12
|
+
recursive: z.boolean().default(false),
|
13
|
+
});
|
14
|
+
export const GetStructureSchema = ToolInputSchema.extend({
|
15
|
+
basePath: z.string().optional(),
|
16
|
+
});
|
17
|
+
export const GetNavigationSchema = ToolInputSchema.extend({
|
18
|
+
basePath: z.string().optional(),
|
19
|
+
});
|
20
|
+
export const GetDocsKnowledgeBaseSchema = ToolInputSchema.extend({
|
21
|
+
basePath: z.string().optional(),
|
22
|
+
includeSummaries: z.boolean().optional(),
|
23
|
+
maxSummaryLength: z.number().optional(),
|
24
|
+
});
|
25
|
+
export const WriteDocumentSchema = ToolInputSchema.extend({
|
26
|
+
path: z.string(),
|
27
|
+
content: z.string(),
|
28
|
+
createDirectories: z.boolean().default(true),
|
29
|
+
});
|
30
|
+
export const EditDocumentSchema = ToolInputSchema.extend({
|
31
|
+
path: z.string(),
|
32
|
+
edits: z.array(z.object({
|
33
|
+
oldText: z.string(),
|
34
|
+
newText: z.string(),
|
35
|
+
})),
|
36
|
+
dryRun: z.boolean().default(false),
|
37
|
+
});
|
38
|
+
export const DeleteDocumentSchema = ToolInputSchema.extend({
|
39
|
+
path: z.string(),
|
40
|
+
});
|
41
|
+
export const SearchDocumentsSchema = ToolInputSchema.extend({
|
42
|
+
query: z.string(),
|
43
|
+
basePath: z.string().optional().default(""),
|
44
|
+
});
|
45
|
+
export const CheckDocumentationHealthSchema = ToolInputSchema.extend({
|
46
|
+
basePath: z.string().optional().default(""),
|
47
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/schemas/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8BAA8B;AAC9B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAEH,wBAAwB;AACxB,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC,MAAM,CAAC;IAC/D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,KAAK,CACZ,CAAC,CAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;IACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAC,MAAM,CAAC;IAC1D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,eAAe,CAAC,MAAM,CAAC;IACnE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAClC,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACrC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,sBAAsB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC,CAAC"}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/**
|
2
|
+
* Metadata for documentation files
|
3
|
+
*/
|
4
|
+
export interface DocumentMetadata {
|
5
|
+
title?: string;
|
6
|
+
order?: number;
|
7
|
+
description?: string;
|
8
|
+
author?: string;
|
9
|
+
date?: Date;
|
10
|
+
tags?: string[];
|
11
|
+
status?: string;
|
12
|
+
[key: string]: any;
|
13
|
+
}
|
14
|
+
/**
|
15
|
+
* Entry for a documentation file
|
16
|
+
*/
|
17
|
+
export interface DocumentEntry {
|
18
|
+
path: string;
|
19
|
+
name: string;
|
20
|
+
metadata: DocumentMetadata;
|
21
|
+
}
|
22
|
+
/**
|
23
|
+
* Tree entry for documentation structure
|
24
|
+
*/
|
25
|
+
export interface TreeEntry {
|
26
|
+
name: string;
|
27
|
+
path: string;
|
28
|
+
type: string;
|
29
|
+
metadata?: DocumentMetadata;
|
30
|
+
children: TreeEntry[];
|
31
|
+
error?: string;
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Navigation item for documentation
|
35
|
+
*/
|
36
|
+
export interface NavigationItem {
|
37
|
+
title: string;
|
38
|
+
path: string | null;
|
39
|
+
order: number;
|
40
|
+
items?: NavigationItem[];
|
41
|
+
}
|
42
|
+
/**
|
43
|
+
* Navigation section for documentation
|
44
|
+
*/
|
45
|
+
export interface NavigationSection {
|
46
|
+
title: string;
|
47
|
+
path: string | null;
|
48
|
+
items: NavigationItem[];
|
49
|
+
order: number;
|
50
|
+
}
|
51
|
+
/**
|
52
|
+
* Health issue for documentation
|
53
|
+
*/
|
54
|
+
export interface HealthIssue {
|
55
|
+
path: string;
|
56
|
+
type: "missing_metadata" | "broken_link" | "orphaned" | "missing_reference";
|
57
|
+
severity: "error" | "warning" | "info";
|
58
|
+
message: string;
|
59
|
+
details?: any;
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* Health check result for documentation
|
63
|
+
*/
|
64
|
+
export interface HealthCheckResult {
|
65
|
+
score: number;
|
66
|
+
totalDocuments: number;
|
67
|
+
issues: HealthIssue[];
|
68
|
+
metadataCompleteness: number;
|
69
|
+
brokenLinks: number;
|
70
|
+
orphanedDocuments: number;
|
71
|
+
missingReferences: number;
|
72
|
+
documentsByStatus?: Record<string, number>;
|
73
|
+
documentsByTag?: Record<string, number>;
|
74
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/types/docs.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/**
|
2
|
+
* File information structure
|
3
|
+
*/
|
4
|
+
export interface FileInfo {
|
5
|
+
size: number;
|
6
|
+
created: Date;
|
7
|
+
modified: Date;
|
8
|
+
accessed: Date;
|
9
|
+
isDirectory: boolean;
|
10
|
+
isFile: boolean;
|
11
|
+
permissions: string;
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* Tree entry for directory structure
|
15
|
+
*/
|
16
|
+
export interface FileTreeEntry {
|
17
|
+
name: string;
|
18
|
+
path: string;
|
19
|
+
type: "file" | "directory";
|
20
|
+
children?: FileTreeEntry[];
|
21
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/types/file.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
export interface DocumentMetadata {
|
2
|
+
title?: string;
|
3
|
+
order?: number;
|
4
|
+
description?: string;
|
5
|
+
author?: string;
|
6
|
+
date?: Date;
|
7
|
+
tags?: string[];
|
8
|
+
status?: string;
|
9
|
+
[key: string]: any;
|
10
|
+
}
|
11
|
+
export interface DocumentEntry {
|
12
|
+
path: string;
|
13
|
+
name: string;
|
14
|
+
metadata: DocumentMetadata;
|
15
|
+
}
|
16
|
+
export interface TreeEntry {
|
17
|
+
name: string;
|
18
|
+
path: string;
|
19
|
+
type: string;
|
20
|
+
metadata?: DocumentMetadata;
|
21
|
+
children: TreeEntry[];
|
22
|
+
error?: string;
|
23
|
+
}
|
24
|
+
export interface NavigationItem {
|
25
|
+
title: string;
|
26
|
+
path: string | null;
|
27
|
+
order: number;
|
28
|
+
}
|
29
|
+
export interface NavigationSection {
|
30
|
+
title: string;
|
31
|
+
path: string | null;
|
32
|
+
items: NavigationItem[];
|
33
|
+
order: number;
|
34
|
+
}
|
35
|
+
export type ToolResponse = {
|
36
|
+
content: Array<{
|
37
|
+
type: string;
|
38
|
+
text: string;
|
39
|
+
}>;
|
40
|
+
metadata?: Record<string, any>;
|
41
|
+
isError?: boolean;
|
42
|
+
};
|
43
|
+
export * from "./docs.js";
|
44
|
+
export * from "./tools.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAiDA,+CAA+C;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { FileInfo } from "../types/file.js";
|
2
|
+
/**
|
3
|
+
* Gets file statistics and information
|
4
|
+
*/
|
5
|
+
export declare function getFileStats(filePath: string): Promise<FileInfo>;
|
6
|
+
/**
|
7
|
+
* Searches for files matching a pattern
|
8
|
+
*/
|
9
|
+
export declare function searchFiles(rootPath: string, pattern: string, excludePatterns?: string[]): Promise<string[]>;
|
10
|
+
/**
|
11
|
+
* Normalizes line endings to LF
|
12
|
+
*/
|
13
|
+
export declare function normalizeLineEndings(text: string): string;
|
14
|
+
/**
|
15
|
+
* Creates a unified diff between two text contents
|
16
|
+
*/
|
17
|
+
export declare function createUnifiedDiff(originalContent: string, newContent: string, filepath?: string): string;
|
18
|
+
/**
|
19
|
+
* Applies edits to a file
|
20
|
+
*/
|
21
|
+
export declare function applyFileEdits(filePath: string, edits: Array<{
|
22
|
+
oldText: string;
|
23
|
+
newText: string;
|
24
|
+
}>, dryRun?: boolean): Promise<string>;
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import fs from "fs/promises";
|
2
|
+
import path from "path";
|
3
|
+
import { createTwoFilesPatch } from "diff";
|
4
|
+
import { minimatch } from "minimatch";
|
5
|
+
/**
|
6
|
+
* Gets file statistics and information
|
7
|
+
*/
|
8
|
+
export async function getFileStats(filePath) {
|
9
|
+
const stats = await fs.stat(filePath);
|
10
|
+
// Convert file mode to permission string (e.g., "rwxr-xr-x")
|
11
|
+
const mode = stats.mode;
|
12
|
+
const permissions = [
|
13
|
+
stats.mode & 0o400 ? "r" : "-",
|
14
|
+
stats.mode & 0o200 ? "w" : "-",
|
15
|
+
stats.mode & 0o100 ? "x" : "-",
|
16
|
+
stats.mode & 0o040 ? "r" : "-",
|
17
|
+
stats.mode & 0o020 ? "w" : "-",
|
18
|
+
stats.mode & 0o010 ? "x" : "-",
|
19
|
+
stats.mode & 0o004 ? "r" : "-",
|
20
|
+
stats.mode & 0o002 ? "w" : "-",
|
21
|
+
stats.mode & 0o001 ? "x" : "-",
|
22
|
+
].join("");
|
23
|
+
return {
|
24
|
+
size: stats.size,
|
25
|
+
created: stats.birthtime,
|
26
|
+
modified: stats.mtime,
|
27
|
+
accessed: stats.atime,
|
28
|
+
isDirectory: stats.isDirectory(),
|
29
|
+
isFile: stats.isFile(),
|
30
|
+
permissions,
|
31
|
+
};
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Searches for files matching a pattern
|
35
|
+
*/
|
36
|
+
export async function searchFiles(rootPath, pattern, excludePatterns = []) {
|
37
|
+
const results = [];
|
38
|
+
async function search(currentPath) {
|
39
|
+
const entries = await fs.readdir(currentPath, { withFileTypes: true });
|
40
|
+
for (const entry of entries) {
|
41
|
+
const entryPath = path.join(currentPath, entry.name);
|
42
|
+
const relativePath = path.relative(rootPath, entryPath);
|
43
|
+
// Check if path should be excluded
|
44
|
+
if (excludePatterns.some((excludePattern) => minimatch(relativePath, excludePattern))) {
|
45
|
+
continue;
|
46
|
+
}
|
47
|
+
if (entry.isDirectory()) {
|
48
|
+
await search(entryPath);
|
49
|
+
}
|
50
|
+
else if (minimatch(relativePath, pattern)) {
|
51
|
+
results.push(entryPath);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
await search(rootPath);
|
56
|
+
return results;
|
57
|
+
}
|
58
|
+
/**
|
59
|
+
* Normalizes line endings to LF
|
60
|
+
*/
|
61
|
+
export function normalizeLineEndings(text) {
|
62
|
+
return text.replace(/\r\n/g, "\n");
|
63
|
+
}
|
64
|
+
/**
|
65
|
+
* Creates a unified diff between two text contents
|
66
|
+
*/
|
67
|
+
export function createUnifiedDiff(originalContent, newContent, filepath = "file") {
|
68
|
+
return createTwoFilesPatch(filepath, filepath, normalizeLineEndings(originalContent), normalizeLineEndings(newContent), "", "", { context: 3 });
|
69
|
+
}
|
70
|
+
/**
|
71
|
+
* Applies edits to a file
|
72
|
+
*/
|
73
|
+
export async function applyFileEdits(filePath, edits, dryRun = false) {
|
74
|
+
let content = await fs.readFile(filePath, "utf-8");
|
75
|
+
content = normalizeLineEndings(content);
|
76
|
+
// Apply all edits
|
77
|
+
for (const edit of edits) {
|
78
|
+
const { oldText, newText } = edit;
|
79
|
+
const normalizedOldText = normalizeLineEndings(oldText);
|
80
|
+
if (!content.includes(normalizedOldText)) {
|
81
|
+
throw new Error(`Edit failed: Could not find text to replace in ${filePath}`);
|
82
|
+
}
|
83
|
+
content = content.replace(normalizedOldText, normalizeLineEndings(newText));
|
84
|
+
}
|
85
|
+
// Create a diff to show changes
|
86
|
+
const originalContent = await fs.readFile(filePath, "utf-8");
|
87
|
+
const diff = createUnifiedDiff(originalContent, content, filePath);
|
88
|
+
// Write the changes if not a dry run
|
89
|
+
if (!dryRun) {
|
90
|
+
await fs.writeFile(filePath, content);
|
91
|
+
}
|
92
|
+
return diff;
|
93
|
+
}
|
94
|
+
//# sourceMappingURL=file.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./path.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,cAAc,WAAW,CAAC"}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
/**
|
2
|
+
* Logging utilities for the MCP Docs Service
|
3
|
+
*
|
4
|
+
* These utilities ensure that logs don't interfere with the MCP protocol communication.
|
5
|
+
*/
|
6
|
+
// Environment detection for different execution contexts
|
7
|
+
export const isCursorWrapper = process.env.MCP_CURSOR_WRAPPER === "true";
|
8
|
+
export const isNpxWrapper = process.env.MCP_NPX_WRAPPER === "true";
|
9
|
+
export const isInspector = process.env.MCP_INSPECTOR === "true";
|
10
|
+
/**
|
11
|
+
* Safe logging function that won't interfere with MCP protocol
|
12
|
+
* When running under Cursor or NPX, redirects all logs to stderr
|
13
|
+
*/
|
14
|
+
export const safeLog = (...args) => {
|
15
|
+
if (isCursorWrapper || isNpxWrapper) {
|
16
|
+
console.error(...args);
|
17
|
+
}
|
18
|
+
else {
|
19
|
+
console.log(...args);
|
20
|
+
}
|
21
|
+
};
|
22
|
+
/**
|
23
|
+
* Safe error logging function
|
24
|
+
*/
|
25
|
+
export const safeError = (...args) => {
|
26
|
+
console.error(...args);
|
27
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Normalizes a path consistently
|
3
|
+
*/
|
4
|
+
export declare function normalizePath(p: string): string;
|
5
|
+
/**
|
6
|
+
* Expands the home directory in a path (e.g., ~/docs -> /home/user/docs)
|
7
|
+
*/
|
8
|
+
export declare function expandHome(p: string): string;
|
9
|
+
/**
|
10
|
+
* Validates that a path is within allowed directories
|
11
|
+
* @param p The path to validate
|
12
|
+
* @param allowedDirectories Array of allowed directory paths
|
13
|
+
* @returns The normalized path if valid
|
14
|
+
* @throws Error if path is not within allowed directories
|
15
|
+
*/
|
16
|
+
export declare function validatePath(p: string, allowedDirectories: string[]): Promise<string>;
|
@@ -0,0 +1,69 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import os from "os";
|
3
|
+
import fs from "fs/promises";
|
4
|
+
/**
|
5
|
+
* Normalizes a path consistently
|
6
|
+
*/
|
7
|
+
export function normalizePath(p) {
|
8
|
+
return path.normalize(p);
|
9
|
+
}
|
10
|
+
/**
|
11
|
+
* Expands the home directory in a path (e.g., ~/docs -> /home/user/docs)
|
12
|
+
*/
|
13
|
+
export function expandHome(p) {
|
14
|
+
if (!p)
|
15
|
+
return p;
|
16
|
+
if (p === "~" || p.startsWith("~/")) {
|
17
|
+
return p.replace(/^~/, os.homedir());
|
18
|
+
}
|
19
|
+
return p;
|
20
|
+
}
|
21
|
+
/**
|
22
|
+
* Validates that a path is within allowed directories
|
23
|
+
* @param p The path to validate
|
24
|
+
* @param allowedDirectories Array of allowed directory paths
|
25
|
+
* @returns The normalized path if valid
|
26
|
+
* @throws Error if path is not within allowed directories
|
27
|
+
*/
|
28
|
+
export async function validatePath(p, allowedDirectories) {
|
29
|
+
// Handle empty path by using the first allowed directory
|
30
|
+
if (!p) {
|
31
|
+
return allowedDirectories[0];
|
32
|
+
}
|
33
|
+
// Resolve the path
|
34
|
+
const normalizedPath = normalizePath(path.resolve(expandHome(p)));
|
35
|
+
// Check if the path is exactly an allowed directory
|
36
|
+
if (allowedDirectories.some((dir) => dir === normalizedPath)) {
|
37
|
+
return normalizedPath;
|
38
|
+
}
|
39
|
+
// Check if the path is within any of the allowed directories
|
40
|
+
const isAllowed = allowedDirectories.some((dir) => {
|
41
|
+
const relativePath = path.relative(dir, normalizedPath);
|
42
|
+
return (relativePath !== "" &&
|
43
|
+
!relativePath.startsWith("..") &&
|
44
|
+
!path.isAbsolute(relativePath));
|
45
|
+
});
|
46
|
+
if (!isAllowed) {
|
47
|
+
// Try to resolve the path relative to the allowed directories
|
48
|
+
for (const dir of allowedDirectories) {
|
49
|
+
const resolvedPath = path.resolve(dir, p);
|
50
|
+
try {
|
51
|
+
// Check if the path exists
|
52
|
+
await fs.access(resolvedPath);
|
53
|
+
// If it exists, check if it's within an allowed directory
|
54
|
+
const relativePath = path.relative(dir, resolvedPath);
|
55
|
+
if (relativePath !== "" &&
|
56
|
+
!relativePath.startsWith("..") &&
|
57
|
+
!path.isAbsolute(relativePath)) {
|
58
|
+
return resolvedPath;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
catch (error) {
|
62
|
+
// Path doesn't exist, continue to the next directory
|
63
|
+
}
|
64
|
+
}
|
65
|
+
// If we get here, the path is not allowed
|
66
|
+
throw new Error(`Access denied: ${p} is not within allowed directories. Allowed directories: ${allowedDirectories.join(", ")}`);
|
67
|
+
}
|
68
|
+
return normalizedPath;
|
69
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,aAAa,CAAC;AAE7B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,CAAS,EACT,kBAA4B;IAE5B,yDAAyD;IACzD,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,mBAAmB;IACnB,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAElE,oDAAoD;IACpD,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,cAAc,CAAC,EAAE,CAAC;QAC7D,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,6DAA6D;IAC7D,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QACxD,OAAO,CACL,YAAY,KAAK,EAAE;YACnB,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;YAC9B,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAC/B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,8DAA8D;QAC9D,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC;gBACH,2BAA2B;gBAC3B,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC9B,0DAA0D;gBAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gBACtD,IACE,YAAY,KAAK,EAAE;oBACnB,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;oBAC9B,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAC9B,CAAC;oBACD,OAAO,YAAY,CAAC;gBACtB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qDAAqD;YACvD,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,MAAM,IAAI,KAAK,CACb,kBAAkB,CAAC,4DAA4D,kBAAkB,CAAC,IAAI,CACpG,IAAI,CACL,EAAE,CACJ,CAAC;IACJ,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC"}
|