@leanmcp/core 0.3.7 → 0.3.9
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.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +147 -4
- package/dist/index.mjs +147 -4
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -411,6 +411,7 @@ declare class MCPServer {
|
|
|
411
411
|
private options;
|
|
412
412
|
private initPromise;
|
|
413
413
|
private autoDiscovered;
|
|
414
|
+
private manifestWatcher;
|
|
414
415
|
constructor(options: MCPServerConstructorOptions);
|
|
415
416
|
/**
|
|
416
417
|
* Internal initialization - runs automatically in constructor
|
|
@@ -462,6 +463,14 @@ declare class MCPServer {
|
|
|
462
463
|
* Register a service instance with decorated methods
|
|
463
464
|
*/
|
|
464
465
|
registerService(instance: any): void;
|
|
466
|
+
/**
|
|
467
|
+
* Watch UI manifest for changes and reload resources dynamically
|
|
468
|
+
*/
|
|
469
|
+
private watchUIManifest;
|
|
470
|
+
/**
|
|
471
|
+
* Reload UI manifest and update resource registrations
|
|
472
|
+
*/
|
|
473
|
+
private reloadUIManifest;
|
|
465
474
|
/**
|
|
466
475
|
* Load UI manifest and auto-register resources for pre-built @UIApp components.
|
|
467
476
|
* The manifest is generated by `leanmcp dev` or `leanmcp start` commands.
|
|
@@ -511,6 +520,10 @@ declare class MCPServer {
|
|
|
511
520
|
} | undefined;
|
|
512
521
|
} | undefined;
|
|
513
522
|
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Cleanup resources (call on server shutdown)
|
|
525
|
+
*/
|
|
526
|
+
cleanup(): Promise<void>;
|
|
514
527
|
}
|
|
515
528
|
declare class MCPServerRuntime {
|
|
516
529
|
private server;
|
package/dist/index.d.ts
CHANGED
|
@@ -411,6 +411,7 @@ declare class MCPServer {
|
|
|
411
411
|
private options;
|
|
412
412
|
private initPromise;
|
|
413
413
|
private autoDiscovered;
|
|
414
|
+
private manifestWatcher;
|
|
414
415
|
constructor(options: MCPServerConstructorOptions);
|
|
415
416
|
/**
|
|
416
417
|
* Internal initialization - runs automatically in constructor
|
|
@@ -462,6 +463,14 @@ declare class MCPServer {
|
|
|
462
463
|
* Register a service instance with decorated methods
|
|
463
464
|
*/
|
|
464
465
|
registerService(instance: any): void;
|
|
466
|
+
/**
|
|
467
|
+
* Watch UI manifest for changes and reload resources dynamically
|
|
468
|
+
*/
|
|
469
|
+
private watchUIManifest;
|
|
470
|
+
/**
|
|
471
|
+
* Reload UI manifest and update resource registrations
|
|
472
|
+
*/
|
|
473
|
+
private reloadUIManifest;
|
|
465
474
|
/**
|
|
466
475
|
* Load UI manifest and auto-register resources for pre-built @UIApp components.
|
|
467
476
|
* The manifest is generated by `leanmcp dev` or `leanmcp start` commands.
|
|
@@ -511,6 +520,10 @@ declare class MCPServer {
|
|
|
511
520
|
} | undefined;
|
|
512
521
|
} | undefined;
|
|
513
522
|
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Cleanup resources (call on server shutdown)
|
|
525
|
+
*/
|
|
526
|
+
cleanup(): Promise<void>;
|
|
514
527
|
}
|
|
515
528
|
declare class MCPServerRuntime {
|
|
516
529
|
private server;
|
package/dist/index.js
CHANGED
|
@@ -812,8 +812,29 @@ async function createHTTPServer(serverInput, options) {
|
|
|
812
812
|
}
|
|
813
813
|
}
|
|
814
814
|
}, "handleMCPRequestStateless");
|
|
815
|
-
|
|
816
|
-
|
|
815
|
+
app.get("/mcp", async (req, res) => {
|
|
816
|
+
const acceptHeader = req.headers["accept"] || "";
|
|
817
|
+
if (acceptHeader.includes("text/event-stream")) {
|
|
818
|
+
if (!isStateless) {
|
|
819
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
820
|
+
if (sessionId && transports[sessionId]) {
|
|
821
|
+
const transport = transports[sessionId];
|
|
822
|
+
logger.info(`GET /mcp SSE request (session: ${sessionId.substring(0, 8)}...)`);
|
|
823
|
+
await transport.handleRequest(req, res);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
res.status(405).json({
|
|
828
|
+
jsonrpc: "2.0",
|
|
829
|
+
error: {
|
|
830
|
+
code: -32e3,
|
|
831
|
+
message: "SSE streaming not supported in stateless mode or invalid session"
|
|
832
|
+
},
|
|
833
|
+
id: null
|
|
834
|
+
});
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (isDashboardEnabled) {
|
|
817
838
|
try {
|
|
818
839
|
const html = await fetchDashboard();
|
|
819
840
|
res.setHeader("Content-Type", "text/html");
|
|
@@ -821,8 +842,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
821
842
|
} catch (error) {
|
|
822
843
|
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
823
844
|
}
|
|
824
|
-
}
|
|
825
|
-
|
|
845
|
+
} else {
|
|
846
|
+
res.status(404).json({
|
|
847
|
+
error: "Dashboard disabled"
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
});
|
|
826
851
|
if (isStateless) {
|
|
827
852
|
app.post("/mcp", handleMCPRequestStateless);
|
|
828
853
|
app.delete("/mcp", (_req, res) => {
|
|
@@ -965,6 +990,7 @@ var init_index = __esm({
|
|
|
965
990
|
options;
|
|
966
991
|
initPromise;
|
|
967
992
|
autoDiscovered = false;
|
|
993
|
+
manifestWatcher = null;
|
|
968
994
|
constructor(options) {
|
|
969
995
|
this.options = options;
|
|
970
996
|
this.logging = options.logging || false;
|
|
@@ -998,6 +1024,7 @@ var init_index = __esm({
|
|
|
998
1024
|
await this.autoDiscoverServices(options.mcpDir, options.serviceFactories);
|
|
999
1025
|
}
|
|
1000
1026
|
await this.loadUIManifest();
|
|
1027
|
+
this.watchUIManifest();
|
|
1001
1028
|
}
|
|
1002
1029
|
/**
|
|
1003
1030
|
* Wait for initialization to complete
|
|
@@ -1395,6 +1422,113 @@ var init_index = __esm({
|
|
|
1395
1422
|
}
|
|
1396
1423
|
}
|
|
1397
1424
|
/**
|
|
1425
|
+
* Watch UI manifest for changes and reload resources dynamically
|
|
1426
|
+
*/
|
|
1427
|
+
watchUIManifest() {
|
|
1428
|
+
try {
|
|
1429
|
+
const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
|
|
1430
|
+
if (!import_fs.default.existsSync(manifestPath)) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (this.logging) {
|
|
1434
|
+
this.logger.debug(`Watching UI manifest: ${manifestPath}`);
|
|
1435
|
+
}
|
|
1436
|
+
import("chokidar").then(({ default: chokidar }) => {
|
|
1437
|
+
this.manifestWatcher = chokidar.watch(manifestPath, {
|
|
1438
|
+
ignoreInitial: true,
|
|
1439
|
+
persistent: true,
|
|
1440
|
+
awaitWriteFinish: {
|
|
1441
|
+
stabilityThreshold: 100,
|
|
1442
|
+
pollInterval: 50
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
this.manifestWatcher.on("change", async () => {
|
|
1446
|
+
if (this.logging) {
|
|
1447
|
+
this.logger.debug("UI manifest changed, reloading resources");
|
|
1448
|
+
}
|
|
1449
|
+
await this.reloadUIManifest();
|
|
1450
|
+
});
|
|
1451
|
+
this.manifestWatcher.on("error", (error) => {
|
|
1452
|
+
if (this.logging) {
|
|
1453
|
+
this.logger.warn(`Manifest watcher error: ${error.message}`);
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
}).catch((error) => {
|
|
1457
|
+
if (this.logging) {
|
|
1458
|
+
this.logger.warn(`Failed to initialize manifest watcher: ${error.message}`);
|
|
1459
|
+
}
|
|
1460
|
+
});
|
|
1461
|
+
} catch (error) {
|
|
1462
|
+
if (this.logging) {
|
|
1463
|
+
this.logger.warn(`Failed to setup manifest watcher: ${error.message}`);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Reload UI manifest and update resource registrations
|
|
1469
|
+
*/
|
|
1470
|
+
async reloadUIManifest() {
|
|
1471
|
+
try {
|
|
1472
|
+
const manifestPath = import_path.default.join(process.cwd(), "dist", "ui-manifest.json");
|
|
1473
|
+
if (!import_fs.default.existsSync(manifestPath)) {
|
|
1474
|
+
const uiResourceUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
|
|
1475
|
+
for (const uri of uiResourceUris) {
|
|
1476
|
+
this.resources.delete(uri);
|
|
1477
|
+
if (this.logging) {
|
|
1478
|
+
this.logger.debug(`Removed UI resource: ${uri}`);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
const manifest = JSON.parse(import_fs.default.readFileSync(manifestPath, "utf-8"));
|
|
1484
|
+
const currentUIUris = new Set(Object.keys(manifest));
|
|
1485
|
+
const registeredUIUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
|
|
1486
|
+
for (const uri of registeredUIUris) {
|
|
1487
|
+
if (!currentUIUris.has(uri)) {
|
|
1488
|
+
this.resources.delete(uri);
|
|
1489
|
+
if (this.logging) {
|
|
1490
|
+
this.logger.debug(`Removed UI resource: ${uri}`);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
for (const [uri, htmlPath] of Object.entries(manifest)) {
|
|
1495
|
+
if (!import_fs.default.existsSync(htmlPath)) {
|
|
1496
|
+
if (this.logging) {
|
|
1497
|
+
this.logger.warn(`UI HTML file not found: ${htmlPath}`);
|
|
1498
|
+
}
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
const wasRegistered = this.resources.has(uri);
|
|
1502
|
+
this.resources.set(uri, {
|
|
1503
|
+
uri,
|
|
1504
|
+
name: uri.replace("ui://", "").replace(/\//g, "-"),
|
|
1505
|
+
description: `Auto-generated UI resource from pre-built HTML`,
|
|
1506
|
+
mimeType: "text/html;profile=mcp-app",
|
|
1507
|
+
inputSchema: void 0,
|
|
1508
|
+
method: /* @__PURE__ */ __name(async () => {
|
|
1509
|
+
if (import_fs.default.existsSync(htmlPath)) {
|
|
1510
|
+
const html = import_fs.default.readFileSync(htmlPath, "utf-8");
|
|
1511
|
+
return {
|
|
1512
|
+
text: html
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
throw new Error(`UI HTML file not found: ${htmlPath}`);
|
|
1516
|
+
}, "method"),
|
|
1517
|
+
instance: null,
|
|
1518
|
+
propertyKey: "getUI"
|
|
1519
|
+
});
|
|
1520
|
+
if (this.logging) {
|
|
1521
|
+
const action = wasRegistered ? "Updated" : "Registered";
|
|
1522
|
+
this.logger.debug(`${action} UI resource: ${uri}`);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
} catch (error) {
|
|
1526
|
+
if (this.logging) {
|
|
1527
|
+
this.logger.warn(`Failed to reload UI manifest: ${error.message}`);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1398
1532
|
* Load UI manifest and auto-register resources for pre-built @UIApp components.
|
|
1399
1533
|
* The manifest is generated by `leanmcp dev` or `leanmcp start` commands.
|
|
1400
1534
|
*/
|
|
@@ -1449,6 +1583,15 @@ var init_index = __esm({
|
|
|
1449
1583
|
this.server.waitForInit = () => this.waitForInit();
|
|
1450
1584
|
return this.server;
|
|
1451
1585
|
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Cleanup resources (call on server shutdown)
|
|
1588
|
+
*/
|
|
1589
|
+
async cleanup() {
|
|
1590
|
+
if (this.manifestWatcher) {
|
|
1591
|
+
await this.manifestWatcher.close();
|
|
1592
|
+
this.manifestWatcher = null;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1452
1595
|
};
|
|
1453
1596
|
MCPServerRuntime = class {
|
|
1454
1597
|
static {
|
package/dist/index.mjs
CHANGED
|
@@ -774,8 +774,29 @@ async function createHTTPServer(serverInput, options) {
|
|
|
774
774
|
}
|
|
775
775
|
}
|
|
776
776
|
}, "handleMCPRequestStateless");
|
|
777
|
-
|
|
778
|
-
|
|
777
|
+
app.get("/mcp", async (req, res) => {
|
|
778
|
+
const acceptHeader = req.headers["accept"] || "";
|
|
779
|
+
if (acceptHeader.includes("text/event-stream")) {
|
|
780
|
+
if (!isStateless) {
|
|
781
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
782
|
+
if (sessionId && transports[sessionId]) {
|
|
783
|
+
const transport = transports[sessionId];
|
|
784
|
+
logger.info(`GET /mcp SSE request (session: ${sessionId.substring(0, 8)}...)`);
|
|
785
|
+
await transport.handleRequest(req, res);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
res.status(405).json({
|
|
790
|
+
jsonrpc: "2.0",
|
|
791
|
+
error: {
|
|
792
|
+
code: -32e3,
|
|
793
|
+
message: "SSE streaming not supported in stateless mode or invalid session"
|
|
794
|
+
},
|
|
795
|
+
id: null
|
|
796
|
+
});
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (isDashboardEnabled) {
|
|
779
800
|
try {
|
|
780
801
|
const html = await fetchDashboard();
|
|
781
802
|
res.setHeader("Content-Type", "text/html");
|
|
@@ -783,8 +804,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
783
804
|
} catch (error) {
|
|
784
805
|
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
785
806
|
}
|
|
786
|
-
}
|
|
787
|
-
|
|
807
|
+
} else {
|
|
808
|
+
res.status(404).json({
|
|
809
|
+
error: "Dashboard disabled"
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
});
|
|
788
813
|
if (isStateless) {
|
|
789
814
|
app.post("/mcp", handleMCPRequestStateless);
|
|
790
815
|
app.delete("/mcp", (_req, res) => {
|
|
@@ -862,6 +887,7 @@ var MCPServer = class {
|
|
|
862
887
|
options;
|
|
863
888
|
initPromise;
|
|
864
889
|
autoDiscovered = false;
|
|
890
|
+
manifestWatcher = null;
|
|
865
891
|
constructor(options) {
|
|
866
892
|
this.options = options;
|
|
867
893
|
this.logging = options.logging || false;
|
|
@@ -895,6 +921,7 @@ var MCPServer = class {
|
|
|
895
921
|
await this.autoDiscoverServices(options.mcpDir, options.serviceFactories);
|
|
896
922
|
}
|
|
897
923
|
await this.loadUIManifest();
|
|
924
|
+
this.watchUIManifest();
|
|
898
925
|
}
|
|
899
926
|
/**
|
|
900
927
|
* Wait for initialization to complete
|
|
@@ -1292,6 +1319,113 @@ var MCPServer = class {
|
|
|
1292
1319
|
}
|
|
1293
1320
|
}
|
|
1294
1321
|
/**
|
|
1322
|
+
* Watch UI manifest for changes and reload resources dynamically
|
|
1323
|
+
*/
|
|
1324
|
+
watchUIManifest() {
|
|
1325
|
+
try {
|
|
1326
|
+
const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
|
|
1327
|
+
if (!fs.existsSync(manifestPath)) {
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
if (this.logging) {
|
|
1331
|
+
this.logger.debug(`Watching UI manifest: ${manifestPath}`);
|
|
1332
|
+
}
|
|
1333
|
+
import("chokidar").then(({ default: chokidar }) => {
|
|
1334
|
+
this.manifestWatcher = chokidar.watch(manifestPath, {
|
|
1335
|
+
ignoreInitial: true,
|
|
1336
|
+
persistent: true,
|
|
1337
|
+
awaitWriteFinish: {
|
|
1338
|
+
stabilityThreshold: 100,
|
|
1339
|
+
pollInterval: 50
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
this.manifestWatcher.on("change", async () => {
|
|
1343
|
+
if (this.logging) {
|
|
1344
|
+
this.logger.debug("UI manifest changed, reloading resources");
|
|
1345
|
+
}
|
|
1346
|
+
await this.reloadUIManifest();
|
|
1347
|
+
});
|
|
1348
|
+
this.manifestWatcher.on("error", (error) => {
|
|
1349
|
+
if (this.logging) {
|
|
1350
|
+
this.logger.warn(`Manifest watcher error: ${error.message}`);
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
}).catch((error) => {
|
|
1354
|
+
if (this.logging) {
|
|
1355
|
+
this.logger.warn(`Failed to initialize manifest watcher: ${error.message}`);
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
} catch (error) {
|
|
1359
|
+
if (this.logging) {
|
|
1360
|
+
this.logger.warn(`Failed to setup manifest watcher: ${error.message}`);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Reload UI manifest and update resource registrations
|
|
1366
|
+
*/
|
|
1367
|
+
async reloadUIManifest() {
|
|
1368
|
+
try {
|
|
1369
|
+
const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
|
|
1370
|
+
if (!fs.existsSync(manifestPath)) {
|
|
1371
|
+
const uiResourceUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
|
|
1372
|
+
for (const uri of uiResourceUris) {
|
|
1373
|
+
this.resources.delete(uri);
|
|
1374
|
+
if (this.logging) {
|
|
1375
|
+
this.logger.debug(`Removed UI resource: ${uri}`);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return;
|
|
1379
|
+
}
|
|
1380
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
1381
|
+
const currentUIUris = new Set(Object.keys(manifest));
|
|
1382
|
+
const registeredUIUris = Array.from(this.resources.keys()).filter((uri) => uri.startsWith("ui://"));
|
|
1383
|
+
for (const uri of registeredUIUris) {
|
|
1384
|
+
if (!currentUIUris.has(uri)) {
|
|
1385
|
+
this.resources.delete(uri);
|
|
1386
|
+
if (this.logging) {
|
|
1387
|
+
this.logger.debug(`Removed UI resource: ${uri}`);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
for (const [uri, htmlPath] of Object.entries(manifest)) {
|
|
1392
|
+
if (!fs.existsSync(htmlPath)) {
|
|
1393
|
+
if (this.logging) {
|
|
1394
|
+
this.logger.warn(`UI HTML file not found: ${htmlPath}`);
|
|
1395
|
+
}
|
|
1396
|
+
continue;
|
|
1397
|
+
}
|
|
1398
|
+
const wasRegistered = this.resources.has(uri);
|
|
1399
|
+
this.resources.set(uri, {
|
|
1400
|
+
uri,
|
|
1401
|
+
name: uri.replace("ui://", "").replace(/\//g, "-"),
|
|
1402
|
+
description: `Auto-generated UI resource from pre-built HTML`,
|
|
1403
|
+
mimeType: "text/html;profile=mcp-app",
|
|
1404
|
+
inputSchema: void 0,
|
|
1405
|
+
method: /* @__PURE__ */ __name(async () => {
|
|
1406
|
+
if (fs.existsSync(htmlPath)) {
|
|
1407
|
+
const html = fs.readFileSync(htmlPath, "utf-8");
|
|
1408
|
+
return {
|
|
1409
|
+
text: html
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
throw new Error(`UI HTML file not found: ${htmlPath}`);
|
|
1413
|
+
}, "method"),
|
|
1414
|
+
instance: null,
|
|
1415
|
+
propertyKey: "getUI"
|
|
1416
|
+
});
|
|
1417
|
+
if (this.logging) {
|
|
1418
|
+
const action = wasRegistered ? "Updated" : "Registered";
|
|
1419
|
+
this.logger.debug(`${action} UI resource: ${uri}`);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
if (this.logging) {
|
|
1424
|
+
this.logger.warn(`Failed to reload UI manifest: ${error.message}`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1295
1429
|
* Load UI manifest and auto-register resources for pre-built @UIApp components.
|
|
1296
1430
|
* The manifest is generated by `leanmcp dev` or `leanmcp start` commands.
|
|
1297
1431
|
*/
|
|
@@ -1346,6 +1480,15 @@ var MCPServer = class {
|
|
|
1346
1480
|
this.server.waitForInit = () => this.waitForInit();
|
|
1347
1481
|
return this.server;
|
|
1348
1482
|
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Cleanup resources (call on server shutdown)
|
|
1485
|
+
*/
|
|
1486
|
+
async cleanup() {
|
|
1487
|
+
if (this.manifestWatcher) {
|
|
1488
|
+
await this.manifestWatcher.close();
|
|
1489
|
+
this.manifestWatcher = null;
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1349
1492
|
};
|
|
1350
1493
|
var MCPServerRuntime = class {
|
|
1351
1494
|
static {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leanmcp/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"description": "Core library implementing decorators, reflection, and MCP runtime server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
28
|
"ajv": "^8.12.0",
|
|
29
|
+
"chokidar": "^4.0.0",
|
|
29
30
|
"dotenv": "^16.3.1",
|
|
30
31
|
"reflect-metadata": "^0.2.1"
|
|
31
32
|
},
|