@aiready/ast-mcp-server 0.1.0 → 0.1.1

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/index.js ADDED
@@ -0,0 +1,742 @@
1
+ // src/index.ts
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import {
5
+ CallToolRequestSchema,
6
+ ListToolsRequestSchema
7
+ } from "@modelcontextprotocol/sdk/types.js";
8
+
9
+ // src/schemas.ts
10
+ import { z } from "zod";
11
+ var ResolveDefinitionSchema = z.object({
12
+ symbol: z.string().describe(
13
+ "Symbol name to resolve (function, class, type, interface, etc.)"
14
+ ),
15
+ path: z.string().describe("Project root or target directory")
16
+ });
17
+ var FindReferencesSchema = z.object({
18
+ symbol: z.string().describe("Symbol name to find references for"),
19
+ path: z.string().describe("Project root directory"),
20
+ limit: z.number().optional().default(50).describe("Max results per page (default 50)"),
21
+ offset: z.number().optional().default(0).describe("Pagination offset")
22
+ });
23
+ var FindImplementationsSchema = z.object({
24
+ symbol: z.string().describe("Interface or abstract class name to find implementations for"),
25
+ path: z.string().describe("Project root directory"),
26
+ limit: z.number().optional().default(50).describe("Max results per page"),
27
+ offset: z.number().optional().default(0).describe("Pagination offset")
28
+ });
29
+ var GetFileStructureSchema = z.object({
30
+ file: z.string().describe("Absolute path to the file to analyze")
31
+ });
32
+ var SearchCodeSchema = z.object({
33
+ pattern: z.string().describe("Search pattern (regex)"),
34
+ path: z.string().describe("Directory to search in"),
35
+ filePattern: z.string().optional().describe('Glob filter (e.g., "*.ts")'),
36
+ limit: z.number().optional().default(50).describe("Max matches to return")
37
+ });
38
+ var GetSymbolDocsSchema = z.object({
39
+ symbol: z.string().describe("Symbol name to get documentation for"),
40
+ path: z.string().describe("Project root directory")
41
+ });
42
+ var BuildSymbolIndexSchema = z.object({
43
+ path: z.string().describe("Project root directory to index")
44
+ });
45
+
46
+ // src/adapters/typescript-adapter.ts
47
+ import {
48
+ Node,
49
+ SyntaxKind
50
+ } from "ts-morph";
51
+
52
+ // src/project-manager.ts
53
+ import { Project } from "ts-morph";
54
+ import path from "path";
55
+ import fs from "fs";
56
+ import { glob } from "glob";
57
+ var ProjectManager = class {
58
+ projects = /* @__PURE__ */ new Map();
59
+ tsconfigCache = /* @__PURE__ */ new Map();
60
+ /**
61
+ * Find all tsconfig.json files in a directory (recursive)
62
+ */
63
+ async findTsConfigs(rootDir) {
64
+ if (this.tsconfigCache.has(rootDir)) {
65
+ return this.tsconfigCache.get(rootDir);
66
+ }
67
+ const configs = await glob("**/tsconfig.json", {
68
+ cwd: rootDir,
69
+ absolute: true,
70
+ ignore: ["**/node_modules/**", "**/dist/**"]
71
+ });
72
+ this.tsconfigCache.set(rootDir, configs);
73
+ return configs;
74
+ }
75
+ /**
76
+ * Get or create a Project for a specific file path
77
+ */
78
+ async getProjectForFile(filePath) {
79
+ const tsconfigPath = await this.findNearestTsConfig(filePath);
80
+ if (!tsconfigPath) return void 0;
81
+ return this.getOrCreateProject(tsconfigPath);
82
+ }
83
+ /**
84
+ * Get or create a Project for a tsconfig path
85
+ */
86
+ getOrCreateProject(tsconfigPath) {
87
+ if (this.projects.has(tsconfigPath)) {
88
+ return this.projects.get(tsconfigPath);
89
+ }
90
+ const project = new Project({
91
+ tsConfigFilePath: tsconfigPath,
92
+ skipAddingFilesFromTsConfig: false
93
+ });
94
+ this.projects.set(tsconfigPath, project);
95
+ return project;
96
+ }
97
+ /**
98
+ * Find the nearest tsconfig.json for a file
99
+ */
100
+ async findNearestTsConfig(filePath) {
101
+ let currentDir = path.dirname(filePath);
102
+ const root = path.parse(currentDir).root;
103
+ while (currentDir !== root) {
104
+ const tsconfigPath = path.join(currentDir, "tsconfig.json");
105
+ if (fs.existsSync(tsconfigPath)) {
106
+ return tsconfigPath;
107
+ }
108
+ currentDir = path.dirname(currentDir);
109
+ }
110
+ return void 0;
111
+ }
112
+ /**
113
+ * Get all projects that might contain a file or serve a path
114
+ */
115
+ async getProjectsForPath(rootDir) {
116
+ const configs = await this.findTsConfigs(rootDir);
117
+ return configs.map((config) => this.getOrCreateProject(config));
118
+ }
119
+ /**
120
+ * Dispose all projects to free memory
121
+ */
122
+ disposeAll() {
123
+ for (const project of this.projects.values()) {
124
+ project.getLanguageService().compilerObject.dispose();
125
+ }
126
+ this.projects.clear();
127
+ }
128
+ };
129
+ var projectManager = new ProjectManager();
130
+
131
+ // src/adapters/typescript-adapter.ts
132
+ var TypeScriptAdapter = class {
133
+ /**
134
+ * Resolve definition of a symbol at a path
135
+ */
136
+ async resolveDefinition(symbolName, path2) {
137
+ const projects = await projectManager.getProjectsForPath(path2);
138
+ const results = [];
139
+ for (const project of projects) {
140
+ const sourceFiles = project.getSourceFiles();
141
+ for (const sourceFile of sourceFiles) {
142
+ const nodes = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).filter((id) => id.getText() === symbolName);
143
+ for (const node of nodes) {
144
+ const definitions = node.getDefinitionNodes();
145
+ for (const defNode of definitions) {
146
+ results.push(this.mapToDefinitionLocation(defNode));
147
+ }
148
+ }
149
+ }
150
+ }
151
+ return this.deduplicateLocations(results);
152
+ }
153
+ /**
154
+ * Find references to a symbol
155
+ */
156
+ async findReferences(symbolName, path2, limit = 50, offset = 0) {
157
+ const projects = await projectManager.getProjectsForPath(path2);
158
+ const results = [];
159
+ for (const project of projects) {
160
+ const sourceFiles = project.getSourceFiles();
161
+ for (const sourceFile of sourceFiles) {
162
+ const nodes = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).filter((id) => id.getText() === symbolName);
163
+ for (const node of nodes) {
164
+ const referencedSymbols = node.findReferences();
165
+ for (const referencedSymbol of referencedSymbols) {
166
+ const references = referencedSymbol.getReferences();
167
+ for (const ref of references) {
168
+ const sourceFile2 = ref.getSourceFile();
169
+ const lineAndColumn = sourceFile2.getLineAndColumnAtPos(
170
+ ref.getTextSpan().getStart()
171
+ );
172
+ results.push({
173
+ file: sourceFile2.getFilePath(),
174
+ line: lineAndColumn.line,
175
+ column: lineAndColumn.column,
176
+ text: ref.getNode().getParent()?.getText() || ref.getNode().getText()
177
+ });
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ const uniqueResults = this.deduplicateLocations(results);
184
+ return {
185
+ references: uniqueResults.slice(offset, offset + limit),
186
+ total_count: uniqueResults.length
187
+ };
188
+ }
189
+ /**
190
+ * Find implementations for a symbol
191
+ */
192
+ async findImplementations(symbolName, path2, limit = 50, offset = 0) {
193
+ const projects = await projectManager.getProjectsForPath(path2);
194
+ const results = [];
195
+ for (const project of projects) {
196
+ const sourceFiles = project.getSourceFiles();
197
+ for (const sourceFile of sourceFiles) {
198
+ const nodes = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).filter((id) => id.getText() === symbolName);
199
+ for (const node of nodes) {
200
+ const implementations = node.getImplementations();
201
+ for (const impl of implementations) {
202
+ const sourceFile2 = impl.getSourceFile();
203
+ const lineAndColumn = sourceFile2.getLineAndColumnAtPos(
204
+ impl.getTextSpan().getStart()
205
+ );
206
+ results.push({
207
+ file: sourceFile2.getFilePath(),
208
+ line: lineAndColumn.line,
209
+ column: lineAndColumn.column,
210
+ text: impl.getNode().getParent()?.getText() || impl.getNode().getText()
211
+ });
212
+ }
213
+ }
214
+ }
215
+ }
216
+ const uniqueResults = this.deduplicateLocations(results);
217
+ return {
218
+ implementations: uniqueResults.slice(offset, offset + limit),
219
+ total_count: uniqueResults.length
220
+ };
221
+ }
222
+ /**
223
+ * Get file structure overview
224
+ */
225
+ async getFileStructure(filePath) {
226
+ const project = await projectManager.getProjectForFile(filePath);
227
+ if (!project) return void 0;
228
+ const sourceFile = project.getSourceFile(filePath);
229
+ if (!sourceFile) return void 0;
230
+ const structure = {
231
+ file: filePath,
232
+ imports: sourceFile.getImportDeclarations().map((imp) => ({
233
+ module: imp.getModuleSpecifierValue(),
234
+ names: imp.getNamedImports().map((ni) => ni.getName())
235
+ })),
236
+ exports: sourceFile.getExportSymbols().map((sym) => ({
237
+ name: sym.getName(),
238
+ kind: this.mapSymbolKind(sym)
239
+ })),
240
+ classes: sourceFile.getClasses().map((cls) => this.mapToClassInfo(cls)),
241
+ functions: sourceFile.getFunctions().map((fn) => this.mapToFunctionInfo(fn)),
242
+ interfaces: sourceFile.getInterfaces().map((itf) => this.mapToInterfaceInfo(itf)),
243
+ typeAliases: sourceFile.getTypeAliases().map((ta) => this.mapToTypeAliasInfo(ta)),
244
+ enums: sourceFile.getEnums().map((enm) => this.mapToEnumInfo(enm))
245
+ };
246
+ return structure;
247
+ }
248
+ /**
249
+ * Helper: Map ts-morph Node (Declaration) to DefinitionLocation
250
+ */
251
+ mapToDefinitionLocation(node) {
252
+ const sourceFile = node.getSourceFile();
253
+ const lineAndColumn = sourceFile.getLineAndColumnAtPos(node.getStart());
254
+ return {
255
+ file: sourceFile.getFilePath(),
256
+ line: lineAndColumn.line,
257
+ column: lineAndColumn.column,
258
+ kind: this.mapNodeToSymbolKind(node),
259
+ snippet: node.getText(),
260
+ documentation: this.getJsDoc(node)
261
+ };
262
+ }
263
+ /**
264
+ * Helper: Map ts-morph Node to SymbolKind
265
+ */
266
+ mapNodeToSymbolKind(node) {
267
+ if (Node.isClassDeclaration(node)) return "class";
268
+ if (Node.isFunctionDeclaration(node)) return "function";
269
+ if (Node.isInterfaceDeclaration(node)) return "interface";
270
+ if (Node.isTypeAliasDeclaration(node)) return "type_alias";
271
+ if (Node.isEnumDeclaration(node)) return "enum";
272
+ if (Node.isVariableDeclaration(node)) return "variable";
273
+ if (Node.isMethodDeclaration(node)) return "method";
274
+ if (Node.isPropertyDeclaration(node)) return "property";
275
+ if (Node.isParameterDeclaration(node)) return "parameter";
276
+ return "variable";
277
+ }
278
+ /**
279
+ * Helper: Map Symbol to SymbolKind
280
+ */
281
+ mapSymbolKind(symbol) {
282
+ const decls = symbol.getDeclarations();
283
+ if (decls.length > 0) return this.mapNodeToSymbolKind(decls[0]);
284
+ return "variable";
285
+ }
286
+ /**
287
+ * Helper: Get JSDoc from Node
288
+ */
289
+ getJsDoc(node) {
290
+ if (Node.isJSDocable(node)) {
291
+ const docs = node.getJsDocs();
292
+ if (docs.length > 0) {
293
+ return docs[0].getCommentText();
294
+ }
295
+ }
296
+ return void 0;
297
+ }
298
+ /**
299
+ * Helper: Get full JSDoc info (with tags)
300
+ */
301
+ getSymbolDocs(node) {
302
+ if (Node.isJSDocable(node)) {
303
+ const docs = node.getJsDocs();
304
+ if (docs.length > 0) {
305
+ const doc = docs[0];
306
+ return {
307
+ documentation: doc.getCommentText(),
308
+ tags: doc.getTags().map((tag) => ({
309
+ name: tag.getTagName(),
310
+ text: tag.getCommentText() || ""
311
+ }))
312
+ };
313
+ }
314
+ }
315
+ return void 0;
316
+ }
317
+ mapToClassInfo(cls) {
318
+ return {
319
+ name: cls.getName() || "anonymous",
320
+ ...this.getSymbolDocs(cls),
321
+ methods: cls.getMethods().map((m) => this.mapToFunctionInfo(m)),
322
+ properties: cls.getProperties().map((p) => this.mapToPropertyInfo(p))
323
+ };
324
+ }
325
+ mapToFunctionInfo(fn) {
326
+ return {
327
+ name: fn.getName() || "anonymous",
328
+ ...this.getSymbolDocs(fn),
329
+ params: fn.getParameters().map((p) => ({
330
+ name: p.getName(),
331
+ type: p.getType().getText()
332
+ })),
333
+ returnType: fn.getReturnType().getText()
334
+ };
335
+ }
336
+ mapToPropertyInfo(p) {
337
+ return {
338
+ name: p.getName(),
339
+ type: p.getType().getText(),
340
+ ...this.getSymbolDocs(p)
341
+ };
342
+ }
343
+ mapToInterfaceInfo(itf) {
344
+ return {
345
+ name: itf.getName(),
346
+ ...this.getSymbolDocs(itf),
347
+ properties: itf.getProperties().map((p) => this.mapToPropertyInfo(p)),
348
+ methods: itf.getMethods().map((m) => this.mapToFunctionInfo(m))
349
+ };
350
+ }
351
+ mapToTypeAliasInfo(ta) {
352
+ return {
353
+ name: ta.getName(),
354
+ type: ta.getType().getText(),
355
+ ...this.getSymbolDocs(ta)
356
+ };
357
+ }
358
+ mapToEnumInfo(enm) {
359
+ return {
360
+ name: enm.getName(),
361
+ ...this.getSymbolDocs(enm),
362
+ members: enm.getMembers().map((m) => m.getName())
363
+ };
364
+ }
365
+ /**
366
+ * Helper: Deduplicate locations
367
+ */
368
+ deduplicateLocations(locations) {
369
+ const seen = /* @__PURE__ */ new Set();
370
+ return locations.filter((loc) => {
371
+ const key = `${loc.file}:${loc.line}:${loc.column}`;
372
+ if (seen.has(key)) return false;
373
+ seen.add(key);
374
+ return true;
375
+ });
376
+ }
377
+ };
378
+ var typescriptAdapter = new TypeScriptAdapter();
379
+
380
+ // src/tools/resolve-definition.ts
381
+ async function resolveDefinition(symbol, path2) {
382
+ return await typescriptAdapter.resolveDefinition(symbol, path2);
383
+ }
384
+
385
+ // src/tools/find-references.ts
386
+ async function findReferences(symbol, path2, limit = 50, offset = 0) {
387
+ return await typescriptAdapter.findReferences(symbol, path2, limit, offset);
388
+ }
389
+
390
+ // src/tools/find-implementations.ts
391
+ async function findImplementations(symbol, path2, limit = 50, offset = 0) {
392
+ return await typescriptAdapter.findImplementations(
393
+ symbol,
394
+ path2,
395
+ limit,
396
+ offset
397
+ );
398
+ }
399
+
400
+ // src/tools/get-file-structure.ts
401
+ async function getFileStructure(file) {
402
+ return await typescriptAdapter.getFileStructure(file);
403
+ }
404
+
405
+ // src/tools/search-code.ts
406
+ import { execFile } from "child_process";
407
+ import { promisify } from "util";
408
+ import { rgPath } from "@vscode/ripgrep";
409
+ var execFileAsync = promisify(execFile);
410
+ async function searchCode(pattern, searchPath, filePattern, limit = 50) {
411
+ const args = [
412
+ "--json",
413
+ "--max-count",
414
+ limit.toString(),
415
+ "--fixed-strings",
416
+ // Default to fixed strings unless we want regex
417
+ pattern,
418
+ searchPath
419
+ ];
420
+ if (filePattern) {
421
+ args.push("--glob", filePattern);
422
+ }
423
+ args.push("--glob", "!**/node_modules/**");
424
+ args.push("--glob", "!**/dist/**");
425
+ args.push("--glob", "!**/.git/**");
426
+ try {
427
+ const { stdout } = await execFileAsync(rgPath, args);
428
+ const lines = stdout.split("\n").filter(Boolean);
429
+ const results = [];
430
+ for (const line of lines) {
431
+ const data = JSON.parse(line);
432
+ if (data.type === "match") {
433
+ const file = data.data.path.text;
434
+ const lineNumber = data.data.line_number;
435
+ const submatches = data.data.submatches;
436
+ for (const submatch of submatches) {
437
+ results.push({
438
+ file,
439
+ line: lineNumber,
440
+ column: submatch.start,
441
+ text: data.data.lines.text.trim()
442
+ });
443
+ }
444
+ }
445
+ }
446
+ return results.slice(0, limit);
447
+ } catch (error) {
448
+ if (error.code === 1) {
449
+ return [];
450
+ }
451
+ throw error;
452
+ }
453
+ }
454
+
455
+ // src/tools/get-symbol-docs.ts
456
+ import { SyntaxKind as SyntaxKind2 } from "ts-morph";
457
+ async function getSymbolDocs(symbol, filePath) {
458
+ const projects = await projectManager.getProjectsForPath(filePath);
459
+ for (const project of projects) {
460
+ const sourceFile = project.getSourceFile(filePath);
461
+ if (sourceFile) {
462
+ const node = sourceFile.getDescendantsOfKind(SyntaxKind2.Identifier).find((id) => id.getText() === symbol);
463
+ if (node) {
464
+ const decls = node.getSymbol()?.getDeclarations();
465
+ if (decls && decls.length > 0) {
466
+ const docs = typescriptAdapter.getSymbolDocs(decls[0]);
467
+ if (docs) {
468
+ return {
469
+ symbol,
470
+ file: sourceFile.getFilePath(),
471
+ line: sourceFile.getLineAndColumnAtPos(decls[0].getStart()).line,
472
+ ...docs
473
+ };
474
+ }
475
+ }
476
+ }
477
+ }
478
+ }
479
+ return void 0;
480
+ }
481
+
482
+ // src/index/symbol-index.ts
483
+ var SymbolIndex = class {
484
+ /**
485
+ * Build/Warm the index for a given path
486
+ */
487
+ async buildIndex(rootDir) {
488
+ const startTime = Date.now();
489
+ const projects = await projectManager.getProjectsForPath(rootDir);
490
+ let fileCount = 0;
491
+ let functionCount = 0;
492
+ let classCount = 0;
493
+ let interfaceCount = 0;
494
+ let typeCount = 0;
495
+ for (const project of projects) {
496
+ const sourceFiles = project.getSourceFiles();
497
+ fileCount += sourceFiles.length;
498
+ for (const sourceFile of sourceFiles) {
499
+ functionCount += sourceFile.getFunctions().length;
500
+ classCount += sourceFile.getClasses().length;
501
+ interfaceCount += sourceFile.getInterfaces().length;
502
+ typeCount += sourceFile.getTypeAliases().length;
503
+ }
504
+ }
505
+ const duration = Date.now() - startTime;
506
+ const memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024;
507
+ return {
508
+ indexed: {
509
+ files: fileCount,
510
+ functions: functionCount,
511
+ classes: classCount,
512
+ interfaces: interfaceCount,
513
+ types: typeCount
514
+ },
515
+ duration_ms: duration,
516
+ memory_mb: Math.round(memoryUsage)
517
+ };
518
+ }
519
+ };
520
+ var symbolIndex = new SymbolIndex();
521
+
522
+ // src/tools/build-symbol-index.ts
523
+ async function buildSymbolIndex(path2) {
524
+ return await symbolIndex.buildIndex(path2);
525
+ }
526
+
527
+ // src/index.ts
528
+ var ASTExplorerServer = class {
529
+ server;
530
+ version = "0.1.0";
531
+ constructor() {
532
+ this.server = new Server(
533
+ {
534
+ name: "ast-explorer-server",
535
+ version: this.version
536
+ },
537
+ {
538
+ capabilities: {
539
+ tools: {}
540
+ }
541
+ }
542
+ );
543
+ this.setupHandlers();
544
+ this.server.onerror = (error) => {
545
+ console.error("[MCP Error]", error);
546
+ };
547
+ }
548
+ setupHandlers() {
549
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
550
+ return {
551
+ tools: [
552
+ {
553
+ name: "resolve_definition",
554
+ description: "Find where a symbol is defined using TypeScript AST.",
555
+ inputSchema: {
556
+ type: "object",
557
+ properties: {
558
+ symbol: {
559
+ type: "string",
560
+ description: "Symbol name (e.g., function, class)"
561
+ },
562
+ path: {
563
+ type: "string",
564
+ description: "Project root or target directory"
565
+ }
566
+ },
567
+ required: ["symbol", "path"]
568
+ }
569
+ },
570
+ {
571
+ name: "find_references",
572
+ description: "Find all usages of a symbol across the project.",
573
+ inputSchema: {
574
+ type: "object",
575
+ properties: {
576
+ symbol: { type: "string", description: "Symbol name" },
577
+ path: { type: "string", description: "Project root" },
578
+ limit: { type: "number", default: 50 },
579
+ offset: { type: "number", default: 0 }
580
+ },
581
+ required: ["symbol", "path"]
582
+ }
583
+ },
584
+ {
585
+ name: "find_implementations",
586
+ description: "Find implementations of interfaces or abstract classes.",
587
+ inputSchema: {
588
+ type: "object",
589
+ properties: {
590
+ symbol: { type: "string", description: "Interface/Class name" },
591
+ path: { type: "string", description: "Project root" },
592
+ limit: { type: "number", default: 50 },
593
+ offset: { type: "number", default: 0 }
594
+ },
595
+ required: ["symbol", "path"]
596
+ }
597
+ },
598
+ {
599
+ name: "get_file_structure",
600
+ description: "Get structural overview of a file (imports, exports, symbols).",
601
+ inputSchema: {
602
+ type: "object",
603
+ properties: {
604
+ file: { type: "string", description: "Absolute path to file" }
605
+ },
606
+ required: ["file"]
607
+ }
608
+ },
609
+ {
610
+ name: "search_code",
611
+ description: "Fast regex search via bundled ripgrep.",
612
+ inputSchema: {
613
+ type: "object",
614
+ properties: {
615
+ pattern: { type: "string", description: "Search pattern" },
616
+ path: { type: "string", description: "Directory to search" },
617
+ filePattern: { type: "string", description: "Glob filter" },
618
+ limit: { type: "number", default: 50 }
619
+ },
620
+ required: ["pattern", "path"]
621
+ }
622
+ },
623
+ {
624
+ name: "get_symbol_docs",
625
+ description: "Get JSDoc/TSDoc for a specific symbol.",
626
+ inputSchema: {
627
+ type: "object",
628
+ properties: {
629
+ symbol: { type: "string", description: "Symbol name" },
630
+ path: { type: "string", description: "Project root" }
631
+ },
632
+ required: ["symbol", "path"]
633
+ }
634
+ },
635
+ {
636
+ name: "build_symbol_index",
637
+ description: "Warm the symbol index for faster navigation.",
638
+ inputSchema: {
639
+ type: "object",
640
+ properties: {
641
+ path: { type: "string", description: "Project root to index" }
642
+ },
643
+ required: ["path"]
644
+ }
645
+ }
646
+ ]
647
+ };
648
+ });
649
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
650
+ const { name, arguments: args } = request.params;
651
+ try {
652
+ switch (name) {
653
+ case "resolve_definition": {
654
+ const { symbol, path: path2 } = ResolveDefinitionSchema.parse(args);
655
+ const results = await resolveDefinition(symbol, path2);
656
+ return {
657
+ content: [
658
+ { type: "text", text: JSON.stringify(results, null, 2) }
659
+ ]
660
+ };
661
+ }
662
+ case "find_references": {
663
+ const { symbol, path: path2, limit, offset } = FindReferencesSchema.parse(args);
664
+ const results = await findReferences(symbol, path2, limit, offset);
665
+ return {
666
+ content: [
667
+ { type: "text", text: JSON.stringify(results, null, 2) }
668
+ ]
669
+ };
670
+ }
671
+ case "find_implementations": {
672
+ const { symbol, path: path2, limit, offset } = FindImplementationsSchema.parse(args);
673
+ const results = await findImplementations(
674
+ symbol,
675
+ path2,
676
+ limit,
677
+ offset
678
+ );
679
+ return {
680
+ content: [
681
+ { type: "text", text: JSON.stringify(results, null, 2) }
682
+ ]
683
+ };
684
+ }
685
+ case "get_file_structure": {
686
+ const { file } = GetFileStructureSchema.parse(args);
687
+ const structure = await getFileStructure(file);
688
+ return {
689
+ content: [
690
+ { type: "text", text: JSON.stringify(structure, null, 2) }
691
+ ]
692
+ };
693
+ }
694
+ case "search_code": {
695
+ const { pattern, path: path2, filePattern, limit } = SearchCodeSchema.parse(args);
696
+ const results = await searchCode(pattern, path2, filePattern, limit);
697
+ return {
698
+ content: [
699
+ { type: "text", text: JSON.stringify(results, null, 2) }
700
+ ]
701
+ };
702
+ }
703
+ case "get_symbol_docs": {
704
+ const { symbol, path: path2 } = GetSymbolDocsSchema.parse(args);
705
+ const docs = await getSymbolDocs(symbol, path2);
706
+ return {
707
+ content: [{ type: "text", text: JSON.stringify(docs, null, 2) }]
708
+ };
709
+ }
710
+ case "build_symbol_index": {
711
+ const { path: path2 } = BuildSymbolIndexSchema.parse(args);
712
+ const stats = await buildSymbolIndex(path2);
713
+ return {
714
+ content: [{ type: "text", text: JSON.stringify(stats, null, 2) }]
715
+ };
716
+ }
717
+ default:
718
+ throw new Error(`Unknown tool: ${name}`);
719
+ }
720
+ } catch (error) {
721
+ return {
722
+ content: [{ type: "text", text: `Error: ${error.message}` }],
723
+ isError: true
724
+ };
725
+ }
726
+ });
727
+ }
728
+ async run() {
729
+ const transport = new StdioServerTransport();
730
+ await this.server.connect(transport);
731
+ console.error("AST Explorer MCP Server started");
732
+ }
733
+ };
734
+ var server = new ASTExplorerServer();
735
+ server.run().catch((error) => {
736
+ console.error("Fatal error starting AST Explorer MCP Server:", error);
737
+ process.exit(1);
738
+ });
739
+ export {
740
+ ASTExplorerServer
741
+ };
742
+ //# sourceMappingURL=index.js.map