@deplens/mcp 0.1.2 → 0.1.4
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 +93 -0
- package/package.json +2 -2
- package/src/core/inspect.mjs +1145 -0
- package/src/core/parse-dts.mjs +416 -0
- package/src/server.mjs +23 -1
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
// parse-dts.mjs - TypeScript Compiler API based .d.ts parser
|
|
2
|
+
import ts from "typescript"
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import path from "path"
|
|
5
|
+
|
|
6
|
+
function getScriptKind(filePath) {
|
|
7
|
+
if (typeof ts.getScriptKindFromFileName === "function") {
|
|
8
|
+
const kind = ts.getScriptKindFromFileName(filePath)
|
|
9
|
+
return kind === ts.ScriptKind.Unknown ? ts.ScriptKind.TS : kind
|
|
10
|
+
}
|
|
11
|
+
return ts.ScriptKind.TS
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Find re-exported symbols and their source files
|
|
16
|
+
* @param {string} dtsPath - Path to the .d.ts file
|
|
17
|
+
* @param {string[]} filterList - List of symbol names to find
|
|
18
|
+
* @returns {Map<string, string>} Map of symbol name -> source file path
|
|
19
|
+
*/
|
|
20
|
+
function findReExports(dtsPath, filterList) {
|
|
21
|
+
const content = fs.readFileSync(dtsPath, "utf-8")
|
|
22
|
+
const sourceFile = ts.createSourceFile(
|
|
23
|
+
dtsPath,
|
|
24
|
+
content,
|
|
25
|
+
ts.ScriptTarget.Latest,
|
|
26
|
+
true,
|
|
27
|
+
getScriptKind(dtsPath),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const dtsDir = path.dirname(dtsPath)
|
|
31
|
+
const reExports = new Map()
|
|
32
|
+
const wildcardSources = []
|
|
33
|
+
const filterSet = filterList ? new Set(filterList.map((n) => n.toLowerCase())) : null
|
|
34
|
+
|
|
35
|
+
function resolveDtsPath(moduleSpec) {
|
|
36
|
+
// Handle .cjs/.mjs/.js -> .d.cts/.d.mts/.d.ts
|
|
37
|
+
let sourceFile = moduleSpec
|
|
38
|
+
.replace(/\.cjs$/, ".d.cts")
|
|
39
|
+
.replace(/\.mjs$/, ".d.mts")
|
|
40
|
+
.replace(/\.js$/, ".d.ts")
|
|
41
|
+
if (!sourceFile.endsWith(".d.ts") && !sourceFile.endsWith(".d.cts") && !sourceFile.endsWith(".d.mts")) {
|
|
42
|
+
// Try all extensions
|
|
43
|
+
const dtsCandidate = path.resolve(dtsDir, sourceFile + ".d.ts")
|
|
44
|
+
const ctsCandidate = path.resolve(dtsDir, sourceFile + ".d.cts")
|
|
45
|
+
const mtsCandidate = path.resolve(dtsDir, sourceFile + ".d.mts")
|
|
46
|
+
if (fs.existsSync(dtsCandidate)) return dtsCandidate
|
|
47
|
+
if (fs.existsSync(ctsCandidate)) return ctsCandidate
|
|
48
|
+
if (fs.existsSync(mtsCandidate)) return mtsCandidate
|
|
49
|
+
return null
|
|
50
|
+
}
|
|
51
|
+
const fullPath = path.resolve(dtsDir, sourceFile)
|
|
52
|
+
return fs.existsSync(fullPath) ? fullPath : null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function visit(node) {
|
|
56
|
+
// Handle: export { foo } from './foo.js'
|
|
57
|
+
if (ts.isExportDeclaration(node) && node.moduleSpecifier) {
|
|
58
|
+
const moduleSpec = node.moduleSpecifier.text
|
|
59
|
+
|
|
60
|
+
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
61
|
+
// Named exports
|
|
62
|
+
for (const elem of node.exportClause.elements) {
|
|
63
|
+
const exportedName = elem.name.text
|
|
64
|
+
if (!filterSet || filterSet.has(exportedName.toLowerCase())) {
|
|
65
|
+
const fullPath = resolveDtsPath(moduleSpec)
|
|
66
|
+
if (fullPath) {
|
|
67
|
+
reExports.set(exportedName, fullPath)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} else if (!node.exportClause) {
|
|
72
|
+
// Wildcard: export * from './module'
|
|
73
|
+
const fullPath = resolveDtsPath(moduleSpec)
|
|
74
|
+
if (fullPath) {
|
|
75
|
+
wildcardSources.push(fullPath)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
ts.forEachChild(node, visit)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
visit(sourceFile)
|
|
83
|
+
|
|
84
|
+
// For wildcard exports, we return them all as potential sources
|
|
85
|
+
return { named: reExports, wildcards: wildcardSources }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Parse a .d.ts file and extract type information for specified symbols
|
|
90
|
+
* @param {string} dtsPath - Path to the .d.ts file
|
|
91
|
+
* @param {string[]} filterList - List of symbol names to extract (null = all)
|
|
92
|
+
* @returns {object} Type information
|
|
93
|
+
*/
|
|
94
|
+
export function parseDtsFile(dtsPath, filterList, visited = new Set()) {
|
|
95
|
+
if (!fs.existsSync(dtsPath)) {
|
|
96
|
+
return null
|
|
97
|
+
}
|
|
98
|
+
if (visited.has(dtsPath)) {
|
|
99
|
+
return null
|
|
100
|
+
}
|
|
101
|
+
visited.add(dtsPath)
|
|
102
|
+
|
|
103
|
+
const content = fs.readFileSync(dtsPath, "utf-8")
|
|
104
|
+
const sourceFile = ts.createSourceFile(
|
|
105
|
+
dtsPath,
|
|
106
|
+
content,
|
|
107
|
+
ts.ScriptTarget.Latest,
|
|
108
|
+
true,
|
|
109
|
+
getScriptKind(dtsPath),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const typeInfo = {
|
|
113
|
+
functions: {},
|
|
114
|
+
interfaces: {},
|
|
115
|
+
types: {},
|
|
116
|
+
classes: {},
|
|
117
|
+
enums: {},
|
|
118
|
+
namespaces: {},
|
|
119
|
+
defaults: [],
|
|
120
|
+
jsdoc: {},
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const filterSet = filterList ? new Set(filterList.map((n) => n.toLowerCase())) : null
|
|
124
|
+
|
|
125
|
+
function shouldInclude(name) {
|
|
126
|
+
if (!filterSet) return true
|
|
127
|
+
return filterSet.has(name.toLowerCase())
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getNodeText(node) {
|
|
131
|
+
return node.getText(sourceFile)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function formatType(typeNode, maxLen = 80) {
|
|
135
|
+
if (!typeNode) return "any"
|
|
136
|
+
const text = getNodeText(typeNode).replace(/\s+/g, " ").trim()
|
|
137
|
+
return text.length > maxLen ? text.substring(0, maxLen) + "..." : text
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function formatParams(params) {
|
|
141
|
+
if (!params || params.length === 0) return ""
|
|
142
|
+
|
|
143
|
+
// For complex destructuring, simplify
|
|
144
|
+
const paramStrs = params.map((p) => {
|
|
145
|
+
const name = p.name ? getNodeText(p.name) : "arg"
|
|
146
|
+
|
|
147
|
+
// Handle destructuring pattern - just show "options"
|
|
148
|
+
if (name.startsWith("{")) {
|
|
149
|
+
return "options: object"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const optional = p.questionToken ? "?" : ""
|
|
153
|
+
const type = p.type ? formatType(p.type, 40) : "any"
|
|
154
|
+
|
|
155
|
+
// Simplify long type names
|
|
156
|
+
const shortType = type.length > 40 ? type.split("<")[0] + "<...>" : type
|
|
157
|
+
return `${name}${optional}: ${shortType}`
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// If total length too long, just show count
|
|
161
|
+
const joined = paramStrs.join(", ")
|
|
162
|
+
if (joined.length > 100) {
|
|
163
|
+
return `${params.length} param${params.length > 1 ? "s" : ""}`
|
|
164
|
+
}
|
|
165
|
+
return joined
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function jsDocText(comment) {
|
|
169
|
+
if (!comment) return ""
|
|
170
|
+
if (typeof comment === "string") return comment.trim()
|
|
171
|
+
if (Array.isArray(comment)) {
|
|
172
|
+
return comment.map((part) => part.text || "").join("").trim()
|
|
173
|
+
}
|
|
174
|
+
return ""
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function collectJSDocTags(tagNodes) {
|
|
178
|
+
const tags = {}
|
|
179
|
+
if (!tagNodes || tagNodes.length === 0) return tags
|
|
180
|
+
for (const tag of tagNodes) {
|
|
181
|
+
if (!tag?.tagName?.text) continue
|
|
182
|
+
const tagName = tag.tagName.text
|
|
183
|
+
const comment = jsDocText(tag.comment)
|
|
184
|
+
if (!tags[tagName]) tags[tagName] = []
|
|
185
|
+
tags[tagName].push(comment || "")
|
|
186
|
+
}
|
|
187
|
+
return tags
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function extractJSDoc(node) {
|
|
191
|
+
const entries = ts.getJSDocCommentsAndTags(node)
|
|
192
|
+
if (!entries || entries.length === 0) return null
|
|
193
|
+
let summary = ""
|
|
194
|
+
const tags = {}
|
|
195
|
+
for (const entry of entries) {
|
|
196
|
+
if (ts.isJSDoc(entry)) {
|
|
197
|
+
if (!summary) summary = jsDocText(entry.comment)
|
|
198
|
+
const entryTags = collectJSDocTags(entry.tags)
|
|
199
|
+
for (const [name, values] of Object.entries(entryTags)) {
|
|
200
|
+
if (!tags[name]) tags[name] = []
|
|
201
|
+
tags[name].push(...values)
|
|
202
|
+
}
|
|
203
|
+
} else if (ts.isJSDocTag(entry)) {
|
|
204
|
+
const tagName = entry.tagName?.text
|
|
205
|
+
if (tagName) {
|
|
206
|
+
const comment = jsDocText(entry.comment)
|
|
207
|
+
if (!tags[tagName]) tags[tagName] = []
|
|
208
|
+
tags[tagName].push(comment || "")
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (!summary && Object.keys(tags).length === 0) return null
|
|
213
|
+
return { summary, tags }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function attachJSDoc(name, node) {
|
|
217
|
+
if (!name || !node) return
|
|
218
|
+
const doc = extractJSDoc(node)
|
|
219
|
+
if (!doc) return
|
|
220
|
+
typeInfo.jsdoc[name] = doc
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function visit(node) {
|
|
224
|
+
// Function declarations
|
|
225
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
226
|
+
const isDefault = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
|
|
227
|
+
const name = node.name?.text || (isDefault ? "default" : null)
|
|
228
|
+
if (name && shouldInclude(name)) {
|
|
229
|
+
const params = formatParams(node.parameters)
|
|
230
|
+
const returnType = formatType(node.type, 60)
|
|
231
|
+
typeInfo.functions[name] = { params, returnType }
|
|
232
|
+
attachJSDoc(name, node)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Interface declarations
|
|
237
|
+
if (ts.isInterfaceDeclaration(node)) {
|
|
238
|
+
const name = node.name.text
|
|
239
|
+
const isDefault = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
|
|
240
|
+
const exportName = isDefault ? "default" : name
|
|
241
|
+
if (shouldInclude(exportName)) {
|
|
242
|
+
const props = []
|
|
243
|
+
node.members.slice(0, 5).forEach((member) => {
|
|
244
|
+
if (ts.isPropertySignature(member) && member.name) {
|
|
245
|
+
const propName = getNodeText(member.name)
|
|
246
|
+
const optional = member.questionToken ? "?" : ""
|
|
247
|
+
const propType = formatType(member.type, 30)
|
|
248
|
+
props.push(`${propName}${optional}: ${propType}`)
|
|
249
|
+
}
|
|
250
|
+
})
|
|
251
|
+
if (props.length > 0) {
|
|
252
|
+
typeInfo.interfaces[exportName] = props
|
|
253
|
+
attachJSDoc(exportName, node)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Type aliases
|
|
259
|
+
if (ts.isTypeAliasDeclaration(node)) {
|
|
260
|
+
const name = node.name.text
|
|
261
|
+
const isDefault = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
|
|
262
|
+
const exportName = isDefault ? "default" : name
|
|
263
|
+
if (shouldInclude(exportName)) {
|
|
264
|
+
typeInfo.types[exportName] = formatType(node.type, 80)
|
|
265
|
+
attachJSDoc(exportName, node)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Class declarations
|
|
270
|
+
if (ts.isClassDeclaration(node)) {
|
|
271
|
+
const isDefault = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)
|
|
272
|
+
const name = node.name?.text || (isDefault ? "default" : null)
|
|
273
|
+
if (name && shouldInclude(name)) {
|
|
274
|
+
let extendsClause = null
|
|
275
|
+
if (node.heritageClauses) {
|
|
276
|
+
for (const clause of node.heritageClauses) {
|
|
277
|
+
if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
|
|
278
|
+
extendsClause = getNodeText(clause.types[0].expression)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
typeInfo.classes[name] = extendsClause
|
|
283
|
+
attachJSDoc(name, node)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Enum declarations
|
|
288
|
+
if (ts.isEnumDeclaration(node)) {
|
|
289
|
+
const name = node.name.text
|
|
290
|
+
if (shouldInclude(name)) {
|
|
291
|
+
const members = node.members.slice(0, 5).map((member) => getNodeText(member.name))
|
|
292
|
+
typeInfo.enums[name] = members
|
|
293
|
+
attachJSDoc(name, node)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Namespace/module declarations
|
|
298
|
+
if (ts.isModuleDeclaration(node) && node.name) {
|
|
299
|
+
const name = getNodeText(node.name)
|
|
300
|
+
if (shouldInclude(name)) {
|
|
301
|
+
typeInfo.namespaces[name] = true
|
|
302
|
+
attachJSDoc(name, node)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Variable statements (export const foo: Type)
|
|
307
|
+
if (ts.isVariableStatement(node)) {
|
|
308
|
+
const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)
|
|
309
|
+
if (isExported && node.declarationList.declarations) {
|
|
310
|
+
for (const decl of node.declarationList.declarations) {
|
|
311
|
+
if (ts.isIdentifier(decl.name)) {
|
|
312
|
+
const name = decl.name.text
|
|
313
|
+
if (shouldInclude(name) && decl.type) {
|
|
314
|
+
// Check if it's a function type
|
|
315
|
+
if (ts.isFunctionTypeNode(decl.type)) {
|
|
316
|
+
const params = formatParams(decl.type.parameters)
|
|
317
|
+
const returnType = formatType(decl.type.type, 60)
|
|
318
|
+
typeInfo.functions[name] = { params, returnType }
|
|
319
|
+
attachJSDoc(name, node)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// export = Foo or export default Foo
|
|
328
|
+
if (ts.isExportAssignment(node)) {
|
|
329
|
+
const assignment = getNodeText(node.expression)
|
|
330
|
+
if (assignment) {
|
|
331
|
+
typeInfo.defaults.push(assignment)
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
ts.forEachChild(node, visit)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
visit(sourceFile)
|
|
339
|
+
|
|
340
|
+
// If we have a filter, try to follow re-exports for missing symbols
|
|
341
|
+
if (filterList && filterList.length > 0) {
|
|
342
|
+
const found = new Set([
|
|
343
|
+
...Object.keys(typeInfo.functions),
|
|
344
|
+
...Object.keys(typeInfo.interfaces),
|
|
345
|
+
...Object.keys(typeInfo.types),
|
|
346
|
+
...Object.keys(typeInfo.classes),
|
|
347
|
+
...Object.keys(typeInfo.enums),
|
|
348
|
+
...Object.keys(typeInfo.namespaces),
|
|
349
|
+
])
|
|
350
|
+
const missing = filterList.filter((name) => !found.has(name))
|
|
351
|
+
|
|
352
|
+
if (missing.length > 0) {
|
|
353
|
+
const { named, wildcards } = findReExports(dtsPath, missing)
|
|
354
|
+
|
|
355
|
+
// Try named exports first
|
|
356
|
+
for (const [symbolName, sourcePath] of named) {
|
|
357
|
+
const subResult = parseDtsFile(sourcePath, [symbolName], visited)
|
|
358
|
+
if (subResult) {
|
|
359
|
+
Object.assign(typeInfo.functions, subResult.functions)
|
|
360
|
+
Object.assign(typeInfo.interfaces, subResult.interfaces)
|
|
361
|
+
Object.assign(typeInfo.types, subResult.types)
|
|
362
|
+
Object.assign(typeInfo.classes, subResult.classes)
|
|
363
|
+
Object.assign(typeInfo.enums, subResult.enums)
|
|
364
|
+
Object.assign(typeInfo.namespaces, subResult.namespaces)
|
|
365
|
+
Object.assign(typeInfo.jsdoc, subResult.jsdoc)
|
|
366
|
+
typeInfo.defaults.push(...subResult.defaults)
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// If still missing, try wildcard sources
|
|
371
|
+
if (wildcards.length > 0) {
|
|
372
|
+
for (const wildcardPath of wildcards) {
|
|
373
|
+
const subResult = parseDtsFile(wildcardPath, missing, visited)
|
|
374
|
+
if (subResult) {
|
|
375
|
+
Object.assign(typeInfo.functions, subResult.functions)
|
|
376
|
+
Object.assign(typeInfo.interfaces, subResult.interfaces)
|
|
377
|
+
Object.assign(typeInfo.types, subResult.types)
|
|
378
|
+
Object.assign(typeInfo.classes, subResult.classes)
|
|
379
|
+
Object.assign(typeInfo.enums, subResult.enums)
|
|
380
|
+
Object.assign(typeInfo.namespaces, subResult.namespaces)
|
|
381
|
+
Object.assign(typeInfo.jsdoc, subResult.jsdoc)
|
|
382
|
+
typeInfo.defaults.push(...subResult.defaults)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return typeInfo
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const isMain =
|
|
393
|
+
typeof import.meta.main === "boolean"
|
|
394
|
+
? import.meta.main
|
|
395
|
+
: Boolean(process.argv?.[1] && process.argv[1].endsWith("parse-dts.mjs"))
|
|
396
|
+
|
|
397
|
+
// CLI mode
|
|
398
|
+
if (isMain) {
|
|
399
|
+
const dtsPath = process.argv[2]
|
|
400
|
+
const filter = process.argv[3]
|
|
401
|
+
|
|
402
|
+
if (!dtsPath) {
|
|
403
|
+
console.error("Usage: node parse-dts.mjs <path-to-dts> [filter]")
|
|
404
|
+
process.exit(1)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const filterList = filter ? filter.split(",") : null
|
|
408
|
+
const result = parseDtsFile(dtsPath, filterList)
|
|
409
|
+
|
|
410
|
+
if (result) {
|
|
411
|
+
console.log(JSON.stringify(result, null, 2))
|
|
412
|
+
} else {
|
|
413
|
+
console.error("Failed to parse:", dtsPath)
|
|
414
|
+
process.exit(1)
|
|
415
|
+
}
|
|
416
|
+
}
|
package/src/server.mjs
CHANGED
|
@@ -2,7 +2,24 @@
|
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
-
|
|
5
|
+
let corePromise = null;
|
|
6
|
+
|
|
7
|
+
async function loadCore() {
|
|
8
|
+
if (!corePromise) {
|
|
9
|
+
corePromise = import("@deplens/core").catch(async (error) => {
|
|
10
|
+
try {
|
|
11
|
+
const fallbackUrl = new URL("./core/inspect.mjs", import.meta.url);
|
|
12
|
+
return await import(fallbackUrl.href);
|
|
13
|
+
} catch (fallbackError) {
|
|
14
|
+
const message = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
15
|
+
const err = new Error(`Failed to load @deplens/core. Fallback also failed: ${message}`);
|
|
16
|
+
err.cause = error;
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return corePromise;
|
|
22
|
+
}
|
|
6
23
|
|
|
7
24
|
const tools = [
|
|
8
25
|
{
|
|
@@ -80,6 +97,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
80
97
|
const target = args?.subpath ? `${args.target}/${args.subpath}` : args?.target;
|
|
81
98
|
if (!target) throw new Error("Missing required field: target");
|
|
82
99
|
|
|
100
|
+
const core = await loadCore();
|
|
101
|
+
const runInspect = core.runInspect || core.default?.runInspect;
|
|
102
|
+
if (!runInspect) {
|
|
103
|
+
throw new Error("Failed to load runInspect from @deplens/core");
|
|
104
|
+
}
|
|
83
105
|
const output = await runInspect({
|
|
84
106
|
target,
|
|
85
107
|
filter: args?.filter,
|