@leanmcp/core 0.3.6 → 0.3.8
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 +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +69 -6
- package/dist/index.mjs +69 -6
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -550,7 +550,8 @@ async function createHTTPServer(serverInput, options) {
|
|
|
550
550
|
cors: serverOptions.cors,
|
|
551
551
|
logging: serverOptions.logging,
|
|
552
552
|
sessionTimeout: serverOptions.sessionTimeout,
|
|
553
|
-
stateless: serverOptions.stateless
|
|
553
|
+
stateless: serverOptions.stateless,
|
|
554
|
+
dashboard: serverOptions.dashboard
|
|
554
555
|
};
|
|
555
556
|
}
|
|
556
557
|
const [express, { StreamableHTTPServerTransport }, cors] = await Promise.all([
|
|
@@ -668,6 +669,42 @@ async function createHTTPServer(serverInput, options) {
|
|
|
668
669
|
app.use(express.json());
|
|
669
670
|
const isStateless = httpOptions.stateless !== false;
|
|
670
671
|
console.log(`Starting LeanMCP HTTP Server (${isStateless ? "STATELESS" : "STATEFUL"})...`);
|
|
672
|
+
const DASHBOARD_URL = process.env.DASHBOARD_URL || "https://s3-dashboard-build.s3.us-west-2.amazonaws.com/out/index.html";
|
|
673
|
+
let cachedDashboard = null;
|
|
674
|
+
let cacheTimestamp = 0;
|
|
675
|
+
const CACHE_DURATION = 5 * 60 * 1e3;
|
|
676
|
+
async function fetchDashboard() {
|
|
677
|
+
const now = Date.now();
|
|
678
|
+
if (cachedDashboard && now - cacheTimestamp < CACHE_DURATION) {
|
|
679
|
+
return cachedDashboard;
|
|
680
|
+
}
|
|
681
|
+
try {
|
|
682
|
+
const response = await fetch(DASHBOARD_URL);
|
|
683
|
+
if (!response.ok) {
|
|
684
|
+
throw new Error(`Failed to fetch dashboard: ${response.status}`);
|
|
685
|
+
}
|
|
686
|
+
const html = await response.text();
|
|
687
|
+
cachedDashboard = html;
|
|
688
|
+
cacheTimestamp = now;
|
|
689
|
+
return html;
|
|
690
|
+
} catch (error) {
|
|
691
|
+
logger.error("Error fetching dashboard from S3:", error);
|
|
692
|
+
throw error;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
__name(fetchDashboard, "fetchDashboard");
|
|
696
|
+
const isDashboardEnabled = httpOptions.dashboard !== false;
|
|
697
|
+
if (isDashboardEnabled) {
|
|
698
|
+
app.get("/", async (req, res) => {
|
|
699
|
+
try {
|
|
700
|
+
const html = await fetchDashboard();
|
|
701
|
+
res.setHeader("Content-Type", "text/html");
|
|
702
|
+
res.send(html);
|
|
703
|
+
} catch (error) {
|
|
704
|
+
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
}
|
|
671
708
|
app.get("/health", (req, res) => {
|
|
672
709
|
res.json({
|
|
673
710
|
status: "ok",
|
|
@@ -775,18 +812,44 @@ async function createHTTPServer(serverInput, options) {
|
|
|
775
812
|
}
|
|
776
813
|
}
|
|
777
814
|
}, "handleMCPRequestStateless");
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
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
|
+
}
|
|
781
827
|
res.status(405).json({
|
|
782
828
|
jsonrpc: "2.0",
|
|
783
829
|
error: {
|
|
784
830
|
code: -32e3,
|
|
785
|
-
message: "
|
|
831
|
+
message: "SSE streaming not supported in stateless mode or invalid session"
|
|
786
832
|
},
|
|
787
833
|
id: null
|
|
788
834
|
});
|
|
789
|
-
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (isDashboardEnabled) {
|
|
838
|
+
try {
|
|
839
|
+
const html = await fetchDashboard();
|
|
840
|
+
res.setHeader("Content-Type", "text/html");
|
|
841
|
+
res.send(html);
|
|
842
|
+
} catch (error) {
|
|
843
|
+
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
844
|
+
}
|
|
845
|
+
} else {
|
|
846
|
+
res.status(404).json({
|
|
847
|
+
error: "Dashboard disabled"
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
if (isStateless) {
|
|
852
|
+
app.post("/mcp", handleMCPRequestStateless);
|
|
790
853
|
app.delete("/mcp", (_req, res) => {
|
|
791
854
|
res.status(405).json({
|
|
792
855
|
jsonrpc: "2.0",
|
package/dist/index.mjs
CHANGED
|
@@ -512,7 +512,8 @@ async function createHTTPServer(serverInput, options) {
|
|
|
512
512
|
cors: serverOptions.cors,
|
|
513
513
|
logging: serverOptions.logging,
|
|
514
514
|
sessionTimeout: serverOptions.sessionTimeout,
|
|
515
|
-
stateless: serverOptions.stateless
|
|
515
|
+
stateless: serverOptions.stateless,
|
|
516
|
+
dashboard: serverOptions.dashboard
|
|
516
517
|
};
|
|
517
518
|
}
|
|
518
519
|
const [express, { StreamableHTTPServerTransport }, cors] = await Promise.all([
|
|
@@ -630,6 +631,42 @@ async function createHTTPServer(serverInput, options) {
|
|
|
630
631
|
app.use(express.json());
|
|
631
632
|
const isStateless = httpOptions.stateless !== false;
|
|
632
633
|
console.log(`Starting LeanMCP HTTP Server (${isStateless ? "STATELESS" : "STATEFUL"})...`);
|
|
634
|
+
const DASHBOARD_URL = process.env.DASHBOARD_URL || "https://s3-dashboard-build.s3.us-west-2.amazonaws.com/out/index.html";
|
|
635
|
+
let cachedDashboard = null;
|
|
636
|
+
let cacheTimestamp = 0;
|
|
637
|
+
const CACHE_DURATION = 5 * 60 * 1e3;
|
|
638
|
+
async function fetchDashboard() {
|
|
639
|
+
const now = Date.now();
|
|
640
|
+
if (cachedDashboard && now - cacheTimestamp < CACHE_DURATION) {
|
|
641
|
+
return cachedDashboard;
|
|
642
|
+
}
|
|
643
|
+
try {
|
|
644
|
+
const response = await fetch(DASHBOARD_URL);
|
|
645
|
+
if (!response.ok) {
|
|
646
|
+
throw new Error(`Failed to fetch dashboard: ${response.status}`);
|
|
647
|
+
}
|
|
648
|
+
const html = await response.text();
|
|
649
|
+
cachedDashboard = html;
|
|
650
|
+
cacheTimestamp = now;
|
|
651
|
+
return html;
|
|
652
|
+
} catch (error) {
|
|
653
|
+
logger.error("Error fetching dashboard from S3:", error);
|
|
654
|
+
throw error;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
__name(fetchDashboard, "fetchDashboard");
|
|
658
|
+
const isDashboardEnabled = httpOptions.dashboard !== false;
|
|
659
|
+
if (isDashboardEnabled) {
|
|
660
|
+
app.get("/", async (req, res) => {
|
|
661
|
+
try {
|
|
662
|
+
const html = await fetchDashboard();
|
|
663
|
+
res.setHeader("Content-Type", "text/html");
|
|
664
|
+
res.send(html);
|
|
665
|
+
} catch (error) {
|
|
666
|
+
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
}
|
|
633
670
|
app.get("/health", (req, res) => {
|
|
634
671
|
res.json({
|
|
635
672
|
status: "ok",
|
|
@@ -737,18 +774,44 @@ async function createHTTPServer(serverInput, options) {
|
|
|
737
774
|
}
|
|
738
775
|
}
|
|
739
776
|
}, "handleMCPRequestStateless");
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
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
|
+
}
|
|
743
789
|
res.status(405).json({
|
|
744
790
|
jsonrpc: "2.0",
|
|
745
791
|
error: {
|
|
746
792
|
code: -32e3,
|
|
747
|
-
message: "
|
|
793
|
+
message: "SSE streaming not supported in stateless mode or invalid session"
|
|
748
794
|
},
|
|
749
795
|
id: null
|
|
750
796
|
});
|
|
751
|
-
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (isDashboardEnabled) {
|
|
800
|
+
try {
|
|
801
|
+
const html = await fetchDashboard();
|
|
802
|
+
res.setHeader("Content-Type", "text/html");
|
|
803
|
+
res.send(html);
|
|
804
|
+
} catch (error) {
|
|
805
|
+
res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
|
|
806
|
+
}
|
|
807
|
+
} else {
|
|
808
|
+
res.status(404).json({
|
|
809
|
+
error: "Dashboard disabled"
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
if (isStateless) {
|
|
814
|
+
app.post("/mcp", handleMCPRequestStateless);
|
|
752
815
|
app.delete("/mcp", (_req, res) => {
|
|
753
816
|
res.status(405).json({
|
|
754
817
|
jsonrpc: "2.0",
|