@leanmcp/core 0.4.6 → 0.4.7-alpha.29.3837d4c

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 LeanMCP Contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 LeanMCP Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.d.mts CHANGED
@@ -386,8 +386,8 @@ declare function SchemaConstraint(constraints: {
386
386
  }): PropertyDecorator;
387
387
  /**
388
388
  * Enhanced schema generator that includes constraints.
389
- * Now integrates with type-parser to extract actual TypeScript types
390
- * (including array element types like `string[]`).
389
+ * Uses pre-computed metadata (from leanmcp build) when available for fast startup.
390
+ * Falls back to ts-morph parsing in dev mode.
391
391
  */
392
392
  declare function classToJsonSchemaWithConstraints(classConstructor: new () => any, sourceFilePath?: string): any;
393
393
 
package/dist/index.d.ts CHANGED
@@ -386,8 +386,8 @@ declare function SchemaConstraint(constraints: {
386
386
  }): PropertyDecorator;
387
387
  /**
388
388
  * Enhanced schema generator that includes constraints.
389
- * Now integrates with type-parser to extract actual TypeScript types
390
- * (including array element types like `string[]`).
389
+ * Uses pre-computed metadata (from leanmcp build) when available for fast startup.
390
+ * Falls back to ts-morph parsing in dev mode.
391
391
  */
392
392
  declare function classToJsonSchemaWithConstraints(classConstructor: new () => any, sourceFilePath?: string): any;
393
393
 
package/dist/index.js CHANGED
@@ -444,13 +444,20 @@ function classToJsonSchemaWithConstraints(classConstructor, sourceFilePath) {
444
444
  const instance = new classConstructor();
445
445
  const properties = {};
446
446
  const required = [];
447
- const parsedTypes = parseClassTypesSync(classConstructor, sourceFilePath);
447
+ const className = classConstructor.name;
448
+ const precomputedTypes = schemaMetadata?.[className];
449
+ const parsedTypes = precomputedTypes ? null : parseClassTypesSync(classConstructor, sourceFilePath);
448
450
  const propertyNames = Object.keys(instance);
449
451
  for (const propertyName of propertyNames) {
450
452
  const propertyType = Reflect.getMetadata("design:type", instance, propertyName);
451
453
  const constraints = Reflect.getMetadata("schema:constraints", instance, propertyName);
452
454
  const isOptional = Reflect.getMetadata("optional", instance, propertyName);
453
- const parsedType = parsedTypes.get(propertyName);
455
+ let parsedType;
456
+ if (precomputedTypes) {
457
+ parsedType = precomputedTypes[propertyName];
458
+ } else if (parsedTypes) {
459
+ parsedType = parsedTypes.get(propertyName);
460
+ }
454
461
  let propertySchema;
455
462
  if (parsedType && parsedType.type) {
456
463
  propertySchema = {
@@ -534,12 +541,22 @@ function classToJsonSchemaWithConstraints(classConstructor, sourceFilePath) {
534
541
  required: required.length > 0 ? required : void 0
535
542
  };
536
543
  }
537
- var import_reflect_metadata2;
544
+ var import_reflect_metadata2, import_path, import_fs2, schemaMetadata;
538
545
  var init_schema_generator = __esm({
539
546
  "src/schema-generator.ts"() {
540
547
  "use strict";
541
548
  import_reflect_metadata2 = require("reflect-metadata");
542
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
+ }
543
560
  __name(classToJsonSchema, "classToJsonSchema");
544
561
  __name(Optional, "Optional");
545
562
  __name(SchemaConstraint, "SchemaConstraint");
@@ -672,9 +689,9 @@ function validatePort(port) {
672
689
  throw new Error(`Invalid port: ${port}. Must be an integer between 1-65535`);
673
690
  }
674
691
  }
675
- function validatePath(path2) {
676
- if (path2.includes("..") || path2.includes("~")) {
677
- 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`);
678
695
  }
679
696
  }
680
697
  function validateServiceName(name) {
@@ -925,9 +942,9 @@ async function createHTTPServer(serverInput, options) {
925
942
  if (!serverOptions.mcpDir) {
926
943
  const callerFile = getCallerFile();
927
944
  if (callerFile) {
928
- const path2 = await import("path");
929
- const callerDir = path2.dirname(callerFile);
930
- resolvedMcpDir = path2.join(callerDir, "mcp");
945
+ const path3 = await import("path");
946
+ const callerDir = path3.dirname(callerFile);
947
+ resolvedMcpDir = path3.join(callerDir, "mcp");
931
948
  }
932
949
  } else {
933
950
  resolvedMcpDir = serverOptions.mcpDir;
@@ -1868,12 +1885,12 @@ async function startMCPServer(options) {
1868
1885
  await runtime.start();
1869
1886
  return runtime;
1870
1887
  }
1871
- var import_reflect_metadata3, import_fs2, 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;
1872
1889
  var init_index = __esm({
1873
1890
  "src/index.ts"() {
1874
1891
  import_reflect_metadata3 = require("reflect-metadata");
1875
- import_fs2 = __toESM(require("fs"));
1876
- import_path = __toESM(require("path"));
1892
+ import_fs3 = __toESM(require("fs"));
1893
+ import_path2 = __toESM(require("path"));
1877
1894
  import_url = require("url");
1878
1895
  import_server = require("@modelcontextprotocol/sdk/server/index.js");
1879
1896
  import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
@@ -1964,13 +1981,13 @@ var init_index = __esm({
1964
1981
  } else {
1965
1982
  const callerFile = this.getCallerFile();
1966
1983
  if (callerFile) {
1967
- const callerDir = import_path.default.dirname(callerFile);
1968
- mcpDir = import_path.default.join(callerDir, "mcp");
1984
+ const callerDir = import_path2.default.dirname(callerFile);
1985
+ mcpDir = import_path2.default.join(callerDir, "mcp");
1969
1986
  } else {
1970
- mcpDir = import_path.default.join(process.cwd(), "mcp");
1987
+ mcpDir = import_path2.default.join(process.cwd(), "mcp");
1971
1988
  }
1972
1989
  }
1973
- if (import_fs2.default.existsSync(mcpDir)) {
1990
+ if (import_fs3.default.existsSync(mcpDir)) {
1974
1991
  this.logger.debug(`Auto-discovering services from: ${mcpDir}`);
1975
1992
  await this.autoRegisterServices(mcpDir, serviceFactories);
1976
1993
  } else {
@@ -2220,7 +2237,7 @@ var init_index = __esm({
2220
2237
  */
2221
2238
  async autoRegisterServices(mcpDir, serviceFactories) {
2222
2239
  this.logger.debug(`Auto-registering services from: ${mcpDir}`);
2223
- if (!import_fs2.default.existsSync(mcpDir)) {
2240
+ if (!import_fs3.default.existsSync(mcpDir)) {
2224
2241
  this.logger.warn(`MCP directory not found: ${mcpDir}`);
2225
2242
  return;
2226
2243
  }
@@ -2239,11 +2256,11 @@ var init_index = __esm({
2239
2256
  */
2240
2257
  findServiceFiles(dir) {
2241
2258
  const files = [];
2242
- const entries = import_fs2.default.readdirSync(dir, {
2259
+ const entries = import_fs3.default.readdirSync(dir, {
2243
2260
  withFileTypes: true
2244
2261
  });
2245
2262
  for (const entry of entries) {
2246
- const fullPath = import_path.default.join(dir, entry.name);
2263
+ const fullPath = import_path2.default.join(dir, entry.name);
2247
2264
  if (entry.isDirectory()) {
2248
2265
  files.push(...this.findServiceFiles(fullPath));
2249
2266
  } else if (entry.isFile()) {
@@ -2274,7 +2291,7 @@ var init_index = __esm({
2274
2291
  }
2275
2292
  this.registerService(instance);
2276
2293
  registeredCount++;
2277
- 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)}`);
2278
2295
  } catch (error) {
2279
2296
  this.logger.warn(`Skipped ${exportName}: ${error.message}`);
2280
2297
  }
@@ -2373,8 +2390,8 @@ var init_index = __esm({
2373
2390
  return;
2374
2391
  }
2375
2392
  try {
2376
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2377
- if (!import_fs2.default.existsSync(manifestPath)) {
2393
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2394
+ if (!import_fs3.default.existsSync(manifestPath)) {
2378
2395
  return;
2379
2396
  }
2380
2397
  if (this.logging) {
@@ -2416,8 +2433,8 @@ var init_index = __esm({
2416
2433
  */
2417
2434
  async reloadUIManifest() {
2418
2435
  try {
2419
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2420
- if (!import_fs2.default.existsSync(manifestPath)) {
2436
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2437
+ if (!import_fs3.default.existsSync(manifestPath)) {
2421
2438
  const uiResourceUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2422
2439
  for (const uri of uiResourceUris) {
2423
2440
  this.resources.delete(uri);
@@ -2427,7 +2444,7 @@ var init_index = __esm({
2427
2444
  }
2428
2445
  return;
2429
2446
  }
2430
- const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
2447
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
2431
2448
  const currentUIUris = new Set(Object.keys(manifest));
2432
2449
  const registeredUIUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2433
2450
  for (const uri of registeredUIUris) {
@@ -2443,7 +2460,7 @@ var init_index = __esm({
2443
2460
  const htmlPath = isString ? entry : entry.htmlPath;
2444
2461
  const isGPTApp = !isString && entry.isGPTApp;
2445
2462
  const gptMeta = !isString ? entry.gptMeta : void 0;
2446
- if (!import_fs2.default.existsSync(htmlPath)) {
2463
+ if (!import_fs3.default.existsSync(htmlPath)) {
2447
2464
  if (this.logging) {
2448
2465
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2449
2466
  }
@@ -2464,8 +2481,8 @@ var init_index = __esm({
2464
2481
  mimeType,
2465
2482
  inputSchema: void 0,
2466
2483
  method: /* @__PURE__ */ __name(async () => {
2467
- if (import_fs2.default.existsSync(htmlPath)) {
2468
- const html = import_fs2.default.readFileSync(htmlPath, "utf-8");
2484
+ if (import_fs3.default.existsSync(htmlPath)) {
2485
+ const html = import_fs3.default.readFileSync(htmlPath, "utf-8");
2469
2486
  return {
2470
2487
  text: html,
2471
2488
  _meta: Object.keys(_meta).length > 0 ? _meta : void 0
@@ -2493,11 +2510,11 @@ var init_index = __esm({
2493
2510
  */
2494
2511
  async loadUIManifest() {
2495
2512
  try {
2496
- const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
2497
- if (!import_fs2.default.existsSync(manifestPath)) {
2513
+ const manifestPath = import_path2.default.join(process.cwd(), "dist", "ui-manifest.json");
2514
+ if (!import_fs3.default.existsSync(manifestPath)) {
2498
2515
  return;
2499
2516
  }
2500
- const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
2517
+ const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
2501
2518
  for (const [uri, entry] of Object.entries(manifest)) {
2502
2519
  const isString = typeof entry === "string";
2503
2520
  const htmlPath = isString ? entry : entry.htmlPath;
@@ -2509,13 +2526,13 @@ var init_index = __esm({
2509
2526
  }
2510
2527
  continue;
2511
2528
  }
2512
- if (!import_fs2.default.existsSync(htmlPath)) {
2529
+ if (!import_fs3.default.existsSync(htmlPath)) {
2513
2530
  if (this.logging) {
2514
2531
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2515
2532
  }
2516
2533
  continue;
2517
2534
  }
2518
- const html = import_fs2.default.readFileSync(htmlPath, "utf-8");
2535
+ const html = import_fs3.default.readFileSync(htmlPath, "utf-8");
2519
2536
  const mimeType = isGPTApp ? "text/html+skybridge" : "text/html;profile=mcp-app";
2520
2537
  const _meta = {};
2521
2538
  if (isGPTApp) {
@@ -2766,19 +2783,19 @@ var init_index = __esm({
2766
2783
  });
2767
2784
  }
2768
2785
  async loadServices() {
2769
- const absPath = import_path.default.resolve(this.options.servicesDir);
2770
- if (!import_fs2.default.existsSync(absPath)) {
2786
+ const absPath = import_path2.default.resolve(this.options.servicesDir);
2787
+ if (!import_fs3.default.existsSync(absPath)) {
2771
2788
  this.logger.error(`Services directory not found: ${absPath}`);
2772
2789
  return;
2773
2790
  }
2774
- const files = import_fs2.default.readdirSync(absPath);
2791
+ const files = import_fs3.default.readdirSync(absPath);
2775
2792
  let toolCount = 0;
2776
2793
  let promptCount = 0;
2777
2794
  let resourceCount = 0;
2778
2795
  for (const dir of files) {
2779
- const modulePath = import_path.default.join(absPath, dir, "index.ts");
2780
- const modulePathJs = import_path.default.join(absPath, dir, "index.js");
2781
- const finalPath = import_fs2.default.existsSync(modulePath) ? modulePath : import_fs2.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;
2782
2799
  if (finalPath) {
2783
2800
  try {
2784
2801
  const fileUrl = (0, import_url.pathToFileURL)(finalPath).href;
package/dist/index.mjs CHANGED
@@ -10,8 +10,8 @@ import {
10
10
 
11
11
  // src/index.ts
12
12
  import "reflect-metadata";
13
- import fs2 from "fs";
14
- import path from "path";
13
+ import fs3 from "fs";
14
+ import path2 from "path";
15
15
  import { pathToFileURL } from "url";
16
16
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
17
17
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -343,6 +343,16 @@ function clearTypeCache() {
343
343
  __name(clearTypeCache, "clearTypeCache");
344
344
 
345
345
  // src/schema-generator.ts
346
+ import path from "path";
347
+ import fs2 from "fs";
348
+ var schemaMetadata = null;
349
+ try {
350
+ const metadataPath = path.join(process.cwd(), "dist", "schema-metadata.json");
351
+ if (fs2.existsSync(metadataPath)) {
352
+ schemaMetadata = JSON.parse(fs2.readFileSync(metadataPath, "utf-8"));
353
+ }
354
+ } catch {
355
+ }
346
356
  function classToJsonSchema(classConstructor) {
347
357
  const instance = new classConstructor();
348
358
  const properties = {};
@@ -424,13 +434,20 @@ function classToJsonSchemaWithConstraints(classConstructor, sourceFilePath) {
424
434
  const instance = new classConstructor();
425
435
  const properties = {};
426
436
  const required = [];
427
- const parsedTypes = parseClassTypesSync(classConstructor, sourceFilePath);
437
+ const className = classConstructor.name;
438
+ const precomputedTypes = schemaMetadata?.[className];
439
+ const parsedTypes = precomputedTypes ? null : parseClassTypesSync(classConstructor, sourceFilePath);
428
440
  const propertyNames = Object.keys(instance);
429
441
  for (const propertyName of propertyNames) {
430
442
  const propertyType = Reflect.getMetadata("design:type", instance, propertyName);
431
443
  const constraints = Reflect.getMetadata("schema:constraints", instance, propertyName);
432
444
  const isOptional = Reflect.getMetadata("optional", instance, propertyName);
433
- const parsedType = parsedTypes.get(propertyName);
445
+ let parsedType;
446
+ if (precomputedTypes) {
447
+ parsedType = precomputedTypes[propertyName];
448
+ } else if (parsedTypes) {
449
+ parsedType = parsedTypes.get(propertyName);
450
+ }
434
451
  let propertySchema;
435
452
  if (parsedType && parsedType.type) {
436
453
  propertySchema = {
@@ -526,9 +543,9 @@ function validatePort(port) {
526
543
  }
527
544
  }
528
545
  __name(validatePort, "validatePort");
529
- function validatePath(path2) {
530
- if (path2.includes("..") || path2.includes("~")) {
531
- throw new Error(`Invalid path: ${path2}. Path traversal patterns are not allowed`);
546
+ function validatePath(path3) {
547
+ if (path3.includes("..") || path3.includes("~")) {
548
+ throw new Error(`Invalid path: ${path3}. Path traversal patterns are not allowed`);
532
549
  }
533
550
  }
534
551
  __name(validatePath, "validatePath");
@@ -617,9 +634,9 @@ async function createHTTPServer(serverInput, options) {
617
634
  if (!serverOptions.mcpDir) {
618
635
  const callerFile = getCallerFile();
619
636
  if (callerFile) {
620
- const path2 = await import("path");
621
- const callerDir = path2.dirname(callerFile);
622
- resolvedMcpDir = path2.join(callerDir, "mcp");
637
+ const path3 = await import("path");
638
+ const callerDir = path3.dirname(callerFile);
639
+ resolvedMcpDir = path3.join(callerDir, "mcp");
623
640
  }
624
641
  } else {
625
642
  resolvedMcpDir = serverOptions.mcpDir;
@@ -1549,13 +1566,13 @@ var MCPServer = class {
1549
1566
  } else {
1550
1567
  const callerFile = this.getCallerFile();
1551
1568
  if (callerFile) {
1552
- const callerDir = path.dirname(callerFile);
1553
- mcpDir = path.join(callerDir, "mcp");
1569
+ const callerDir = path2.dirname(callerFile);
1570
+ mcpDir = path2.join(callerDir, "mcp");
1554
1571
  } else {
1555
- mcpDir = path.join(process.cwd(), "mcp");
1572
+ mcpDir = path2.join(process.cwd(), "mcp");
1556
1573
  }
1557
1574
  }
1558
- if (fs2.existsSync(mcpDir)) {
1575
+ if (fs3.existsSync(mcpDir)) {
1559
1576
  this.logger.debug(`Auto-discovering services from: ${mcpDir}`);
1560
1577
  await this.autoRegisterServices(mcpDir, serviceFactories);
1561
1578
  } else {
@@ -1805,7 +1822,7 @@ var MCPServer = class {
1805
1822
  */
1806
1823
  async autoRegisterServices(mcpDir, serviceFactories) {
1807
1824
  this.logger.debug(`Auto-registering services from: ${mcpDir}`);
1808
- if (!fs2.existsSync(mcpDir)) {
1825
+ if (!fs3.existsSync(mcpDir)) {
1809
1826
  this.logger.warn(`MCP directory not found: ${mcpDir}`);
1810
1827
  return;
1811
1828
  }
@@ -1824,11 +1841,11 @@ var MCPServer = class {
1824
1841
  */
1825
1842
  findServiceFiles(dir) {
1826
1843
  const files = [];
1827
- const entries = fs2.readdirSync(dir, {
1844
+ const entries = fs3.readdirSync(dir, {
1828
1845
  withFileTypes: true
1829
1846
  });
1830
1847
  for (const entry of entries) {
1831
- const fullPath = path.join(dir, entry.name);
1848
+ const fullPath = path2.join(dir, entry.name);
1832
1849
  if (entry.isDirectory()) {
1833
1850
  files.push(...this.findServiceFiles(fullPath));
1834
1851
  } else if (entry.isFile()) {
@@ -1859,7 +1876,7 @@ var MCPServer = class {
1859
1876
  }
1860
1877
  this.registerService(instance);
1861
1878
  registeredCount++;
1862
- this.logger.debug(`Registered service: ${exportName} from ${path.basename(filePath)}`);
1879
+ this.logger.debug(`Registered service: ${exportName} from ${path2.basename(filePath)}`);
1863
1880
  } catch (error) {
1864
1881
  this.logger.warn(`Skipped ${exportName}: ${error.message}`);
1865
1882
  }
@@ -1958,8 +1975,8 @@ var MCPServer = class {
1958
1975
  return;
1959
1976
  }
1960
1977
  try {
1961
- const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
1962
- if (!fs2.existsSync(manifestPath)) {
1978
+ const manifestPath = path2.join(process.cwd(), "dist", "ui-manifest.json");
1979
+ if (!fs3.existsSync(manifestPath)) {
1963
1980
  return;
1964
1981
  }
1965
1982
  if (this.logging) {
@@ -2001,8 +2018,8 @@ var MCPServer = class {
2001
2018
  */
2002
2019
  async reloadUIManifest() {
2003
2020
  try {
2004
- const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
2005
- if (!fs2.existsSync(manifestPath)) {
2021
+ const manifestPath = path2.join(process.cwd(), "dist", "ui-manifest.json");
2022
+ if (!fs3.existsSync(manifestPath)) {
2006
2023
  const uiResourceUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2007
2024
  for (const uri of uiResourceUris) {
2008
2025
  this.resources.delete(uri);
@@ -2012,7 +2029,7 @@ var MCPServer = class {
2012
2029
  }
2013
2030
  return;
2014
2031
  }
2015
- const manifest = JSON.parse(fs2.readFileSync(manifestPath, "utf-8"));
2032
+ const manifest = JSON.parse(fs3.readFileSync(manifestPath, "utf-8"));
2016
2033
  const currentUIUris = new Set(Object.keys(manifest));
2017
2034
  const registeredUIUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
2018
2035
  for (const uri of registeredUIUris) {
@@ -2028,7 +2045,7 @@ var MCPServer = class {
2028
2045
  const htmlPath = isString ? entry : entry.htmlPath;
2029
2046
  const isGPTApp = !isString && entry.isGPTApp;
2030
2047
  const gptMeta = !isString ? entry.gptMeta : void 0;
2031
- if (!fs2.existsSync(htmlPath)) {
2048
+ if (!fs3.existsSync(htmlPath)) {
2032
2049
  if (this.logging) {
2033
2050
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2034
2051
  }
@@ -2049,8 +2066,8 @@ var MCPServer = class {
2049
2066
  mimeType,
2050
2067
  inputSchema: void 0,
2051
2068
  method: /* @__PURE__ */ __name(async () => {
2052
- if (fs2.existsSync(htmlPath)) {
2053
- const html = fs2.readFileSync(htmlPath, "utf-8");
2069
+ if (fs3.existsSync(htmlPath)) {
2070
+ const html = fs3.readFileSync(htmlPath, "utf-8");
2054
2071
  return {
2055
2072
  text: html,
2056
2073
  _meta: Object.keys(_meta).length > 0 ? _meta : void 0
@@ -2078,11 +2095,11 @@ var MCPServer = class {
2078
2095
  */
2079
2096
  async loadUIManifest() {
2080
2097
  try {
2081
- const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
2082
- if (!fs2.existsSync(manifestPath)) {
2098
+ const manifestPath = path2.join(process.cwd(), "dist", "ui-manifest.json");
2099
+ if (!fs3.existsSync(manifestPath)) {
2083
2100
  return;
2084
2101
  }
2085
- const manifest = JSON.parse(fs2.readFileSync(manifestPath, "utf-8"));
2102
+ const manifest = JSON.parse(fs3.readFileSync(manifestPath, "utf-8"));
2086
2103
  for (const [uri, entry] of Object.entries(manifest)) {
2087
2104
  const isString = typeof entry === "string";
2088
2105
  const htmlPath = isString ? entry : entry.htmlPath;
@@ -2094,13 +2111,13 @@ var MCPServer = class {
2094
2111
  }
2095
2112
  continue;
2096
2113
  }
2097
- if (!fs2.existsSync(htmlPath)) {
2114
+ if (!fs3.existsSync(htmlPath)) {
2098
2115
  if (this.logging) {
2099
2116
  this.logger.warn(`UI HTML file not found: ${htmlPath}`);
2100
2117
  }
2101
2118
  continue;
2102
2119
  }
2103
- const html = fs2.readFileSync(htmlPath, "utf-8");
2120
+ const html = fs3.readFileSync(htmlPath, "utf-8");
2104
2121
  const mimeType = isGPTApp ? "text/html+skybridge" : "text/html;profile=mcp-app";
2105
2122
  const _meta = {};
2106
2123
  if (isGPTApp) {
@@ -2351,19 +2368,19 @@ var MCPServerRuntime = class {
2351
2368
  });
2352
2369
  }
2353
2370
  async loadServices() {
2354
- const absPath = path.resolve(this.options.servicesDir);
2355
- if (!fs2.existsSync(absPath)) {
2371
+ const absPath = path2.resolve(this.options.servicesDir);
2372
+ if (!fs3.existsSync(absPath)) {
2356
2373
  this.logger.error(`Services directory not found: ${absPath}`);
2357
2374
  return;
2358
2375
  }
2359
- const files = fs2.readdirSync(absPath);
2376
+ const files = fs3.readdirSync(absPath);
2360
2377
  let toolCount = 0;
2361
2378
  let promptCount = 0;
2362
2379
  let resourceCount = 0;
2363
2380
  for (const dir of files) {
2364
- const modulePath = path.join(absPath, dir, "index.ts");
2365
- const modulePathJs = path.join(absPath, dir, "index.js");
2366
- const finalPath = fs2.existsSync(modulePath) ? modulePath : fs2.existsSync(modulePathJs) ? modulePathJs : null;
2381
+ const modulePath = path2.join(absPath, dir, "index.ts");
2382
+ const modulePathJs = path2.join(absPath, dir, "index.js");
2383
+ const finalPath = fs3.existsSync(modulePath) ? modulePath : fs3.existsSync(modulePathJs) ? modulePathJs : null;
2367
2384
  if (finalPath) {
2368
2385
  try {
2369
2386
  const fileUrl = pathToFileURL(finalPath).href;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanmcp/core",
3
- "version": "0.4.6",
3
+ "version": "0.4.7-alpha.29.3837d4c",
4
4
  "description": "Core library implementing decorators, reflection, and MCP runtime server",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -30,7 +30,9 @@
30
30
  "ajv": "^8.12.0",
31
31
  "chokidar": "^4.0.0",
32
32
  "dotenv": "^16.3.1",
33
- "reflect-metadata": "^0.2.1",
33
+ "reflect-metadata": "^0.2.1"
34
+ },
35
+ "optionalDependencies": {
34
36
  "ts-morph": "^24.0.0"
35
37
  },
36
38
  "peerDependencies": {
@@ -76,4 +78,4 @@
76
78
  "publishConfig": {
77
79
  "access": "public"
78
80
  }
79
- }
81
+ }