mcp-use 1.2.5-dev.4 → 1.2.5-dev.5
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/.tsbuildinfo +1 -1
- package/dist/src/server/connect-adapter.d.ts +31 -0
- package/dist/src/server/connect-adapter.d.ts.map +1 -0
- package/dist/src/server/index.cjs +303 -113
- package/dist/src/server/index.d.ts +2 -1
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +303 -113
- package/dist/src/server/logging.d.ts.map +1 -1
- package/dist/src/server/mcp-server.d.ts +2 -2
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from "hono";
|
|
2
|
+
/**
|
|
3
|
+
* Detects if a middleware is Express/Connect style or Hono style
|
|
4
|
+
*
|
|
5
|
+
* Express/Connect middleware: (req, res, next) => void or (err, req, res, next) => void
|
|
6
|
+
* Hono middleware: (c, next) => Promise<Response | void> or (c, next) => Response | void
|
|
7
|
+
*
|
|
8
|
+
* @param middleware - The middleware function to check
|
|
9
|
+
* @returns true if it's Express/Connect middleware, false if it's Hono middleware
|
|
10
|
+
*/
|
|
11
|
+
export declare function isExpressMiddleware(middleware: any): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Automatically adapts middleware to work with Hono
|
|
14
|
+
* Detects if the middleware is Express/Connect style and adapts it accordingly
|
|
15
|
+
* If it's already Hono-compatible middleware, returns it as-is
|
|
16
|
+
*
|
|
17
|
+
* @param middleware - The middleware function (Express/Connect or Hono)
|
|
18
|
+
* @param middlewarePath - The path pattern the middleware is mounted at (optional, only used for Express/Connect middleware)
|
|
19
|
+
* @returns A Hono middleware function
|
|
20
|
+
*/
|
|
21
|
+
export declare function adaptMiddleware(middleware: any, middlewarePath?: string): Promise<MiddlewareHandler>;
|
|
22
|
+
/**
|
|
23
|
+
* Adapts Connect/Express middleware to work with Hono
|
|
24
|
+
* Based on @hono/connect approach using node-mocks-http
|
|
25
|
+
*
|
|
26
|
+
* @param connectMiddleware - The Connect middleware handler
|
|
27
|
+
* @param middlewarePath - The path pattern the middleware is mounted at (e.g., "/mcp-use/widgets/*")
|
|
28
|
+
* @returns A Hono middleware function
|
|
29
|
+
*/
|
|
30
|
+
export declare function adaptConnectMiddleware(connectMiddleware: any, middlewarePath: string): Promise<MiddlewareHandler>;
|
|
31
|
+
//# sourceMappingURL=connect-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-adapter.d.ts","sourceRoot":"","sources":["../../../src/server/connect-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,iBAAiB,EAAQ,MAAM,MAAM,CAAC;AAE7D;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,GAAG,GAAG,OAAO,CA0C5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,GAAG,EACf,cAAc,GAAE,MAAY,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAQ5B;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,iBAAiB,EAAE,GAAG,EACtB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,iBAAiB,CAAC,CAqJ5B"}
|
|
@@ -31,12 +31,15 @@ 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
|
|
|
@@ -153,6 +156,149 @@ function createUIResourceFromDefinition(definition, params, config) {
|
|
|
153
156
|
}
|
|
154
157
|
__name(createUIResourceFromDefinition, "createUIResourceFromDefinition");
|
|
155
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
|
+
|
|
156
302
|
// src/server/logging.ts
|
|
157
303
|
async function requestLogger(c, next) {
|
|
158
304
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
|
|
@@ -161,7 +307,8 @@ async function requestLogger(c, next) {
|
|
|
161
307
|
let body = null;
|
|
162
308
|
if (method === "POST" && url.includes("/mcp")) {
|
|
163
309
|
try {
|
|
164
|
-
|
|
310
|
+
const clonedRequest = c.req.raw.clone();
|
|
311
|
+
body = await clonedRequest.json().catch(() => null);
|
|
165
312
|
} catch {
|
|
166
313
|
}
|
|
167
314
|
}
|
|
@@ -219,7 +366,10 @@ var fsHelpers = {
|
|
|
219
366
|
}
|
|
220
367
|
const { readFileSync } = await import("fs");
|
|
221
368
|
const buffer = readFileSync(path);
|
|
222
|
-
return buffer.buffer.slice(
|
|
369
|
+
return buffer.buffer.slice(
|
|
370
|
+
buffer.byteOffset,
|
|
371
|
+
buffer.byteOffset + buffer.byteLength
|
|
372
|
+
);
|
|
223
373
|
},
|
|
224
374
|
async existsSync(path) {
|
|
225
375
|
if (isDeno) {
|
|
@@ -314,6 +464,52 @@ var McpServer = class {
|
|
|
314
464
|
this.app.use("*", requestLogger);
|
|
315
465
|
return new Proxy(this, {
|
|
316
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
|
+
}
|
|
317
513
|
if (prop in target) {
|
|
318
514
|
return target[prop];
|
|
319
515
|
}
|
|
@@ -880,13 +1076,11 @@ var McpServer = class {
|
|
|
880
1076
|
* @returns Promise that resolves when all widgets are mounted
|
|
881
1077
|
*/
|
|
882
1078
|
async mountWidgets(options) {
|
|
883
|
-
if (this.isProductionMode()) {
|
|
1079
|
+
if (this.isProductionMode() || isDeno) {
|
|
1080
|
+
console.log("[WIDGETS] Mounting widgets in production mode");
|
|
884
1081
|
await this.mountWidgetsProduction(options);
|
|
885
1082
|
} else {
|
|
886
|
-
|
|
887
|
-
console.log("[WIDGETS] Skipping dev mode widget mounting in Deno runtime (use production build)");
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
1083
|
+
console.log("[WIDGETS] Mounting widgets in development mode");
|
|
890
1084
|
await this.mountWidgetsDev(options);
|
|
891
1085
|
}
|
|
892
1086
|
}
|
|
@@ -937,13 +1131,21 @@ var McpServer = class {
|
|
|
937
1131
|
try {
|
|
938
1132
|
const viteModule = await new Function('return import("vite")')();
|
|
939
1133
|
createServer = viteModule.createServer;
|
|
940
|
-
const reactModule = await new Function(
|
|
1134
|
+
const reactModule = await new Function(
|
|
1135
|
+
'return import("@vitejs/plugin-react")'
|
|
1136
|
+
)();
|
|
941
1137
|
react = reactModule.default;
|
|
942
|
-
const tailwindModule = await new Function(
|
|
1138
|
+
const tailwindModule = await new Function(
|
|
1139
|
+
'return import("@tailwindcss/vite")'
|
|
1140
|
+
)();
|
|
943
1141
|
tailwindcss = tailwindModule.default;
|
|
944
1142
|
} catch (error) {
|
|
945
|
-
console.error(
|
|
946
|
-
|
|
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
|
+
);
|
|
947
1149
|
return;
|
|
948
1150
|
}
|
|
949
1151
|
const widgets = entries.map((entry) => {
|
|
@@ -959,16 +1161,17 @@ var McpServer = class {
|
|
|
959
1161
|
const widgetTempDir = pathHelpers.join(tempDir, widget.name);
|
|
960
1162
|
await fs.mkdir(widgetTempDir, { recursive: true });
|
|
961
1163
|
const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
|
|
962
|
-
const relativeResourcesPath = pathHelpers.relative(
|
|
963
|
-
widgetTempDir,
|
|
964
|
-
resourcesPath
|
|
965
|
-
).replace(/\\/g, "/");
|
|
1164
|
+
const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
|
|
966
1165
|
const cssContent = `@import "tailwindcss";
|
|
967
1166
|
|
|
968
1167
|
/* Configure Tailwind to scan the resources directory */
|
|
969
1168
|
@source "${relativeResourcesPath}";
|
|
970
1169
|
`;
|
|
971
|
-
await fs.writeFile(
|
|
1170
|
+
await fs.writeFile(
|
|
1171
|
+
pathHelpers.join(widgetTempDir, "styles.css"),
|
|
1172
|
+
cssContent,
|
|
1173
|
+
"utf8"
|
|
1174
|
+
);
|
|
972
1175
|
const entryContent = `import React from 'react'
|
|
973
1176
|
import { createRoot } from 'react-dom/client'
|
|
974
1177
|
import './styles.css'
|
|
@@ -1021,67 +1224,6 @@ if (container && Component) {
|
|
|
1021
1224
|
origin: serverOrigin
|
|
1022
1225
|
}
|
|
1023
1226
|
});
|
|
1024
|
-
const adaptExpressMiddleware = /* @__PURE__ */ __name((middleware) => {
|
|
1025
|
-
return async (c, next) => {
|
|
1026
|
-
const req = c.req.raw;
|
|
1027
|
-
let handled = false;
|
|
1028
|
-
const responseBody = [];
|
|
1029
|
-
let statusCode = 200;
|
|
1030
|
-
const headers = {};
|
|
1031
|
-
const res = {
|
|
1032
|
-
statusCode: 200,
|
|
1033
|
-
status: /* @__PURE__ */ __name((code) => {
|
|
1034
|
-
statusCode = code;
|
|
1035
|
-
res.statusCode = code;
|
|
1036
|
-
return res;
|
|
1037
|
-
}, "status"),
|
|
1038
|
-
setHeader: /* @__PURE__ */ __name((name, value) => {
|
|
1039
|
-
headers[name] = value;
|
|
1040
|
-
}, "setHeader"),
|
|
1041
|
-
getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
|
|
1042
|
-
write: /* @__PURE__ */ __name((chunk) => {
|
|
1043
|
-
responseBody.push(typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk);
|
|
1044
|
-
}, "write"),
|
|
1045
|
-
end: /* @__PURE__ */ __name((chunk) => {
|
|
1046
|
-
if (chunk) {
|
|
1047
|
-
responseBody.push(typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk);
|
|
1048
|
-
}
|
|
1049
|
-
handled = true;
|
|
1050
|
-
}, "end"),
|
|
1051
|
-
on: /* @__PURE__ */ __name(() => {
|
|
1052
|
-
}, "on"),
|
|
1053
|
-
once: /* @__PURE__ */ __name(() => {
|
|
1054
|
-
}, "once"),
|
|
1055
|
-
removeListener: /* @__PURE__ */ __name(() => {
|
|
1056
|
-
}, "removeListener")
|
|
1057
|
-
};
|
|
1058
|
-
const expressReq = {
|
|
1059
|
-
...req,
|
|
1060
|
-
url: new URL(req.url).pathname + new URL(req.url).search,
|
|
1061
|
-
originalUrl: req.url,
|
|
1062
|
-
baseUrl: "",
|
|
1063
|
-
path: new URL(req.url).pathname,
|
|
1064
|
-
query: Object.fromEntries(new URL(req.url).searchParams),
|
|
1065
|
-
params: {},
|
|
1066
|
-
body: {},
|
|
1067
|
-
headers: Object.fromEntries(req.headers.entries())
|
|
1068
|
-
};
|
|
1069
|
-
await new Promise((resolve, reject) => {
|
|
1070
|
-
middleware(expressReq, res, (err) => {
|
|
1071
|
-
if (err) reject(err);
|
|
1072
|
-
else resolve();
|
|
1073
|
-
});
|
|
1074
|
-
});
|
|
1075
|
-
if (handled) {
|
|
1076
|
-
const body = Buffer.concat(responseBody);
|
|
1077
|
-
return new Response(body, {
|
|
1078
|
-
status: statusCode,
|
|
1079
|
-
headers
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
|
-
return next();
|
|
1083
|
-
};
|
|
1084
|
-
}, "adaptExpressMiddleware");
|
|
1085
1227
|
this.app.use(`${baseRoute}/*`, async (c, next) => {
|
|
1086
1228
|
const url = new URL(c.req.url);
|
|
1087
1229
|
const pathname = url.pathname;
|
|
@@ -1109,7 +1251,11 @@ if (container && Component) {
|
|
|
1109
1251
|
}
|
|
1110
1252
|
await next();
|
|
1111
1253
|
});
|
|
1112
|
-
|
|
1254
|
+
const viteMiddleware = await adaptConnectMiddleware(
|
|
1255
|
+
viteServer.middlewares,
|
|
1256
|
+
`${baseRoute}/*`
|
|
1257
|
+
);
|
|
1258
|
+
this.app.use(`${baseRoute}/*`, viteMiddleware);
|
|
1113
1259
|
widgets.forEach((widget) => {
|
|
1114
1260
|
console.log(
|
|
1115
1261
|
`[WIDGET] ${widget.name} mounted at ${baseRoute}/${widget.name}`
|
|
@@ -1249,26 +1395,46 @@ if (container && Component) {
|
|
|
1249
1395
|
*/
|
|
1250
1396
|
async mountWidgetsProduction(options) {
|
|
1251
1397
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
1252
|
-
const widgetsDir = pathHelpers.join(
|
|
1253
|
-
|
|
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 = pathHelpers.join(getCwd(), "dist", ".mcp-use-manifest.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) {
|
|
1254
1418
|
console.log(
|
|
1255
|
-
"[WIDGETS]
|
|
1419
|
+
"[WIDGETS] Could not read manifest file, falling back to directory listing:",
|
|
1420
|
+
error
|
|
1256
1421
|
);
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
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);
|
|
1267
1433
|
}
|
|
1268
1434
|
}
|
|
1269
1435
|
if (widgets.length === 0) {
|
|
1270
1436
|
console.log(
|
|
1271
|
-
"[WIDGETS] No built widgets found
|
|
1437
|
+
"[WIDGETS] No built widgets found"
|
|
1272
1438
|
);
|
|
1273
1439
|
return;
|
|
1274
1440
|
}
|
|
@@ -1329,7 +1495,10 @@ if (container && Component) {
|
|
|
1329
1495
|
let props = {};
|
|
1330
1496
|
let description = `Widget: ${widgetName}`;
|
|
1331
1497
|
try {
|
|
1332
|
-
const metadataContent = await fsHelpers.readFileSync(
|
|
1498
|
+
const metadataContent = await fsHelpers.readFileSync(
|
|
1499
|
+
metadataPath,
|
|
1500
|
+
"utf8"
|
|
1501
|
+
);
|
|
1333
1502
|
metadata = JSON.parse(metadataContent);
|
|
1334
1503
|
if (metadata.description) {
|
|
1335
1504
|
description = metadata.description;
|
|
@@ -1497,23 +1666,27 @@ if (container && Component) {
|
|
|
1497
1666
|
}
|
|
1498
1667
|
}, "send")
|
|
1499
1668
|
};
|
|
1500
|
-
return {
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
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
|
+
}
|
|
1513
1686
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
}
|
|
1687
|
+
return null;
|
|
1688
|
+
}, "getResponse")
|
|
1689
|
+
};
|
|
1517
1690
|
}, "createExpressLikeObjects");
|
|
1518
1691
|
this.app.post(endpoint, async (c) => {
|
|
1519
1692
|
const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
|
|
@@ -1677,19 +1850,26 @@ if (container && Component) {
|
|
|
1677
1850
|
* ```
|
|
1678
1851
|
*/
|
|
1679
1852
|
async getHandler(options) {
|
|
1853
|
+
console.log("[MCP] Mounting widgets");
|
|
1680
1854
|
await this.mountWidgets({
|
|
1681
1855
|
baseRoute: "/mcp-use/widgets",
|
|
1682
1856
|
resourcesDir: "resources"
|
|
1683
1857
|
});
|
|
1858
|
+
console.log("[MCP] Mounted widgets");
|
|
1684
1859
|
await this.mountMcp();
|
|
1860
|
+
console.log("[MCP] Mounted MCP");
|
|
1861
|
+
console.log("[MCP] Mounting inspector");
|
|
1685
1862
|
await this.mountInspector();
|
|
1863
|
+
console.log("[MCP] Mounted inspector");
|
|
1686
1864
|
const fetchHandler = this.app.fetch.bind(this.app);
|
|
1687
1865
|
if (options?.provider === "supabase") {
|
|
1688
1866
|
return async (req) => {
|
|
1689
1867
|
const url = new URL(req.url);
|
|
1690
1868
|
const pathname = url.pathname;
|
|
1691
1869
|
let newPathname = pathname;
|
|
1692
|
-
const functionsMatch = pathname.match(
|
|
1870
|
+
const functionsMatch = pathname.match(
|
|
1871
|
+
/^\/functions\/v1\/[^/]+(\/.*)?$/
|
|
1872
|
+
);
|
|
1693
1873
|
if (functionsMatch) {
|
|
1694
1874
|
newPathname = functionsMatch[1] || "/";
|
|
1695
1875
|
} else {
|
|
@@ -1808,11 +1988,21 @@ if (container && Component) {
|
|
|
1808
1988
|
});
|
|
1809
1989
|
this.app.get("/mcp-use/widgets/assets/*", async (c) => {
|
|
1810
1990
|
const assetFile = c.req.path.split("/assets/")[1];
|
|
1811
|
-
const widgetsDir = pathHelpers.join(
|
|
1991
|
+
const widgetsDir = pathHelpers.join(
|
|
1992
|
+
getCwd(),
|
|
1993
|
+
"dist",
|
|
1994
|
+
"resources",
|
|
1995
|
+
"widgets"
|
|
1996
|
+
);
|
|
1812
1997
|
try {
|
|
1813
1998
|
const widgets = await fsHelpers.readdirSync(widgetsDir);
|
|
1814
1999
|
for (const widget of widgets) {
|
|
1815
|
-
const assetPath = pathHelpers.join(
|
|
2000
|
+
const assetPath = pathHelpers.join(
|
|
2001
|
+
widgetsDir,
|
|
2002
|
+
widget,
|
|
2003
|
+
"assets",
|
|
2004
|
+
assetFile
|
|
2005
|
+
);
|
|
1816
2006
|
if (await fsHelpers.existsSync(assetPath)) {
|
|
1817
2007
|
const content = await fsHelpers.readFile(assetPath);
|
|
1818
2008
|
const ext = assetFile.split(".").pop()?.toLowerCase();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { createMCPServer, type McpServerInstance } from "./mcp-server.js";
|
|
2
2
|
export * from "./types/index.js";
|
|
3
3
|
export { buildWidgetUrl, createExternalUrlResource, createRawHtmlResource, createRemoteDomResource, createUIResourceFromDefinition, type UrlConfig, } from "./adapters/mcp-ui-adapter.js";
|
|
4
|
-
export
|
|
4
|
+
export { adaptConnectMiddleware, adaptMiddleware, isExpressMiddleware, } from "./connect-adapter.js";
|
|
5
|
+
export type { DiscoverWidgetsOptions, ExternalUrlUIResource, InputDefinition, PromptCallback, PromptDefinition, RawHtmlUIResource, ReadResourceCallback, ReadResourceTemplateCallback, RemoteDomUIResource, ResourceDefinition, ServerConfig, ToolCallback, ToolDefinition, UIResourceDefinition, WidgetConfig, WidgetManifest, WidgetProps, } from "./types/index.js";
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,SAAS,GACf,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,SAAS,GACf,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EAEd,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
|