@leanmcp/core 0.3.6 → 0.3.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.d.mts CHANGED
@@ -252,6 +252,7 @@ interface HTTPServerOptions {
252
252
  logger?: Logger;
253
253
  sessionTimeout?: number;
254
254
  stateless?: boolean;
255
+ dashboard?: boolean;
255
256
  }
256
257
  interface MCPServerFactory {
257
258
  (): Server | Promise<Server>;
package/dist/index.d.ts CHANGED
@@ -252,6 +252,7 @@ interface HTTPServerOptions {
252
252
  logger?: Logger;
253
253
  sessionTimeout?: number;
254
254
  stateless?: boolean;
255
+ dashboard?: boolean;
255
256
  }
256
257
  interface MCPServerFactory {
257
258
  (): Server | Promise<Server>;
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,19 @@ async function createHTTPServer(serverInput, options) {
775
812
  }
776
813
  }
777
814
  }, "handleMCPRequestStateless");
815
+ if (isDashboardEnabled) {
816
+ app.get("/mcp", async (req, res) => {
817
+ try {
818
+ const html = await fetchDashboard();
819
+ res.setHeader("Content-Type", "text/html");
820
+ res.send(html);
821
+ } catch (error) {
822
+ res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
823
+ }
824
+ });
825
+ }
778
826
  if (isStateless) {
779
827
  app.post("/mcp", handleMCPRequestStateless);
780
- app.get("/mcp", (_req, res) => {
781
- res.status(405).json({
782
- jsonrpc: "2.0",
783
- error: {
784
- code: -32e3,
785
- message: "Method not allowed (stateless mode)"
786
- },
787
- id: null
788
- });
789
- });
790
828
  app.delete("/mcp", (_req, res) => {
791
829
  res.status(405).json({
792
830
  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,19 @@ async function createHTTPServer(serverInput, options) {
737
774
  }
738
775
  }
739
776
  }, "handleMCPRequestStateless");
777
+ if (isDashboardEnabled) {
778
+ app.get("/mcp", async (req, res) => {
779
+ try {
780
+ const html = await fetchDashboard();
781
+ res.setHeader("Content-Type", "text/html");
782
+ res.send(html);
783
+ } catch (error) {
784
+ res.status(500).send("<h1>Dashboard temporarily unavailable</h1><p>Please try again later.</p>");
785
+ }
786
+ });
787
+ }
740
788
  if (isStateless) {
741
789
  app.post("/mcp", handleMCPRequestStateless);
742
- app.get("/mcp", (_req, res) => {
743
- res.status(405).json({
744
- jsonrpc: "2.0",
745
- error: {
746
- code: -32e3,
747
- message: "Method not allowed (stateless mode)"
748
- },
749
- id: null
750
- });
751
- });
752
790
  app.delete("/mcp", (_req, res) => {
753
791
  res.status(405).json({
754
792
  jsonrpc: "2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanmcp/core",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Core library implementing decorators, reflection, and MCP runtime server",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",