@leanmcp/core 0.4.0 → 0.4.1
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 +62 -5
- package/dist/index.mjs +62 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -985,6 +985,62 @@ async function createHTTPServer(serverInput, options) {
|
|
|
985
985
|
if (sessionId && transports[sessionId]) {
|
|
986
986
|
transport = transports[sessionId];
|
|
987
987
|
logger.debug(`Reusing session: ${sessionId}`);
|
|
988
|
+
} else if (sessionId && isInitializeRequest(req.body)) {
|
|
989
|
+
logger.info(`Initialize request with session ${sessionId} - checking for session restoration...`);
|
|
990
|
+
if (httpOptions.sessionStore) {
|
|
991
|
+
const exists = await httpOptions.sessionStore.sessionExists(sessionId);
|
|
992
|
+
if (exists) {
|
|
993
|
+
logger.info(`Restoring session: ${sessionId}`);
|
|
994
|
+
transport = new StreamableHTTPServerTransport2({
|
|
995
|
+
sessionIdGenerator: /* @__PURE__ */ __name(() => sessionId, "sessionIdGenerator"),
|
|
996
|
+
onsessioninitialized: /* @__PURE__ */ __name((sid) => {
|
|
997
|
+
transports[sid] = transport;
|
|
998
|
+
logger.info(`Session restored: ${sid}`);
|
|
999
|
+
}, "onsessioninitialized")
|
|
1000
|
+
});
|
|
1001
|
+
transport.onclose = async () => {
|
|
1002
|
+
if (transport.sessionId) {
|
|
1003
|
+
delete transports[transport.sessionId];
|
|
1004
|
+
logger.debug(`Session cleaned up: ${transport.sessionId}`);
|
|
1005
|
+
if (httpOptions.sessionStore) {
|
|
1006
|
+
await httpOptions.sessionStore.deleteSession(transport.sessionId);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
const freshServer = await serverFactory();
|
|
1011
|
+
if (freshServer && typeof freshServer.waitForInit === "function") {
|
|
1012
|
+
await freshServer.waitForInit();
|
|
1013
|
+
}
|
|
1014
|
+
await freshServer.connect(transport);
|
|
1015
|
+
} else {
|
|
1016
|
+
logger.info(`Session ${sessionId} not found in store, creating new session`);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
if (!transport) {
|
|
1020
|
+
transport = new StreamableHTTPServerTransport2({
|
|
1021
|
+
sessionIdGenerator: /* @__PURE__ */ __name(() => (0, import_node_crypto.randomUUID)(), "sessionIdGenerator"),
|
|
1022
|
+
onsessioninitialized: /* @__PURE__ */ __name(async (newSessionId) => {
|
|
1023
|
+
transports[newSessionId] = transport;
|
|
1024
|
+
logger.info(`Session initialized: ${newSessionId}`);
|
|
1025
|
+
if (httpOptions.sessionStore) {
|
|
1026
|
+
await httpOptions.sessionStore.createSession(newSessionId);
|
|
1027
|
+
}
|
|
1028
|
+
}, "onsessioninitialized")
|
|
1029
|
+
});
|
|
1030
|
+
transport.onclose = async () => {
|
|
1031
|
+
if (transport.sessionId) {
|
|
1032
|
+
delete transports[transport.sessionId];
|
|
1033
|
+
logger.debug(`Session cleaned up: ${transport.sessionId}`);
|
|
1034
|
+
if (httpOptions.sessionStore) {
|
|
1035
|
+
await httpOptions.sessionStore.deleteSession(transport.sessionId);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
if (!mcpServer) {
|
|
1040
|
+
throw new Error("MCP server not initialized");
|
|
1041
|
+
}
|
|
1042
|
+
await mcpServer.connect(transport);
|
|
1043
|
+
}
|
|
988
1044
|
} else if (sessionId && !isInitializeRequest(req.body)) {
|
|
989
1045
|
logger.info(`Transport missing for session ${sessionId}, checking session store...`);
|
|
990
1046
|
if (httpOptions.sessionStore) {
|
|
@@ -1000,11 +1056,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
1000
1056
|
});
|
|
1001
1057
|
return;
|
|
1002
1058
|
}
|
|
1059
|
+
logger.info(`Auto-restoring session: ${sessionId}`);
|
|
1003
1060
|
transport = new StreamableHTTPServerTransport2({
|
|
1004
1061
|
sessionIdGenerator: /* @__PURE__ */ __name(() => sessionId, "sessionIdGenerator"),
|
|
1005
1062
|
onsessioninitialized: /* @__PURE__ */ __name((sid) => {
|
|
1006
1063
|
transports[sid] = transport;
|
|
1007
|
-
logger.info(`
|
|
1064
|
+
logger.info(`Session auto-restored: ${sid}`);
|
|
1008
1065
|
}, "onsessioninitialized")
|
|
1009
1066
|
});
|
|
1010
1067
|
transport.onclose = async () => {
|
|
@@ -1822,14 +1879,14 @@ var init_index = __esm({
|
|
|
1822
1879
|
/**
|
|
1823
1880
|
* Auto-register all services from the mcp directory
|
|
1824
1881
|
* Scans the directory recursively and registers all exported classes
|
|
1825
|
-
*
|
|
1882
|
+
*
|
|
1826
1883
|
* @param mcpDir - Path to the mcp directory containing service files
|
|
1827
1884
|
* @param serviceFactories - Optional map of service class names to factory functions for dependency injection
|
|
1828
|
-
*
|
|
1885
|
+
*
|
|
1829
1886
|
* @example
|
|
1830
1887
|
* // Auto-register services with no dependencies
|
|
1831
1888
|
* await server.autoRegisterServices('./mcp');
|
|
1832
|
-
*
|
|
1889
|
+
*
|
|
1833
1890
|
* @example
|
|
1834
1891
|
* // Auto-register with dependency injection
|
|
1835
1892
|
* await server.autoRegisterServices('./mcp', {
|
|
@@ -1982,7 +2039,7 @@ var init_index = __esm({
|
|
|
1982
2039
|
}
|
|
1983
2040
|
/**
|
|
1984
2041
|
* Watch UI manifest for changes and reload resources dynamically
|
|
1985
|
-
*
|
|
2042
|
+
*
|
|
1986
2043
|
* CRITICAL: Only for stateful mode. In stateless mode, each request
|
|
1987
2044
|
* creates a fresh server that reads the manifest directly, making
|
|
1988
2045
|
* watchers both unnecessary and a memory leak source.
|
package/dist/index.mjs
CHANGED
|
@@ -683,6 +683,62 @@ async function createHTTPServer(serverInput, options) {
|
|
|
683
683
|
if (sessionId && transports[sessionId]) {
|
|
684
684
|
transport = transports[sessionId];
|
|
685
685
|
logger.debug(`Reusing session: ${sessionId}`);
|
|
686
|
+
} else if (sessionId && isInitializeRequest(req.body)) {
|
|
687
|
+
logger.info(`Initialize request with session ${sessionId} - checking for session restoration...`);
|
|
688
|
+
if (httpOptions.sessionStore) {
|
|
689
|
+
const exists = await httpOptions.sessionStore.sessionExists(sessionId);
|
|
690
|
+
if (exists) {
|
|
691
|
+
logger.info(`Restoring session: ${sessionId}`);
|
|
692
|
+
transport = new StreamableHTTPServerTransport2({
|
|
693
|
+
sessionIdGenerator: /* @__PURE__ */ __name(() => sessionId, "sessionIdGenerator"),
|
|
694
|
+
onsessioninitialized: /* @__PURE__ */ __name((sid) => {
|
|
695
|
+
transports[sid] = transport;
|
|
696
|
+
logger.info(`Session restored: ${sid}`);
|
|
697
|
+
}, "onsessioninitialized")
|
|
698
|
+
});
|
|
699
|
+
transport.onclose = async () => {
|
|
700
|
+
if (transport.sessionId) {
|
|
701
|
+
delete transports[transport.sessionId];
|
|
702
|
+
logger.debug(`Session cleaned up: ${transport.sessionId}`);
|
|
703
|
+
if (httpOptions.sessionStore) {
|
|
704
|
+
await httpOptions.sessionStore.deleteSession(transport.sessionId);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
const freshServer = await serverFactory();
|
|
709
|
+
if (freshServer && typeof freshServer.waitForInit === "function") {
|
|
710
|
+
await freshServer.waitForInit();
|
|
711
|
+
}
|
|
712
|
+
await freshServer.connect(transport);
|
|
713
|
+
} else {
|
|
714
|
+
logger.info(`Session ${sessionId} not found in store, creating new session`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (!transport) {
|
|
718
|
+
transport = new StreamableHTTPServerTransport2({
|
|
719
|
+
sessionIdGenerator: /* @__PURE__ */ __name(() => randomUUID(), "sessionIdGenerator"),
|
|
720
|
+
onsessioninitialized: /* @__PURE__ */ __name(async (newSessionId) => {
|
|
721
|
+
transports[newSessionId] = transport;
|
|
722
|
+
logger.info(`Session initialized: ${newSessionId}`);
|
|
723
|
+
if (httpOptions.sessionStore) {
|
|
724
|
+
await httpOptions.sessionStore.createSession(newSessionId);
|
|
725
|
+
}
|
|
726
|
+
}, "onsessioninitialized")
|
|
727
|
+
});
|
|
728
|
+
transport.onclose = async () => {
|
|
729
|
+
if (transport.sessionId) {
|
|
730
|
+
delete transports[transport.sessionId];
|
|
731
|
+
logger.debug(`Session cleaned up: ${transport.sessionId}`);
|
|
732
|
+
if (httpOptions.sessionStore) {
|
|
733
|
+
await httpOptions.sessionStore.deleteSession(transport.sessionId);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
if (!mcpServer) {
|
|
738
|
+
throw new Error("MCP server not initialized");
|
|
739
|
+
}
|
|
740
|
+
await mcpServer.connect(transport);
|
|
741
|
+
}
|
|
686
742
|
} else if (sessionId && !isInitializeRequest(req.body)) {
|
|
687
743
|
logger.info(`Transport missing for session ${sessionId}, checking session store...`);
|
|
688
744
|
if (httpOptions.sessionStore) {
|
|
@@ -698,11 +754,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
698
754
|
});
|
|
699
755
|
return;
|
|
700
756
|
}
|
|
757
|
+
logger.info(`Auto-restoring session: ${sessionId}`);
|
|
701
758
|
transport = new StreamableHTTPServerTransport2({
|
|
702
759
|
sessionIdGenerator: /* @__PURE__ */ __name(() => sessionId, "sessionIdGenerator"),
|
|
703
760
|
onsessioninitialized: /* @__PURE__ */ __name((sid) => {
|
|
704
761
|
transports[sid] = transport;
|
|
705
|
-
logger.info(`
|
|
762
|
+
logger.info(`Session auto-restored: ${sid}`);
|
|
706
763
|
}, "onsessioninitialized")
|
|
707
764
|
});
|
|
708
765
|
transport.onclose = async () => {
|
|
@@ -1424,14 +1481,14 @@ var MCPServer = class {
|
|
|
1424
1481
|
/**
|
|
1425
1482
|
* Auto-register all services from the mcp directory
|
|
1426
1483
|
* Scans the directory recursively and registers all exported classes
|
|
1427
|
-
*
|
|
1484
|
+
*
|
|
1428
1485
|
* @param mcpDir - Path to the mcp directory containing service files
|
|
1429
1486
|
* @param serviceFactories - Optional map of service class names to factory functions for dependency injection
|
|
1430
|
-
*
|
|
1487
|
+
*
|
|
1431
1488
|
* @example
|
|
1432
1489
|
* // Auto-register services with no dependencies
|
|
1433
1490
|
* await server.autoRegisterServices('./mcp');
|
|
1434
|
-
*
|
|
1491
|
+
*
|
|
1435
1492
|
* @example
|
|
1436
1493
|
* // Auto-register with dependency injection
|
|
1437
1494
|
* await server.autoRegisterServices('./mcp', {
|
|
@@ -1584,7 +1641,7 @@ var MCPServer = class {
|
|
|
1584
1641
|
}
|
|
1585
1642
|
/**
|
|
1586
1643
|
* Watch UI manifest for changes and reload resources dynamically
|
|
1587
|
-
*
|
|
1644
|
+
*
|
|
1588
1645
|
* CRITICAL: Only for stateful mode. In stateless mode, each request
|
|
1589
1646
|
* creates a fresh server that reads the manifest directly, making
|
|
1590
1647
|
* watchers both unnecessary and a memory leak source.
|