@leanmcp/core 0.4.5 → 0.4.7

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 CHANGED
@@ -185,6 +185,186 @@ var init_decorators = __esm({
185
185
  }
186
186
  });
187
187
 
188
+ // src/type-parser.ts
189
+ function loadTsMorph() {
190
+ if (tsMorphLoaded) {
191
+ return tsMorphProject !== null;
192
+ }
193
+ tsMorphLoaded = true;
194
+ try {
195
+ const customRequire = (0, import_node_module.createRequire)(import_meta.url);
196
+ const tsMorph = customRequire("ts-morph");
197
+ tsMorphProject = tsMorph.Project;
198
+ tsMorphNode = tsMorph.Node;
199
+ return true;
200
+ } catch (error) {
201
+ console.warn(`[type-parser] ts-morph not available: ${error.message}`);
202
+ return false;
203
+ }
204
+ }
205
+ function registerClassSource(className, sourceFile) {
206
+ classSourceMap.set(className, sourceFile);
207
+ }
208
+ function parseClassTypesSync(classConstructor, sourceFilePath) {
209
+ if (!loadTsMorph()) {
210
+ return /* @__PURE__ */ new Map();
211
+ }
212
+ const className = classConstructor.name;
213
+ let filePath = sourceFilePath || classSourceMap.get(className) || findSourceFile();
214
+ if (!filePath) {
215
+ return /* @__PURE__ */ new Map();
216
+ }
217
+ if (filePath.endsWith(".js")) {
218
+ const tsPath = filePath.replace(/\.js$/, ".ts");
219
+ if (import_fs.default.existsSync(tsPath)) {
220
+ filePath = tsPath;
221
+ }
222
+ }
223
+ const cacheKey = `${filePath}:${className}`;
224
+ if (typeCache.has(cacheKey)) {
225
+ return typeCache.get(cacheKey);
226
+ }
227
+ if (!import_fs.default.existsSync(filePath)) {
228
+ return /* @__PURE__ */ new Map();
229
+ }
230
+ try {
231
+ const project = new tsMorphProject({
232
+ skipAddingFilesFromTsConfig: true,
233
+ skipFileDependencyResolution: true,
234
+ useInMemoryFileSystem: false
235
+ });
236
+ const sourceFile = project.addSourceFileAtPath(filePath);
237
+ const classDecl = sourceFile.getClass(className);
238
+ if (!classDecl) {
239
+ return /* @__PURE__ */ new Map();
240
+ }
241
+ const propertyTypes = /* @__PURE__ */ new Map();
242
+ for (const prop of classDecl.getInstanceProperties()) {
243
+ if (tsMorphNode.isPropertyDeclaration(prop)) {
244
+ const propName = prop.getName();
245
+ const typeNode = prop.getTypeNode();
246
+ if (typeNode) {
247
+ const typeText = typeNode.getText();
248
+ const jsonSchemaType = typeTextToJsonSchema(typeText);
249
+ propertyTypes.set(propName, jsonSchemaType);
250
+ }
251
+ }
252
+ }
253
+ typeCache.set(cacheKey, propertyTypes);
254
+ return propertyTypes;
255
+ } catch (error) {
256
+ console.warn(`[type-parser] Failed to parse ${filePath}: ${error.message}`);
257
+ return /* @__PURE__ */ new Map();
258
+ }
259
+ }
260
+ function typeTextToJsonSchema(typeText) {
261
+ const type = typeText.trim().replace(/\?$/, "");
262
+ if (type.endsWith("[]")) {
263
+ const elementType = type.slice(0, -2);
264
+ return {
265
+ type: "array",
266
+ items: typeTextToJsonSchema(elementType)
267
+ };
268
+ }
269
+ const arrayMatch = type.match(/^Array<(.+)>$/);
270
+ if (arrayMatch) {
271
+ return {
272
+ type: "array",
273
+ items: typeTextToJsonSchema(arrayMatch[1])
274
+ };
275
+ }
276
+ const lowerType = type.toLowerCase();
277
+ switch (lowerType) {
278
+ case "string":
279
+ return {
280
+ type: "string"
281
+ };
282
+ case "number":
283
+ return {
284
+ type: "number"
285
+ };
286
+ case "integer":
287
+ return {
288
+ type: "integer"
289
+ };
290
+ case "boolean":
291
+ return {
292
+ type: "boolean"
293
+ };
294
+ case "object":
295
+ return {
296
+ type: "object"
297
+ };
298
+ case "any":
299
+ case "unknown":
300
+ return {};
301
+ // No constraints
302
+ case "null":
303
+ return {
304
+ type: "null"
305
+ };
306
+ }
307
+ if (type.includes("|")) {
308
+ const parts = type.split("|").map((p) => p.trim());
309
+ const nonNullParts = parts.filter((p) => p.toLowerCase() !== "null");
310
+ if (nonNullParts.length === 1) {
311
+ return typeTextToJsonSchema(nonNullParts[0]);
312
+ }
313
+ return {
314
+ anyOf: nonNullParts.map((p) => typeTextToJsonSchema(p))
315
+ };
316
+ }
317
+ return {
318
+ type: "object"
319
+ };
320
+ }
321
+ function findSourceFile() {
322
+ const originalPrepareStackTrace = Error.prepareStackTrace;
323
+ try {
324
+ Error.prepareStackTrace = (_, stack2) => stack2;
325
+ const err = new Error();
326
+ const stack = err.stack;
327
+ for (const site of stack) {
328
+ const fileName = site.getFileName();
329
+ if (fileName && !fileName.includes("node_modules") && !fileName.includes("type-parser") && !fileName.includes("schema-generator") && (fileName.endsWith(".ts") || fileName.endsWith(".js"))) {
330
+ if (fileName.endsWith(".js")) {
331
+ const tsPath = fileName.replace(/\.js$/, ".ts");
332
+ if (import_fs.default.existsSync(tsPath)) {
333
+ return tsPath;
334
+ }
335
+ }
336
+ return fileName;
337
+ }
338
+ }
339
+ } finally {
340
+ Error.prepareStackTrace = originalPrepareStackTrace;
341
+ }
342
+ return null;
343
+ }
344
+ function clearTypeCache() {
345
+ typeCache.clear();
346
+ }
347
+ var import_fs, import_node_module, import_meta, typeCache, classSourceMap, tsMorphProject, tsMorphNode, tsMorphLoaded;
348
+ var init_type_parser = __esm({
349
+ "src/type-parser.ts"() {
350
+ "use strict";
351
+ import_fs = __toESM(require("fs"));
352
+ import_node_module = require("module");
353
+ import_meta = {};
354
+ typeCache = /* @__PURE__ */ new Map();
355
+ classSourceMap = /* @__PURE__ */ new Map();
356
+ tsMorphProject = null;
357
+ tsMorphNode = null;
358
+ tsMorphLoaded = false;
359
+ __name(loadTsMorph, "loadTsMorph");
360
+ __name(registerClassSource, "registerClassSource");
361
+ __name(parseClassTypesSync, "parseClassTypesSync");
362
+ __name(typeTextToJsonSchema, "typeTextToJsonSchema");
363
+ __name(findSourceFile, "findSourceFile");
364
+ __name(clearTypeCache, "clearTypeCache");
365
+ }
366
+ });
367
+
188
368
  // src/schema-generator.ts
189
369
  function classToJsonSchema(classConstructor) {
190
370
  const instance = new classConstructor();
@@ -240,19 +420,51 @@ function Optional() {
240
420
  function SchemaConstraint(constraints) {
241
421
  return (target, propertyKey) => {
242
422
  Reflect.defineMetadata("schema:constraints", constraints, target, propertyKey);
423
+ const originalPrepareStackTrace = Error.prepareStackTrace;
424
+ try {
425
+ Error.prepareStackTrace = (_, stack2) => stack2;
426
+ const err = new Error();
427
+ const stack = err.stack;
428
+ for (const site of stack) {
429
+ const fileName = site.getFileName();
430
+ if (fileName && !fileName.includes("node_modules") && !fileName.includes("schema-generator") && (fileName.endsWith(".ts") || fileName.endsWith(".js"))) {
431
+ const className = target.constructor.name;
432
+ if (className && className !== "Object") {
433
+ registerClassSource(className, fileName);
434
+ }
435
+ break;
436
+ }
437
+ }
438
+ } finally {
439
+ Error.prepareStackTrace = originalPrepareStackTrace;
440
+ }
243
441
  };
244
442
  }
245
- function classToJsonSchemaWithConstraints(classConstructor) {
443
+ function classToJsonSchemaWithConstraints(classConstructor, sourceFilePath) {
246
444
  const instance = new classConstructor();
247
445
  const properties = {};
248
446
  const required = [];
447
+ const className = classConstructor.name;
448
+ const precomputedTypes = schemaMetadata?.[className];
449
+ const parsedTypes = precomputedTypes ? null : parseClassTypesSync(classConstructor, sourceFilePath);
249
450
  const propertyNames = Object.keys(instance);
250
451
  for (const propertyName of propertyNames) {
251
452
  const propertyType = Reflect.getMetadata("design:type", instance, propertyName);
252
453
  const constraints = Reflect.getMetadata("schema:constraints", instance, propertyName);
253
454
  const isOptional = Reflect.getMetadata("optional", instance, propertyName);
254
- let jsonSchemaType = "string";
255
- if (propertyType) {
455
+ let parsedType;
456
+ if (precomputedTypes) {
457
+ parsedType = precomputedTypes[propertyName];
458
+ } else if (parsedTypes) {
459
+ parsedType = parsedTypes.get(propertyName);
460
+ }
461
+ let propertySchema;
462
+ if (parsedType && parsedType.type) {
463
+ propertySchema = {
464
+ ...parsedType
465
+ };
466
+ } else if (propertyType) {
467
+ let jsonSchemaType = "string";
256
468
  switch (propertyType.name) {
257
469
  case "String":
258
470
  jsonSchemaType = "string";
@@ -272,8 +484,16 @@ function classToJsonSchemaWithConstraints(classConstructor) {
272
484
  default:
273
485
  jsonSchemaType = "object";
274
486
  }
487
+ propertySchema = {
488
+ type: jsonSchemaType
489
+ };
275
490
  } else if (constraints) {
276
- if (constraints.minLength !== void 0 || constraints.maxLength !== void 0 || constraints.pattern) {
491
+ let jsonSchemaType = "string";
492
+ if (constraints.type) {
493
+ jsonSchemaType = constraints.type;
494
+ } else if (constraints.items) {
495
+ jsonSchemaType = "array";
496
+ } else if (constraints.minLength !== void 0 || constraints.maxLength !== void 0 || constraints.pattern) {
277
497
  jsonSchemaType = "string";
278
498
  } else if (constraints.minimum !== void 0 || constraints.maximum !== void 0) {
279
499
  jsonSchemaType = "number";
@@ -287,12 +507,25 @@ function classToJsonSchemaWithConstraints(classConstructor) {
287
507
  jsonSchemaType = "string";
288
508
  }
289
509
  }
510
+ propertySchema = {
511
+ type: jsonSchemaType
512
+ };
513
+ } else {
514
+ propertySchema = {
515
+ type: "string"
516
+ };
517
+ }
518
+ if (constraints) {
519
+ const parsedItems = propertySchema.items;
520
+ propertySchema = {
521
+ ...propertySchema,
522
+ ...constraints
523
+ };
524
+ if (parsedItems && !constraints.items) {
525
+ propertySchema.items = parsedItems;
526
+ }
290
527
  }
291
- const propertySchema = {
292
- type: jsonSchemaType,
293
- ...constraints || {}
294
- };
295
- if (jsonSchemaType === "array" && !propertySchema.items) {
528
+ if (propertySchema.type === "array" && !propertySchema.items) {
296
529
  propertySchema.items = {
297
530
  type: "string"
298
531
  };
@@ -308,11 +541,22 @@ function classToJsonSchemaWithConstraints(classConstructor) {
308
541
  required: required.length > 0 ? required : void 0
309
542
  };
310
543
  }
311
- var import_reflect_metadata2;
544
+ var import_reflect_metadata2, import_path, import_fs2, schemaMetadata;
312
545
  var init_schema_generator = __esm({
313
546
  "src/schema-generator.ts"() {
314
547
  "use strict";
315
548
  import_reflect_metadata2 = require("reflect-metadata");
549
+ init_type_parser();
550
+ import_path = __toESM(require("path"));
551
+ import_fs2 = __toESM(require("fs"));
552
+ schemaMetadata = null;
553
+ try {
554
+ const metadataPath = import_path.default.join(process.cwd(), "dist", "schema-metadata.json");
555
+ if (import_fs2.default.existsSync(metadataPath)) {
556
+ schemaMetadata = JSON.parse(import_fs2.default.readFileSync(metadataPath, "utf-8"));
557
+ }
558
+ } catch {
559
+ }
316
560
  __name(classToJsonSchema, "classToJsonSchema");
317
561
  __name(Optional, "Optional");
318
562
  __name(SchemaConstraint, "SchemaConstraint");
@@ -445,9 +689,9 @@ function validatePort(port) {
445
689
  throw new Error(`Invalid port: ${port}. Must be an integer between 1-65535`);
446
690
  }
447
691
  }
448
- function validatePath(path2) {
449
- if (path2.includes("..") || path2.includes("~")) {
450
- throw new Error(`Invalid path: ${path2}. Path traversal patterns are not allowed`);
692
+ function validatePath(path3) {
693
+ if (path3.includes("..") || path3.includes("~")) {
694
+ throw new Error(`Invalid path: ${path3}. Path traversal patterns are not allowed`);
451
695
  }
452
696
  }
453
697
  function validateServiceName(name) {
@@ -698,9 +942,9 @@ async function createHTTPServer(serverInput, options) {
698
942
  if (!serverOptions.mcpDir) {
699
943
  const callerFile = getCallerFile();
700
944
  if (callerFile) {
701
- const path2 = await import("path");
702
- const callerDir = path2.dirname(callerFile);
703
- resolvedMcpDir = path2.join(callerDir, "mcp");
945
+ const path3 = await import("path");
946
+ const callerDir = path3.dirname(callerFile);
947
+ resolvedMcpDir = path3.join(callerDir, "mcp");
704
948
  }
705
949
  } else {
706
950
  resolvedMcpDir = serverOptions.mcpDir;
@@ -1617,6 +1861,7 @@ __export(index_exports, {
1617
1861
  UserEnvs: () => UserEnvs,
1618
1862
  classToJsonSchema: () => classToJsonSchema,
1619
1863
  classToJsonSchemaWithConstraints: () => classToJsonSchemaWithConstraints,
1864
+ clearTypeCache: () => clearTypeCache,
1620
1865
  createAuthError: () => createAuthError,
1621
1866
  createHTTPServer: () => createHTTPServer,
1622
1867
  createProtectedResourceMetadata: () => createProtectedResourceMetadata,
@@ -1625,6 +1870,8 @@ __export(index_exports, {
1625
1870
  getDecoratedMethods: () => getDecoratedMethods,
1626
1871
  getMethodMetadata: () => getMethodMetadata,
1627
1872
  isAuthError: () => isAuthError,
1873
+ parseClassTypesSync: () => parseClassTypesSync,
1874
+ registerClassSource: () => registerClassSource,
1628
1875
  startMCPServer: () => startMCPServer,
1629
1876
  validateNonEmpty: () => validateNonEmpty,
1630
1877
  validatePath: () => validatePath,
@@ -1638,12 +1885,12 @@ async function startMCPServer(options) {
1638
1885
  await runtime.start();
1639
1886
  return runtime;
1640
1887
  }
1641
- var import_reflect_metadata3, import_fs, import_path, import_url, import_server, import_stdio, import_types, import_ajv, ajv, MCPServer, MCPServerRuntime;
1888
+ var import_reflect_metadata3, import_fs3, import_path2, import_url, import_server, import_stdio, import_types, import_ajv, ajv, MCPServer, MCPServerRuntime;
1642
1889
  var init_index = __esm({
1643
1890
  "src/index.ts"() {
1644
1891
  import_reflect_metadata3 = require("reflect-metadata");
1645
- import_fs = __toESM(require("fs"));
1646
- import_path = __toESM(require("path"));
1892
+ import_fs3 = __toESM(require("fs"));
1893
+ import_path2 = __toESM(require("path"));
1647
1894
  import_url = require("url");
1648
1895
  import_server = require("@modelcontextprotocol/sdk/server/index.js");
1649
1896
  import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
@@ -1651,6 +1898,7 @@ var init_index = __esm({
1651
1898
  import_ajv = __toESM(require("ajv"));
1652
1899
  init_decorators();
1653
1900
  init_schema_generator();
1901
+ init_type_parser();
1654
1902
  init_http_server();
1655
1903
  init_logger();
1656
1904
  init_validation();
@@ -1733,13 +1981,13 @@ var init_index = __esm({
1733
1981
  } else {
1734
1982
  const callerFile = this.getCallerFile();
1735
1983
  if (callerFile) {
1736
- const callerDir = import_path.default.dirname(callerFile);
1737
- mcpDir = import_path.default.join(callerDir, "mcp");
1984
+ const callerDir = import_path2.default.dirname(callerFile);
1985
+ mcpDir = import_path2.default.join(callerDir, "mcp");
1738
1986
  } else {
1739
- mcpDir = import_path.default.join(process.cwd(), "mcp");
1987
+ mcpDir = import_path2.default.join(process.cwd(), "mcp");
1740
1988
  }
1741
1989
  }
1742
- if (import_fs.default.existsSync(mcpDir)) {
1990
+ if (import_fs3.default.existsSync(mcpDir)) {
1743
1991
  this.logger.debug(`Auto-discovering services from: ${mcpDir}`);
1744
1992
  await this.autoRegisterServices(mcpDir, serviceFactories);
1745
1993
  } else {
@@ -1989,7 +2237,7 @@ var init_index = __esm({
1989
2237
  */
1990
2238
  async autoRegisterServices(mcpDir, serviceFactories) {
1991
2239
  this.logger.debug(`Auto-registering services from: ${mcpDir}`);
1992
- if (!import_fs.default.existsSync(mcpDir)) {
2240
+ if (!import_fs3.default.existsSync(mcpDir)) {
1993
2241
  this.logger.warn(`MCP directory not found: ${mcpDir}`);
1994
2242
  return;
1995
2243
  }
@@ -2008,11 +2256,11 @@ var init_index = __esm({
2008
2256
  */
2009
2257
  findServiceFiles(dir) {
2010
2258
  const files = [];
2011
- const entries = import_fs.default.readdirSync(dir, {
2259
+ const entries = import_fs3.default.readdirSync(dir, {
2012
2260
  withFileTypes: true
2013
2261
  });
2014
2262
  for (const entry of entries) {
2015
- const fullPath = import_path.default.join(dir, entry.name);
2263
+ const fullPath = import_path2.default.join(dir, entry.name);
2016
2264
  if (entry.isDirectory()) {
2017
2265
  files.push(...this.findServiceFiles(fullPath));
2018
2266
  } else if (entry.isFile()) {
@@ -2043,7 +2291,7 @@ var init_index = __esm({
2043
2291
  }
2044
2292
  this.registerService(instance);
2045
2293
  registeredCount++;
2046
- this.logger.debug(`Registered service: ${exportName} from ${import_path.default.basename(filePath)}`);
2294
+ this.logger.debug(`Registered service: ${exportName} from ${import_path2.default.basename(filePath)}`);
2047
2295
  } catch (error) {
2048
2296
  this.logger.warn(`Skipped ${exportName}: ${error.message}`);
2049
2297
  }
@@ -2142,8 +2390,8 @@ var init_index = __esm({
2142
2390
  return;
2143
2391
  }
2144
2392
  try {
2145
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2146
- if (!import_fs.default.existsSync(manifestPath)) {
2393
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2394
+ if (!import_fs3.default.existsSync(manifestPath)) {
2147
2395
  return;
2148
2396
  }
2149
2397
  if (this.logging) {
@@ -2185,8 +2433,8 @@ var init_index = __esm({
2185
2433
  */
2186
2434
  async reloadUIManifest() {
2187
2435
  try {
2188
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2189
- if (!import_fs.default.existsSync(manifestPath)) {
2436
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2437
+ if (!import_fs3.default.existsSync(manifestPath)) {
2190
2438
  const uiResourceUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2191
2439
  for (const uri of uiResourceUris) {
2192
2440
  this.resources.delete(uri);
@@ -2196,7 +2444,7 @@ var init_index = __esm({
2196
2444
  }
2197
2445
  return;
2198
2446
  }
2199
- const manifest = JSON.parse(import_fs.default.readFileSync(manifestPath, "utf-8"));
2447
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
2200
2448
  const currentUIUris = new Set(Object.keys(manifest));
2201
2449
  const registeredUIUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2202
2450
  for (const uri of registeredUIUris) {
@@ -2212,7 +2460,7 @@ var init_index = __esm({
2212
2460
  const htmlPath = isString ? entry : entry.htmlPath;
2213
2461
  const isGPTApp = !isString && entry.isGPTApp;
2214
2462
  const gptMeta = !isString ? entry.gptMeta : void 0;
2215
- if (!import_fs.default.existsSync(htmlPath)) {
2463
+ if (!import_fs3.default.existsSync(htmlPath)) {
2216
2464
  if (this.logging) {
2217
2465
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2218
2466
  }
@@ -2233,8 +2481,8 @@ var init_index = __esm({
2233
2481
  mimeType,
2234
2482
  inputSchema: void 0,
2235
2483
  method: /* @__PURE__ */ __name(async () => {
2236
- if (import_fs.default.existsSync(htmlPath)) {
2237
- const html = import_fs.default.readFileSync(htmlPath, "utf-8");
2484
+ if (import_fs3.default.existsSync(htmlPath)) {
2485
+ const html = import_fs3.default.readFileSync(htmlPath, "utf-8");
2238
2486
  return {
2239
2487
  text: html,
2240
2488
  _meta: Object.keys(_meta).length > 0 ? _meta : void 0
@@ -2262,11 +2510,11 @@ var init_index = __esm({
2262
2510
  */
2263
2511
  async loadUIManifest() {
2264
2512
  try {
2265
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2266
- if (!import_fs.default.existsSync(manifestPath)) {
2513
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2514
+ if (!import_fs3.default.existsSync(manifestPath)) {
2267
2515
  return;
2268
2516
  }
2269
- const manifest = JSON.parse(import_fs.default.readFileSync(manifestPath, "utf-8"));
2517
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
2270
2518
  for (const [uri, entry] of Object.entries(manifest)) {
2271
2519
  const isString = typeof entry === "string";
2272
2520
  const htmlPath = isString ? entry : entry.htmlPath;
@@ -2278,13 +2526,13 @@ var init_index = __esm({
2278
2526
  }
2279
2527
  continue;
2280
2528
  }
2281
- if (!import_fs.default.existsSync(htmlPath)) {
2529
+ if (!import_fs3.default.existsSync(htmlPath)) {
2282
2530
  if (this.logging) {
2283
2531
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2284
2532
  }
2285
2533
  continue;
2286
2534
  }
2287
- const html = import_fs.default.readFileSync(htmlPath, "utf-8");
2535
+ const html = import_fs3.default.readFileSync(htmlPath, "utf-8");
2288
2536
  const mimeType = isGPTApp ? "text/html+skybridge" : "text/html;profile=mcp-app";
2289
2537
  const _meta = {};
2290
2538
  if (isGPTApp) {
@@ -2535,19 +2783,19 @@ var init_index = __esm({
2535
2783
  });
2536
2784
  }
2537
2785
  async loadServices() {
2538
- const absPath = import_path.default.resolve(this.options.servicesDir);
2539
- if (!import_fs.default.existsSync(absPath)) {
2786
+ const absPath = import_path2.default.resolve(this.options.servicesDir);
2787
+ if (!import_fs3.default.existsSync(absPath)) {
2540
2788
  this.logger.error(`Services directory not found: ${absPath}`);
2541
2789
  return;
2542
2790
  }
2543
- const files = import_fs.default.readdirSync(absPath);
2791
+ const files = import_fs3.default.readdirSync(absPath);
2544
2792
  let toolCount = 0;
2545
2793
  let promptCount = 0;
2546
2794
  let resourceCount = 0;
2547
2795
  for (const dir of files) {
2548
- const modulePath = import_path.default.join(absPath, dir, "index.ts");
2549
- const modulePathJs = import_path.default.join(absPath, dir, "index.js");
2550
- const finalPath = import_fs.default.existsSync(modulePath) ? modulePath : import_fs.default.existsSync(modulePathJs) ? modulePathJs : null;
2796
+ const modulePath = import_path2.default.join(absPath, dir, "index.ts");
2797
+ const modulePathJs = import_path2.default.join(absPath, dir, "index.js");
2798
+ const finalPath = import_fs3.default.existsSync(modulePath) ? modulePath : import_fs3.default.existsSync(modulePathJs) ? modulePathJs : null;
2551
2799
  if (finalPath) {
2552
2800
  try {
2553
2801
  const fileUrl = (0, import_url.pathToFileURL)(finalPath).href;
@@ -2681,6 +2929,7 @@ init_index();
2681
2929
  UserEnvs,
2682
2930
  classToJsonSchema,
2683
2931
  classToJsonSchemaWithConstraints,
2932
+ clearTypeCache,
2684
2933
  createAuthError,
2685
2934
  createHTTPServer,
2686
2935
  createProtectedResourceMetadata,
@@ -2689,6 +2938,8 @@ init_index();
2689
2938
  getDecoratedMethods,
2690
2939
  getMethodMetadata,
2691
2940
  isAuthError,
2941
+ parseClassTypesSync,
2942
+ registerClassSource,
2692
2943
  startMCPServer,
2693
2944
  validateNonEmpty,
2694
2945
  validatePath,