mdcontext 0.0.1 → 0.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/.changeset/README.md +28 -0
- package/.changeset/config.json +11 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/release.yml +113 -0
- package/.tldrignore +112 -0
- package/AGENTS.md +46 -0
- package/BACKLOG.md +338 -0
- package/README.md +231 -11
- package/biome.json +36 -0
- package/cspell.config.yaml +14 -0
- package/dist/chunk-KRYIFLQR.js +92 -0
- package/dist/chunk-S7E6TFX6.js +742 -0
- package/dist/chunk-VVTGZNBT.js +1519 -0
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +2015 -0
- package/dist/index.d.ts +266 -0
- package/dist/index.js +86 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +376 -0
- package/docs/019-USAGE.md +586 -0
- package/docs/020-current-implementation.md +364 -0
- package/docs/021-DOGFOODING-FINDINGS.md +175 -0
- package/docs/BACKLOG.md +80 -0
- package/docs/DESIGN.md +439 -0
- package/docs/PROJECT.md +88 -0
- package/docs/ROADMAP.md +407 -0
- package/docs/test-links.md +9 -0
- package/package.json +69 -10
- package/pnpm-workspace.yaml +5 -0
- package/research/config-analysis/01-current-implementation.md +470 -0
- package/research/config-analysis/02-strategy-recommendation.md +428 -0
- package/research/config-analysis/03-task-candidates.md +715 -0
- package/research/config-analysis/033-research-configuration-management.md +828 -0
- package/research/config-analysis/034-research-effect-cli-config.md +1504 -0
- package/research/config-analysis/04-consolidated-task-candidates.md +277 -0
- package/research/dogfood/consolidated-tool-evaluation.md +373 -0
- package/research/dogfood/strategy-a/a-synthesis.md +184 -0
- package/research/dogfood/strategy-a/a1-docs.md +226 -0
- package/research/dogfood/strategy-a/a2-amorphic.md +156 -0
- package/research/dogfood/strategy-a/a3-llm.md +164 -0
- package/research/dogfood/strategy-b/b-synthesis.md +228 -0
- package/research/dogfood/strategy-b/b1-architecture.md +207 -0
- package/research/dogfood/strategy-b/b2-gaps.md +258 -0
- package/research/dogfood/strategy-b/b3-workflows.md +250 -0
- package/research/dogfood/strategy-c/c-synthesis.md +451 -0
- package/research/dogfood/strategy-c/c1-explorer.md +192 -0
- package/research/dogfood/strategy-c/c2-diver-memory.md +145 -0
- package/research/dogfood/strategy-c/c3-diver-control.md +148 -0
- package/research/dogfood/strategy-c/c4-diver-failure.md +151 -0
- package/research/dogfood/strategy-c/c5-diver-execution.md +221 -0
- package/research/dogfood/strategy-c/c6-diver-org.md +221 -0
- package/research/effect-cli-error-handling.md +845 -0
- package/research/effect-errors-as-values.md +943 -0
- package/research/errors-task-analysis/00-consolidated-tasks.md +207 -0
- package/research/errors-task-analysis/cli-commands-analysis.md +909 -0
- package/research/errors-task-analysis/embeddings-analysis.md +709 -0
- package/research/errors-task-analysis/index-search-analysis.md +812 -0
- package/research/mdcontext-error-analysis.md +521 -0
- package/research/npm_publish/011-npm-workflow-research-agent2.md +792 -0
- package/research/npm_publish/012-npm-workflow-research-agent1.md +530 -0
- package/research/npm_publish/013-npm-workflow-research-agent3.md +722 -0
- package/research/npm_publish/014-npm-workflow-synthesis.md +556 -0
- package/research/npm_publish/031-npm-workflow-task-analysis.md +134 -0
- package/research/semantic-search/002-research-embedding-models.md +490 -0
- package/research/semantic-search/003-research-rag-alternatives.md +523 -0
- package/research/semantic-search/004-research-vector-search.md +841 -0
- package/research/semantic-search/032-research-semantic-search.md +427 -0
- package/research/task-management-2026/00-synthesis-recommendations.md +295 -0
- package/research/task-management-2026/01-ai-workflow-tools.md +416 -0
- package/research/task-management-2026/02-agent-framework-patterns.md +476 -0
- package/research/task-management-2026/03-lightweight-file-based.md +567 -0
- package/research/task-management-2026/04-established-tools-ai-features.md +541 -0
- package/research/task-management-2026/linear/01-core-features-workflow.md +771 -0
- package/research/task-management-2026/linear/02-api-integrations.md +930 -0
- package/research/task-management-2026/linear/03-ai-features.md +368 -0
- package/research/task-management-2026/linear/04-pricing-setup.md +205 -0
- package/research/task-management-2026/linear/05-usage-patterns-best-practices.md +605 -0
- package/scripts/rebuild-hnswlib.js +63 -0
- package/src/cli/argv-preprocessor.test.ts +210 -0
- package/src/cli/argv-preprocessor.ts +202 -0
- package/src/cli/cli.test.ts +430 -0
- package/src/cli/commands/backlinks.ts +54 -0
- package/src/cli/commands/context.ts +197 -0
- package/src/cli/commands/index-cmd.ts +300 -0
- package/src/cli/commands/index.ts +13 -0
- package/src/cli/commands/links.ts +52 -0
- package/src/cli/commands/search.ts +451 -0
- package/src/cli/commands/stats.ts +146 -0
- package/src/cli/commands/tree.ts +107 -0
- package/src/cli/flag-schemas.ts +275 -0
- package/src/cli/help.ts +386 -0
- package/src/cli/index.ts +9 -0
- package/src/cli/main.ts +145 -0
- package/src/cli/options.ts +31 -0
- package/src/cli/typo-suggester.test.ts +105 -0
- package/src/cli/typo-suggester.ts +130 -0
- package/src/cli/utils.ts +126 -0
- package/src/core/index.ts +1 -0
- package/src/core/types.ts +140 -0
- package/src/embeddings/index.ts +8 -0
- package/src/embeddings/openai-provider.ts +165 -0
- package/src/embeddings/semantic-search.ts +583 -0
- package/src/embeddings/types.ts +82 -0
- package/src/embeddings/vector-store.ts +299 -0
- package/src/index/index.ts +4 -0
- package/src/index/indexer.ts +446 -0
- package/src/index/storage.ts +196 -0
- package/src/index/types.ts +109 -0
- package/src/index/watcher.ts +131 -0
- package/src/index.ts +8 -0
- package/src/mcp/server.ts +483 -0
- package/src/parser/index.ts +1 -0
- package/src/parser/parser.test.ts +291 -0
- package/src/parser/parser.ts +395 -0
- package/src/parser/section-filter.ts +270 -0
- package/src/search/query-parser.test.ts +260 -0
- package/src/search/query-parser.ts +319 -0
- package/src/search/searcher.test.ts +182 -0
- package/src/search/searcher.ts +602 -0
- package/src/summarize/budget-bugs.test.ts +620 -0
- package/src/summarize/formatters.ts +419 -0
- package/src/summarize/index.ts +20 -0
- package/src/summarize/summarizer.test.ts +275 -0
- package/src/summarize/summarizer.ts +528 -0
- package/src/summarize/verify-bugs.test.ts +238 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/tokens.test.ts +142 -0
- package/src/utils/tokens.ts +186 -0
- package/tests/fixtures/cli/.mdcontext/config.json +8 -0
- package/tests/fixtures/cli/.mdcontext/indexes/documents.json +33 -0
- package/tests/fixtures/cli/.mdcontext/indexes/links.json +12 -0
- package/tests/fixtures/cli/.mdcontext/indexes/sections.json +233 -0
- package/tests/fixtures/cli/.mdcontext/vectors.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/vectors.meta.json +1264 -0
- package/tests/fixtures/cli/README.md +9 -0
- package/tests/fixtures/cli/api-reference.md +11 -0
- package/tests/fixtures/cli/getting-started.md +11 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +21 -0
- package/vitest.setup.ts +12 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
formatSummary,
|
|
4
|
+
search,
|
|
5
|
+
semanticSearch,
|
|
6
|
+
summarizeFile
|
|
7
|
+
} from "../chunk-VVTGZNBT.js";
|
|
8
|
+
import {
|
|
9
|
+
buildIndex,
|
|
10
|
+
parseFile
|
|
11
|
+
} from "../chunk-S7E6TFX6.js";
|
|
12
|
+
|
|
13
|
+
// src/mcp/server.ts
|
|
14
|
+
import * as path from "path";
|
|
15
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
16
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17
|
+
import {
|
|
18
|
+
CallToolRequestSchema,
|
|
19
|
+
ListToolsRequestSchema
|
|
20
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
21
|
+
import { Effect } from "effect";
|
|
22
|
+
var tools = [
|
|
23
|
+
{
|
|
24
|
+
name: "md_search",
|
|
25
|
+
description: "Search markdown documents by meaning using semantic search. Returns relevant sections based on natural language queries.",
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
query: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Natural language search query"
|
|
32
|
+
},
|
|
33
|
+
limit: {
|
|
34
|
+
type: "number",
|
|
35
|
+
description: "Maximum number of results (default: 5)",
|
|
36
|
+
default: 5
|
|
37
|
+
},
|
|
38
|
+
path_filter: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Glob pattern to filter files (e.g., '*.md', 'docs/**/*.md')"
|
|
41
|
+
},
|
|
42
|
+
threshold: {
|
|
43
|
+
type: "number",
|
|
44
|
+
description: "Minimum similarity threshold 0-1 (default: 0.5)",
|
|
45
|
+
default: 0.5
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
required: ["query"]
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "md_context",
|
|
53
|
+
description: "Get LLM-ready context from a markdown file. Provides compressed, token-efficient summaries at various detail levels.",
|
|
54
|
+
inputSchema: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
path: {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "Path to the markdown file"
|
|
60
|
+
},
|
|
61
|
+
level: {
|
|
62
|
+
type: "string",
|
|
63
|
+
enum: ["full", "summary", "brief"],
|
|
64
|
+
description: "Compression level (default: summary)",
|
|
65
|
+
default: "summary"
|
|
66
|
+
},
|
|
67
|
+
max_tokens: {
|
|
68
|
+
type: "number",
|
|
69
|
+
description: "Maximum tokens to include in output"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
required: ["path"]
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "md_structure",
|
|
77
|
+
description: "Get the structure/outline of a markdown file. Shows heading hierarchy with token counts.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
path: {
|
|
82
|
+
type: "string",
|
|
83
|
+
description: "Path to the markdown file"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
required: ["path"]
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "md_keyword_search",
|
|
91
|
+
description: "Search markdown documents by keyword search (headings, code blocks, lists, tables).",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
type: "object",
|
|
94
|
+
properties: {
|
|
95
|
+
heading: {
|
|
96
|
+
type: "string",
|
|
97
|
+
description: "Filter by heading pattern (regex)"
|
|
98
|
+
},
|
|
99
|
+
path_filter: {
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "Glob pattern to filter files"
|
|
102
|
+
},
|
|
103
|
+
has_code: {
|
|
104
|
+
type: "boolean",
|
|
105
|
+
description: "Only sections with code blocks"
|
|
106
|
+
},
|
|
107
|
+
has_list: {
|
|
108
|
+
type: "boolean",
|
|
109
|
+
description: "Only sections with lists"
|
|
110
|
+
},
|
|
111
|
+
has_table: {
|
|
112
|
+
type: "boolean",
|
|
113
|
+
description: "Only sections with tables"
|
|
114
|
+
},
|
|
115
|
+
limit: {
|
|
116
|
+
type: "number",
|
|
117
|
+
description: "Maximum results (default: 20)",
|
|
118
|
+
default: 20
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "md_index",
|
|
125
|
+
description: "Build or rebuild the index for a directory. Required before using search tools.",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
path: {
|
|
130
|
+
type: "string",
|
|
131
|
+
description: "Directory to index (default: current directory)",
|
|
132
|
+
default: "."
|
|
133
|
+
},
|
|
134
|
+
force: {
|
|
135
|
+
type: "boolean",
|
|
136
|
+
description: "Force full rebuild (default: false)",
|
|
137
|
+
default: false
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
];
|
|
143
|
+
var handleMdSearch = async (args, rootPath) => {
|
|
144
|
+
const query = args.query;
|
|
145
|
+
const limit = args.limit ?? 5;
|
|
146
|
+
const pathFilter = args.path_filter;
|
|
147
|
+
const threshold = args.threshold ?? 0.5;
|
|
148
|
+
const result = await Effect.runPromise(
|
|
149
|
+
semanticSearch(rootPath, query, {
|
|
150
|
+
limit,
|
|
151
|
+
threshold,
|
|
152
|
+
pathPattern: pathFilter
|
|
153
|
+
}).pipe(
|
|
154
|
+
Effect.catchAll((e) => Effect.succeed([{ error: e.message }]))
|
|
155
|
+
)
|
|
156
|
+
);
|
|
157
|
+
if (Array.isArray(result) && result.length > 0 && "error" in result[0]) {
|
|
158
|
+
return {
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: `Error: ${result[0].error}`
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
isError: true
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const formattedResults = result.map((r, i) => {
|
|
169
|
+
const similarity = (r.similarity * 100).toFixed(1);
|
|
170
|
+
return `${i + 1}. **${r.heading}** (${similarity}% match)
|
|
171
|
+
${r.documentPath}`;
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
content: [
|
|
175
|
+
{
|
|
176
|
+
type: "text",
|
|
177
|
+
text: formattedResults.length > 0 ? `Found ${formattedResults.length} results for "${query}":
|
|
178
|
+
|
|
179
|
+
${formattedResults.join("\n\n")}` : `No results found for "${query}"`
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
var handleMdContext = async (args, rootPath) => {
|
|
185
|
+
const filePath = args.path;
|
|
186
|
+
const level = args.level ?? "summary";
|
|
187
|
+
const maxTokens = args.max_tokens;
|
|
188
|
+
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(rootPath, filePath);
|
|
189
|
+
const result = await Effect.runPromise(
|
|
190
|
+
summarizeFile(resolvedPath, { level, maxTokens }).pipe(
|
|
191
|
+
Effect.catchAll((e) => Effect.succeed({ error: e.message }))
|
|
192
|
+
)
|
|
193
|
+
);
|
|
194
|
+
if ("error" in result) {
|
|
195
|
+
return {
|
|
196
|
+
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
197
|
+
isError: true
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
content: [{ type: "text", text: formatSummary(result) }]
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
var handleMdStructure = async (args, rootPath) => {
|
|
205
|
+
const filePath = args.path;
|
|
206
|
+
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(rootPath, filePath);
|
|
207
|
+
const result = await Effect.runPromise(
|
|
208
|
+
parseFile(resolvedPath).pipe(
|
|
209
|
+
Effect.mapError((e) => new Error(`${e._tag}: ${e.message}`)),
|
|
210
|
+
Effect.catchAll((e) => Effect.succeed({ error: e.message }))
|
|
211
|
+
)
|
|
212
|
+
);
|
|
213
|
+
if ("error" in result) {
|
|
214
|
+
return {
|
|
215
|
+
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
216
|
+
isError: true
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const formatSection = (section, depth = 0) => {
|
|
220
|
+
const indent = " ".repeat(depth);
|
|
221
|
+
const marker = "#".repeat(section.level);
|
|
222
|
+
const meta = [];
|
|
223
|
+
if (section.metadata.hasCode) meta.push("code");
|
|
224
|
+
if (section.metadata.hasList) meta.push("list");
|
|
225
|
+
if (section.metadata.hasTable) meta.push("table");
|
|
226
|
+
const metaStr = meta.length > 0 ? ` [${meta.join(", ")}]` : "";
|
|
227
|
+
let output = `${indent}${marker} ${section.heading}${metaStr} (${section.metadata.tokenCount} tokens)
|
|
228
|
+
`;
|
|
229
|
+
for (const child of section.children) {
|
|
230
|
+
output += formatSection(child, depth + 1);
|
|
231
|
+
}
|
|
232
|
+
return output;
|
|
233
|
+
};
|
|
234
|
+
const structure = result.sections.map((s) => formatSection(s)).join("");
|
|
235
|
+
return {
|
|
236
|
+
content: [
|
|
237
|
+
{
|
|
238
|
+
type: "text",
|
|
239
|
+
text: `# ${result.title}
|
|
240
|
+
Path: ${result.path}
|
|
241
|
+
Total tokens: ${result.metadata.tokenCount}
|
|
242
|
+
|
|
243
|
+
${structure}`
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
var handleMdKeywordSearch = async (args, rootPath) => {
|
|
249
|
+
const heading = args.heading;
|
|
250
|
+
const pathFilter = args.path_filter;
|
|
251
|
+
const hasCode = args.has_code;
|
|
252
|
+
const hasList = args.has_list;
|
|
253
|
+
const hasTable = args.has_table;
|
|
254
|
+
const limit = args.limit ?? 20;
|
|
255
|
+
const result = await Effect.runPromise(
|
|
256
|
+
search(rootPath, {
|
|
257
|
+
heading,
|
|
258
|
+
pathPattern: pathFilter,
|
|
259
|
+
hasCode,
|
|
260
|
+
hasList,
|
|
261
|
+
hasTable,
|
|
262
|
+
limit
|
|
263
|
+
}).pipe(
|
|
264
|
+
Effect.catchAll((e) => Effect.succeed([{ error: e.message }]))
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
if (Array.isArray(result) && result.length > 0 && "error" in result[0]) {
|
|
268
|
+
return {
|
|
269
|
+
content: [
|
|
270
|
+
{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: `Error: ${result[0].error}`
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
isError: true
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const formattedResults = result.map((r, i) => {
|
|
279
|
+
const meta = [];
|
|
280
|
+
if (r.section.hasCode) meta.push("code");
|
|
281
|
+
if (r.section.hasList) meta.push("list");
|
|
282
|
+
if (r.section.hasTable) meta.push("table");
|
|
283
|
+
const metaStr = meta.length > 0 ? ` [${meta.join(", ")}]` : "";
|
|
284
|
+
return `${i + 1}. **${r.section.heading}**${metaStr}
|
|
285
|
+
${r.section.documentPath} (${r.section.tokenCount} tokens)`;
|
|
286
|
+
});
|
|
287
|
+
return {
|
|
288
|
+
content: [
|
|
289
|
+
{
|
|
290
|
+
type: "text",
|
|
291
|
+
text: formattedResults.length > 0 ? `Found ${formattedResults.length} sections:
|
|
292
|
+
|
|
293
|
+
${formattedResults.join("\n\n")}` : "No sections found matching criteria"
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
var handleMdIndex = async (args, rootPath) => {
|
|
299
|
+
const indexPath = args.path ?? ".";
|
|
300
|
+
const force = args.force ?? false;
|
|
301
|
+
const resolvedPath = path.isAbsolute(indexPath) ? indexPath : path.join(rootPath, indexPath);
|
|
302
|
+
const result = await Effect.runPromise(
|
|
303
|
+
buildIndex(resolvedPath, { force }).pipe(
|
|
304
|
+
Effect.catchAll((e) => Effect.succeed({ error: e.message }))
|
|
305
|
+
)
|
|
306
|
+
);
|
|
307
|
+
if ("error" in result) {
|
|
308
|
+
return {
|
|
309
|
+
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
310
|
+
isError: true
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
content: [
|
|
315
|
+
{
|
|
316
|
+
type: "text",
|
|
317
|
+
text: `Indexed ${result.documentsIndexed} documents, ${result.sectionsIndexed} sections, ${result.linksIndexed} links in ${result.duration}ms`
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
var createServer = (rootPath) => {
|
|
323
|
+
const server = new Server(
|
|
324
|
+
{
|
|
325
|
+
name: "mdcontext-mcp",
|
|
326
|
+
version: "0.1.0"
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
capabilities: {
|
|
330
|
+
tools: {}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
335
|
+
tools
|
|
336
|
+
}));
|
|
337
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
338
|
+
const { name, arguments: args } = request.params;
|
|
339
|
+
switch (name) {
|
|
340
|
+
case "md_search":
|
|
341
|
+
return handleMdSearch(args ?? {}, rootPath);
|
|
342
|
+
case "md_context":
|
|
343
|
+
return handleMdContext(args ?? {}, rootPath);
|
|
344
|
+
case "md_structure":
|
|
345
|
+
return handleMdStructure(args ?? {}, rootPath);
|
|
346
|
+
case "md_keyword_search":
|
|
347
|
+
return handleMdKeywordSearch(args ?? {}, rootPath);
|
|
348
|
+
case "md_index":
|
|
349
|
+
return handleMdIndex(args ?? {}, rootPath);
|
|
350
|
+
default:
|
|
351
|
+
return {
|
|
352
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
353
|
+
isError: true
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
return server;
|
|
358
|
+
};
|
|
359
|
+
var main = async () => {
|
|
360
|
+
const rootPath = process.cwd();
|
|
361
|
+
const server = createServer(rootPath);
|
|
362
|
+
const transport = new StdioServerTransport();
|
|
363
|
+
await server.connect(transport);
|
|
364
|
+
process.on("SIGINT", async () => {
|
|
365
|
+
await server.close();
|
|
366
|
+
process.exit(0);
|
|
367
|
+
});
|
|
368
|
+
process.on("SIGTERM", async () => {
|
|
369
|
+
await server.close();
|
|
370
|
+
process.exit(0);
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
main().catch((error) => {
|
|
374
|
+
console.error("Fatal error:", error);
|
|
375
|
+
process.exit(1);
|
|
376
|
+
});
|