mcp-use 1.2.4 → 1.2.5-canary.2

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.
@@ -31,53 +31,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/server/index.ts
32
32
  var server_exports = {};
33
33
  __export(server_exports, {
34
+ adaptConnectMiddleware: () => adaptConnectMiddleware,
35
+ adaptMiddleware: () => adaptMiddleware,
34
36
  buildWidgetUrl: () => buildWidgetUrl,
35
37
  createExternalUrlResource: () => createExternalUrlResource,
36
38
  createMCPServer: () => createMCPServer,
37
39
  createRawHtmlResource: () => createRawHtmlResource,
38
40
  createRemoteDomResource: () => createRemoteDomResource,
39
- createUIResourceFromDefinition: () => createUIResourceFromDefinition
41
+ createUIResourceFromDefinition: () => createUIResourceFromDefinition,
42
+ isExpressMiddleware: () => isExpressMiddleware
40
43
  });
41
44
  module.exports = __toCommonJS(server_exports);
42
45
 
43
46
  // src/server/mcp-server.ts
44
47
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
48
+ var import_hono = require("hono");
49
+ var import_cors = require("hono/cors");
45
50
  var import_zod = require("zod");
46
- var import_express = __toESM(require("express"), 1);
47
- var import_cors = __toESM(require("cors"), 1);
48
- var import_node_fs = require("fs");
49
- var import_node_path = require("path");
50
- var import_node_fs2 = require("fs");
51
-
52
- // src/server/logging.ts
53
- function requestLogger(req, res, next) {
54
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
55
- const method = req.method;
56
- const url = req.url;
57
- const originalEnd = res.end.bind(res);
58
- res.end = function(chunk, encoding, cb) {
59
- const statusCode = res.statusCode;
60
- let statusColor = "";
61
- if (statusCode >= 200 && statusCode < 300) {
62
- statusColor = "\x1B[32m";
63
- } else if (statusCode >= 300 && statusCode < 400) {
64
- statusColor = "\x1B[33m";
65
- } else if (statusCode >= 400 && statusCode < 500) {
66
- statusColor = "\x1B[31m";
67
- } else if (statusCode >= 500) {
68
- statusColor = "\x1B[35m";
69
- }
70
- let logMessage = `[${timestamp}] ${method} \x1B[1m${url}\x1B[0m`;
71
- if (method === "POST" && url === "/mcp" && req.body?.method) {
72
- logMessage += ` \x1B[1m[${req.body.method}]\x1B[0m`;
73
- }
74
- logMessage += ` ${statusColor}${statusCode}\x1B[0m`;
75
- console.log(logMessage);
76
- return originalEnd(chunk, encoding, cb);
77
- };
78
- next();
79
- }
80
- __name(requestLogger, "requestLogger");
81
51
 
82
52
  // src/server/adapters/mcp-ui-adapter.ts
83
53
  var import_server = require("@mcp-ui/server");
@@ -186,9 +156,264 @@ function createUIResourceFromDefinition(definition, params, config) {
186
156
  }
187
157
  __name(createUIResourceFromDefinition, "createUIResourceFromDefinition");
188
158
 
159
+ // src/server/connect-adapter.ts
160
+ function isExpressMiddleware(middleware) {
161
+ if (!middleware || typeof middleware !== "function") {
162
+ return false;
163
+ }
164
+ const paramCount = middleware.length;
165
+ if (paramCount === 3 || paramCount === 4) {
166
+ return true;
167
+ }
168
+ if (paramCount === 2) {
169
+ const fnString = middleware.toString();
170
+ const expressPatterns = [
171
+ /\bres\.(send|json|status|end|redirect|render|sendFile|download)\b/,
172
+ /\breq\.(body|params|query|cookies|session)\b/,
173
+ /\breq\.get\s*\(/,
174
+ /\bres\.set\s*\(/
175
+ ];
176
+ const hasExpressPattern = expressPatterns.some(
177
+ (pattern) => pattern.test(fnString)
178
+ );
179
+ if (hasExpressPattern) {
180
+ return true;
181
+ }
182
+ return false;
183
+ }
184
+ return false;
185
+ }
186
+ __name(isExpressMiddleware, "isExpressMiddleware");
187
+ async function adaptMiddleware(middleware, middlewarePath = "*") {
188
+ if (isExpressMiddleware(middleware)) {
189
+ return adaptConnectMiddleware(middleware, middlewarePath);
190
+ }
191
+ return middleware;
192
+ }
193
+ __name(adaptMiddleware, "adaptMiddleware");
194
+ async function adaptConnectMiddleware(connectMiddleware, middlewarePath) {
195
+ let createRequest;
196
+ let createResponse;
197
+ try {
198
+ const httpMocks = await import("node-mocks-http");
199
+ createRequest = httpMocks.createRequest;
200
+ createResponse = httpMocks.createResponse;
201
+ } catch (error) {
202
+ console.error(
203
+ "[WIDGETS] node-mocks-http not available. Install connect and node-mocks-http for Vite middleware support."
204
+ );
205
+ throw error;
206
+ }
207
+ let normalizedPath = middlewarePath;
208
+ if (normalizedPath.endsWith("*")) {
209
+ normalizedPath = normalizedPath.slice(0, -1);
210
+ }
211
+ if (normalizedPath.endsWith("/")) {
212
+ normalizedPath = normalizedPath.slice(0, -1);
213
+ }
214
+ const honoMiddleware = /* @__PURE__ */ __name(async (c, next) => {
215
+ const request = c.req.raw;
216
+ const parsedURL = new URL(request.url, "http://localhost");
217
+ const query = {};
218
+ for (const [key, value] of parsedURL.searchParams.entries()) {
219
+ query[key] = value;
220
+ }
221
+ let middlewarePathname = parsedURL.pathname;
222
+ if (normalizedPath && middlewarePathname.startsWith(normalizedPath)) {
223
+ middlewarePathname = middlewarePathname.substring(normalizedPath.length);
224
+ if (middlewarePathname === "") {
225
+ middlewarePathname = "/";
226
+ } else if (!middlewarePathname.startsWith("/")) {
227
+ middlewarePathname = "/" + middlewarePathname;
228
+ }
229
+ }
230
+ const mockRequest = createRequest({
231
+ method: request.method.toUpperCase(),
232
+ url: middlewarePathname + parsedURL.search,
233
+ headers: Object.fromEntries(request.headers.entries()),
234
+ query,
235
+ ...request.body && { body: request.body }
236
+ });
237
+ const mockResponse = createResponse();
238
+ let responseResolved = false;
239
+ const res = await new Promise((resolve) => {
240
+ const originalEnd = mockResponse.end.bind(mockResponse);
241
+ mockResponse.end = (...args) => {
242
+ const result = originalEnd(...args);
243
+ if (!responseResolved && mockResponse.writableEnded) {
244
+ responseResolved = true;
245
+ const statusCode = mockResponse.statusCode;
246
+ const noBodyStatuses = [204, 304];
247
+ const responseBody = noBodyStatuses.includes(statusCode) ? null : mockResponse._getData() || mockResponse._getBuffer() || null;
248
+ const connectResponse = new Response(responseBody, {
249
+ status: statusCode,
250
+ statusText: mockResponse.statusMessage,
251
+ headers: mockResponse.getHeaders()
252
+ });
253
+ resolve(connectResponse);
254
+ }
255
+ return result;
256
+ };
257
+ connectMiddleware(mockRequest, mockResponse, () => {
258
+ if (!responseResolved && !mockResponse.writableEnded) {
259
+ responseResolved = true;
260
+ const statusCode = mockResponse.statusCode;
261
+ const noBodyStatuses = [204, 304];
262
+ const responseBody = noBodyStatuses.includes(statusCode) ? null : mockResponse._getData() || mockResponse._getBuffer() || null;
263
+ const preparedHeaders = c.newResponse(null, 204, {}).headers;
264
+ for (const key of [...preparedHeaders.keys()]) {
265
+ if (preparedHeaders.has(key)) {
266
+ c.header(key, void 0);
267
+ }
268
+ if (c.res && c.res.headers.has(key)) {
269
+ c.res.headers.delete(key);
270
+ }
271
+ }
272
+ const connectHeaders = mockResponse.getHeaders();
273
+ for (const [key, value] of Object.entries(connectHeaders)) {
274
+ if (value !== void 0) {
275
+ c.header(
276
+ key,
277
+ Array.isArray(value) ? value.join(", ") : String(value)
278
+ );
279
+ }
280
+ }
281
+ c.status(statusCode);
282
+ if (noBodyStatuses.includes(statusCode)) {
283
+ resolve(c.newResponse(null, statusCode));
284
+ } else if (responseBody) {
285
+ resolve(c.body(responseBody));
286
+ } else {
287
+ resolve(void 0);
288
+ }
289
+ }
290
+ });
291
+ });
292
+ if (res) {
293
+ c.res = res;
294
+ return res;
295
+ }
296
+ await next();
297
+ }, "honoMiddleware");
298
+ return honoMiddleware;
299
+ }
300
+ __name(adaptConnectMiddleware, "adaptConnectMiddleware");
301
+
302
+ // src/server/logging.ts
303
+ async function requestLogger(c, next) {
304
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
305
+ const method = c.req.method;
306
+ const url = c.req.url;
307
+ let body = null;
308
+ if (method === "POST" && url.includes("/mcp")) {
309
+ try {
310
+ const clonedRequest = c.req.raw.clone();
311
+ body = await clonedRequest.json().catch(() => null);
312
+ } catch {
313
+ }
314
+ }
315
+ await next();
316
+ const statusCode = c.res.status;
317
+ let statusColor = "";
318
+ if (statusCode >= 200 && statusCode < 300) {
319
+ statusColor = "\x1B[32m";
320
+ } else if (statusCode >= 300 && statusCode < 400) {
321
+ statusColor = "\x1B[33m";
322
+ } else if (statusCode >= 400 && statusCode < 500) {
323
+ statusColor = "\x1B[31m";
324
+ } else if (statusCode >= 500) {
325
+ statusColor = "\x1B[35m";
326
+ }
327
+ let logMessage = `[${timestamp}] ${method} \x1B[1m${new URL(url).pathname}\x1B[0m`;
328
+ if (method === "POST" && url.includes("/mcp") && body?.method) {
329
+ logMessage += ` \x1B[1m[${body.method}]\x1B[0m`;
330
+ }
331
+ logMessage += ` ${statusColor}${statusCode}\x1B[0m`;
332
+ console.log(logMessage);
333
+ }
334
+ __name(requestLogger, "requestLogger");
335
+
189
336
  // src/server/mcp-server.ts
190
- var import_vite = require("vite");
191
337
  var TMP_MCP_USE_DIR = ".mcp-use";
338
+ var isDeno = typeof globalThis.Deno !== "undefined";
339
+ function getEnv(key) {
340
+ if (isDeno) {
341
+ return globalThis.Deno.env.get(key);
342
+ }
343
+ return process.env[key];
344
+ }
345
+ __name(getEnv, "getEnv");
346
+ function getCwd() {
347
+ if (isDeno) {
348
+ return globalThis.Deno.cwd();
349
+ }
350
+ return process.cwd();
351
+ }
352
+ __name(getCwd, "getCwd");
353
+ var fsHelpers = {
354
+ async readFileSync(path, encoding = "utf8") {
355
+ if (isDeno) {
356
+ return await globalThis.Deno.readTextFile(path);
357
+ }
358
+ const { readFileSync } = await import("fs");
359
+ const result = readFileSync(path, encoding);
360
+ return typeof result === "string" ? result : result.toString(encoding);
361
+ },
362
+ async readFile(path) {
363
+ if (isDeno) {
364
+ const data = await globalThis.Deno.readFile(path);
365
+ return data.buffer;
366
+ }
367
+ const { readFileSync } = await import("fs");
368
+ const buffer = readFileSync(path);
369
+ return buffer.buffer.slice(
370
+ buffer.byteOffset,
371
+ buffer.byteOffset + buffer.byteLength
372
+ );
373
+ },
374
+ async existsSync(path) {
375
+ if (isDeno) {
376
+ try {
377
+ await globalThis.Deno.stat(path);
378
+ return true;
379
+ } catch {
380
+ return false;
381
+ }
382
+ }
383
+ const { existsSync } = await import("fs");
384
+ return existsSync(path);
385
+ },
386
+ async readdirSync(path) {
387
+ if (isDeno) {
388
+ const entries = [];
389
+ for await (const entry of globalThis.Deno.readDir(path)) {
390
+ entries.push(entry.name);
391
+ }
392
+ return entries;
393
+ }
394
+ const { readdirSync } = await import("fs");
395
+ return readdirSync(path);
396
+ }
397
+ };
398
+ var pathHelpers = {
399
+ join(...paths) {
400
+ if (isDeno) {
401
+ return paths.join("/").replace(/\/+/g, "/");
402
+ }
403
+ return paths.join("/").replace(/\/+/g, "/");
404
+ },
405
+ relative(from, to) {
406
+ const fromParts = from.split("/").filter((p) => p);
407
+ const toParts = to.split("/").filter((p) => p);
408
+ let i = 0;
409
+ while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {
410
+ i++;
411
+ }
412
+ const upCount = fromParts.length - i;
413
+ const relativeParts = [...Array(upCount).fill(".."), ...toParts.slice(i)];
414
+ return relativeParts.join("/");
415
+ }
416
+ };
192
417
  var McpServer = class {
193
418
  static {
194
419
  __name(this, "McpServer");
@@ -202,14 +427,14 @@ var McpServer = class {
202
427
  serverHost;
203
428
  serverBaseUrl;
204
429
  /**
205
- * Creates a new MCP server instance with Express integration
430
+ * Creates a new MCP server instance with Hono integration
206
431
  *
207
432
  * Initializes the server with the provided configuration, sets up CORS headers,
208
433
  * configures widget serving routes, and creates a proxy that allows direct
209
- * access to Express methods while preserving MCP server functionality.
434
+ * access to Hono methods while preserving MCP server functionality.
210
435
  *
211
436
  * @param config - Server configuration including name, version, and description
212
- * @returns A proxied McpServer instance that supports both MCP and Express methods
437
+ * @returns A proxied McpServer instance that supports both MCP and Hono methods
213
438
  */
214
439
  constructor(config) {
215
440
  this.config = config;
@@ -219,13 +444,13 @@ var McpServer = class {
219
444
  name: config.name,
220
445
  version: config.version
221
446
  });
222
- this.app = (0, import_express.default)();
223
- this.app.use(import_express.default.json());
447
+ this.app = new import_hono.Hono();
224
448
  this.app.use(
225
- (0, import_cors.default)({
449
+ "*",
450
+ (0, import_cors.cors)({
226
451
  origin: "*",
227
- methods: ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"],
228
- allowedHeaders: [
452
+ allowMethods: ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"],
453
+ allowHeaders: [
229
454
  "Content-Type",
230
455
  "Accept",
231
456
  "Authorization",
@@ -236,9 +461,55 @@ var McpServer = class {
236
461
  ]
237
462
  })
238
463
  );
239
- this.app.use(requestLogger);
464
+ this.app.use("*", requestLogger);
240
465
  return new Proxy(this, {
241
466
  get(target, prop) {
467
+ if (prop === "use") {
468
+ return (...args) => {
469
+ const hasPath = typeof args[0] === "string";
470
+ const path = hasPath ? args[0] : "*";
471
+ const handlers = hasPath ? args.slice(1) : args;
472
+ const adaptedHandlers = handlers.map((handler) => {
473
+ if (isExpressMiddleware(handler)) {
474
+ return { __isExpressMiddleware: true, handler, path };
475
+ }
476
+ return handler;
477
+ });
478
+ const hasExpressMiddleware = adaptedHandlers.some(
479
+ (h) => h.__isExpressMiddleware
480
+ );
481
+ if (hasExpressMiddleware) {
482
+ Promise.all(
483
+ adaptedHandlers.map(async (h) => {
484
+ if (h.__isExpressMiddleware) {
485
+ const adapted = await adaptConnectMiddleware(
486
+ h.handler,
487
+ h.path
488
+ );
489
+ if (hasPath) {
490
+ target.app.use(path, adapted);
491
+ } else {
492
+ target.app.use(adapted);
493
+ }
494
+ } else {
495
+ if (hasPath) {
496
+ target.app.use(path, h);
497
+ } else {
498
+ target.app.use(h);
499
+ }
500
+ }
501
+ })
502
+ ).catch((err) => {
503
+ console.error(
504
+ "[MIDDLEWARE] Failed to adapt Express middleware:",
505
+ err
506
+ );
507
+ });
508
+ return target;
509
+ }
510
+ return target.app.use(...args);
511
+ };
512
+ }
242
513
  if (prop in target) {
243
514
  return target[prop];
244
515
  }
@@ -772,7 +1043,7 @@ var McpServer = class {
772
1043
  * @returns true if in production mode, false otherwise
773
1044
  */
774
1045
  isProductionMode() {
775
- return process.env.NODE_ENV === "production";
1046
+ return getEnv("NODE_ENV") === "production";
776
1047
  }
777
1048
  /**
778
1049
  * Read build manifest file
@@ -780,14 +1051,14 @@ var McpServer = class {
780
1051
  * @private
781
1052
  * @returns Build manifest or null if not found
782
1053
  */
783
- readBuildManifest() {
1054
+ async readBuildManifest() {
784
1055
  try {
785
- const manifestPath = (0, import_node_path.join)(
786
- process.cwd(),
1056
+ const manifestPath = pathHelpers.join(
1057
+ getCwd(),
787
1058
  "dist",
788
- ".mcp-use-manifest.json"
1059
+ "mcp-use.json"
789
1060
  );
790
- const content = (0, import_node_fs2.readFileSync)(manifestPath, "utf8");
1061
+ const content = await fsHelpers.readFileSync(manifestPath, "utf8");
791
1062
  return JSON.parse(content);
792
1063
  } catch {
793
1064
  return null;
@@ -805,9 +1076,11 @@ var McpServer = class {
805
1076
  * @returns Promise that resolves when all widgets are mounted
806
1077
  */
807
1078
  async mountWidgets(options) {
808
- if (this.isProductionMode()) {
1079
+ if (this.isProductionMode() || isDeno) {
1080
+ console.log("[WIDGETS] Mounting widgets in production mode");
809
1081
  await this.mountWidgetsProduction(options);
810
1082
  } else {
1083
+ console.log("[WIDGETS] Mounting widgets in development mode");
811
1084
  await this.mountWidgetsDev(options);
812
1085
  }
813
1086
  }
@@ -828,7 +1101,7 @@ var McpServer = class {
828
1101
  const { promises: fs } = await import("fs");
829
1102
  const baseRoute = options?.baseRoute || "/mcp-use/widgets";
830
1103
  const resourcesDir = options?.resourcesDir || "resources";
831
- const srcDir = (0, import_node_path.join)(process.cwd(), resourcesDir);
1104
+ const srcDir = pathHelpers.join(getCwd(), resourcesDir);
832
1105
  try {
833
1106
  await fs.access(srcDir);
834
1107
  } catch (error) {
@@ -840,7 +1113,7 @@ var McpServer = class {
840
1113
  let entries = [];
841
1114
  try {
842
1115
  const files = await fs.readdir(srcDir);
843
- entries = files.filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => (0, import_node_path.join)(srcDir, f));
1116
+ entries = files.filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => pathHelpers.join(srcDir, f));
844
1117
  } catch (error) {
845
1118
  console.log(`[WIDGETS] No widgets found in ${resourcesDir}/ directory`);
846
1119
  return;
@@ -849,12 +1122,32 @@ var McpServer = class {
849
1122
  console.log(`[WIDGETS] No widgets found in ${resourcesDir}/ directory`);
850
1123
  return;
851
1124
  }
852
- const tempDir = (0, import_node_path.join)(process.cwd(), TMP_MCP_USE_DIR);
1125
+ const tempDir = pathHelpers.join(getCwd(), TMP_MCP_USE_DIR);
853
1126
  await fs.mkdir(tempDir, { recursive: true }).catch(() => {
854
1127
  });
855
- const react = (await import("@vitejs/plugin-react")).default;
856
- const tailwindcss = (await import("@tailwindcss/vite")).default;
857
- console.log(react, tailwindcss);
1128
+ let createServer;
1129
+ let react;
1130
+ let tailwindcss;
1131
+ try {
1132
+ const viteModule = await new Function('return import("vite")')();
1133
+ createServer = viteModule.createServer;
1134
+ const reactModule = await new Function(
1135
+ 'return import("@vitejs/plugin-react")'
1136
+ )();
1137
+ react = reactModule.default;
1138
+ const tailwindModule = await new Function(
1139
+ 'return import("@tailwindcss/vite")'
1140
+ )();
1141
+ tailwindcss = tailwindModule.default;
1142
+ } catch (error) {
1143
+ console.error(
1144
+ "[WIDGETS] Dev dependencies not available. Install vite, @vitejs/plugin-react, and @tailwindcss/vite for widget development."
1145
+ );
1146
+ console.error(
1147
+ "[WIDGETS] For production, use 'mcp-use build' to pre-build widgets."
1148
+ );
1149
+ return;
1150
+ }
858
1151
  const widgets = entries.map((entry) => {
859
1152
  const baseName = entry.split("/").pop()?.replace(/\.tsx?$/, "") || "widget";
860
1153
  const widgetName = baseName;
@@ -865,20 +1158,20 @@ var McpServer = class {
865
1158
  };
866
1159
  });
867
1160
  for (const widget of widgets) {
868
- const widgetTempDir = (0, import_node_path.join)(tempDir, widget.name);
1161
+ const widgetTempDir = pathHelpers.join(tempDir, widget.name);
869
1162
  await fs.mkdir(widgetTempDir, { recursive: true });
870
- const resourcesPath = (0, import_node_path.join)(process.cwd(), resourcesDir);
871
- const { relative } = await import("path");
872
- const relativeResourcesPath = relative(
873
- widgetTempDir,
874
- resourcesPath
875
- ).replace(/\\/g, "/");
1163
+ const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
1164
+ const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
876
1165
  const cssContent = `@import "tailwindcss";
877
1166
 
878
1167
  /* Configure Tailwind to scan the resources directory */
879
1168
  @source "${relativeResourcesPath}";
880
1169
  `;
881
- await fs.writeFile((0, import_node_path.join)(widgetTempDir, "styles.css"), cssContent, "utf8");
1170
+ await fs.writeFile(
1171
+ pathHelpers.join(widgetTempDir, "styles.css"),
1172
+ cssContent,
1173
+ "utf8"
1174
+ );
882
1175
  const entryContent = `import React from 'react'
883
1176
  import { createRoot } from 'react-dom/client'
884
1177
  import './styles.css'
@@ -903,12 +1196,12 @@ if (container && Component) {
903
1196
  </body>
904
1197
  </html>`;
905
1198
  await fs.writeFile(
906
- (0, import_node_path.join)(widgetTempDir, "entry.tsx"),
1199
+ pathHelpers.join(widgetTempDir, "entry.tsx"),
907
1200
  entryContent,
908
1201
  "utf8"
909
1202
  );
910
1203
  await fs.writeFile(
911
- (0, import_node_path.join)(widgetTempDir, "index.html"),
1204
+ pathHelpers.join(widgetTempDir, "index.html"),
912
1205
  htmlContent,
913
1206
  "utf8"
914
1207
  );
@@ -917,13 +1210,13 @@ if (container && Component) {
917
1210
  console.log(
918
1211
  `[WIDGETS] Serving ${entries.length} widget(s) with shared Vite dev server and HMR`
919
1212
  );
920
- const viteServer = await (0, import_vite.createServer)({
1213
+ const viteServer = await createServer({
921
1214
  root: tempDir,
922
1215
  base: baseRoute + "/",
923
1216
  plugins: [tailwindcss(), react()],
924
1217
  resolve: {
925
1218
  alias: {
926
- "@": (0, import_node_path.join)(process.cwd(), resourcesDir)
1219
+ "@": pathHelpers.join(getCwd(), resourcesDir)
927
1220
  }
928
1221
  },
929
1222
  server: {
@@ -931,22 +1224,38 @@ if (container && Component) {
931
1224
  origin: serverOrigin
932
1225
  }
933
1226
  });
934
- this.app.use(baseRoute, (req, res, next) => {
935
- const urlPath = req.url || "";
936
- const [pathname, queryString] = urlPath.split("?");
937
- const widgetMatch = pathname.match(/^\/([^/]+)/);
1227
+ this.app.use(`${baseRoute}/*`, async (c, next) => {
1228
+ const url = new URL(c.req.url);
1229
+ const pathname = url.pathname;
1230
+ const widgetMatch = pathname.replace(baseRoute, "").match(/^\/([^/]+)/);
938
1231
  if (widgetMatch) {
939
1232
  const widgetName = widgetMatch[1];
940
1233
  const widget = widgets.find((w) => w.name === widgetName);
941
1234
  if (widget) {
942
- if (pathname === `/${widgetName}` || pathname === `/${widgetName}/`) {
943
- req.url = `/${widgetName}/index.html${queryString ? "?" + queryString : ""}`;
1235
+ const relativePath = pathname.replace(baseRoute, "");
1236
+ if (relativePath === `/${widgetName}` || relativePath === `/${widgetName}/`) {
1237
+ const newUrl = new URL(c.req.url);
1238
+ newUrl.pathname = `${baseRoute}/${widgetName}/index.html`;
1239
+ const newRequest = new Request(newUrl.toString(), c.req.raw);
1240
+ Object.defineProperty(c, "req", {
1241
+ value: {
1242
+ ...c.req,
1243
+ url: newUrl.toString(),
1244
+ raw: newRequest
1245
+ },
1246
+ writable: false,
1247
+ configurable: true
1248
+ });
944
1249
  }
945
1250
  }
946
1251
  }
947
- next();
1252
+ await next();
948
1253
  });
949
- this.app.use(baseRoute, viteServer.middlewares);
1254
+ const viteMiddleware = await adaptConnectMiddleware(
1255
+ viteServer.middlewares,
1256
+ `${baseRoute}/*`
1257
+ );
1258
+ this.app.use(`${baseRoute}/*`, viteMiddleware);
950
1259
  widgets.forEach((widget) => {
951
1260
  console.log(
952
1261
  `[WIDGET] ${widget.name} mounted at ${baseRoute}/${widget.name}`
@@ -982,8 +1291,11 @@ if (container && Component) {
982
1291
  console.log("[WIDGET dev] Metadata:", metadata);
983
1292
  let html = "";
984
1293
  try {
985
- html = (0, import_node_fs2.readFileSync)((0, import_node_path.join)(tempDir, widget.name, "index.html"), "utf8");
986
- const mcpUrl = process.env.MCP_URL || "/";
1294
+ html = await fsHelpers.readFileSync(
1295
+ pathHelpers.join(tempDir, widget.name, "index.html"),
1296
+ "utf8"
1297
+ );
1298
+ const mcpUrl = getEnv("MCP_URL") || "/";
987
1299
  if (mcpUrl && html) {
988
1300
  const htmlWithoutComments = html.replace(/<!--[\s\S]*?-->/g, "");
989
1301
  const baseTagRegex = /<base\s+[^>]*\/?>/i;
@@ -1083,22 +1395,46 @@ if (container && Component) {
1083
1395
  */
1084
1396
  async mountWidgetsProduction(options) {
1085
1397
  const baseRoute = options?.baseRoute || "/mcp-use/widgets";
1086
- const widgetsDir = (0, import_node_path.join)(process.cwd(), "dist", "resources", "widgets");
1087
- if (!(0, import_node_fs.existsSync)(widgetsDir)) {
1398
+ const widgetsDir = pathHelpers.join(
1399
+ getCwd(),
1400
+ "dist",
1401
+ "resources",
1402
+ "widgets"
1403
+ );
1404
+ console.log("widgetsDir", widgetsDir);
1405
+ this.setupWidgetRoutes();
1406
+ const manifestPath = "./dist/mcp-use.json";
1407
+ let widgets = [];
1408
+ try {
1409
+ const manifestContent = await fsHelpers.readFileSync(manifestPath, "utf8");
1410
+ const manifest = JSON.parse(manifestContent);
1411
+ if (manifest.widgets && Array.isArray(manifest.widgets)) {
1412
+ widgets = manifest.widgets;
1413
+ console.log(`[WIDGETS] Loaded ${widgets.length} widget(s) from manifest`);
1414
+ } else {
1415
+ console.log("[WIDGETS] No widgets array found in manifest");
1416
+ }
1417
+ } catch (error) {
1088
1418
  console.log(
1089
- "[WIDGETS] No dist/resources/widgets/ directory found - skipping widget serving"
1419
+ "[WIDGETS] Could not read manifest file, falling back to directory listing:",
1420
+ error
1090
1421
  );
1091
- return;
1422
+ try {
1423
+ const allEntries = await fsHelpers.readdirSync(widgetsDir);
1424
+ for (const name of allEntries) {
1425
+ const widgetPath = pathHelpers.join(widgetsDir, name);
1426
+ const indexPath = pathHelpers.join(widgetPath, "index.html");
1427
+ if (await fsHelpers.existsSync(indexPath)) {
1428
+ widgets.push(name);
1429
+ }
1430
+ }
1431
+ } catch (dirError) {
1432
+ console.log("[WIDGETS] Directory listing also failed:", dirError);
1433
+ }
1092
1434
  }
1093
- this.setupWidgetRoutes();
1094
- const widgets = (0, import_node_fs.readdirSync)(widgetsDir).filter((name) => {
1095
- const widgetPath = (0, import_node_path.join)(widgetsDir, name);
1096
- const indexPath = (0, import_node_path.join)(widgetPath, "index.html");
1097
- return (0, import_node_fs.existsSync)(indexPath);
1098
- });
1099
1435
  if (widgets.length === 0) {
1100
1436
  console.log(
1101
- "[WIDGETS] No built widgets found in dist/resources/widgets/"
1437
+ "[WIDGETS] No built widgets found"
1102
1438
  );
1103
1439
  return;
1104
1440
  }
@@ -1106,13 +1442,13 @@ if (container && Component) {
1106
1442
  `[WIDGETS] Serving ${widgets.length} pre-built widget(s) from dist/resources/widgets/`
1107
1443
  );
1108
1444
  for (const widgetName of widgets) {
1109
- const widgetPath = (0, import_node_path.join)(widgetsDir, widgetName);
1110
- const indexPath = (0, import_node_path.join)(widgetPath, "index.html");
1111
- const metadataPath = (0, import_node_path.join)(widgetPath, "metadata.json");
1445
+ const widgetPath = pathHelpers.join(widgetsDir, widgetName);
1446
+ const indexPath = pathHelpers.join(widgetPath, "index.html");
1447
+ const metadataPath = pathHelpers.join(widgetPath, "metadata.json");
1112
1448
  let html = "";
1113
1449
  try {
1114
- html = (0, import_node_fs2.readFileSync)(indexPath, "utf8");
1115
- const mcpUrl = process.env.MCP_URL || "/";
1450
+ html = await fsHelpers.readFileSync(indexPath, "utf8");
1451
+ const mcpUrl = getEnv("MCP_URL") || "/";
1116
1452
  if (mcpUrl && html) {
1117
1453
  const htmlWithoutComments = html.replace(/<!--[\s\S]*?-->/g, "");
1118
1454
  const baseTagRegex = /<base\s+[^>]*\/?>/i;
@@ -1159,7 +1495,10 @@ if (container && Component) {
1159
1495
  let props = {};
1160
1496
  let description = `Widget: ${widgetName}`;
1161
1497
  try {
1162
- const metadataContent = (0, import_node_fs2.readFileSync)(metadataPath, "utf8");
1498
+ const metadataContent = await fsHelpers.readFileSync(
1499
+ metadataPath,
1500
+ "utf8"
1501
+ );
1163
1502
  metadata = JSON.parse(metadataContent);
1164
1503
  if (metadata.description) {
1165
1504
  description = metadata.description;
@@ -1242,47 +1581,182 @@ if (container && Component) {
1242
1581
  if (this.mcpMounted) return;
1243
1582
  const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
1244
1583
  const endpoint = "/mcp";
1245
- this.app.post(endpoint, import_express.default.json(), async (req, res) => {
1584
+ const createExpressLikeObjects = /* @__PURE__ */ __name((c) => {
1585
+ const req = c.req.raw;
1586
+ const responseBody = [];
1587
+ let statusCode = 200;
1588
+ const headers = {};
1589
+ let ended = false;
1590
+ let headersSent = false;
1591
+ const expressReq = {
1592
+ ...req,
1593
+ url: new URL(req.url).pathname + new URL(req.url).search,
1594
+ originalUrl: req.url,
1595
+ baseUrl: "",
1596
+ path: new URL(req.url).pathname,
1597
+ query: Object.fromEntries(new URL(req.url).searchParams),
1598
+ params: {},
1599
+ body: {},
1600
+ headers: Object.fromEntries(req.headers.entries()),
1601
+ method: req.method
1602
+ };
1603
+ const expressRes = {
1604
+ statusCode: 200,
1605
+ headersSent: false,
1606
+ status: /* @__PURE__ */ __name((code) => {
1607
+ statusCode = code;
1608
+ expressRes.statusCode = code;
1609
+ return expressRes;
1610
+ }, "status"),
1611
+ setHeader: /* @__PURE__ */ __name((name, value) => {
1612
+ if (!headersSent) {
1613
+ headers[name] = Array.isArray(value) ? value.join(", ") : value;
1614
+ }
1615
+ }, "setHeader"),
1616
+ getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
1617
+ write: /* @__PURE__ */ __name((chunk, encoding, callback) => {
1618
+ if (!ended) {
1619
+ const data = typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
1620
+ responseBody.push(data);
1621
+ }
1622
+ if (typeof encoding === "function") {
1623
+ encoding();
1624
+ } else if (callback) {
1625
+ callback();
1626
+ }
1627
+ return true;
1628
+ }, "write"),
1629
+ end: /* @__PURE__ */ __name((chunk, encoding, callback) => {
1630
+ if (chunk && !ended) {
1631
+ const data = typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
1632
+ responseBody.push(data);
1633
+ }
1634
+ ended = true;
1635
+ if (typeof encoding === "function") {
1636
+ encoding();
1637
+ } else if (callback) {
1638
+ callback();
1639
+ }
1640
+ }, "end"),
1641
+ on: /* @__PURE__ */ __name((event, handler) => {
1642
+ if (event === "close") {
1643
+ expressRes._closeHandler = handler;
1644
+ }
1645
+ }, "on"),
1646
+ once: /* @__PURE__ */ __name(() => {
1647
+ }, "once"),
1648
+ removeListener: /* @__PURE__ */ __name(() => {
1649
+ }, "removeListener"),
1650
+ writeHead: /* @__PURE__ */ __name((code, _headers) => {
1651
+ statusCode = code;
1652
+ expressRes.statusCode = code;
1653
+ headersSent = true;
1654
+ if (_headers) {
1655
+ Object.assign(headers, _headers);
1656
+ }
1657
+ return expressRes;
1658
+ }, "writeHead"),
1659
+ flushHeaders: /* @__PURE__ */ __name(() => {
1660
+ headersSent = true;
1661
+ }, "flushHeaders"),
1662
+ send: /* @__PURE__ */ __name((body) => {
1663
+ if (!ended) {
1664
+ expressRes.write(body);
1665
+ expressRes.end();
1666
+ }
1667
+ }, "send")
1668
+ };
1669
+ return {
1670
+ expressReq,
1671
+ expressRes,
1672
+ getResponse: /* @__PURE__ */ __name(() => {
1673
+ if (ended) {
1674
+ if (responseBody.length > 0) {
1675
+ const body = isDeno ? Buffer.concat(responseBody) : Buffer.concat(responseBody);
1676
+ return new Response(body, {
1677
+ status: statusCode,
1678
+ headers
1679
+ });
1680
+ } else {
1681
+ return new Response(null, {
1682
+ status: statusCode,
1683
+ headers
1684
+ });
1685
+ }
1686
+ }
1687
+ return null;
1688
+ }, "getResponse")
1689
+ };
1690
+ }, "createExpressLikeObjects");
1691
+ this.app.post(endpoint, async (c) => {
1692
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1693
+ try {
1694
+ expressReq.body = await c.req.json();
1695
+ } catch {
1696
+ expressReq.body = {};
1697
+ }
1246
1698
  const transport = new StreamableHTTPServerTransport({
1247
1699
  sessionIdGenerator: void 0,
1248
1700
  enableJsonResponse: true
1249
1701
  });
1250
- res.on("close", () => {
1251
- transport.close();
1252
- });
1702
+ if (expressRes._closeHandler) {
1703
+ c.req.raw.signal?.addEventListener("abort", () => {
1704
+ transport.close();
1705
+ });
1706
+ }
1253
1707
  await this.server.connect(transport);
1254
- await transport.handleRequest(req, res, req.body);
1708
+ await transport.handleRequest(expressReq, expressRes, expressReq.body);
1709
+ await new Promise((resolve) => setTimeout(resolve, 10));
1710
+ const response = getResponse();
1711
+ if (response) {
1712
+ return response;
1713
+ }
1714
+ return c.text("", 200);
1255
1715
  });
1256
- this.app.get(endpoint, async (req, res) => {
1716
+ this.app.get(endpoint, async (c) => {
1717
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1257
1718
  const transport = new StreamableHTTPServerTransport({
1258
1719
  sessionIdGenerator: void 0,
1259
1720
  enableJsonResponse: true
1260
1721
  });
1261
- res.on("close", () => {
1722
+ c.req.raw.signal?.addEventListener("abort", () => {
1262
1723
  transport.close();
1263
1724
  });
1264
1725
  await this.server.connect(transport);
1265
- await transport.handleRequest(req, res);
1726
+ await transport.handleRequest(expressReq, expressRes);
1727
+ await new Promise((resolve) => setTimeout(resolve, 10));
1728
+ const response = getResponse();
1729
+ if (response) {
1730
+ return response;
1731
+ }
1732
+ return c.text("", 200);
1266
1733
  });
1267
- this.app.delete(endpoint, async (req, res) => {
1734
+ this.app.delete(endpoint, async (c) => {
1735
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1268
1736
  const transport = new StreamableHTTPServerTransport({
1269
1737
  sessionIdGenerator: void 0,
1270
1738
  enableJsonResponse: true
1271
1739
  });
1272
- res.on("close", () => {
1740
+ c.req.raw.signal?.addEventListener("abort", () => {
1273
1741
  transport.close();
1274
1742
  });
1275
1743
  await this.server.connect(transport);
1276
- await transport.handleRequest(req, res);
1744
+ await transport.handleRequest(expressReq, expressRes);
1745
+ await new Promise((resolve) => setTimeout(resolve, 10));
1746
+ const response = getResponse();
1747
+ if (response) {
1748
+ return response;
1749
+ }
1750
+ return c.text("", 200);
1277
1751
  });
1278
1752
  this.mcpMounted = true;
1279
1753
  console.log(`[MCP] Server mounted at ${endpoint}`);
1280
1754
  }
1281
1755
  /**
1282
- * Start the Express server with MCP endpoints
1756
+ * Start the Hono server with MCP endpoints
1283
1757
  *
1284
1758
  * Initiates the server startup process by mounting MCP endpoints, configuring
1285
- * the inspector UI (if available), and starting the Express server to listen
1759
+ * the inspector UI (if available), and starting the server to listen
1286
1760
  * for incoming connections. This is the main entry point for running the server.
1287
1761
  *
1288
1762
  * The server will be accessible at the specified port with MCP endpoints at /mcp
@@ -1300,24 +1774,125 @@ if (container && Component) {
1300
1774
  * ```
1301
1775
  */
1302
1776
  async listen(port) {
1303
- this.serverPort = port || (process.env.PORT ? parseInt(process.env.PORT, 10) : 3001);
1304
- if (process.env.HOST) {
1305
- this.serverHost = process.env.HOST;
1777
+ const portEnv = getEnv("PORT");
1778
+ this.serverPort = port || (portEnv ? parseInt(portEnv, 10) : 3001);
1779
+ const hostEnv = getEnv("HOST");
1780
+ if (hostEnv) {
1781
+ this.serverHost = hostEnv;
1306
1782
  }
1307
1783
  await this.mountWidgets({
1308
1784
  baseRoute: "/mcp-use/widgets",
1309
1785
  resourcesDir: "resources"
1310
1786
  });
1311
1787
  await this.mountMcp();
1312
- this.mountInspector();
1313
- this.app.listen(this.serverPort, () => {
1788
+ await this.mountInspector();
1789
+ if (isDeno) {
1790
+ globalThis.Deno.serve(
1791
+ { port: this.serverPort, hostname: this.serverHost },
1792
+ this.app.fetch
1793
+ );
1314
1794
  console.log(
1315
1795
  `[SERVER] Listening on http://${this.serverHost}:${this.serverPort}`
1316
1796
  );
1317
1797
  console.log(
1318
1798
  `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp`
1319
1799
  );
1800
+ } else {
1801
+ const { serve } = await import("@hono/node-server");
1802
+ serve(
1803
+ {
1804
+ fetch: this.app.fetch,
1805
+ port: this.serverPort,
1806
+ hostname: this.serverHost
1807
+ },
1808
+ (_info) => {
1809
+ console.log(
1810
+ `[SERVER] Listening on http://${this.serverHost}:${this.serverPort}`
1811
+ );
1812
+ console.log(
1813
+ `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp`
1814
+ );
1815
+ }
1816
+ );
1817
+ }
1818
+ }
1819
+ /**
1820
+ * Get the fetch handler for the server after mounting all endpoints
1821
+ *
1822
+ * This method prepares the server by mounting MCP endpoints, widgets, and inspector
1823
+ * (if available), then returns the fetch handler. This is useful for integrating
1824
+ * with external server frameworks like Supabase Edge Functions, Cloudflare Workers,
1825
+ * or other platforms that handle the server lifecycle themselves.
1826
+ *
1827
+ * Unlike `listen()`, this method does not start a server - it only prepares the
1828
+ * routes and returns the handler function that can be used with external servers.
1829
+ *
1830
+ * @param options - Optional configuration for the handler
1831
+ * @param options.provider - Platform provider (e.g., 'supabase') to handle platform-specific path rewriting
1832
+ * @returns Promise that resolves to the fetch handler function
1833
+ *
1834
+ * @example
1835
+ * ```typescript
1836
+ * // For Supabase Edge Functions (handles path rewriting automatically)
1837
+ * const server = createMCPServer('my-server');
1838
+ * server.tool({ ... });
1839
+ * const handler = await server.getHandler({ provider: 'supabase' });
1840
+ * Deno.serve(handler);
1841
+ * ```
1842
+ *
1843
+ * @example
1844
+ * ```typescript
1845
+ * // For Cloudflare Workers
1846
+ * const server = createMCPServer('my-server');
1847
+ * server.tool({ ... });
1848
+ * const handler = await server.getHandler();
1849
+ * export default { fetch: handler };
1850
+ * ```
1851
+ */
1852
+ async getHandler(options) {
1853
+ console.log("[MCP] Mounting widgets");
1854
+ await this.mountWidgets({
1855
+ baseRoute: "/mcp-use/widgets",
1856
+ resourcesDir: "resources"
1320
1857
  });
1858
+ console.log("[MCP] Mounted widgets");
1859
+ await this.mountMcp();
1860
+ console.log("[MCP] Mounted MCP");
1861
+ console.log("[MCP] Mounting inspector");
1862
+ await this.mountInspector();
1863
+ console.log("[MCP] Mounted inspector");
1864
+ const fetchHandler = this.app.fetch.bind(this.app);
1865
+ if (options?.provider === "supabase") {
1866
+ return async (req) => {
1867
+ const url = new URL(req.url);
1868
+ const pathname = url.pathname;
1869
+ let newPathname = pathname;
1870
+ const functionsMatch = pathname.match(
1871
+ /^\/functions\/v1\/[^/]+(\/.*)?$/
1872
+ );
1873
+ if (functionsMatch) {
1874
+ newPathname = functionsMatch[1] || "/";
1875
+ } else {
1876
+ const functionNameMatch = pathname.match(/^\/([^/]+)(\/.*)?$/);
1877
+ if (functionNameMatch && functionNameMatch[2]) {
1878
+ newPathname = functionNameMatch[2] || "/";
1879
+ }
1880
+ }
1881
+ const newUrl = new URL(newPathname + url.search, url.origin);
1882
+ const newReq = new Request(newUrl, {
1883
+ method: req.method,
1884
+ headers: req.headers,
1885
+ body: req.body,
1886
+ redirect: req.redirect
1887
+ });
1888
+ const result = await fetchHandler(newReq);
1889
+ return result;
1890
+ };
1891
+ }
1892
+ return async (req) => {
1893
+ const result = await fetchHandler(req);
1894
+ return result;
1895
+ };
1321
1896
  }
1322
1897
  /**
1323
1898
  * Mount MCP Inspector UI at /inspector
@@ -1341,10 +1916,10 @@ if (container && Component) {
1341
1916
  * - Server continues to function normally
1342
1917
  * - No inspector UI available
1343
1918
  */
1344
- mountInspector() {
1919
+ async mountInspector() {
1345
1920
  if (this.inspectorMounted) return;
1346
1921
  if (this.isProductionMode()) {
1347
- const manifest = this.readBuildManifest();
1922
+ const manifest = await this.readBuildManifest();
1348
1923
  if (!manifest?.includeInspector) {
1349
1924
  console.log(
1350
1925
  "[INSPECTOR] Skipped in production (use --with-inspector flag during build)"
@@ -1352,19 +1927,20 @@ if (container && Component) {
1352
1927
  return;
1353
1928
  }
1354
1929
  }
1355
- import("@mcp-use/inspector").then(({ mountInspector }) => {
1930
+ try {
1931
+ const { mountInspector } = await import("@mcp-use/inspector");
1356
1932
  mountInspector(this.app);
1357
1933
  this.inspectorMounted = true;
1358
1934
  console.log(
1359
1935
  `[INSPECTOR] UI available at http://${this.serverHost}:${this.serverPort}/inspector`
1360
1936
  );
1361
- }).catch(() => {
1362
- });
1937
+ } catch {
1938
+ }
1363
1939
  }
1364
1940
  /**
1365
1941
  * Setup default widget serving routes
1366
1942
  *
1367
- * Configures Express routes to serve MCP UI widgets and their static assets.
1943
+ * Configures Hono routes to serve MCP UI widgets and their static assets.
1368
1944
  * Widgets are served from the dist/resources/widgets directory and can
1369
1945
  * be accessed via HTTP endpoints for embedding in web applications.
1370
1946
  *
@@ -1383,11 +1959,11 @@ if (container && Component) {
1383
1959
  * - http://localhost:3001/mcp-use/widgets/assets/script.js (auto-discovered)
1384
1960
  */
1385
1961
  setupWidgetRoutes() {
1386
- this.app.get("/mcp-use/widgets/:widget/assets/*", (req, res, next) => {
1387
- const widget = req.params.widget;
1388
- const assetFile = req.params[0];
1389
- const assetPath = (0, import_node_path.join)(
1390
- process.cwd(),
1962
+ this.app.get("/mcp-use/widgets/:widget/assets/*", async (c) => {
1963
+ const widget = c.req.param("widget");
1964
+ const assetFile = c.req.path.split("/assets/")[1];
1965
+ const assetPath = pathHelpers.join(
1966
+ getCwd(),
1391
1967
  "dist",
1392
1968
  "resources",
1393
1969
  "widgets",
@@ -1395,48 +1971,82 @@ if (container && Component) {
1395
1971
  "assets",
1396
1972
  assetFile
1397
1973
  );
1398
- res.sendFile(assetPath, (err) => err ? next() : void 0);
1974
+ try {
1975
+ if (await fsHelpers.existsSync(assetPath)) {
1976
+ const content = await fsHelpers.readFile(assetPath);
1977
+ const ext = assetFile.split(".").pop()?.toLowerCase();
1978
+ const contentType = ext === "js" ? "application/javascript" : ext === "css" ? "text/css" : ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : "application/octet-stream";
1979
+ return new Response(content, {
1980
+ status: 200,
1981
+ headers: { "Content-Type": contentType }
1982
+ });
1983
+ }
1984
+ return c.notFound();
1985
+ } catch {
1986
+ return c.notFound();
1987
+ }
1399
1988
  });
1400
- this.app.get("/mcp-use/widgets/assets/*", (req, res, next) => {
1401
- const assetFile = req.params[0];
1402
- const widgetsDir = (0, import_node_path.join)(process.cwd(), "dist", "resources", "widgets");
1989
+ this.app.get("/mcp-use/widgets/assets/*", async (c) => {
1990
+ const assetFile = c.req.path.split("/assets/")[1];
1991
+ const widgetsDir = pathHelpers.join(
1992
+ getCwd(),
1993
+ "dist",
1994
+ "resources",
1995
+ "widgets"
1996
+ );
1403
1997
  try {
1404
- const widgets = (0, import_node_fs.readdirSync)(widgetsDir);
1998
+ const widgets = await fsHelpers.readdirSync(widgetsDir);
1405
1999
  for (const widget of widgets) {
1406
- const assetPath = (0, import_node_path.join)(widgetsDir, widget, "assets", assetFile);
1407
- if ((0, import_node_fs.existsSync)(assetPath)) {
1408
- return res.sendFile(assetPath);
2000
+ const assetPath = pathHelpers.join(
2001
+ widgetsDir,
2002
+ widget,
2003
+ "assets",
2004
+ assetFile
2005
+ );
2006
+ if (await fsHelpers.existsSync(assetPath)) {
2007
+ const content = await fsHelpers.readFile(assetPath);
2008
+ const ext = assetFile.split(".").pop()?.toLowerCase();
2009
+ const contentType = ext === "js" ? "application/javascript" : ext === "css" ? "text/css" : ext === "png" ? "image/png" : ext === "jpg" || ext === "jpeg" ? "image/jpeg" : ext === "svg" ? "image/svg+xml" : "application/octet-stream";
2010
+ return new Response(content, {
2011
+ status: 200,
2012
+ headers: { "Content-Type": contentType }
2013
+ });
1409
2014
  }
1410
2015
  }
1411
- next();
2016
+ return c.notFound();
1412
2017
  } catch {
1413
- next();
2018
+ return c.notFound();
1414
2019
  }
1415
2020
  });
1416
- this.app.get("/mcp-use/widgets/:widget", (req, res, next) => {
1417
- const filePath = (0, import_node_path.join)(
1418
- process.cwd(),
2021
+ this.app.get("/mcp-use/widgets/:widget", async (c) => {
2022
+ const widget = c.req.param("widget");
2023
+ const filePath = pathHelpers.join(
2024
+ getCwd(),
1419
2025
  "dist",
1420
2026
  "resources",
1421
2027
  "widgets",
1422
- req.params.widget,
2028
+ widget,
1423
2029
  "index.html"
1424
2030
  );
1425
- let html = (0, import_node_fs2.readFileSync)(filePath, "utf8");
1426
- html = html.replace(
1427
- /src="\/mcp-use\/widgets\/([^"]+)"/g,
1428
- `src="${this.serverBaseUrl}/mcp-use/widgets/$1"`
1429
- );
1430
- html = html.replace(
1431
- /href="\/mcp-use\/widgets\/([^"]+)"/g,
1432
- `href="${this.serverBaseUrl}/mcp-use/widgets/$1"`
1433
- );
1434
- html = html.replace(
1435
- /<head[^>]*>/i,
1436
- `<head>
1437
- <script>window.__getFile = (filename) => { return "${this.serverBaseUrl}/mcp-use/widgets/${req.params.widget}/"+filename }</script>`
1438
- );
1439
- res.send(html);
2031
+ try {
2032
+ let html = await fsHelpers.readFileSync(filePath, "utf8");
2033
+ html = html.replace(
2034
+ /src="\/mcp-use\/widgets\/([^"]+)"/g,
2035
+ `src="${this.serverBaseUrl}/mcp-use/widgets/$1"`
2036
+ );
2037
+ html = html.replace(
2038
+ /href="\/mcp-use\/widgets\/([^"]+)"/g,
2039
+ `href="${this.serverBaseUrl}/mcp-use/widgets/$1"`
2040
+ );
2041
+ html = html.replace(
2042
+ /<head[^>]*>/i,
2043
+ `<head>
2044
+ <script>window.__getFile = (filename) => { return "${this.serverBaseUrl}/mcp-use/widgets/${widget}/"+filename }</script>`
2045
+ );
2046
+ return c.html(html);
2047
+ } catch {
2048
+ return c.notFound();
2049
+ }
1440
2050
  });
1441
2051
  }
1442
2052
  /**
@@ -1629,12 +2239,3 @@ function createMCPServer(name, config = {}) {
1629
2239
  return instance;
1630
2240
  }
1631
2241
  __name(createMCPServer, "createMCPServer");
1632
- // Annotate the CommonJS export names for ESM import in node:
1633
- 0 && (module.exports = {
1634
- buildWidgetUrl,
1635
- createExternalUrlResource,
1636
- createMCPServer,
1637
- createRawHtmlResource,
1638
- createRemoteDomResource,
1639
- createUIResourceFromDefinition
1640
- });