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
package/dist/src/server/index.js
CHANGED
|
@@ -118,6 +118,149 @@ function createUIResourceFromDefinition(definition, params, config) {
|
|
|
118
118
|
}
|
|
119
119
|
__name(createUIResourceFromDefinition, "createUIResourceFromDefinition");
|
|
120
120
|
|
|
121
|
+
// src/server/connect-adapter.ts
|
|
122
|
+
function isExpressMiddleware(middleware) {
|
|
123
|
+
if (!middleware || typeof middleware !== "function") {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const paramCount = middleware.length;
|
|
127
|
+
if (paramCount === 3 || paramCount === 4) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
if (paramCount === 2) {
|
|
131
|
+
const fnString = middleware.toString();
|
|
132
|
+
const expressPatterns = [
|
|
133
|
+
/\bres\.(send|json|status|end|redirect|render|sendFile|download)\b/,
|
|
134
|
+
/\breq\.(body|params|query|cookies|session)\b/,
|
|
135
|
+
/\breq\.get\s*\(/,
|
|
136
|
+
/\bres\.set\s*\(/
|
|
137
|
+
];
|
|
138
|
+
const hasExpressPattern = expressPatterns.some(
|
|
139
|
+
(pattern) => pattern.test(fnString)
|
|
140
|
+
);
|
|
141
|
+
if (hasExpressPattern) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
__name(isExpressMiddleware, "isExpressMiddleware");
|
|
149
|
+
async function adaptMiddleware(middleware, middlewarePath = "*") {
|
|
150
|
+
if (isExpressMiddleware(middleware)) {
|
|
151
|
+
return adaptConnectMiddleware(middleware, middlewarePath);
|
|
152
|
+
}
|
|
153
|
+
return middleware;
|
|
154
|
+
}
|
|
155
|
+
__name(adaptMiddleware, "adaptMiddleware");
|
|
156
|
+
async function adaptConnectMiddleware(connectMiddleware, middlewarePath) {
|
|
157
|
+
let createRequest;
|
|
158
|
+
let createResponse;
|
|
159
|
+
try {
|
|
160
|
+
const httpMocks = await import("node-mocks-http");
|
|
161
|
+
createRequest = httpMocks.createRequest;
|
|
162
|
+
createResponse = httpMocks.createResponse;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error(
|
|
165
|
+
"[WIDGETS] node-mocks-http not available. Install connect and node-mocks-http for Vite middleware support."
|
|
166
|
+
);
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
let normalizedPath = middlewarePath;
|
|
170
|
+
if (normalizedPath.endsWith("*")) {
|
|
171
|
+
normalizedPath = normalizedPath.slice(0, -1);
|
|
172
|
+
}
|
|
173
|
+
if (normalizedPath.endsWith("/")) {
|
|
174
|
+
normalizedPath = normalizedPath.slice(0, -1);
|
|
175
|
+
}
|
|
176
|
+
const honoMiddleware = /* @__PURE__ */ __name(async (c, next) => {
|
|
177
|
+
const request = c.req.raw;
|
|
178
|
+
const parsedURL = new URL(request.url, "http://localhost");
|
|
179
|
+
const query = {};
|
|
180
|
+
for (const [key, value] of parsedURL.searchParams.entries()) {
|
|
181
|
+
query[key] = value;
|
|
182
|
+
}
|
|
183
|
+
let middlewarePathname = parsedURL.pathname;
|
|
184
|
+
if (normalizedPath && middlewarePathname.startsWith(normalizedPath)) {
|
|
185
|
+
middlewarePathname = middlewarePathname.substring(normalizedPath.length);
|
|
186
|
+
if (middlewarePathname === "") {
|
|
187
|
+
middlewarePathname = "/";
|
|
188
|
+
} else if (!middlewarePathname.startsWith("/")) {
|
|
189
|
+
middlewarePathname = "/" + middlewarePathname;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const mockRequest = createRequest({
|
|
193
|
+
method: request.method.toUpperCase(),
|
|
194
|
+
url: middlewarePathname + parsedURL.search,
|
|
195
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
196
|
+
query,
|
|
197
|
+
...request.body && { body: request.body }
|
|
198
|
+
});
|
|
199
|
+
const mockResponse = createResponse();
|
|
200
|
+
let responseResolved = false;
|
|
201
|
+
const res = await new Promise((resolve) => {
|
|
202
|
+
const originalEnd = mockResponse.end.bind(mockResponse);
|
|
203
|
+
mockResponse.end = (...args) => {
|
|
204
|
+
const result = originalEnd(...args);
|
|
205
|
+
if (!responseResolved && mockResponse.writableEnded) {
|
|
206
|
+
responseResolved = true;
|
|
207
|
+
const statusCode = mockResponse.statusCode;
|
|
208
|
+
const noBodyStatuses = [204, 304];
|
|
209
|
+
const responseBody = noBodyStatuses.includes(statusCode) ? null : mockResponse._getData() || mockResponse._getBuffer() || null;
|
|
210
|
+
const connectResponse = new Response(responseBody, {
|
|
211
|
+
status: statusCode,
|
|
212
|
+
statusText: mockResponse.statusMessage,
|
|
213
|
+
headers: mockResponse.getHeaders()
|
|
214
|
+
});
|
|
215
|
+
resolve(connectResponse);
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
};
|
|
219
|
+
connectMiddleware(mockRequest, mockResponse, () => {
|
|
220
|
+
if (!responseResolved && !mockResponse.writableEnded) {
|
|
221
|
+
responseResolved = true;
|
|
222
|
+
const statusCode = mockResponse.statusCode;
|
|
223
|
+
const noBodyStatuses = [204, 304];
|
|
224
|
+
const responseBody = noBodyStatuses.includes(statusCode) ? null : mockResponse._getData() || mockResponse._getBuffer() || null;
|
|
225
|
+
const preparedHeaders = c.newResponse(null, 204, {}).headers;
|
|
226
|
+
for (const key of [...preparedHeaders.keys()]) {
|
|
227
|
+
if (preparedHeaders.has(key)) {
|
|
228
|
+
c.header(key, void 0);
|
|
229
|
+
}
|
|
230
|
+
if (c.res && c.res.headers.has(key)) {
|
|
231
|
+
c.res.headers.delete(key);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const connectHeaders = mockResponse.getHeaders();
|
|
235
|
+
for (const [key, value] of Object.entries(connectHeaders)) {
|
|
236
|
+
if (value !== void 0) {
|
|
237
|
+
c.header(
|
|
238
|
+
key,
|
|
239
|
+
Array.isArray(value) ? value.join(", ") : String(value)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
c.status(statusCode);
|
|
244
|
+
if (noBodyStatuses.includes(statusCode)) {
|
|
245
|
+
resolve(c.newResponse(null, statusCode));
|
|
246
|
+
} else if (responseBody) {
|
|
247
|
+
resolve(c.body(responseBody));
|
|
248
|
+
} else {
|
|
249
|
+
resolve(void 0);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
if (res) {
|
|
255
|
+
c.res = res;
|
|
256
|
+
return res;
|
|
257
|
+
}
|
|
258
|
+
await next();
|
|
259
|
+
}, "honoMiddleware");
|
|
260
|
+
return honoMiddleware;
|
|
261
|
+
}
|
|
262
|
+
__name(adaptConnectMiddleware, "adaptConnectMiddleware");
|
|
263
|
+
|
|
121
264
|
// src/server/logging.ts
|
|
122
265
|
async function requestLogger(c, next) {
|
|
123
266
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
|
|
@@ -126,7 +269,8 @@ async function requestLogger(c, next) {
|
|
|
126
269
|
let body = null;
|
|
127
270
|
if (method === "POST" && url.includes("/mcp")) {
|
|
128
271
|
try {
|
|
129
|
-
|
|
272
|
+
const clonedRequest = c.req.raw.clone();
|
|
273
|
+
body = await clonedRequest.json().catch(() => null);
|
|
130
274
|
} catch {
|
|
131
275
|
}
|
|
132
276
|
}
|
|
@@ -184,7 +328,10 @@ var fsHelpers = {
|
|
|
184
328
|
}
|
|
185
329
|
const { readFileSync } = await import("fs");
|
|
186
330
|
const buffer = readFileSync(path);
|
|
187
|
-
return buffer.buffer.slice(
|
|
331
|
+
return buffer.buffer.slice(
|
|
332
|
+
buffer.byteOffset,
|
|
333
|
+
buffer.byteOffset + buffer.byteLength
|
|
334
|
+
);
|
|
188
335
|
},
|
|
189
336
|
async existsSync(path) {
|
|
190
337
|
if (isDeno) {
|
|
@@ -279,6 +426,47 @@ var McpServer = class {
|
|
|
279
426
|
this.app.use("*", requestLogger);
|
|
280
427
|
return new Proxy(this, {
|
|
281
428
|
get(target, prop) {
|
|
429
|
+
if (prop === "use") {
|
|
430
|
+
return async (...args) => {
|
|
431
|
+
const hasPath = typeof args[0] === "string";
|
|
432
|
+
const path = hasPath ? args[0] : "*";
|
|
433
|
+
const handlers = hasPath ? args.slice(1) : args;
|
|
434
|
+
const adaptedHandlers = handlers.map((handler) => {
|
|
435
|
+
if (isExpressMiddleware(handler)) {
|
|
436
|
+
return { __isExpressMiddleware: true, handler, path };
|
|
437
|
+
}
|
|
438
|
+
return handler;
|
|
439
|
+
});
|
|
440
|
+
const hasExpressMiddleware = adaptedHandlers.some(
|
|
441
|
+
(h) => h.__isExpressMiddleware
|
|
442
|
+
);
|
|
443
|
+
if (hasExpressMiddleware) {
|
|
444
|
+
await Promise.all(
|
|
445
|
+
adaptedHandlers.map(async (h) => {
|
|
446
|
+
if (h.__isExpressMiddleware) {
|
|
447
|
+
const adapted = await adaptConnectMiddleware(
|
|
448
|
+
h.handler,
|
|
449
|
+
h.path
|
|
450
|
+
);
|
|
451
|
+
if (hasPath) {
|
|
452
|
+
target.app.use(path, adapted);
|
|
453
|
+
} else {
|
|
454
|
+
target.app.use(adapted);
|
|
455
|
+
}
|
|
456
|
+
} else {
|
|
457
|
+
if (hasPath) {
|
|
458
|
+
target.app.use(path, h);
|
|
459
|
+
} else {
|
|
460
|
+
target.app.use(h);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
})
|
|
464
|
+
);
|
|
465
|
+
return target;
|
|
466
|
+
}
|
|
467
|
+
return target.app.use(...args);
|
|
468
|
+
};
|
|
469
|
+
}
|
|
282
470
|
if (prop in target) {
|
|
283
471
|
return target[prop];
|
|
284
472
|
}
|
|
@@ -823,9 +1011,9 @@ var McpServer = class {
|
|
|
823
1011
|
async readBuildManifest() {
|
|
824
1012
|
try {
|
|
825
1013
|
const manifestPath = pathHelpers.join(
|
|
826
|
-
getCwd(),
|
|
1014
|
+
isDeno ? "." : getCwd(),
|
|
827
1015
|
"dist",
|
|
828
|
-
"
|
|
1016
|
+
"mcp-use.json"
|
|
829
1017
|
);
|
|
830
1018
|
const content = await fsHelpers.readFileSync(manifestPath, "utf8");
|
|
831
1019
|
return JSON.parse(content);
|
|
@@ -845,13 +1033,11 @@ var McpServer = class {
|
|
|
845
1033
|
* @returns Promise that resolves when all widgets are mounted
|
|
846
1034
|
*/
|
|
847
1035
|
async mountWidgets(options) {
|
|
848
|
-
if (this.isProductionMode()) {
|
|
1036
|
+
if (this.isProductionMode() || isDeno) {
|
|
1037
|
+
console.log("[WIDGETS] Mounting widgets in production mode");
|
|
849
1038
|
await this.mountWidgetsProduction(options);
|
|
850
1039
|
} else {
|
|
851
|
-
|
|
852
|
-
console.log("[WIDGETS] Skipping dev mode widget mounting in Deno runtime (use production build)");
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
1040
|
+
console.log("[WIDGETS] Mounting widgets in development mode");
|
|
855
1041
|
await this.mountWidgetsDev(options);
|
|
856
1042
|
}
|
|
857
1043
|
}
|
|
@@ -902,13 +1088,21 @@ var McpServer = class {
|
|
|
902
1088
|
try {
|
|
903
1089
|
const viteModule = await new Function('return import("vite")')();
|
|
904
1090
|
createServer = viteModule.createServer;
|
|
905
|
-
const reactModule = await new Function(
|
|
1091
|
+
const reactModule = await new Function(
|
|
1092
|
+
'return import("@vitejs/plugin-react")'
|
|
1093
|
+
)();
|
|
906
1094
|
react = reactModule.default;
|
|
907
|
-
const tailwindModule = await new Function(
|
|
1095
|
+
const tailwindModule = await new Function(
|
|
1096
|
+
'return import("@tailwindcss/vite")'
|
|
1097
|
+
)();
|
|
908
1098
|
tailwindcss = tailwindModule.default;
|
|
909
1099
|
} catch (error) {
|
|
910
|
-
console.error(
|
|
911
|
-
|
|
1100
|
+
console.error(
|
|
1101
|
+
"[WIDGETS] Dev dependencies not available. Install vite, @vitejs/plugin-react, and @tailwindcss/vite for widget development."
|
|
1102
|
+
);
|
|
1103
|
+
console.error(
|
|
1104
|
+
"[WIDGETS] For production, use 'mcp-use build' to pre-build widgets."
|
|
1105
|
+
);
|
|
912
1106
|
return;
|
|
913
1107
|
}
|
|
914
1108
|
const widgets = entries.map((entry) => {
|
|
@@ -924,16 +1118,17 @@ var McpServer = class {
|
|
|
924
1118
|
const widgetTempDir = pathHelpers.join(tempDir, widget.name);
|
|
925
1119
|
await fs.mkdir(widgetTempDir, { recursive: true });
|
|
926
1120
|
const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
|
|
927
|
-
const relativeResourcesPath = pathHelpers.relative(
|
|
928
|
-
widgetTempDir,
|
|
929
|
-
resourcesPath
|
|
930
|
-
).replace(/\\/g, "/");
|
|
1121
|
+
const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
|
|
931
1122
|
const cssContent = `@import "tailwindcss";
|
|
932
1123
|
|
|
933
1124
|
/* Configure Tailwind to scan the resources directory */
|
|
934
1125
|
@source "${relativeResourcesPath}";
|
|
935
1126
|
`;
|
|
936
|
-
await fs.writeFile(
|
|
1127
|
+
await fs.writeFile(
|
|
1128
|
+
pathHelpers.join(widgetTempDir, "styles.css"),
|
|
1129
|
+
cssContent,
|
|
1130
|
+
"utf8"
|
|
1131
|
+
);
|
|
937
1132
|
const entryContent = `import React from 'react'
|
|
938
1133
|
import { createRoot } from 'react-dom/client'
|
|
939
1134
|
import './styles.css'
|
|
@@ -986,67 +1181,6 @@ if (container && Component) {
|
|
|
986
1181
|
origin: serverOrigin
|
|
987
1182
|
}
|
|
988
1183
|
});
|
|
989
|
-
const adaptExpressMiddleware = /* @__PURE__ */ __name((middleware) => {
|
|
990
|
-
return async (c, next) => {
|
|
991
|
-
const req = c.req.raw;
|
|
992
|
-
let handled = false;
|
|
993
|
-
const responseBody = [];
|
|
994
|
-
let statusCode = 200;
|
|
995
|
-
const headers = {};
|
|
996
|
-
const res = {
|
|
997
|
-
statusCode: 200,
|
|
998
|
-
status: /* @__PURE__ */ __name((code) => {
|
|
999
|
-
statusCode = code;
|
|
1000
|
-
res.statusCode = code;
|
|
1001
|
-
return res;
|
|
1002
|
-
}, "status"),
|
|
1003
|
-
setHeader: /* @__PURE__ */ __name((name, value) => {
|
|
1004
|
-
headers[name] = value;
|
|
1005
|
-
}, "setHeader"),
|
|
1006
|
-
getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
|
|
1007
|
-
write: /* @__PURE__ */ __name((chunk) => {
|
|
1008
|
-
responseBody.push(typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk);
|
|
1009
|
-
}, "write"),
|
|
1010
|
-
end: /* @__PURE__ */ __name((chunk) => {
|
|
1011
|
-
if (chunk) {
|
|
1012
|
-
responseBody.push(typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk);
|
|
1013
|
-
}
|
|
1014
|
-
handled = true;
|
|
1015
|
-
}, "end"),
|
|
1016
|
-
on: /* @__PURE__ */ __name(() => {
|
|
1017
|
-
}, "on"),
|
|
1018
|
-
once: /* @__PURE__ */ __name(() => {
|
|
1019
|
-
}, "once"),
|
|
1020
|
-
removeListener: /* @__PURE__ */ __name(() => {
|
|
1021
|
-
}, "removeListener")
|
|
1022
|
-
};
|
|
1023
|
-
const expressReq = {
|
|
1024
|
-
...req,
|
|
1025
|
-
url: new URL(req.url).pathname + new URL(req.url).search,
|
|
1026
|
-
originalUrl: req.url,
|
|
1027
|
-
baseUrl: "",
|
|
1028
|
-
path: new URL(req.url).pathname,
|
|
1029
|
-
query: Object.fromEntries(new URL(req.url).searchParams),
|
|
1030
|
-
params: {},
|
|
1031
|
-
body: {},
|
|
1032
|
-
headers: Object.fromEntries(req.headers.entries())
|
|
1033
|
-
};
|
|
1034
|
-
await new Promise((resolve, reject) => {
|
|
1035
|
-
middleware(expressReq, res, (err) => {
|
|
1036
|
-
if (err) reject(err);
|
|
1037
|
-
else resolve();
|
|
1038
|
-
});
|
|
1039
|
-
});
|
|
1040
|
-
if (handled) {
|
|
1041
|
-
const body = Buffer.concat(responseBody);
|
|
1042
|
-
return new Response(body, {
|
|
1043
|
-
status: statusCode,
|
|
1044
|
-
headers
|
|
1045
|
-
});
|
|
1046
|
-
}
|
|
1047
|
-
return next();
|
|
1048
|
-
};
|
|
1049
|
-
}, "adaptExpressMiddleware");
|
|
1050
1184
|
this.app.use(`${baseRoute}/*`, async (c, next) => {
|
|
1051
1185
|
const url = new URL(c.req.url);
|
|
1052
1186
|
const pathname = url.pathname;
|
|
@@ -1074,7 +1208,11 @@ if (container && Component) {
|
|
|
1074
1208
|
}
|
|
1075
1209
|
await next();
|
|
1076
1210
|
});
|
|
1077
|
-
|
|
1211
|
+
const viteMiddleware = await adaptConnectMiddleware(
|
|
1212
|
+
viteServer.middlewares,
|
|
1213
|
+
`${baseRoute}/*`
|
|
1214
|
+
);
|
|
1215
|
+
this.app.use(`${baseRoute}/*`, viteMiddleware);
|
|
1078
1216
|
widgets.forEach((widget) => {
|
|
1079
1217
|
console.log(
|
|
1080
1218
|
`[WIDGET] ${widget.name} mounted at ${baseRoute}/${widget.name}`
|
|
@@ -1107,7 +1245,6 @@ if (container && Component) {
|
|
|
1107
1245
|
error
|
|
1108
1246
|
);
|
|
1109
1247
|
}
|
|
1110
|
-
console.log("[WIDGET dev] Metadata:", metadata);
|
|
1111
1248
|
let html = "";
|
|
1112
1249
|
try {
|
|
1113
1250
|
html = await fsHelpers.readFileSync(
|
|
@@ -1214,27 +1351,57 @@ if (container && Component) {
|
|
|
1214
1351
|
*/
|
|
1215
1352
|
async mountWidgetsProduction(options) {
|
|
1216
1353
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
1217
|
-
const widgetsDir = pathHelpers.join(
|
|
1218
|
-
|
|
1354
|
+
const widgetsDir = pathHelpers.join(
|
|
1355
|
+
isDeno ? "." : getCwd(),
|
|
1356
|
+
"dist",
|
|
1357
|
+
"resources",
|
|
1358
|
+
"widgets"
|
|
1359
|
+
);
|
|
1360
|
+
console.log("widgetsDir", widgetsDir);
|
|
1361
|
+
this.setupWidgetRoutes();
|
|
1362
|
+
const manifestPath = "./dist/mcp-use.json";
|
|
1363
|
+
let widgets = [];
|
|
1364
|
+
let widgetsMetadata = {};
|
|
1365
|
+
try {
|
|
1366
|
+
const manifestContent = await fsHelpers.readFileSync(
|
|
1367
|
+
manifestPath,
|
|
1368
|
+
"utf8"
|
|
1369
|
+
);
|
|
1370
|
+
const manifest = JSON.parse(manifestContent);
|
|
1371
|
+
if (manifest.widgets && typeof manifest.widgets === "object" && !Array.isArray(manifest.widgets)) {
|
|
1372
|
+
widgets = Object.keys(manifest.widgets);
|
|
1373
|
+
widgetsMetadata = manifest.widgets;
|
|
1374
|
+
console.log(
|
|
1375
|
+
`[WIDGETS] Loaded ${widgets.length} widget(s) from manifest`
|
|
1376
|
+
);
|
|
1377
|
+
} else if (manifest.widgets && Array.isArray(manifest.widgets)) {
|
|
1378
|
+
widgets = manifest.widgets;
|
|
1379
|
+
console.log(
|
|
1380
|
+
`[WIDGETS] Loaded ${widgets.length} widget(s) from manifest (legacy format)`
|
|
1381
|
+
);
|
|
1382
|
+
} else {
|
|
1383
|
+
console.log("[WIDGETS] No widgets found in manifest");
|
|
1384
|
+
}
|
|
1385
|
+
} catch (error) {
|
|
1219
1386
|
console.log(
|
|
1220
|
-
"[WIDGETS]
|
|
1387
|
+
"[WIDGETS] Could not read manifest file, falling back to directory listing:",
|
|
1388
|
+
error
|
|
1221
1389
|
);
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1390
|
+
try {
|
|
1391
|
+
const allEntries = await fsHelpers.readdirSync(widgetsDir);
|
|
1392
|
+
for (const name of allEntries) {
|
|
1393
|
+
const widgetPath = pathHelpers.join(widgetsDir, name);
|
|
1394
|
+
const indexPath = pathHelpers.join(widgetPath, "index.html");
|
|
1395
|
+
if (await fsHelpers.existsSync(indexPath)) {
|
|
1396
|
+
widgets.push(name);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
} catch (dirError) {
|
|
1400
|
+
console.log("[WIDGETS] Directory listing also failed:", dirError);
|
|
1232
1401
|
}
|
|
1233
1402
|
}
|
|
1234
1403
|
if (widgets.length === 0) {
|
|
1235
|
-
console.log(
|
|
1236
|
-
"[WIDGETS] No built widgets found in dist/resources/widgets/"
|
|
1237
|
-
);
|
|
1404
|
+
console.log("[WIDGETS] No built widgets found");
|
|
1238
1405
|
return;
|
|
1239
1406
|
}
|
|
1240
1407
|
console.log(
|
|
@@ -1243,7 +1410,6 @@ if (container && Component) {
|
|
|
1243
1410
|
for (const widgetName of widgets) {
|
|
1244
1411
|
const widgetPath = pathHelpers.join(widgetsDir, widgetName);
|
|
1245
1412
|
const indexPath = pathHelpers.join(widgetPath, "index.html");
|
|
1246
|
-
const metadataPath = pathHelpers.join(widgetPath, "metadata.json");
|
|
1247
1413
|
let html = "";
|
|
1248
1414
|
try {
|
|
1249
1415
|
html = await fsHelpers.readFileSync(indexPath, "utf8");
|
|
@@ -1290,22 +1456,14 @@ if (container && Component) {
|
|
|
1290
1456
|
);
|
|
1291
1457
|
continue;
|
|
1292
1458
|
}
|
|
1293
|
-
|
|
1459
|
+
const metadata = widgetsMetadata[widgetName] || {};
|
|
1294
1460
|
let props = {};
|
|
1295
1461
|
let description = `Widget: ${widgetName}`;
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
}
|
|
1302
|
-
if (metadata.inputs) {
|
|
1303
|
-
props = metadata.inputs;
|
|
1304
|
-
}
|
|
1305
|
-
} catch (error) {
|
|
1306
|
-
console.log(
|
|
1307
|
-
`[WIDGET] No metadata found for ${widgetName}, using defaults`
|
|
1308
|
-
);
|
|
1462
|
+
if (metadata.description) {
|
|
1463
|
+
description = metadata.description;
|
|
1464
|
+
}
|
|
1465
|
+
if (metadata.inputs) {
|
|
1466
|
+
props = metadata.inputs;
|
|
1309
1467
|
}
|
|
1310
1468
|
this.uiResource({
|
|
1311
1469
|
name: widgetName,
|
|
@@ -1462,23 +1620,27 @@ if (container && Component) {
|
|
|
1462
1620
|
}
|
|
1463
1621
|
}, "send")
|
|
1464
1622
|
};
|
|
1465
|
-
return {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1623
|
+
return {
|
|
1624
|
+
expressReq,
|
|
1625
|
+
expressRes,
|
|
1626
|
+
getResponse: /* @__PURE__ */ __name(() => {
|
|
1627
|
+
if (ended) {
|
|
1628
|
+
if (responseBody.length > 0) {
|
|
1629
|
+
const body = isDeno ? Buffer.concat(responseBody) : Buffer.concat(responseBody);
|
|
1630
|
+
return new Response(body, {
|
|
1631
|
+
status: statusCode,
|
|
1632
|
+
headers
|
|
1633
|
+
});
|
|
1634
|
+
} else {
|
|
1635
|
+
return new Response(null, {
|
|
1636
|
+
status: statusCode,
|
|
1637
|
+
headers
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1478
1640
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
}
|
|
1641
|
+
return null;
|
|
1642
|
+
}, "getResponse")
|
|
1643
|
+
};
|
|
1482
1644
|
}, "createExpressLikeObjects");
|
|
1483
1645
|
this.app.post(endpoint, async (c) => {
|
|
1484
1646
|
const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
|
|
@@ -1579,16 +1741,53 @@ if (container && Component) {
|
|
|
1579
1741
|
await this.mountMcp();
|
|
1580
1742
|
await this.mountInspector();
|
|
1581
1743
|
if (isDeno) {
|
|
1744
|
+
const corsHeaders = {
|
|
1745
|
+
"Access-Control-Allow-Origin": "*",
|
|
1746
|
+
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type"
|
|
1747
|
+
};
|
|
1582
1748
|
globalThis.Deno.serve(
|
|
1583
1749
|
{ port: this.serverPort, hostname: this.serverHost },
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1750
|
+
async (req) => {
|
|
1751
|
+
if (req.method === "OPTIONS") {
|
|
1752
|
+
return new Response("ok", { headers: corsHeaders });
|
|
1753
|
+
}
|
|
1754
|
+
const url = new URL(req.url);
|
|
1755
|
+
const pathname = url.pathname;
|
|
1756
|
+
let newPathname = pathname;
|
|
1757
|
+
const functionsMatch = pathname.match(
|
|
1758
|
+
/^\/functions\/v1\/[^/]+(\/.*)?$/
|
|
1759
|
+
);
|
|
1760
|
+
if (functionsMatch) {
|
|
1761
|
+
newPathname = functionsMatch[1] || "/";
|
|
1762
|
+
} else {
|
|
1763
|
+
const functionNameMatch = pathname.match(/^\/([^/]+)(\/.*)?$/);
|
|
1764
|
+
if (functionNameMatch && functionNameMatch[2]) {
|
|
1765
|
+
newPathname = functionNameMatch[2] || "/";
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
let finalReq = req;
|
|
1769
|
+
if (newPathname !== pathname) {
|
|
1770
|
+
const newUrl = new URL(newPathname + url.search, url.origin);
|
|
1771
|
+
finalReq = new Request(newUrl, {
|
|
1772
|
+
method: req.method,
|
|
1773
|
+
headers: req.headers,
|
|
1774
|
+
body: req.body,
|
|
1775
|
+
redirect: req.redirect
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
const response = await this.app.fetch(finalReq);
|
|
1779
|
+
const newHeaders = new Headers(response.headers);
|
|
1780
|
+
Object.entries(corsHeaders).forEach(([key, value]) => {
|
|
1781
|
+
newHeaders.set(key, value);
|
|
1782
|
+
});
|
|
1783
|
+
return new Response(response.body, {
|
|
1784
|
+
status: response.status,
|
|
1785
|
+
statusText: response.statusText,
|
|
1786
|
+
headers: newHeaders
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1591
1789
|
);
|
|
1790
|
+
console.log(`[SERVER] Listening`);
|
|
1592
1791
|
} else {
|
|
1593
1792
|
const { serve } = await import("@hono/node-server");
|
|
1594
1793
|
serve(
|
|
@@ -1642,19 +1841,26 @@ if (container && Component) {
|
|
|
1642
1841
|
* ```
|
|
1643
1842
|
*/
|
|
1644
1843
|
async getHandler(options) {
|
|
1844
|
+
console.log("[MCP] Mounting widgets");
|
|
1645
1845
|
await this.mountWidgets({
|
|
1646
1846
|
baseRoute: "/mcp-use/widgets",
|
|
1647
1847
|
resourcesDir: "resources"
|
|
1648
1848
|
});
|
|
1849
|
+
console.log("[MCP] Mounted widgets");
|
|
1649
1850
|
await this.mountMcp();
|
|
1851
|
+
console.log("[MCP] Mounted MCP");
|
|
1852
|
+
console.log("[MCP] Mounting inspector");
|
|
1650
1853
|
await this.mountInspector();
|
|
1854
|
+
console.log("[MCP] Mounted inspector");
|
|
1651
1855
|
const fetchHandler = this.app.fetch.bind(this.app);
|
|
1652
1856
|
if (options?.provider === "supabase") {
|
|
1653
1857
|
return async (req) => {
|
|
1654
1858
|
const url = new URL(req.url);
|
|
1655
1859
|
const pathname = url.pathname;
|
|
1656
1860
|
let newPathname = pathname;
|
|
1657
|
-
const functionsMatch = pathname.match(
|
|
1861
|
+
const functionsMatch = pathname.match(
|
|
1862
|
+
/^\/functions\/v1\/[^/]+(\/.*)?$/
|
|
1863
|
+
);
|
|
1658
1864
|
if (functionsMatch) {
|
|
1659
1865
|
newPathname = functionsMatch[1] || "/";
|
|
1660
1866
|
} else {
|
|
@@ -1773,11 +1979,21 @@ if (container && Component) {
|
|
|
1773
1979
|
});
|
|
1774
1980
|
this.app.get("/mcp-use/widgets/assets/*", async (c) => {
|
|
1775
1981
|
const assetFile = c.req.path.split("/assets/")[1];
|
|
1776
|
-
const widgetsDir = pathHelpers.join(
|
|
1982
|
+
const widgetsDir = pathHelpers.join(
|
|
1983
|
+
getCwd(),
|
|
1984
|
+
"dist",
|
|
1985
|
+
"resources",
|
|
1986
|
+
"widgets"
|
|
1987
|
+
);
|
|
1777
1988
|
try {
|
|
1778
1989
|
const widgets = await fsHelpers.readdirSync(widgetsDir);
|
|
1779
1990
|
for (const widget of widgets) {
|
|
1780
|
-
const assetPath = pathHelpers.join(
|
|
1991
|
+
const assetPath = pathHelpers.join(
|
|
1992
|
+
widgetsDir,
|
|
1993
|
+
widget,
|
|
1994
|
+
"assets",
|
|
1995
|
+
assetFile
|
|
1996
|
+
);
|
|
1781
1997
|
if (await fsHelpers.existsSync(assetPath)) {
|
|
1782
1998
|
const content = await fsHelpers.readFile(assetPath);
|
|
1783
1999
|
const ext = assetFile.split(".").pop()?.toLowerCase();
|
|
@@ -2015,10 +2231,13 @@ function createMCPServer(name, config = {}) {
|
|
|
2015
2231
|
}
|
|
2016
2232
|
__name(createMCPServer, "createMCPServer");
|
|
2017
2233
|
export {
|
|
2234
|
+
adaptConnectMiddleware,
|
|
2235
|
+
adaptMiddleware,
|
|
2018
2236
|
buildWidgetUrl,
|
|
2019
2237
|
createExternalUrlResource,
|
|
2020
2238
|
createMCPServer,
|
|
2021
2239
|
createRawHtmlResource,
|
|
2022
2240
|
createRemoteDomResource,
|
|
2023
|
-
createUIResourceFromDefinition
|
|
2241
|
+
createUIResourceFromDefinition,
|
|
2242
|
+
isExpressMiddleware
|
|
2024
2243
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/server/logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CzE"}
|
|
@@ -416,7 +416,7 @@ export declare class McpServer {
|
|
|
416
416
|
* ```
|
|
417
417
|
*/
|
|
418
418
|
getHandler(options?: {
|
|
419
|
-
provider?:
|
|
419
|
+
provider?: "supabase" | "cloudflare" | "deno-deploy";
|
|
420
420
|
}): Promise<(req: Request) => Promise<Response>>;
|
|
421
421
|
/**
|
|
422
422
|
* Mount MCP Inspector UI at /inspector
|
|
@@ -557,7 +557,7 @@ export declare class McpServer {
|
|
|
557
557
|
}
|
|
558
558
|
export type McpServerInstance = Omit<McpServer, keyof HonoType> & HonoType & {
|
|
559
559
|
getHandler: (options?: {
|
|
560
|
-
provider?:
|
|
560
|
+
provider?: "supabase" | "cloudflare" | "deno-deploy";
|
|
561
561
|
}) => Promise<(req: Request) => Promise<Response>>;
|
|
562
562
|
};
|
|
563
563
|
/**
|