@pikku/inspector 0.7.6 → 0.8.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.
@@ -1,8 +1,7 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
3
  import { pathToRegexp } from 'path-to-regexp'
4
- import { APIDocs } from '@pikku/core'
5
- import { getInputTypes } from './add-http-route.js'
4
+ import { APIDocs, PikkuEventTypes } from '@pikku/core'
6
5
  import {
7
6
  extractFunctionName,
8
7
  getPropertyAssignmentInitializer,
@@ -189,8 +188,6 @@ export function addMessagesRoutes(
189
188
  if (fnMeta) {
190
189
  result[channelKey]![routeKey] = {
191
190
  pikkuFuncName: handlerName,
192
- inputs: fnMeta.inputs ?? null,
193
- outputs: fnMeta.outputs ?? null,
194
191
  }
195
192
  continue
196
193
  }
@@ -208,8 +205,6 @@ export function addMessagesRoutes(
208
205
  if (fnMeta) {
209
206
  result[channelKey]![routeKey] = {
210
207
  pikkuFuncName: handlerName,
211
- inputs: fnMeta.inputs ?? null,
212
- outputs: fnMeta.outputs ?? null,
213
208
  }
214
209
  continue
215
210
  }
@@ -244,8 +239,6 @@ export function addMessagesRoutes(
244
239
  if (fnMeta) {
245
240
  result[channelKey]![routeKey] = {
246
241
  pikkuFuncName: handlerName,
247
- inputs: fnMeta.inputs ?? null,
248
- outputs: fnMeta.outputs ?? null,
249
242
  }
250
243
  continue
251
244
  }
@@ -260,8 +253,6 @@ export function addMessagesRoutes(
260
253
  if (fnMeta) {
261
254
  result[channelKey]![routeKey] = {
262
255
  pikkuFuncName: handlerName,
263
- inputs: fnMeta.inputs ?? null,
264
- outputs: fnMeta.outputs ?? null,
265
256
  }
266
257
  continue
267
258
  }
@@ -294,8 +285,6 @@ export function addMessagesRoutes(
294
285
  }
295
286
  result[channelKey]![routeKey] = {
296
287
  pikkuFuncName: possibleMatch,
297
- inputs: fnMeta.inputs ?? null,
298
- outputs: fnMeta.outputs ?? null,
299
288
  }
300
289
  continue
301
290
  }
@@ -334,8 +323,6 @@ export function addMessagesRoutes(
334
323
  if (fnMeta) {
335
324
  result[channelKey]![routeKey] = {
336
325
  pikkuFuncName: handlerName,
337
- inputs: fnMeta.inputs ?? null,
338
- outputs: fnMeta.outputs ?? null,
339
326
  }
340
327
  continue // Skip the normal processing below
341
328
  }
@@ -361,8 +348,6 @@ export function addMessagesRoutes(
361
348
 
362
349
  result[channelKey]![routeKey] = {
363
350
  pikkuFuncName: handlerName,
364
- inputs: fnMeta.inputs ?? null,
365
- outputs: fnMeta.outputs ?? null,
366
351
  }
367
352
  }
368
353
  }
@@ -406,7 +391,10 @@ export function addChannel(
406
391
  const tags = getPropertyValue(obj, 'tags') as string[] | undefined
407
392
  const query = getPropertyValue(obj, 'query') as string[] | []
408
393
 
409
- if (!matchesFilters(filters, { tags }, { type: 'channel', name })) return
394
+ if (
395
+ !matchesFilters(filters, { tags }, { type: PikkuEventTypes.channel, name })
396
+ )
397
+ return
410
398
 
411
399
  const connect = getPropertyAssignmentInitializer(
412
400
  obj,
@@ -429,6 +417,7 @@ export function addChannel(
429
417
  false,
430
418
  checker
431
419
  )
420
+
432
421
  if (onMsgProp) {
433
422
  const handlerName =
434
423
  onMsgProp && getHandlerNameFromExpression(onMsgProp, checker)
@@ -442,8 +431,6 @@ export function addChannel(
442
431
  message = {
443
432
  pikkuFuncName: extractFunctionName(onMsgProp as any, checker)
444
433
  .pikkuFuncName,
445
- inputs: fnMeta.inputs ?? null,
446
- outputs: fnMeta.outputs ?? null,
447
434
  }
448
435
  }
449
436
  }
@@ -459,21 +446,22 @@ export function addChannel(
459
446
  input: null,
460
447
  params: params.length ? params : undefined,
461
448
  query: query?.length ? query : undefined,
462
- inputTypes: getInputTypes(
463
- state.channels.metaInputTypes,
464
- 'get',
465
- message?.inputs?.[0] ?? null,
466
- query,
467
- params
468
- ),
469
- connectPikkuFuncName: connect
470
- ? extractFunctionName(connect, checker).pikkuFuncName
449
+ // inputTypes: getInputTypes(
450
+ // state.channels.metaInputTypes,
451
+ // 'get',
452
+ // null, // TODO
453
+ // query,
454
+ // params
455
+ // ),
456
+ connect: connect
457
+ ? { pikkuFuncName: extractFunctionName(connect, checker).pikkuFuncName }
471
458
  : null,
472
- connect: !!connect,
473
- disconnectPikkuFuncName: disconnect
474
- ? extractFunctionName(disconnect as any, checker).pikkuFuncName
459
+ disconnect: disconnect
460
+ ? {
461
+ pikkuFuncName: extractFunctionName(disconnect as any, checker)
462
+ .pikkuFuncName,
463
+ }
475
464
  : null,
476
- disconnect: !!disconnect,
477
465
  message,
478
466
  messageRoutes,
479
467
  docs: docs ?? undefined,
@@ -2,7 +2,7 @@ import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
3
  import { pathToRegexp } from 'path-to-regexp'
4
4
  import { HTTPMethod } from '@pikku/core/http'
5
- import { APIDocs } from '@pikku/core'
5
+ import { APIDocs, PikkuEventTypes } from '@pikku/core'
6
6
  import {
7
7
  extractFunctionName,
8
8
  getPropertyAssignmentInitializer,
@@ -69,7 +69,13 @@ export const addHTTPRoute = (
69
69
  const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
70
70
  const query = (getPropertyValue(obj, 'query') as string[]) || []
71
71
 
72
- if (!matchesFilters(filters, { tags }, { type: 'http', name: route })) {
72
+ if (
73
+ !matchesFilters(
74
+ filters,
75
+ { tags },
76
+ { type: PikkuEventTypes.http, name: route }
77
+ )
78
+ ) {
73
79
  return
74
80
  }
75
81
 
@@ -0,0 +1,100 @@
1
+ import * as ts from 'typescript'
2
+ import { getPropertyValue } from './get-property-value.js'
3
+ import { PikkuEventTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState } from './types.js'
5
+ import {
6
+ extractFunctionName,
7
+ getPropertyAssignmentInitializer,
8
+ matchesFilters,
9
+ } from './utils.js'
10
+
11
+ export const addMCPPrompt = (
12
+ node: ts.Node,
13
+ checker: ts.TypeChecker,
14
+ state: InspectorState,
15
+ filters: InspectorFilters
16
+ ) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return
19
+ }
20
+
21
+ const args = node.arguments
22
+ const firstArg = args[0]
23
+ const expression = node.expression
24
+
25
+ // Check if the call is to addMCPPrompt
26
+ if (!ts.isIdentifier(expression) || expression.text !== 'addMCPPrompt') {
27
+ return
28
+ }
29
+
30
+ if (!firstArg) {
31
+ return
32
+ }
33
+
34
+ if (ts.isObjectLiteralExpression(firstArg)) {
35
+ const obj = firstArg
36
+
37
+ const nameValue = getPropertyValue(obj, 'name') as string | null
38
+ const descriptionValue = getPropertyValue(obj, 'description') as
39
+ | string
40
+ | null
41
+ const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
42
+
43
+ const funcInitializer = getPropertyAssignmentInitializer(
44
+ obj,
45
+ 'func',
46
+ true,
47
+ checker
48
+ )
49
+ if (!funcInitializer) {
50
+ console.error(`• No valid 'func' property for MCP prompt '${nameValue}'.`)
51
+ return
52
+ }
53
+
54
+ const pikkuFuncName = extractFunctionName(
55
+ funcInitializer,
56
+ checker
57
+ ).pikkuFuncName
58
+
59
+ if (!nameValue) {
60
+ console.error(`• MCP prompt is missing the required 'name' property.`)
61
+ return
62
+ }
63
+
64
+ if (!descriptionValue) {
65
+ console.error(`• MCP prompt '${nameValue}' is missing a description.`)
66
+ return
67
+ }
68
+
69
+ if (
70
+ !matchesFilters(
71
+ filters,
72
+ { tags },
73
+ { type: PikkuEventTypes.mcp, name: nameValue }
74
+ )
75
+ ) {
76
+ return
77
+ }
78
+
79
+ // lookup existing function metadata
80
+ const fnMeta = state.functions.meta[pikkuFuncName]
81
+ if (!fnMeta) {
82
+ console.error(`• No function metadata found for '${pikkuFuncName}'.`)
83
+ return
84
+ }
85
+ const inputSchema = fnMeta.inputs?.[0] || null
86
+ const outputSchema = fnMeta.outputs?.[0] || null
87
+
88
+ state.mcpEndpoints.files.add(node.getSourceFile().fileName)
89
+
90
+ state.mcpEndpoints.promptsMeta[nameValue] = {
91
+ pikkuFuncName,
92
+ name: nameValue,
93
+ description: descriptionValue,
94
+ tags,
95
+ inputSchema,
96
+ outputSchema,
97
+ arguments: [], // Will be populated by CLI during serialization
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,112 @@
1
+ import * as ts from 'typescript'
2
+ import { getPropertyValue } from './get-property-value.js'
3
+ import { PikkuEventTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState } from './types.js'
5
+ import {
6
+ extractFunctionName,
7
+ getPropertyAssignmentInitializer,
8
+ matchesFilters,
9
+ } from './utils.js'
10
+
11
+ export const addMCPResource = (
12
+ node: ts.Node,
13
+ checker: ts.TypeChecker,
14
+ state: InspectorState,
15
+ filters: InspectorFilters
16
+ ) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return
19
+ }
20
+
21
+ const args = node.arguments
22
+ const firstArg = args[0]
23
+ const expression = node.expression
24
+
25
+ // Check if the call is to addMCPResource
26
+ if (!ts.isIdentifier(expression) || expression.text !== 'addMCPResource') {
27
+ return
28
+ }
29
+
30
+ if (!firstArg) {
31
+ return
32
+ }
33
+
34
+ if (ts.isObjectLiteralExpression(firstArg)) {
35
+ const obj = firstArg
36
+
37
+ const uriValue = getPropertyValue(obj, 'uri') as string | null
38
+ const titleValue = getPropertyValue(obj, 'title') as string | null
39
+ const descriptionValue = getPropertyValue(obj, 'description') as
40
+ | string
41
+ | null
42
+ const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
43
+ const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
44
+
45
+ const funcInitializer = getPropertyAssignmentInitializer(
46
+ obj,
47
+ 'func',
48
+ true,
49
+ checker
50
+ )
51
+ if (!funcInitializer) {
52
+ console.error(
53
+ `• No valid 'func' property for MCP resource '${uriValue}'.`
54
+ )
55
+ return
56
+ }
57
+
58
+ const pikkuFuncName = extractFunctionName(
59
+ funcInitializer,
60
+ checker
61
+ ).pikkuFuncName
62
+
63
+ if (!uriValue) {
64
+ console.error(`• MCP resource is missing the required 'uri' property.`)
65
+ return
66
+ }
67
+
68
+ if (!titleValue) {
69
+ console.error(
70
+ `• MCP resource '${uriValue}' is missing the required 'title' property.`
71
+ )
72
+ return
73
+ }
74
+
75
+ if (!descriptionValue) {
76
+ console.error(`• MCP resource '${uriValue}' is missing a description.`)
77
+ return
78
+ }
79
+
80
+ if (
81
+ !matchesFilters(
82
+ filters,
83
+ { tags },
84
+ { type: PikkuEventTypes.mcp, name: uriValue }
85
+ )
86
+ ) {
87
+ return
88
+ }
89
+
90
+ // lookup existing function metadata
91
+ const fnMeta = state.functions.meta[pikkuFuncName]
92
+ if (!fnMeta) {
93
+ console.error(`• No function metadata found for '${pikkuFuncName}'.`)
94
+ return
95
+ }
96
+ const inputSchema = fnMeta.inputs?.[0] || null
97
+ const outputSchema = fnMeta.outputs?.[0] || null
98
+
99
+ state.mcpEndpoints.files.add(node.getSourceFile().fileName)
100
+
101
+ state.mcpEndpoints.resourcesMeta[uriValue] = {
102
+ pikkuFuncName,
103
+ uri: uriValue,
104
+ title: titleValue,
105
+ description: descriptionValue,
106
+ ...(streamingValue !== null && { streaming: streamingValue }),
107
+ tags,
108
+ inputSchema,
109
+ outputSchema,
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,103 @@
1
+ import * as ts from 'typescript'
2
+ import { getPropertyValue } from './get-property-value.js'
3
+ import { PikkuEventTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState } from './types.js'
5
+ import {
6
+ extractFunctionName,
7
+ getPropertyAssignmentInitializer,
8
+ matchesFilters,
9
+ } from './utils.js'
10
+
11
+ export const addMCPTool = (
12
+ node: ts.Node,
13
+ checker: ts.TypeChecker,
14
+ state: InspectorState,
15
+ filters: InspectorFilters
16
+ ) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return
19
+ }
20
+
21
+ const args = node.arguments
22
+ const firstArg = args[0]
23
+ const expression = node.expression
24
+
25
+ // Check if the call is to addMCPTool
26
+ if (!ts.isIdentifier(expression) || expression.text !== 'addMCPTool') {
27
+ return
28
+ }
29
+
30
+ if (!firstArg) {
31
+ return
32
+ }
33
+
34
+ if (ts.isObjectLiteralExpression(firstArg)) {
35
+ const obj = firstArg
36
+
37
+ const nameValue = getPropertyValue(obj, 'name') as string | null
38
+ const titleValue = getPropertyValue(obj, 'title') as string | null
39
+ const descriptionValue = getPropertyValue(obj, 'description') as
40
+ | string
41
+ | null
42
+ const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
43
+ const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
44
+
45
+ const funcInitializer = getPropertyAssignmentInitializer(
46
+ obj,
47
+ 'func',
48
+ true,
49
+ checker
50
+ )
51
+ if (!funcInitializer) {
52
+ console.error(`• No valid 'func' property for MCP tool '${nameValue}'.`)
53
+ return
54
+ }
55
+
56
+ const pikkuFuncName = extractFunctionName(
57
+ funcInitializer,
58
+ checker
59
+ ).pikkuFuncName
60
+
61
+ if (!nameValue) {
62
+ console.error(`• MCP tool is missing the required 'name' property.`)
63
+ return
64
+ }
65
+
66
+ if (!descriptionValue) {
67
+ console.error(`• MCP tool '${nameValue}' is missing a description.`)
68
+ return
69
+ }
70
+
71
+ if (
72
+ !matchesFilters(
73
+ filters,
74
+ { tags },
75
+ { type: PikkuEventTypes.mcp, name: nameValue }
76
+ )
77
+ ) {
78
+ return
79
+ }
80
+
81
+ // lookup existing function metadata
82
+ const fnMeta = state.functions.meta[pikkuFuncName]
83
+ if (!fnMeta) {
84
+ console.error(`• No function metadata found for '${pikkuFuncName}'.`)
85
+ return
86
+ }
87
+ const inputSchema = fnMeta.inputs?.[0] || null
88
+ const outputSchema = fnMeta.outputs?.[0] || null
89
+
90
+ state.mcpEndpoints.files.add(node.getSourceFile().fileName)
91
+
92
+ state.mcpEndpoints.toolsMeta[nameValue] = {
93
+ pikkuFuncName,
94
+ name: nameValue,
95
+ title: titleValue || undefined,
96
+ description: descriptionValue,
97
+ ...(streamingValue !== null && { streaming: streamingValue }),
98
+ tags,
99
+ inputSchema,
100
+ outputSchema,
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,88 @@
1
+ import * as ts from 'typescript'
2
+ import { getPropertyValue } from './get-property-value.js'
3
+ import { APIDocs, PikkuEventTypes } from '@pikku/core'
4
+ import { InspectorFilters, InspectorState } from './types.js'
5
+ import {
6
+ extractFunctionName,
7
+ getPropertyAssignmentInitializer,
8
+ matchesFilters,
9
+ } from './utils.js'
10
+
11
+ export const addQueueWorker = (
12
+ node: ts.Node,
13
+ checker: ts.TypeChecker,
14
+ state: InspectorState,
15
+ filters: InspectorFilters
16
+ ) => {
17
+ if (!ts.isCallExpression(node)) {
18
+ return
19
+ }
20
+
21
+ const args = node.arguments
22
+ const firstArg = args[0]
23
+ const expression = node.expression
24
+
25
+ // Check if the call is to addQueueWorker
26
+ if (!ts.isIdentifier(expression) || expression.text !== 'addQueueWorker') {
27
+ return
28
+ }
29
+
30
+ if (!firstArg) {
31
+ return
32
+ }
33
+
34
+ if (ts.isObjectLiteralExpression(firstArg)) {
35
+ const obj = firstArg
36
+
37
+ const queueName = getPropertyValue(obj, 'queueName') as string | null
38
+ const docs = (getPropertyValue(obj, 'docs') as APIDocs) || undefined
39
+ const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
40
+
41
+ // --- find the referenced function ---
42
+ const funcInitializer = getPropertyAssignmentInitializer(
43
+ obj,
44
+ 'func',
45
+ true,
46
+ checker
47
+ )
48
+ if (!funcInitializer) {
49
+ console.error(
50
+ `• No valid 'func' property for queue processor '${queueName}'.`
51
+ )
52
+ return
53
+ }
54
+
55
+ const pikkuFuncName = extractFunctionName(
56
+ funcInitializer,
57
+ checker
58
+ ).pikkuFuncName
59
+
60
+ if (!queueName) {
61
+ console.error(
62
+ `• No 'queueName' provided for queue processor function '${pikkuFuncName}'.`
63
+ )
64
+ return
65
+ }
66
+
67
+ if (
68
+ !matchesFilters(
69
+ filters,
70
+ { tags },
71
+ { type: PikkuEventTypes.queue, name: queueName }
72
+ )
73
+ ) {
74
+ console.info(
75
+ `• Skipping queue processor '${pikkuFuncName}' for queue '${queueName}' due to filter mismatch.`
76
+ )
77
+ return
78
+ }
79
+
80
+ state.queueWorkers.files.add(node.getSourceFile().fileName)
81
+ state.queueWorkers.meta[queueName] = {
82
+ pikkuFuncName,
83
+ queueName,
84
+ docs,
85
+ tags,
86
+ }
87
+ }
88
+ }
@@ -1,8 +1,12 @@
1
1
  import * as ts from 'typescript'
2
2
  import { getPropertyValue } from './get-property-value.js'
3
- import { APIDocs } from '@pikku/core'
3
+ import { APIDocs, PikkuEventTypes } from '@pikku/core'
4
4
  import { InspectorFilters, InspectorState } from './types.js'
5
- import { extractFunctionName, matchesFilters } from './utils.js'
5
+ import {
6
+ extractFunctionName,
7
+ getPropertyAssignmentInitializer,
8
+ matchesFilters,
9
+ } from './utils.js'
6
10
 
7
11
  export const addSchedule = (
8
12
  node: ts.Node,
@@ -35,22 +39,21 @@ export const addSchedule = (
35
39
  const docs = (getPropertyValue(obj, 'docs') as APIDocs) || undefined
36
40
  const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
37
41
 
38
- // --- find the referenced function ---
39
- const funcProp = obj.properties.find(
40
- (p) =>
41
- ts.isPropertyAssignment(p) &&
42
- ts.isIdentifier(p.name) &&
43
- p.name.text === 'func'
44
- ) as ts.PropertyAssignment | undefined
45
-
46
- if (!funcProp || !ts.isIdentifier(funcProp.initializer)) {
42
+ const funcInitializer = getPropertyAssignmentInitializer(
43
+ obj,
44
+ 'func',
45
+ true,
46
+ checker
47
+ )
48
+ if (!funcInitializer) {
47
49
  console.error(
48
50
  `• No valid 'func' property for scheduled task '${nameValue}'.`
49
51
  )
50
52
  return
51
53
  }
54
+
52
55
  const pikkuFuncName = extractFunctionName(
53
- funcProp.initializer,
56
+ funcInitializer,
54
57
  checker
55
58
  ).pikkuFuncName
56
59
 
@@ -59,7 +62,11 @@ export const addSchedule = (
59
62
  }
60
63
 
61
64
  if (
62
- !matchesFilters(filters, { tags }, { type: 'schedule', name: nameValue })
65
+ !matchesFilters(
66
+ filters,
67
+ { tags },
68
+ { type: PikkuEventTypes.scheduled, name: nameValue }
69
+ )
63
70
  ) {
64
71
  return
65
72
  }
package/src/inspector.ts CHANGED
@@ -42,7 +42,6 @@ export const inspect = (
42
42
  files: new Set(),
43
43
  },
44
44
  channels: {
45
- metaInputTypes: new Map(),
46
45
  files: new Set(),
47
46
  meta: {},
48
47
  },
@@ -50,9 +49,19 @@ export const inspect = (
50
49
  meta: {},
51
50
  files: new Set(),
52
51
  },
52
+ queueWorkers: {
53
+ meta: {},
54
+ files: new Set(),
55
+ },
53
56
  rpc: {
54
57
  meta: {},
55
58
  },
59
+ mcpEndpoints: {
60
+ resourcesMeta: {},
61
+ toolsMeta: {},
62
+ promptsMeta: {},
63
+ files: new Set(),
64
+ },
56
65
  }
57
66
 
58
67
  // First sweep: add all functions
package/src/types.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { ChannelsMeta } from '@pikku/core/channel'
2
2
  import { HTTPRoutesMeta } from '@pikku/core/http'
3
3
  import { ScheduledTasksMeta } from '@pikku/core/scheduler'
4
+ import { queueWorkersMeta } from '@pikku/core/queue'
5
+ import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core'
4
6
  import { TypesMap } from './types-map.js'
5
7
  import { FunctionsMeta } from '@pikku/core'
6
- import { RPCMeta } from '../../core/src/rpc/rpc-types.js'
8
+ import { RPCMeta } from '@pikku/core/rpc'
7
9
 
8
10
  export type PathToNameAndType = Map<
9
11
  string,
@@ -32,7 +34,6 @@ export interface InspectorFunctionState {
32
34
  }
33
35
 
34
36
  export interface InspectorChannelState {
35
- metaInputTypes: MetaInputTypes
36
37
  meta: ChannelsMeta
37
38
  files: Set<string>
38
39
  }
@@ -54,7 +55,17 @@ export interface InspectorState {
54
55
  meta: ScheduledTasksMeta
55
56
  files: Set<string>
56
57
  }
58
+ queueWorkers: {
59
+ meta: queueWorkersMeta
60
+ files: Set<string>
61
+ }
57
62
  rpc: {
58
63
  meta: Record<string, RPCMeta>
59
64
  }
65
+ mcpEndpoints: {
66
+ resourcesMeta: MCPResourceMeta
67
+ toolsMeta: MCPToolMeta
68
+ promptsMeta: MCPPromptMeta
69
+ files: Set<string>
70
+ }
60
71
  }