mcp-use 1.2.5-dev.4 → 1.3.0-canary.0
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/{chunk-37MPZ3D6.js → chunk-TIUSJAAE.js} +12 -0
- package/dist/{chunk-X2HJQBDI.js → chunk-VNEGDXZO.js} +26 -1
- package/dist/index.cjs +37 -0
- package/dist/index.js +2 -2
- package/dist/src/browser.cjs +12 -0
- package/dist/src/browser.js +1 -1
- package/dist/src/connectors/base.d.ts +11 -0
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/react/index.cjs +37 -0
- package/dist/src/react/index.js +2 -2
- package/dist/src/react/types.d.ts +7 -0
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +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 +358 -139
- 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 +358 -139
- 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 +44 -45
|
@@ -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,47 @@ 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 async (...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
|
+
await 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
|
+
);
|
|
503
|
+
return target;
|
|
504
|
+
}
|
|
505
|
+
return target.app.use(...args);
|
|
506
|
+
};
|
|
507
|
+
}
|
|
317
508
|
if (prop in target) {
|
|
318
509
|
return target[prop];
|
|
319
510
|
}
|
|
@@ -858,9 +1049,9 @@ var McpServer = class {
|
|
|
858
1049
|
async readBuildManifest() {
|
|
859
1050
|
try {
|
|
860
1051
|
const manifestPath = pathHelpers.join(
|
|
861
|
-
getCwd(),
|
|
1052
|
+
isDeno ? "." : getCwd(),
|
|
862
1053
|
"dist",
|
|
863
|
-
"
|
|
1054
|
+
"mcp-use.json"
|
|
864
1055
|
);
|
|
865
1056
|
const content = await fsHelpers.readFileSync(manifestPath, "utf8");
|
|
866
1057
|
return JSON.parse(content);
|
|
@@ -880,13 +1071,11 @@ var McpServer = class {
|
|
|
880
1071
|
* @returns Promise that resolves when all widgets are mounted
|
|
881
1072
|
*/
|
|
882
1073
|
async mountWidgets(options) {
|
|
883
|
-
if (this.isProductionMode()) {
|
|
1074
|
+
if (this.isProductionMode() || isDeno) {
|
|
1075
|
+
console.log("[WIDGETS] Mounting widgets in production mode");
|
|
884
1076
|
await this.mountWidgetsProduction(options);
|
|
885
1077
|
} else {
|
|
886
|
-
|
|
887
|
-
console.log("[WIDGETS] Skipping dev mode widget mounting in Deno runtime (use production build)");
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
1078
|
+
console.log("[WIDGETS] Mounting widgets in development mode");
|
|
890
1079
|
await this.mountWidgetsDev(options);
|
|
891
1080
|
}
|
|
892
1081
|
}
|
|
@@ -937,13 +1126,21 @@ var McpServer = class {
|
|
|
937
1126
|
try {
|
|
938
1127
|
const viteModule = await new Function('return import("vite")')();
|
|
939
1128
|
createServer = viteModule.createServer;
|
|
940
|
-
const reactModule = await new Function(
|
|
1129
|
+
const reactModule = await new Function(
|
|
1130
|
+
'return import("@vitejs/plugin-react")'
|
|
1131
|
+
)();
|
|
941
1132
|
react = reactModule.default;
|
|
942
|
-
const tailwindModule = await new Function(
|
|
1133
|
+
const tailwindModule = await new Function(
|
|
1134
|
+
'return import("@tailwindcss/vite")'
|
|
1135
|
+
)();
|
|
943
1136
|
tailwindcss = tailwindModule.default;
|
|
944
1137
|
} catch (error) {
|
|
945
|
-
console.error(
|
|
946
|
-
|
|
1138
|
+
console.error(
|
|
1139
|
+
"[WIDGETS] Dev dependencies not available. Install vite, @vitejs/plugin-react, and @tailwindcss/vite for widget development."
|
|
1140
|
+
);
|
|
1141
|
+
console.error(
|
|
1142
|
+
"[WIDGETS] For production, use 'mcp-use build' to pre-build widgets."
|
|
1143
|
+
);
|
|
947
1144
|
return;
|
|
948
1145
|
}
|
|
949
1146
|
const widgets = entries.map((entry) => {
|
|
@@ -959,16 +1156,17 @@ var McpServer = class {
|
|
|
959
1156
|
const widgetTempDir = pathHelpers.join(tempDir, widget.name);
|
|
960
1157
|
await fs.mkdir(widgetTempDir, { recursive: true });
|
|
961
1158
|
const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
|
|
962
|
-
const relativeResourcesPath = pathHelpers.relative(
|
|
963
|
-
widgetTempDir,
|
|
964
|
-
resourcesPath
|
|
965
|
-
).replace(/\\/g, "/");
|
|
1159
|
+
const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
|
|
966
1160
|
const cssContent = `@import "tailwindcss";
|
|
967
1161
|
|
|
968
1162
|
/* Configure Tailwind to scan the resources directory */
|
|
969
1163
|
@source "${relativeResourcesPath}";
|
|
970
1164
|
`;
|
|
971
|
-
await fs.writeFile(
|
|
1165
|
+
await fs.writeFile(
|
|
1166
|
+
pathHelpers.join(widgetTempDir, "styles.css"),
|
|
1167
|
+
cssContent,
|
|
1168
|
+
"utf8"
|
|
1169
|
+
);
|
|
972
1170
|
const entryContent = `import React from 'react'
|
|
973
1171
|
import { createRoot } from 'react-dom/client'
|
|
974
1172
|
import './styles.css'
|
|
@@ -1021,67 +1219,6 @@ if (container && Component) {
|
|
|
1021
1219
|
origin: serverOrigin
|
|
1022
1220
|
}
|
|
1023
1221
|
});
|
|
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
1222
|
this.app.use(`${baseRoute}/*`, async (c, next) => {
|
|
1086
1223
|
const url = new URL(c.req.url);
|
|
1087
1224
|
const pathname = url.pathname;
|
|
@@ -1109,7 +1246,11 @@ if (container && Component) {
|
|
|
1109
1246
|
}
|
|
1110
1247
|
await next();
|
|
1111
1248
|
});
|
|
1112
|
-
|
|
1249
|
+
const viteMiddleware = await adaptConnectMiddleware(
|
|
1250
|
+
viteServer.middlewares,
|
|
1251
|
+
`${baseRoute}/*`
|
|
1252
|
+
);
|
|
1253
|
+
this.app.use(`${baseRoute}/*`, viteMiddleware);
|
|
1113
1254
|
widgets.forEach((widget) => {
|
|
1114
1255
|
console.log(
|
|
1115
1256
|
`[WIDGET] ${widget.name} mounted at ${baseRoute}/${widget.name}`
|
|
@@ -1142,7 +1283,6 @@ if (container && Component) {
|
|
|
1142
1283
|
error
|
|
1143
1284
|
);
|
|
1144
1285
|
}
|
|
1145
|
-
console.log("[WIDGET dev] Metadata:", metadata);
|
|
1146
1286
|
let html = "";
|
|
1147
1287
|
try {
|
|
1148
1288
|
html = await fsHelpers.readFileSync(
|
|
@@ -1249,27 +1389,57 @@ if (container && Component) {
|
|
|
1249
1389
|
*/
|
|
1250
1390
|
async mountWidgetsProduction(options) {
|
|
1251
1391
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
1252
|
-
const widgetsDir = pathHelpers.join(
|
|
1253
|
-
|
|
1392
|
+
const widgetsDir = pathHelpers.join(
|
|
1393
|
+
isDeno ? "." : getCwd(),
|
|
1394
|
+
"dist",
|
|
1395
|
+
"resources",
|
|
1396
|
+
"widgets"
|
|
1397
|
+
);
|
|
1398
|
+
console.log("widgetsDir", widgetsDir);
|
|
1399
|
+
this.setupWidgetRoutes();
|
|
1400
|
+
const manifestPath = "./dist/mcp-use.json";
|
|
1401
|
+
let widgets = [];
|
|
1402
|
+
let widgetsMetadata = {};
|
|
1403
|
+
try {
|
|
1404
|
+
const manifestContent = await fsHelpers.readFileSync(
|
|
1405
|
+
manifestPath,
|
|
1406
|
+
"utf8"
|
|
1407
|
+
);
|
|
1408
|
+
const manifest = JSON.parse(manifestContent);
|
|
1409
|
+
if (manifest.widgets && typeof manifest.widgets === "object" && !Array.isArray(manifest.widgets)) {
|
|
1410
|
+
widgets = Object.keys(manifest.widgets);
|
|
1411
|
+
widgetsMetadata = manifest.widgets;
|
|
1412
|
+
console.log(
|
|
1413
|
+
`[WIDGETS] Loaded ${widgets.length} widget(s) from manifest`
|
|
1414
|
+
);
|
|
1415
|
+
} else if (manifest.widgets && Array.isArray(manifest.widgets)) {
|
|
1416
|
+
widgets = manifest.widgets;
|
|
1417
|
+
console.log(
|
|
1418
|
+
`[WIDGETS] Loaded ${widgets.length} widget(s) from manifest (legacy format)`
|
|
1419
|
+
);
|
|
1420
|
+
} else {
|
|
1421
|
+
console.log("[WIDGETS] No widgets found in manifest");
|
|
1422
|
+
}
|
|
1423
|
+
} catch (error) {
|
|
1254
1424
|
console.log(
|
|
1255
|
-
"[WIDGETS]
|
|
1425
|
+
"[WIDGETS] Could not read manifest file, falling back to directory listing:",
|
|
1426
|
+
error
|
|
1256
1427
|
);
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1428
|
+
try {
|
|
1429
|
+
const allEntries = await fsHelpers.readdirSync(widgetsDir);
|
|
1430
|
+
for (const name of allEntries) {
|
|
1431
|
+
const widgetPath = pathHelpers.join(widgetsDir, name);
|
|
1432
|
+
const indexPath = pathHelpers.join(widgetPath, "index.html");
|
|
1433
|
+
if (await fsHelpers.existsSync(indexPath)) {
|
|
1434
|
+
widgets.push(name);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
} catch (dirError) {
|
|
1438
|
+
console.log("[WIDGETS] Directory listing also failed:", dirError);
|
|
1267
1439
|
}
|
|
1268
1440
|
}
|
|
1269
1441
|
if (widgets.length === 0) {
|
|
1270
|
-
console.log(
|
|
1271
|
-
"[WIDGETS] No built widgets found in dist/resources/widgets/"
|
|
1272
|
-
);
|
|
1442
|
+
console.log("[WIDGETS] No built widgets found");
|
|
1273
1443
|
return;
|
|
1274
1444
|
}
|
|
1275
1445
|
console.log(
|
|
@@ -1278,7 +1448,6 @@ if (container && Component) {
|
|
|
1278
1448
|
for (const widgetName of widgets) {
|
|
1279
1449
|
const widgetPath = pathHelpers.join(widgetsDir, widgetName);
|
|
1280
1450
|
const indexPath = pathHelpers.join(widgetPath, "index.html");
|
|
1281
|
-
const metadataPath = pathHelpers.join(widgetPath, "metadata.json");
|
|
1282
1451
|
let html = "";
|
|
1283
1452
|
try {
|
|
1284
1453
|
html = await fsHelpers.readFileSync(indexPath, "utf8");
|
|
@@ -1325,22 +1494,14 @@ if (container && Component) {
|
|
|
1325
1494
|
);
|
|
1326
1495
|
continue;
|
|
1327
1496
|
}
|
|
1328
|
-
|
|
1497
|
+
const metadata = widgetsMetadata[widgetName] || {};
|
|
1329
1498
|
let props = {};
|
|
1330
1499
|
let description = `Widget: ${widgetName}`;
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
}
|
|
1337
|
-
if (metadata.inputs) {
|
|
1338
|
-
props = metadata.inputs;
|
|
1339
|
-
}
|
|
1340
|
-
} catch (error) {
|
|
1341
|
-
console.log(
|
|
1342
|
-
`[WIDGET] No metadata found for ${widgetName}, using defaults`
|
|
1343
|
-
);
|
|
1500
|
+
if (metadata.description) {
|
|
1501
|
+
description = metadata.description;
|
|
1502
|
+
}
|
|
1503
|
+
if (metadata.inputs) {
|
|
1504
|
+
props = metadata.inputs;
|
|
1344
1505
|
}
|
|
1345
1506
|
this.uiResource({
|
|
1346
1507
|
name: widgetName,
|
|
@@ -1497,23 +1658,27 @@ if (container && Component) {
|
|
|
1497
1658
|
}
|
|
1498
1659
|
}, "send")
|
|
1499
1660
|
};
|
|
1500
|
-
return {
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1661
|
+
return {
|
|
1662
|
+
expressReq,
|
|
1663
|
+
expressRes,
|
|
1664
|
+
getResponse: /* @__PURE__ */ __name(() => {
|
|
1665
|
+
if (ended) {
|
|
1666
|
+
if (responseBody.length > 0) {
|
|
1667
|
+
const body = isDeno ? Buffer.concat(responseBody) : Buffer.concat(responseBody);
|
|
1668
|
+
return new Response(body, {
|
|
1669
|
+
status: statusCode,
|
|
1670
|
+
headers
|
|
1671
|
+
});
|
|
1672
|
+
} else {
|
|
1673
|
+
return new Response(null, {
|
|
1674
|
+
status: statusCode,
|
|
1675
|
+
headers
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1513
1678
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
}
|
|
1679
|
+
return null;
|
|
1680
|
+
}, "getResponse")
|
|
1681
|
+
};
|
|
1517
1682
|
}, "createExpressLikeObjects");
|
|
1518
1683
|
this.app.post(endpoint, async (c) => {
|
|
1519
1684
|
const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
|
|
@@ -1614,16 +1779,53 @@ if (container && Component) {
|
|
|
1614
1779
|
await this.mountMcp();
|
|
1615
1780
|
await this.mountInspector();
|
|
1616
1781
|
if (isDeno) {
|
|
1782
|
+
const corsHeaders = {
|
|
1783
|
+
"Access-Control-Allow-Origin": "*",
|
|
1784
|
+
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type"
|
|
1785
|
+
};
|
|
1617
1786
|
globalThis.Deno.serve(
|
|
1618
1787
|
{ port: this.serverPort, hostname: this.serverHost },
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1788
|
+
async (req) => {
|
|
1789
|
+
if (req.method === "OPTIONS") {
|
|
1790
|
+
return new Response("ok", { headers: corsHeaders });
|
|
1791
|
+
}
|
|
1792
|
+
const url = new URL(req.url);
|
|
1793
|
+
const pathname = url.pathname;
|
|
1794
|
+
let newPathname = pathname;
|
|
1795
|
+
const functionsMatch = pathname.match(
|
|
1796
|
+
/^\/functions\/v1\/[^/]+(\/.*)?$/
|
|
1797
|
+
);
|
|
1798
|
+
if (functionsMatch) {
|
|
1799
|
+
newPathname = functionsMatch[1] || "/";
|
|
1800
|
+
} else {
|
|
1801
|
+
const functionNameMatch = pathname.match(/^\/([^/]+)(\/.*)?$/);
|
|
1802
|
+
if (functionNameMatch && functionNameMatch[2]) {
|
|
1803
|
+
newPathname = functionNameMatch[2] || "/";
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
let finalReq = req;
|
|
1807
|
+
if (newPathname !== pathname) {
|
|
1808
|
+
const newUrl = new URL(newPathname + url.search, url.origin);
|
|
1809
|
+
finalReq = new Request(newUrl, {
|
|
1810
|
+
method: req.method,
|
|
1811
|
+
headers: req.headers,
|
|
1812
|
+
body: req.body,
|
|
1813
|
+
redirect: req.redirect
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
const response = await this.app.fetch(finalReq);
|
|
1817
|
+
const newHeaders = new Headers(response.headers);
|
|
1818
|
+
Object.entries(corsHeaders).forEach(([key, value]) => {
|
|
1819
|
+
newHeaders.set(key, value);
|
|
1820
|
+
});
|
|
1821
|
+
return new Response(response.body, {
|
|
1822
|
+
status: response.status,
|
|
1823
|
+
statusText: response.statusText,
|
|
1824
|
+
headers: newHeaders
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1626
1827
|
);
|
|
1828
|
+
console.log(`[SERVER] Listening`);
|
|
1627
1829
|
} else {
|
|
1628
1830
|
const { serve } = await import("@hono/node-server");
|
|
1629
1831
|
serve(
|
|
@@ -1677,19 +1879,26 @@ if (container && Component) {
|
|
|
1677
1879
|
* ```
|
|
1678
1880
|
*/
|
|
1679
1881
|
async getHandler(options) {
|
|
1882
|
+
console.log("[MCP] Mounting widgets");
|
|
1680
1883
|
await this.mountWidgets({
|
|
1681
1884
|
baseRoute: "/mcp-use/widgets",
|
|
1682
1885
|
resourcesDir: "resources"
|
|
1683
1886
|
});
|
|
1887
|
+
console.log("[MCP] Mounted widgets");
|
|
1684
1888
|
await this.mountMcp();
|
|
1889
|
+
console.log("[MCP] Mounted MCP");
|
|
1890
|
+
console.log("[MCP] Mounting inspector");
|
|
1685
1891
|
await this.mountInspector();
|
|
1892
|
+
console.log("[MCP] Mounted inspector");
|
|
1686
1893
|
const fetchHandler = this.app.fetch.bind(this.app);
|
|
1687
1894
|
if (options?.provider === "supabase") {
|
|
1688
1895
|
return async (req) => {
|
|
1689
1896
|
const url = new URL(req.url);
|
|
1690
1897
|
const pathname = url.pathname;
|
|
1691
1898
|
let newPathname = pathname;
|
|
1692
|
-
const functionsMatch = pathname.match(
|
|
1899
|
+
const functionsMatch = pathname.match(
|
|
1900
|
+
/^\/functions\/v1\/[^/]+(\/.*)?$/
|
|
1901
|
+
);
|
|
1693
1902
|
if (functionsMatch) {
|
|
1694
1903
|
newPathname = functionsMatch[1] || "/";
|
|
1695
1904
|
} else {
|
|
@@ -1808,11 +2017,21 @@ if (container && Component) {
|
|
|
1808
2017
|
});
|
|
1809
2018
|
this.app.get("/mcp-use/widgets/assets/*", async (c) => {
|
|
1810
2019
|
const assetFile = c.req.path.split("/assets/")[1];
|
|
1811
|
-
const widgetsDir = pathHelpers.join(
|
|
2020
|
+
const widgetsDir = pathHelpers.join(
|
|
2021
|
+
getCwd(),
|
|
2022
|
+
"dist",
|
|
2023
|
+
"resources",
|
|
2024
|
+
"widgets"
|
|
2025
|
+
);
|
|
1812
2026
|
try {
|
|
1813
2027
|
const widgets = await fsHelpers.readdirSync(widgetsDir);
|
|
1814
2028
|
for (const widget of widgets) {
|
|
1815
|
-
const assetPath = pathHelpers.join(
|
|
2029
|
+
const assetPath = pathHelpers.join(
|
|
2030
|
+
widgetsDir,
|
|
2031
|
+
widget,
|
|
2032
|
+
"assets",
|
|
2033
|
+
assetFile
|
|
2034
|
+
);
|
|
1816
2035
|
if (await fsHelpers.existsSync(assetPath)) {
|
|
1817
2036
|
const content = await fsHelpers.readFile(assetPath);
|
|
1818
2037
|
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"}
|