mcp-use 1.6.3-canary.0 → 1.7.0-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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/chunk-3R5PDYIN.js +403 -0
- package/dist/{chunk-BWOTID2D.js → chunk-AGKMD2ZM.js} +7 -350
- package/dist/{chunk-SJEHVCPM.js → chunk-BG2APH43.js} +120 -26
- package/dist/{chunk-YURRUCIM.js → chunk-CPG2WZUL.js} +9 -11
- package/dist/chunk-F4UHAA5L.js +854 -0
- package/dist/chunk-JQKKMUCT.js +0 -0
- package/dist/chunk-MTHLLDCX.js +97 -0
- package/dist/{chunk-MCF5P6GJ.js → chunk-S6K5QZBJ.js} +739 -29
- package/dist/{display-YIYC6WJE.js → display-A5IEINAP.js} +79 -17
- package/dist/index.cjs +1055 -136
- package/dist/index.js +14 -10
- package/dist/{langfuse-C4HKZ3NL.js → langfuse-N5Y5BSXK.js} +1 -1
- package/dist/oauth-U4NNKN4B.js +30 -0
- package/dist/src/agents/display.d.ts.map +1 -1
- package/dist/src/agents/index.cjs +854 -78
- package/dist/src/agents/index.js +3 -2
- package/dist/src/auth/browser-provider.d.ts +2 -0
- package/dist/src/auth/browser-provider.d.ts.map +1 -1
- package/dist/src/auth/callback.d.ts.map +1 -1
- package/dist/src/auth/index.cjs +421 -0
- package/dist/src/auth/index.js +10 -0
- package/dist/src/auth/types.d.ts +3 -1
- package/dist/src/auth/types.d.ts.map +1 -1
- package/dist/src/browser.cjs +924 -98
- package/dist/src/browser.js +8 -5
- package/dist/src/connectors/base.d.ts +52 -121
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/managers/server_manager.d.ts.map +1 -1
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +2 -2
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/add_server_from_config.d.ts +1 -7
- package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
- package/dist/src/managers/tools/connect_mcp_server.d.ts +2 -10
- package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/list_mcp_servers.d.ts +2 -2
- package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts +2 -2
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
- package/dist/src/observability/langfuse.d.ts +4 -0
- package/dist/src/observability/langfuse.d.ts.map +1 -1
- package/dist/src/react/McpUseProvider.d.ts.map +1 -1
- package/dist/src/react/index.cjs +189 -41
- package/dist/src/react/index.js +4 -2
- package/dist/src/react/types.d.ts +12 -1
- 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.map +1 -1
- package/dist/src/server/context-storage.d.ts +54 -0
- package/dist/src/server/context-storage.d.ts.map +1 -0
- package/dist/src/server/index.cjs +1413 -418
- package/dist/src/server/index.d.ts +4 -1
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +426 -420
- package/dist/src/server/mcp-server.d.ts +50 -81
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/oauth/index.d.ts +13 -0
- package/dist/src/server/oauth/index.d.ts.map +1 -0
- package/dist/src/server/oauth/middleware.d.ts +19 -0
- package/dist/src/server/oauth/middleware.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/auth0.d.ts +22 -0
- package/dist/src/server/oauth/providers/auth0.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/custom.d.ts +19 -0
- package/dist/src/server/oauth/providers/custom.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/keycloak.d.ts +22 -0
- package/dist/src/server/oauth/providers/keycloak.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/supabase.d.ts +24 -0
- package/dist/src/server/oauth/providers/supabase.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/types.d.ts +138 -0
- package/dist/src/server/oauth/providers/types.d.ts.map +1 -0
- package/dist/src/server/oauth/providers/workos.d.ts +30 -0
- package/dist/src/server/oauth/providers/workos.d.ts.map +1 -0
- package/dist/src/server/oauth/providers.d.ts +208 -0
- package/dist/src/server/oauth/providers.d.ts.map +1 -0
- package/dist/src/server/oauth/routes.d.ts +33 -0
- package/dist/src/server/oauth/routes.d.ts.map +1 -0
- package/dist/src/server/oauth/utils.d.ts +155 -0
- package/dist/src/server/oauth/utils.d.ts.map +1 -0
- package/dist/src/server/types/common.d.ts +47 -0
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/server/types/context.d.ts +34 -0
- package/dist/src/server/types/context.d.ts.map +1 -0
- package/dist/src/server/types/index.d.ts +2 -1
- package/dist/src/server/types/index.d.ts.map +1 -1
- package/dist/src/server/types/tool.d.ts +82 -9
- package/dist/src/server/types/tool.d.ts.map +1 -1
- package/dist/src/server/utils/index.d.ts +6 -0
- package/dist/src/server/utils/index.d.ts.map +1 -0
- package/dist/src/server/utils/response-helpers.d.ts +151 -0
- package/dist/src/server/utils/response-helpers.d.ts.map +1 -0
- package/dist/src/server/utils/runtime.d.ts +25 -0
- package/dist/src/server/utils/runtime.d.ts.map +1 -0
- package/dist/src/task_managers/streamable_http.d.ts +1 -0
- package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
- package/dist/src/utils/json-schema-to-zod/JSONSchemaToZod.d.ts +270 -0
- package/dist/src/utils/json-schema-to-zod/JSONSchemaToZod.d.ts.map +1 -0
- package/dist/src/utils/json-schema-to-zod/Type.d.ts +24 -0
- package/dist/src/utils/json-schema-to-zod/Type.d.ts.map +1 -0
- package/dist/src/utils/json-schema-to-zod/index.d.ts +3 -0
- package/dist/src/utils/json-schema-to-zod/index.d.ts.map +1 -0
- package/dist/src/utils/url-sanitize.d.ts +17 -0
- package/dist/src/utils/url-sanitize.d.ts.map +1 -0
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +30 -38
package/dist/src/server/index.js
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAuth,
|
|
3
|
+
hasAnyScope,
|
|
4
|
+
hasScope,
|
|
5
|
+
oauthAuth0Provider,
|
|
6
|
+
oauthCustomProvider,
|
|
7
|
+
oauthKeycloakProvider,
|
|
8
|
+
oauthSupabaseProvider,
|
|
9
|
+
oauthWorkOSProvider,
|
|
10
|
+
requireAnyScope,
|
|
11
|
+
requireScope
|
|
12
|
+
} from "../../chunk-F4UHAA5L.js";
|
|
13
|
+
import {
|
|
14
|
+
fsHelpers,
|
|
15
|
+
generateUUID,
|
|
16
|
+
getCwd,
|
|
17
|
+
getEnv,
|
|
18
|
+
isDeno,
|
|
19
|
+
pathHelpers
|
|
20
|
+
} from "../../chunk-MTHLLDCX.js";
|
|
1
21
|
import {
|
|
2
22
|
__name
|
|
3
23
|
} from "../../chunk-3GQAWCBQ.js";
|
|
@@ -7,15 +27,31 @@ import {
|
|
|
7
27
|
McpServer as OfficialMcpServer,
|
|
8
28
|
ResourceTemplate
|
|
9
29
|
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
30
|
+
import { z } from "zod";
|
|
10
31
|
import { Hono } from "hono";
|
|
11
32
|
import { cors } from "hono/cors";
|
|
12
|
-
|
|
33
|
+
|
|
34
|
+
// src/server/context-storage.ts
|
|
35
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
36
|
+
var requestContextStorage = new AsyncLocalStorage();
|
|
37
|
+
async function runWithContext(context, fn) {
|
|
38
|
+
return requestContextStorage.run(context, fn);
|
|
39
|
+
}
|
|
40
|
+
__name(runWithContext, "runWithContext");
|
|
41
|
+
function getRequestContext() {
|
|
42
|
+
return requestContextStorage.getStore();
|
|
43
|
+
}
|
|
44
|
+
__name(getRequestContext, "getRequestContext");
|
|
45
|
+
function hasRequestContext() {
|
|
46
|
+
return requestContextStorage.getStore() !== void 0;
|
|
47
|
+
}
|
|
48
|
+
__name(hasRequestContext, "hasRequestContext");
|
|
13
49
|
|
|
14
50
|
// src/server/adapters/mcp-ui-adapter.ts
|
|
15
51
|
import { createUIResource } from "@mcp-ui/server";
|
|
16
|
-
function buildWidgetUrl(
|
|
52
|
+
function buildWidgetUrl(widget2, props, config) {
|
|
17
53
|
const url = new URL(
|
|
18
|
-
`/mcp-use/widgets/${
|
|
54
|
+
`/mcp-use/widgets/${widget2}`,
|
|
19
55
|
`${config.baseUrl}:${config.port}`
|
|
20
56
|
);
|
|
21
57
|
if (props && Object.keys(props).length > 0) {
|
|
@@ -55,17 +91,17 @@ function createRemoteDomResource(uri, script, framework = "react", encoding = "t
|
|
|
55
91
|
}
|
|
56
92
|
__name(createRemoteDomResource, "createRemoteDomResource");
|
|
57
93
|
function createAppsSdkResource(uri, htmlTemplate, metadata) {
|
|
58
|
-
const
|
|
94
|
+
const resource2 = {
|
|
59
95
|
uri,
|
|
60
96
|
mimeType: "text/html+skybridge",
|
|
61
97
|
text: htmlTemplate
|
|
62
98
|
};
|
|
63
99
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
64
|
-
|
|
100
|
+
resource2._meta = metadata;
|
|
65
101
|
}
|
|
66
102
|
return {
|
|
67
103
|
type: "resource",
|
|
68
|
-
resource
|
|
104
|
+
resource: resource2
|
|
69
105
|
};
|
|
70
106
|
}
|
|
71
107
|
__name(createAppsSdkResource, "createAppsSdkResource");
|
|
@@ -161,11 +197,10 @@ async function adaptConnectMiddleware(connectMiddleware, middlewarePath) {
|
|
|
161
197
|
const httpMocks = await import("node-mocks-http");
|
|
162
198
|
createRequest = httpMocks.createRequest;
|
|
163
199
|
createResponse = httpMocks.createResponse;
|
|
164
|
-
} catch (
|
|
165
|
-
|
|
166
|
-
"
|
|
200
|
+
} catch (error2) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
"\u274C Widget middleware dependencies not installed!\n\nTo use Connect middleware adapters with MCP widgets, you need to install:\n\n npm install node-mocks-http\n # or\n pnpm add node-mocks-http\n\nThis dependency is automatically included in projects created with 'create-mcp-use-app'."
|
|
167
203
|
);
|
|
168
|
-
throw error;
|
|
169
204
|
}
|
|
170
205
|
let normalizedPath = middlewarePath;
|
|
171
206
|
if (normalizedPath.endsWith("*")) {
|
|
@@ -263,16 +298,16 @@ async function adaptConnectMiddleware(connectMiddleware, middlewarePath) {
|
|
|
263
298
|
__name(adaptConnectMiddleware, "adaptConnectMiddleware");
|
|
264
299
|
|
|
265
300
|
// src/server/logging.ts
|
|
266
|
-
var
|
|
267
|
-
function
|
|
268
|
-
if (
|
|
301
|
+
var isDeno2 = typeof globalThis.Deno !== "undefined";
|
|
302
|
+
function getEnv2(key) {
|
|
303
|
+
if (isDeno2) {
|
|
269
304
|
return globalThis.Deno.env.get(key);
|
|
270
305
|
}
|
|
271
306
|
return typeof process !== "undefined" && process.env ? process.env[key] : void 0;
|
|
272
307
|
}
|
|
273
|
-
__name(
|
|
308
|
+
__name(getEnv2, "getEnv");
|
|
274
309
|
function isDebugMode() {
|
|
275
|
-
const debugEnv =
|
|
310
|
+
const debugEnv = getEnv2("DEBUG");
|
|
276
311
|
return debugEnv !== void 0 && debugEnv !== "" && debugEnv !== "0" && debugEnv.toLowerCase() !== "false";
|
|
277
312
|
}
|
|
278
313
|
__name(isDebugMode, "isDebugMode");
|
|
@@ -378,7 +413,7 @@ async function requestLogger(c, next) {
|
|
|
378
413
|
} else {
|
|
379
414
|
console.log("\x1B[33mResponse Body:\x1B[0m (no body)");
|
|
380
415
|
}
|
|
381
|
-
} catch (
|
|
416
|
+
} catch (error2) {
|
|
382
417
|
console.log("\x1B[33mResponse Body:\x1B[0m (unable to read)");
|
|
383
418
|
}
|
|
384
419
|
console.log("\x1B[36m" + "=".repeat(80) + "\x1B[0m\n");
|
|
@@ -387,90 +422,7 @@ async function requestLogger(c, next) {
|
|
|
387
422
|
__name(requestLogger, "requestLogger");
|
|
388
423
|
|
|
389
424
|
// src/server/mcp-server.ts
|
|
390
|
-
function generateUUID() {
|
|
391
|
-
return globalThis.crypto.randomUUID();
|
|
392
|
-
}
|
|
393
|
-
__name(generateUUID, "generateUUID");
|
|
394
425
|
var TMP_MCP_USE_DIR = ".mcp-use";
|
|
395
|
-
var isDeno2 = typeof globalThis.Deno !== "undefined";
|
|
396
|
-
function getEnv2(key) {
|
|
397
|
-
if (isDeno2) {
|
|
398
|
-
return globalThis.Deno.env.get(key);
|
|
399
|
-
}
|
|
400
|
-
return process.env[key];
|
|
401
|
-
}
|
|
402
|
-
__name(getEnv2, "getEnv");
|
|
403
|
-
function getCwd() {
|
|
404
|
-
if (isDeno2) {
|
|
405
|
-
return globalThis.Deno.cwd();
|
|
406
|
-
}
|
|
407
|
-
return process.cwd();
|
|
408
|
-
}
|
|
409
|
-
__name(getCwd, "getCwd");
|
|
410
|
-
var fsHelpers = {
|
|
411
|
-
async readFileSync(path, encoding = "utf8") {
|
|
412
|
-
if (isDeno2) {
|
|
413
|
-
return await globalThis.Deno.readTextFile(path);
|
|
414
|
-
}
|
|
415
|
-
const { readFileSync } = await import("fs");
|
|
416
|
-
const result = readFileSync(path, encoding);
|
|
417
|
-
return typeof result === "string" ? result : result.toString(encoding);
|
|
418
|
-
},
|
|
419
|
-
async readFile(path) {
|
|
420
|
-
if (isDeno2) {
|
|
421
|
-
const data = await globalThis.Deno.readFile(path);
|
|
422
|
-
return data.buffer;
|
|
423
|
-
}
|
|
424
|
-
const { readFileSync } = await import("fs");
|
|
425
|
-
const buffer = readFileSync(path);
|
|
426
|
-
return buffer.buffer.slice(
|
|
427
|
-
buffer.byteOffset,
|
|
428
|
-
buffer.byteOffset + buffer.byteLength
|
|
429
|
-
);
|
|
430
|
-
},
|
|
431
|
-
async existsSync(path) {
|
|
432
|
-
if (isDeno2) {
|
|
433
|
-
try {
|
|
434
|
-
await globalThis.Deno.stat(path);
|
|
435
|
-
return true;
|
|
436
|
-
} catch {
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
const { existsSync } = await import("fs");
|
|
441
|
-
return existsSync(path);
|
|
442
|
-
},
|
|
443
|
-
async readdirSync(path) {
|
|
444
|
-
if (isDeno2) {
|
|
445
|
-
const entries = [];
|
|
446
|
-
for await (const entry of globalThis.Deno.readDir(path)) {
|
|
447
|
-
entries.push(entry.name);
|
|
448
|
-
}
|
|
449
|
-
return entries;
|
|
450
|
-
}
|
|
451
|
-
const { readdirSync } = await import("fs");
|
|
452
|
-
return readdirSync(path);
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
var pathHelpers = {
|
|
456
|
-
join(...paths) {
|
|
457
|
-
if (isDeno2) {
|
|
458
|
-
return paths.join("/").replace(/\/+/g, "/");
|
|
459
|
-
}
|
|
460
|
-
return paths.join("/").replace(/\/+/g, "/");
|
|
461
|
-
},
|
|
462
|
-
relative(from, to) {
|
|
463
|
-
const fromParts = from.split("/").filter((p) => p);
|
|
464
|
-
const toParts = to.split("/").filter((p) => p);
|
|
465
|
-
let i = 0;
|
|
466
|
-
while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {
|
|
467
|
-
i++;
|
|
468
|
-
}
|
|
469
|
-
const upCount = fromParts.length - i;
|
|
470
|
-
const relativeParts = [...Array(upCount).fill(".."), ...toParts.slice(i)];
|
|
471
|
-
return relativeParts.join("/");
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
426
|
var McpServer = class {
|
|
475
427
|
static {
|
|
476
428
|
__name(this, "McpServer");
|
|
@@ -489,6 +441,13 @@ var McpServer = class {
|
|
|
489
441
|
buildId;
|
|
490
442
|
sessions = /* @__PURE__ */ new Map();
|
|
491
443
|
idleCleanupInterval;
|
|
444
|
+
oauthProvider;
|
|
445
|
+
// OAuthProvider from oauth/index.js
|
|
446
|
+
oauthMiddleware;
|
|
447
|
+
// Bearer auth middleware
|
|
448
|
+
oauthConfig;
|
|
449
|
+
// Store OAuth config for lazy initialization
|
|
450
|
+
oauthSetupComplete = false;
|
|
492
451
|
/**
|
|
493
452
|
* Creates a new MCP server instance with Hono integration
|
|
494
453
|
*
|
|
@@ -527,6 +486,9 @@ var McpServer = class {
|
|
|
527
486
|
})
|
|
528
487
|
);
|
|
529
488
|
this.app.use("*", requestLogger);
|
|
489
|
+
if (config.oauth) {
|
|
490
|
+
this.oauthConfig = config.oauth;
|
|
491
|
+
}
|
|
530
492
|
return new Proxy(this, {
|
|
531
493
|
get(target, prop) {
|
|
532
494
|
if (prop === "use") {
|
|
@@ -586,7 +548,7 @@ var McpServer = class {
|
|
|
586
548
|
if (this.serverBaseUrl) {
|
|
587
549
|
return this.serverBaseUrl;
|
|
588
550
|
}
|
|
589
|
-
const mcpUrl =
|
|
551
|
+
const mcpUrl = getEnv("MCP_URL");
|
|
590
552
|
if (mcpUrl) {
|
|
591
553
|
return mcpUrl;
|
|
592
554
|
}
|
|
@@ -598,7 +560,7 @@ var McpServer = class {
|
|
|
598
560
|
* @returns Array of URLs to add to CSP resource_domains
|
|
599
561
|
*/
|
|
600
562
|
getCSPUrls() {
|
|
601
|
-
const cspUrlsEnv =
|
|
563
|
+
const cspUrlsEnv = getEnv("CSP_URLS");
|
|
602
564
|
if (!cspUrlsEnv) {
|
|
603
565
|
console.log("[CSP] No CSP_URLS environment variable found");
|
|
604
566
|
return [];
|
|
@@ -607,6 +569,42 @@ var McpServer = class {
|
|
|
607
569
|
console.log("[CSP] Parsed CSP URLs:", urls);
|
|
608
570
|
return urls;
|
|
609
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Setup OAuth authentication
|
|
574
|
+
*
|
|
575
|
+
* Initializes OAuth provider, creates bearer auth middleware,
|
|
576
|
+
* sets up OAuth routes, and applies auth to /mcp endpoints.
|
|
577
|
+
*
|
|
578
|
+
* @private
|
|
579
|
+
*/
|
|
580
|
+
async setupOAuth(oauthProvider) {
|
|
581
|
+
if (this.oauthSetupComplete) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
const { setupOAuthRoutes, createBearerAuthMiddleware } = await import("../../oauth-U4NNKN4B.js");
|
|
585
|
+
this.oauthProvider = oauthProvider;
|
|
586
|
+
console.log(`[OAuth] OAuth provider initialized`);
|
|
587
|
+
const baseUrl = this.getServerBaseUrl();
|
|
588
|
+
this.oauthMiddleware = createBearerAuthMiddleware(
|
|
589
|
+
this.oauthProvider,
|
|
590
|
+
baseUrl
|
|
591
|
+
);
|
|
592
|
+
setupOAuthRoutes(this.app, this.oauthProvider, baseUrl);
|
|
593
|
+
const mode = this.oauthProvider.getMode?.() || "proxy";
|
|
594
|
+
if (mode === "direct") {
|
|
595
|
+
console.log(
|
|
596
|
+
"[OAuth] Direct mode: Clients will authenticate with provider directly"
|
|
597
|
+
);
|
|
598
|
+
console.log("[OAuth] Metadata endpoints: /.well-known/*");
|
|
599
|
+
} else {
|
|
600
|
+
console.log(
|
|
601
|
+
"[OAuth] Proxy mode: Routes at /authorize, /token, /.well-known/*"
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
this.app.use("/mcp/*", this.oauthMiddleware);
|
|
605
|
+
console.log("[OAuth] Bearer authentication enabled on /mcp routes");
|
|
606
|
+
this.oauthSetupComplete = true;
|
|
607
|
+
}
|
|
610
608
|
/**
|
|
611
609
|
* Define a static resource that can be accessed by clients
|
|
612
610
|
*
|
|
@@ -733,46 +731,22 @@ var McpServer = class {
|
|
|
733
731
|
this.registeredResources.push(resourceTemplateDefinition.name);
|
|
734
732
|
return this;
|
|
735
733
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
*
|
|
753
|
-
* @example
|
|
754
|
-
* ```typescript
|
|
755
|
-
* server.tool({
|
|
756
|
-
* name: 'calculate',
|
|
757
|
-
* description: 'Performs mathematical calculations',
|
|
758
|
-
* inputs: [
|
|
759
|
-
* { name: 'expression', type: 'string', required: true },
|
|
760
|
-
* { name: 'precision', type: 'number', required: false }
|
|
761
|
-
* ],
|
|
762
|
-
* cb: async ({ expression, precision = 2 }) => {
|
|
763
|
-
* const result = eval(expression)
|
|
764
|
-
* return { result: Number(result.toFixed(precision)) }
|
|
765
|
-
* },
|
|
766
|
-
* _meta: {
|
|
767
|
-
* 'openai/outputTemplate': 'ui://widgets/calculator',
|
|
768
|
-
* 'openai/toolInvocation/invoking': 'Calculating...',
|
|
769
|
-
* 'openai/toolInvocation/invoked': 'Calculation complete'
|
|
770
|
-
* }
|
|
771
|
-
* })
|
|
772
|
-
* ```
|
|
773
|
-
*/
|
|
774
|
-
tool(toolDefinition) {
|
|
775
|
-
const inputSchema = this.createParamsSchema(toolDefinition.inputs || []);
|
|
734
|
+
// Implementation
|
|
735
|
+
tool(toolDefinition, callback) {
|
|
736
|
+
const actualCallback = callback || toolDefinition.cb;
|
|
737
|
+
if (!actualCallback) {
|
|
738
|
+
throw new Error(
|
|
739
|
+
`Tool '${toolDefinition.name}' must have either a cb property or a callback parameter`
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
let inputSchema;
|
|
743
|
+
if (toolDefinition.schema) {
|
|
744
|
+
inputSchema = this.convertZodSchemaToParams(toolDefinition.schema);
|
|
745
|
+
} else if (toolDefinition.inputs && toolDefinition.inputs.length > 0) {
|
|
746
|
+
inputSchema = this.createParamsSchema(toolDefinition.inputs);
|
|
747
|
+
} else {
|
|
748
|
+
inputSchema = {};
|
|
749
|
+
}
|
|
776
750
|
this.server.registerTool(
|
|
777
751
|
toolDefinition.name,
|
|
778
752
|
{
|
|
@@ -783,101 +757,95 @@ var McpServer = class {
|
|
|
783
757
|
_meta: toolDefinition._meta
|
|
784
758
|
},
|
|
785
759
|
async (params, extra) => {
|
|
760
|
+
let requestContext = getRequestContext();
|
|
761
|
+
if (!requestContext) {
|
|
762
|
+
for (const [, session] of this.sessions.entries()) {
|
|
763
|
+
if (session.context) {
|
|
764
|
+
requestContext = session.context;
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
786
769
|
const progressToken = extra?._meta?.progressToken;
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
onProgress
|
|
807
|
-
} = options ?? {};
|
|
808
|
-
let progressCount = 0;
|
|
809
|
-
let completed = false;
|
|
810
|
-
let progressInterval = null;
|
|
811
|
-
if (progressToken && extra?.sendNotification) {
|
|
812
|
-
progressInterval = setInterval(async () => {
|
|
813
|
-
if (completed) return;
|
|
814
|
-
progressCount++;
|
|
815
|
-
const progressData = {
|
|
816
|
-
progress: progressCount,
|
|
817
|
-
total: void 0,
|
|
818
|
-
message: `Waiting for LLM response... (${progressCount * Math.round(progressIntervalMs / 1e3)}s elapsed)`
|
|
819
|
-
};
|
|
820
|
-
if (onProgress) {
|
|
821
|
-
try {
|
|
822
|
-
onProgress(progressData);
|
|
823
|
-
} catch {
|
|
824
|
-
}
|
|
825
|
-
}
|
|
770
|
+
const enhancedContext = requestContext ? Object.create(requestContext) : {};
|
|
771
|
+
enhancedContext.sample = async (sampleParams, options) => {
|
|
772
|
+
const {
|
|
773
|
+
timeout,
|
|
774
|
+
progressIntervalMs = 5e3,
|
|
775
|
+
onProgress
|
|
776
|
+
} = options ?? {};
|
|
777
|
+
let progressCount = 0;
|
|
778
|
+
let completed = false;
|
|
779
|
+
let progressInterval = null;
|
|
780
|
+
if (progressToken && extra?.sendNotification) {
|
|
781
|
+
progressInterval = setInterval(async () => {
|
|
782
|
+
if (completed) return;
|
|
783
|
+
progressCount++;
|
|
784
|
+
const progressData = {
|
|
785
|
+
progress: progressCount,
|
|
786
|
+
total: void 0,
|
|
787
|
+
message: `Waiting for LLM response... (${progressCount * Math.round(progressIntervalMs / 1e3)}s elapsed)`
|
|
788
|
+
};
|
|
789
|
+
if (onProgress) {
|
|
826
790
|
try {
|
|
827
|
-
|
|
828
|
-
method: "notifications/progress",
|
|
829
|
-
params: {
|
|
830
|
-
progressToken,
|
|
831
|
-
progress: progressData.progress,
|
|
832
|
-
total: progressData.total,
|
|
833
|
-
message: progressData.message
|
|
834
|
-
}
|
|
835
|
-
});
|
|
791
|
+
onProgress(progressData);
|
|
836
792
|
} catch {
|
|
837
793
|
}
|
|
838
|
-
}, progressIntervalMs);
|
|
839
|
-
}
|
|
840
|
-
try {
|
|
841
|
-
const samplePromise = this.createMessage(sampleParams);
|
|
842
|
-
if (timeout && timeout !== Infinity) {
|
|
843
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
844
|
-
setTimeout(
|
|
845
|
-
() => reject(
|
|
846
|
-
new Error(`Sampling timed out after ${timeout}ms`)
|
|
847
|
-
),
|
|
848
|
-
timeout
|
|
849
|
-
);
|
|
850
|
-
});
|
|
851
|
-
return await Promise.race([samplePromise, timeoutPromise]);
|
|
852
794
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
795
|
+
try {
|
|
796
|
+
await extra.sendNotification({
|
|
797
|
+
method: "notifications/progress",
|
|
798
|
+
params: {
|
|
799
|
+
progressToken,
|
|
800
|
+
progress: progressData.progress,
|
|
801
|
+
total: progressData.total,
|
|
802
|
+
message: progressData.message
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
} catch {
|
|
858
806
|
}
|
|
807
|
+
}, progressIntervalMs);
|
|
808
|
+
}
|
|
809
|
+
try {
|
|
810
|
+
const samplePromise = this.createMessage(sampleParams);
|
|
811
|
+
if (timeout && timeout !== Infinity) {
|
|
812
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
813
|
+
setTimeout(
|
|
814
|
+
() => reject(new Error(`Sampling timed out after ${timeout}ms`)),
|
|
815
|
+
timeout
|
|
816
|
+
);
|
|
817
|
+
});
|
|
818
|
+
return await Promise.race([samplePromise, timeoutPromise]);
|
|
859
819
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
method: "notifications/progress",
|
|
868
|
-
params: {
|
|
869
|
-
progressToken,
|
|
870
|
-
progress,
|
|
871
|
-
total,
|
|
872
|
-
message
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
} : void 0
|
|
820
|
+
return await samplePromise;
|
|
821
|
+
} finally {
|
|
822
|
+
completed = true;
|
|
823
|
+
if (progressInterval) {
|
|
824
|
+
clearInterval(progressInterval);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
876
827
|
};
|
|
877
|
-
|
|
878
|
-
|
|
828
|
+
enhancedContext.reportProgress = progressToken && extra?.sendNotification ? async (progress, total, message) => {
|
|
829
|
+
await extra.sendNotification({
|
|
830
|
+
method: "notifications/progress",
|
|
831
|
+
params: {
|
|
832
|
+
progressToken,
|
|
833
|
+
progress,
|
|
834
|
+
total,
|
|
835
|
+
message
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
} : void 0;
|
|
839
|
+
const executeCallback = /* @__PURE__ */ __name(async () => {
|
|
840
|
+
if (actualCallback.length >= 2) {
|
|
841
|
+
return await actualCallback(params, enhancedContext);
|
|
842
|
+
}
|
|
843
|
+
return await actualCallback(params);
|
|
844
|
+
}, "executeCallback");
|
|
845
|
+
if (requestContext) {
|
|
846
|
+
return await runWithContext(requestContext, executeCallback);
|
|
879
847
|
}
|
|
880
|
-
return await
|
|
848
|
+
return await executeCallback();
|
|
881
849
|
}
|
|
882
850
|
);
|
|
883
851
|
this.registeredTools.push(toolDefinition.name);
|
|
@@ -925,6 +893,7 @@ var McpServer = class {
|
|
|
925
893
|
title: promptDefinition.title,
|
|
926
894
|
description: promptDefinition.description ?? "",
|
|
927
895
|
argsSchema
|
|
896
|
+
// Type assertion for Zod v4 compatibility
|
|
928
897
|
},
|
|
929
898
|
async (params) => {
|
|
930
899
|
return await promptDefinition.cb(params);
|
|
@@ -1228,35 +1197,6 @@ var McpServer = class {
|
|
|
1228
1197
|
}
|
|
1229
1198
|
return `ui://widget/${parts.join("-")}${extension}`;
|
|
1230
1199
|
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Build a complete URL for a widget including query parameters
|
|
1233
|
-
*
|
|
1234
|
-
* Constructs the full URL to access a widget's iframe, encoding any provided
|
|
1235
|
-
* parameters as query string parameters. Complex objects are JSON-stringified
|
|
1236
|
-
* for transmission.
|
|
1237
|
-
*
|
|
1238
|
-
* @private
|
|
1239
|
-
* @param widget - Widget name/identifier
|
|
1240
|
-
* @param params - Parameters to encode in the URL
|
|
1241
|
-
* @returns Complete URL with encoded parameters
|
|
1242
|
-
*/
|
|
1243
|
-
buildWidgetUrl(widget, params) {
|
|
1244
|
-
const baseUrl = `http://${this.serverHost}:${this.serverPort}/mcp-use/widgets/${widget}`;
|
|
1245
|
-
if (Object.keys(params).length === 0) {
|
|
1246
|
-
return baseUrl;
|
|
1247
|
-
}
|
|
1248
|
-
const queryParams = new URLSearchParams();
|
|
1249
|
-
for (const [key, value] of Object.entries(params)) {
|
|
1250
|
-
if (value !== void 0 && value !== null) {
|
|
1251
|
-
if (typeof value === "object") {
|
|
1252
|
-
queryParams.append(key, JSON.stringify(value));
|
|
1253
|
-
} else {
|
|
1254
|
-
queryParams.append(key, String(value));
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
return `${baseUrl}?${queryParams.toString()}`;
|
|
1259
|
-
}
|
|
1260
1200
|
/**
|
|
1261
1201
|
* Convert widget props definition to tool input schema
|
|
1262
1202
|
*
|
|
@@ -1304,7 +1244,7 @@ var McpServer = class {
|
|
|
1304
1244
|
* @returns true if in production mode, false otherwise
|
|
1305
1245
|
*/
|
|
1306
1246
|
isProductionMode() {
|
|
1307
|
-
return
|
|
1247
|
+
return getEnv("NODE_ENV") === "production";
|
|
1308
1248
|
}
|
|
1309
1249
|
/**
|
|
1310
1250
|
* Read build manifest file
|
|
@@ -1315,7 +1255,7 @@ var McpServer = class {
|
|
|
1315
1255
|
async readBuildManifest() {
|
|
1316
1256
|
try {
|
|
1317
1257
|
const manifestPath = pathHelpers.join(
|
|
1318
|
-
|
|
1258
|
+
isDeno ? "." : getCwd(),
|
|
1319
1259
|
"dist",
|
|
1320
1260
|
"mcp-use.json"
|
|
1321
1261
|
);
|
|
@@ -1337,7 +1277,7 @@ var McpServer = class {
|
|
|
1337
1277
|
* @returns Promise that resolves when all widgets are mounted
|
|
1338
1278
|
*/
|
|
1339
1279
|
async mountWidgets(options) {
|
|
1340
|
-
if (this.isProductionMode() ||
|
|
1280
|
+
if (this.isProductionMode() || isDeno) {
|
|
1341
1281
|
console.log("[WIDGETS] Mounting widgets in production mode");
|
|
1342
1282
|
await this.mountWidgetsProduction(options);
|
|
1343
1283
|
} else {
|
|
@@ -1365,7 +1305,7 @@ var McpServer = class {
|
|
|
1365
1305
|
const srcDir = pathHelpers.join(getCwd(), resourcesDir);
|
|
1366
1306
|
try {
|
|
1367
1307
|
await fs.access(srcDir);
|
|
1368
|
-
} catch (
|
|
1308
|
+
} catch (error2) {
|
|
1369
1309
|
console.log(
|
|
1370
1310
|
`[WIDGETS] No ${resourcesDir}/ directory found - skipping widget serving`
|
|
1371
1311
|
);
|
|
@@ -1399,7 +1339,7 @@ var McpServer = class {
|
|
|
1399
1339
|
}
|
|
1400
1340
|
}
|
|
1401
1341
|
}
|
|
1402
|
-
} catch (
|
|
1342
|
+
} catch (error2) {
|
|
1403
1343
|
console.log(`[WIDGETS] No widgets found in ${resourcesDir}/ directory`);
|
|
1404
1344
|
return;
|
|
1405
1345
|
}
|
|
@@ -1424,14 +1364,10 @@ var McpServer = class {
|
|
|
1424
1364
|
'return import("@tailwindcss/vite")'
|
|
1425
1365
|
)();
|
|
1426
1366
|
tailwindcss = tailwindModule.default;
|
|
1427
|
-
} catch (
|
|
1428
|
-
|
|
1429
|
-
"
|
|
1430
|
-
);
|
|
1431
|
-
console.error(
|
|
1432
|
-
"[WIDGETS] For production, use 'mcp-use build' to pre-build widgets."
|
|
1367
|
+
} catch (error2) {
|
|
1368
|
+
throw new Error(
|
|
1369
|
+
"\u274C Widget dependencies not installed!\n\nTo use MCP widgets with resources folder, you need to install the required dependencies:\n\n npm install vite @vitejs/plugin-react @tailwindcss/vite\n # or\n pnpm add vite @vitejs/plugin-react @tailwindcss/vite\n\nThese dependencies are automatically included in projects created with 'create-mcp-use-app'.\nFor production, pre-build your widgets using 'mcp-use build'."
|
|
1433
1370
|
);
|
|
1434
|
-
return;
|
|
1435
1371
|
}
|
|
1436
1372
|
const widgets = entries.map((entry) => {
|
|
1437
1373
|
return {
|
|
@@ -1440,8 +1376,8 @@ var McpServer = class {
|
|
|
1440
1376
|
entry: entry.path
|
|
1441
1377
|
};
|
|
1442
1378
|
});
|
|
1443
|
-
for (const
|
|
1444
|
-
const widgetTempDir = pathHelpers.join(tempDir,
|
|
1379
|
+
for (const widget2 of widgets) {
|
|
1380
|
+
const widgetTempDir = pathHelpers.join(tempDir, widget2.name);
|
|
1445
1381
|
await fs.mkdir(widgetTempDir, { recursive: true });
|
|
1446
1382
|
const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
|
|
1447
1383
|
const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
|
|
@@ -1458,7 +1394,7 @@ var McpServer = class {
|
|
|
1458
1394
|
const entryContent = `import React from 'react'
|
|
1459
1395
|
import { createRoot } from 'react-dom/client'
|
|
1460
1396
|
import './styles.css'
|
|
1461
|
-
import Component from '${
|
|
1397
|
+
import Component from '${widget2.entry}'
|
|
1462
1398
|
|
|
1463
1399
|
const container = document.getElementById('widget-root')
|
|
1464
1400
|
if (container && Component) {
|
|
@@ -1471,11 +1407,11 @@ if (container && Component) {
|
|
|
1471
1407
|
<head>
|
|
1472
1408
|
<meta charset="UTF-8" />
|
|
1473
1409
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
1474
|
-
<title>${
|
|
1410
|
+
<title>${widget2.name} Widget</title>
|
|
1475
1411
|
</head>
|
|
1476
1412
|
<body>
|
|
1477
1413
|
<div id="widget-root"></div>
|
|
1478
|
-
<script type="module" src="${baseRoute}/${
|
|
1414
|
+
<script type="module" src="${baseRoute}/${widget2.name}/entry.tsx"></script>
|
|
1479
1415
|
</body>
|
|
1480
1416
|
</html>`;
|
|
1481
1417
|
await fs.writeFile(
|
|
@@ -1565,8 +1501,8 @@ if (container && Component) {
|
|
|
1565
1501
|
const widgetMatch = pathname.replace(baseRoute, "").match(/^\/([^/]+)/);
|
|
1566
1502
|
if (widgetMatch) {
|
|
1567
1503
|
const widgetName = widgetMatch[1];
|
|
1568
|
-
const
|
|
1569
|
-
if (
|
|
1504
|
+
const widget2 = widgets.find((w) => w.name === widgetName);
|
|
1505
|
+
if (widget2) {
|
|
1570
1506
|
const relativePath = pathname.replace(baseRoute, "");
|
|
1571
1507
|
if (relativePath === `/${widgetName}` || relativePath === `/${widgetName}/`) {
|
|
1572
1508
|
const newUrl = new URL(c.req.url);
|
|
@@ -1617,42 +1553,42 @@ if (container && Component) {
|
|
|
1617
1553
|
const message = isAsset ? "Widget asset not found" : "Widget not found";
|
|
1618
1554
|
return c.text(message, 404);
|
|
1619
1555
|
});
|
|
1620
|
-
widgets.forEach((
|
|
1556
|
+
widgets.forEach((widget2) => {
|
|
1621
1557
|
console.log(
|
|
1622
|
-
`[WIDGET] ${
|
|
1558
|
+
`[WIDGET] ${widget2.name} mounted at ${baseRoute}/${widget2.name}`
|
|
1623
1559
|
);
|
|
1624
1560
|
});
|
|
1625
|
-
for (const
|
|
1561
|
+
for (const widget2 of widgets) {
|
|
1626
1562
|
const type = "appsSdk";
|
|
1627
1563
|
let metadata = {};
|
|
1628
1564
|
let props = {};
|
|
1629
|
-
let description =
|
|
1565
|
+
let description = widget2.description;
|
|
1630
1566
|
try {
|
|
1631
|
-
const mod = await viteServer.ssrLoadModule(
|
|
1567
|
+
const mod = await viteServer.ssrLoadModule(widget2.entry);
|
|
1632
1568
|
if (mod.widgetMetadata) {
|
|
1633
1569
|
metadata = mod.widgetMetadata;
|
|
1634
|
-
description = metadata.description ||
|
|
1570
|
+
description = metadata.description || widget2.description;
|
|
1635
1571
|
if (metadata.inputs) {
|
|
1636
1572
|
try {
|
|
1637
1573
|
props = metadata.inputs.shape || {};
|
|
1638
|
-
} catch (
|
|
1574
|
+
} catch (error2) {
|
|
1639
1575
|
console.warn(
|
|
1640
|
-
`[WIDGET] Failed to extract props schema for ${
|
|
1641
|
-
|
|
1576
|
+
`[WIDGET] Failed to extract props schema for ${widget2.name}:`,
|
|
1577
|
+
error2
|
|
1642
1578
|
);
|
|
1643
1579
|
}
|
|
1644
1580
|
}
|
|
1645
1581
|
}
|
|
1646
|
-
} catch (
|
|
1582
|
+
} catch (error2) {
|
|
1647
1583
|
console.warn(
|
|
1648
|
-
`[WIDGET] Failed to load metadata for ${
|
|
1649
|
-
|
|
1584
|
+
`[WIDGET] Failed to load metadata for ${widget2.name}:`,
|
|
1585
|
+
error2
|
|
1650
1586
|
);
|
|
1651
1587
|
}
|
|
1652
1588
|
let html = "";
|
|
1653
1589
|
try {
|
|
1654
1590
|
html = await fsHelpers.readFileSync(
|
|
1655
|
-
pathHelpers.join(tempDir,
|
|
1591
|
+
pathHelpers.join(tempDir, widget2.name, "index.html"),
|
|
1656
1592
|
"utf8"
|
|
1657
1593
|
);
|
|
1658
1594
|
const mcpUrl = this.getServerBaseUrl();
|
|
@@ -1690,25 +1626,25 @@ if (container && Component) {
|
|
|
1690
1626
|
html = html.replace(
|
|
1691
1627
|
/<head[^>]*>/i,
|
|
1692
1628
|
`<head>
|
|
1693
|
-
<script>window.__getFile = (filename) => { return "${baseUrl}/mcp-use/widgets/${
|
|
1629
|
+
<script>window.__getFile = (filename) => { return "${baseUrl}/mcp-use/widgets/${widget2.name}/"+filename }; window.__mcpPublicUrl = "${baseUrl}/mcp-use/public";</script>`
|
|
1694
1630
|
);
|
|
1695
|
-
} catch (
|
|
1631
|
+
} catch (error2) {
|
|
1696
1632
|
console.error(
|
|
1697
|
-
`Failed to read html template for widget ${
|
|
1698
|
-
|
|
1633
|
+
`Failed to read html template for widget ${widget2.name}`,
|
|
1634
|
+
error2
|
|
1699
1635
|
);
|
|
1700
1636
|
}
|
|
1701
1637
|
const mcp_connect_domain = this.getServerBaseUrl() ? new URL(this.getServerBaseUrl() || "").origin : null;
|
|
1702
1638
|
this.uiResource({
|
|
1703
|
-
name:
|
|
1704
|
-
title: metadata.title ||
|
|
1639
|
+
name: widget2.name,
|
|
1640
|
+
title: metadata.title || widget2.name,
|
|
1705
1641
|
description,
|
|
1706
1642
|
type,
|
|
1707
1643
|
props,
|
|
1708
1644
|
_meta: {
|
|
1709
1645
|
"mcp-use/widget": {
|
|
1710
|
-
name:
|
|
1711
|
-
title: metadata.title ||
|
|
1646
|
+
name: widget2.name,
|
|
1647
|
+
title: metadata.title || widget2.name,
|
|
1712
1648
|
description,
|
|
1713
1649
|
type,
|
|
1714
1650
|
props,
|
|
@@ -1720,8 +1656,8 @@ if (container && Component) {
|
|
|
1720
1656
|
htmlTemplate: html,
|
|
1721
1657
|
appsSdkMetadata: {
|
|
1722
1658
|
"openai/widgetDescription": description,
|
|
1723
|
-
"openai/toolInvocation/invoking": `Loading ${
|
|
1724
|
-
"openai/toolInvocation/invoked": `${
|
|
1659
|
+
"openai/toolInvocation/invoking": `Loading ${widget2.name}...`,
|
|
1660
|
+
"openai/toolInvocation/invoked": `${widget2.name} ready`,
|
|
1725
1661
|
"openai/widgetAccessible": true,
|
|
1726
1662
|
"openai/resultCanProduceWidget": true,
|
|
1727
1663
|
...metadata.appsSdkMetadata || {},
|
|
@@ -1760,7 +1696,7 @@ if (container && Component) {
|
|
|
1760
1696
|
async mountWidgetsProduction(options) {
|
|
1761
1697
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
1762
1698
|
const widgetsDir = pathHelpers.join(
|
|
1763
|
-
|
|
1699
|
+
isDeno ? "." : getCwd(),
|
|
1764
1700
|
"dist",
|
|
1765
1701
|
"resources",
|
|
1766
1702
|
"widgets"
|
|
@@ -1794,10 +1730,10 @@ if (container && Component) {
|
|
|
1794
1730
|
} else {
|
|
1795
1731
|
console.log("[WIDGETS] No widgets found in manifest");
|
|
1796
1732
|
}
|
|
1797
|
-
} catch (
|
|
1733
|
+
} catch (error2) {
|
|
1798
1734
|
console.log(
|
|
1799
1735
|
"[WIDGETS] Could not read manifest file, falling back to directory listing:",
|
|
1800
|
-
|
|
1736
|
+
error2
|
|
1801
1737
|
);
|
|
1802
1738
|
try {
|
|
1803
1739
|
const allEntries = await fsHelpers.readdirSync(widgetsDir);
|
|
@@ -1862,10 +1798,10 @@ if (container && Component) {
|
|
|
1862
1798
|
<script>window.__getFile = (filename) => { return "${baseUrl}/mcp-use/widgets/${widgetName}/"+filename }; window.__mcpPublicUrl = "${baseUrl}/mcp-use/public";</script>`
|
|
1863
1799
|
);
|
|
1864
1800
|
}
|
|
1865
|
-
} catch (
|
|
1801
|
+
} catch (error2) {
|
|
1866
1802
|
console.error(
|
|
1867
1803
|
`[WIDGET] Failed to read ${widgetName}/index.html:`,
|
|
1868
|
-
|
|
1804
|
+
error2
|
|
1869
1805
|
);
|
|
1870
1806
|
continue;
|
|
1871
1807
|
}
|
|
@@ -1992,7 +1928,7 @@ if (container && Component) {
|
|
|
1992
1928
|
if (closeOldSessionId && this.sessions.has(closeOldSessionId)) {
|
|
1993
1929
|
try {
|
|
1994
1930
|
this.sessions.get(closeOldSessionId).transport.close();
|
|
1995
|
-
} catch (
|
|
1931
|
+
} catch (error2) {
|
|
1996
1932
|
}
|
|
1997
1933
|
this.sessions.delete(closeOldSessionId);
|
|
1998
1934
|
}
|
|
@@ -2123,7 +2059,7 @@ if (container && Component) {
|
|
|
2123
2059
|
if (now - session.lastAccessedAt > idleTimeoutMs) {
|
|
2124
2060
|
try {
|
|
2125
2061
|
session.transport.close();
|
|
2126
|
-
} catch (
|
|
2062
|
+
} catch (error2) {
|
|
2127
2063
|
}
|
|
2128
2064
|
this.sessions.delete(sessionId);
|
|
2129
2065
|
}
|
|
@@ -2221,7 +2157,7 @@ if (container && Component) {
|
|
|
2221
2157
|
getResponse: /* @__PURE__ */ __name(() => {
|
|
2222
2158
|
if (ended) {
|
|
2223
2159
|
if (responseBody.length > 0) {
|
|
2224
|
-
const body =
|
|
2160
|
+
const body = isDeno ? Buffer.concat(responseBody) : Buffer.concat(responseBody);
|
|
2225
2161
|
return new Response(body, {
|
|
2226
2162
|
status: statusCode,
|
|
2227
2163
|
headers
|
|
@@ -2279,19 +2215,23 @@ if (container && Component) {
|
|
|
2279
2215
|
}
|
|
2280
2216
|
}
|
|
2281
2217
|
if (sessionId && this.sessions.has(sessionId)) {
|
|
2282
|
-
this.sessions.get(sessionId)
|
|
2218
|
+
const session = this.sessions.get(sessionId);
|
|
2219
|
+
session.lastAccessedAt = Date.now();
|
|
2220
|
+
session.context = c;
|
|
2283
2221
|
}
|
|
2284
2222
|
if (expressRes._closeHandler) {
|
|
2285
2223
|
c.req.raw.signal?.addEventListener("abort", () => {
|
|
2286
2224
|
transport.close();
|
|
2287
2225
|
});
|
|
2288
2226
|
}
|
|
2289
|
-
await
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2227
|
+
await runWithContext(c, async () => {
|
|
2228
|
+
await this.waitForRequestComplete(
|
|
2229
|
+
transport,
|
|
2230
|
+
expressReq,
|
|
2231
|
+
expressRes,
|
|
2232
|
+
expressReq.body
|
|
2233
|
+
);
|
|
2234
|
+
});
|
|
2295
2235
|
const response = getResponse();
|
|
2296
2236
|
if (response) {
|
|
2297
2237
|
return response;
|
|
@@ -2529,12 +2469,15 @@ if (container && Component) {
|
|
|
2529
2469
|
console.log("");
|
|
2530
2470
|
}
|
|
2531
2471
|
async listen(port) {
|
|
2532
|
-
const portEnv =
|
|
2472
|
+
const portEnv = getEnv("PORT");
|
|
2533
2473
|
this.serverPort = port || (portEnv ? parseInt(portEnv, 10) : 3001);
|
|
2534
|
-
const hostEnv =
|
|
2474
|
+
const hostEnv = getEnv("HOST");
|
|
2535
2475
|
if (hostEnv) {
|
|
2536
2476
|
this.serverHost = hostEnv;
|
|
2537
2477
|
}
|
|
2478
|
+
if (this.oauthConfig && !this.oauthSetupComplete) {
|
|
2479
|
+
await this.setupOAuth(this.oauthConfig);
|
|
2480
|
+
}
|
|
2538
2481
|
await this.mountWidgets({
|
|
2539
2482
|
baseRoute: "/mcp-use/widgets",
|
|
2540
2483
|
resourcesDir: "resources"
|
|
@@ -2542,7 +2485,7 @@ if (container && Component) {
|
|
|
2542
2485
|
await this.mountMcp();
|
|
2543
2486
|
await this.mountInspector();
|
|
2544
2487
|
this.logRegisteredItems();
|
|
2545
|
-
if (
|
|
2488
|
+
if (isDeno) {
|
|
2546
2489
|
const corsHeaders = {
|
|
2547
2490
|
"Access-Control-Allow-Origin": "*",
|
|
2548
2491
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type"
|
|
@@ -2643,6 +2586,9 @@ if (container && Component) {
|
|
|
2643
2586
|
* ```
|
|
2644
2587
|
*/
|
|
2645
2588
|
async getHandler(options) {
|
|
2589
|
+
if (this.oauthConfig && !this.oauthSetupComplete) {
|
|
2590
|
+
await this.setupOAuth(this.oauthConfig);
|
|
2591
|
+
}
|
|
2646
2592
|
console.log("[MCP] Mounting widgets");
|
|
2647
2593
|
await this.mountWidgets({
|
|
2648
2594
|
baseRoute: "/mcp-use/widgets",
|
|
@@ -2746,10 +2692,10 @@ if (container && Component) {
|
|
|
2746
2692
|
for (const [sessionId, session] of this.sessions.entries()) {
|
|
2747
2693
|
try {
|
|
2748
2694
|
await session.transport.send(notification);
|
|
2749
|
-
} catch (
|
|
2695
|
+
} catch (error2) {
|
|
2750
2696
|
console.warn(
|
|
2751
2697
|
`[MCP] Failed to send notification to session ${sessionId}:`,
|
|
2752
|
-
|
|
2698
|
+
error2
|
|
2753
2699
|
);
|
|
2754
2700
|
}
|
|
2755
2701
|
}
|
|
@@ -2794,10 +2740,10 @@ if (container && Component) {
|
|
|
2794
2740
|
try {
|
|
2795
2741
|
await session.transport.send(notification);
|
|
2796
2742
|
return true;
|
|
2797
|
-
} catch (
|
|
2743
|
+
} catch (error2) {
|
|
2798
2744
|
console.warn(
|
|
2799
2745
|
`[MCP] Failed to send notification to session ${sessionId}:`,
|
|
2800
|
-
|
|
2746
|
+
error2
|
|
2801
2747
|
);
|
|
2802
2748
|
return false;
|
|
2803
2749
|
}
|
|
@@ -2865,10 +2811,10 @@ if (container && Component) {
|
|
|
2865
2811
|
return response.roots;
|
|
2866
2812
|
}
|
|
2867
2813
|
return [];
|
|
2868
|
-
} catch (
|
|
2814
|
+
} catch (error2) {
|
|
2869
2815
|
console.warn(
|
|
2870
2816
|
`[MCP] Failed to list roots from session ${sessionId}:`,
|
|
2871
|
-
|
|
2817
|
+
error2
|
|
2872
2818
|
);
|
|
2873
2819
|
return null;
|
|
2874
2820
|
}
|
|
@@ -2946,14 +2892,14 @@ if (container && Component) {
|
|
|
2946
2892
|
*/
|
|
2947
2893
|
setupWidgetRoutes() {
|
|
2948
2894
|
this.app.get("/mcp-use/widgets/:widget/assets/*", async (c) => {
|
|
2949
|
-
const
|
|
2895
|
+
const widget2 = c.req.param("widget");
|
|
2950
2896
|
const assetFile = c.req.path.split("/assets/")[1];
|
|
2951
2897
|
const assetPath = pathHelpers.join(
|
|
2952
2898
|
getCwd(),
|
|
2953
2899
|
"dist",
|
|
2954
2900
|
"resources",
|
|
2955
2901
|
"widgets",
|
|
2956
|
-
|
|
2902
|
+
widget2,
|
|
2957
2903
|
"assets",
|
|
2958
2904
|
assetFile
|
|
2959
2905
|
);
|
|
@@ -2982,10 +2928,10 @@ if (container && Component) {
|
|
|
2982
2928
|
);
|
|
2983
2929
|
try {
|
|
2984
2930
|
const widgets = await fsHelpers.readdirSync(widgetsDir);
|
|
2985
|
-
for (const
|
|
2931
|
+
for (const widget2 of widgets) {
|
|
2986
2932
|
const assetPath = pathHelpers.join(
|
|
2987
2933
|
widgetsDir,
|
|
2988
|
-
|
|
2934
|
+
widget2,
|
|
2989
2935
|
"assets",
|
|
2990
2936
|
assetFile
|
|
2991
2937
|
);
|
|
@@ -3005,13 +2951,13 @@ if (container && Component) {
|
|
|
3005
2951
|
}
|
|
3006
2952
|
});
|
|
3007
2953
|
this.app.get("/mcp-use/widgets/:widget", async (c) => {
|
|
3008
|
-
const
|
|
2954
|
+
const widget2 = c.req.param("widget");
|
|
3009
2955
|
const filePath = pathHelpers.join(
|
|
3010
2956
|
getCwd(),
|
|
3011
2957
|
"dist",
|
|
3012
2958
|
"resources",
|
|
3013
2959
|
"widgets",
|
|
3014
|
-
|
|
2960
|
+
widget2,
|
|
3015
2961
|
"index.html"
|
|
3016
2962
|
);
|
|
3017
2963
|
try {
|
|
@@ -3028,7 +2974,7 @@ if (container && Component) {
|
|
|
3028
2974
|
html = html.replace(
|
|
3029
2975
|
/<head[^>]*>/i,
|
|
3030
2976
|
`<head>
|
|
3031
|
-
<script>window.__getFile = (filename) => { return "${baseUrl}/mcp-use/widgets/${
|
|
2977
|
+
<script>window.__getFile = (filename) => { return "${baseUrl}/mcp-use/widgets/${widget2}/"+filename }</script>`
|
|
3032
2978
|
);
|
|
3033
2979
|
return c.html(html);
|
|
3034
2980
|
} catch {
|
|
@@ -3055,28 +3001,21 @@ if (container && Component) {
|
|
|
3055
3001
|
});
|
|
3056
3002
|
}
|
|
3057
3003
|
/**
|
|
3058
|
-
*
|
|
3004
|
+
* Convert a Zod object schema to the internal Record<string, z.ZodSchema> format
|
|
3059
3005
|
*
|
|
3060
|
-
*
|
|
3061
|
-
*
|
|
3062
|
-
* template parameters before processing requests.
|
|
3063
|
-
*
|
|
3064
|
-
* @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
|
|
3065
|
-
* @returns Object mapping parameter names to Zod string schemas
|
|
3066
|
-
*
|
|
3067
|
-
* @example
|
|
3068
|
-
* ```typescript
|
|
3069
|
-
* const schema = this.createInputSchema("/users/{id}/posts/{postId}")
|
|
3070
|
-
* // Returns: { id: z.string(), postId: z.string() }
|
|
3071
|
-
* ```
|
|
3006
|
+
* @param zodSchema - Zod object schema to convert
|
|
3007
|
+
* @returns Object mapping parameter names to Zod validation schemas
|
|
3072
3008
|
*/
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
}
|
|
3079
|
-
|
|
3009
|
+
convertZodSchemaToParams(zodSchema) {
|
|
3010
|
+
if (!(zodSchema instanceof z.ZodObject)) {
|
|
3011
|
+
throw new Error("schema must be a Zod object schema (z.object({...}))");
|
|
3012
|
+
}
|
|
3013
|
+
const shape = zodSchema.shape;
|
|
3014
|
+
const params = {};
|
|
3015
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
3016
|
+
params[key] = value;
|
|
3017
|
+
}
|
|
3018
|
+
return params;
|
|
3080
3019
|
}
|
|
3081
3020
|
/**
|
|
3082
3021
|
* Create input schema for tools
|
|
@@ -3130,75 +3069,6 @@ if (container && Component) {
|
|
|
3130
3069
|
});
|
|
3131
3070
|
return schema;
|
|
3132
3071
|
}
|
|
3133
|
-
/**
|
|
3134
|
-
* Create arguments schema for prompts
|
|
3135
|
-
*
|
|
3136
|
-
* Converts prompt argument definitions into Zod validation schemas for runtime validation.
|
|
3137
|
-
* Supports common data types (string, number, boolean, object, array) and optional
|
|
3138
|
-
* parameters. Used internally when registering prompt templates with the MCP server.
|
|
3139
|
-
*
|
|
3140
|
-
* @param inputs - Array of argument definitions with name, type, and optional flag
|
|
3141
|
-
* @returns Object mapping argument names to Zod validation schemas
|
|
3142
|
-
*
|
|
3143
|
-
* @example
|
|
3144
|
-
* ```typescript
|
|
3145
|
-
* const schema = this.createPromptArgsSchema([
|
|
3146
|
-
* { name: 'topic', type: 'string', required: true },
|
|
3147
|
-
* { name: 'style', type: 'string', required: false }
|
|
3148
|
-
* ])
|
|
3149
|
-
* // Returns: { topic: z.string(), style: z.string().optional() }
|
|
3150
|
-
* ```
|
|
3151
|
-
*/
|
|
3152
|
-
createPromptArgsSchema(inputs) {
|
|
3153
|
-
const schema = {};
|
|
3154
|
-
inputs.forEach((input) => {
|
|
3155
|
-
let zodType;
|
|
3156
|
-
switch (input.type) {
|
|
3157
|
-
case "string":
|
|
3158
|
-
zodType = z.string();
|
|
3159
|
-
break;
|
|
3160
|
-
case "number":
|
|
3161
|
-
zodType = z.number();
|
|
3162
|
-
break;
|
|
3163
|
-
case "boolean":
|
|
3164
|
-
zodType = z.boolean();
|
|
3165
|
-
break;
|
|
3166
|
-
case "object":
|
|
3167
|
-
zodType = z.object({});
|
|
3168
|
-
break;
|
|
3169
|
-
case "array":
|
|
3170
|
-
zodType = z.array(z.any());
|
|
3171
|
-
break;
|
|
3172
|
-
default:
|
|
3173
|
-
zodType = z.any();
|
|
3174
|
-
}
|
|
3175
|
-
if (!input.required) {
|
|
3176
|
-
zodType = zodType.optional();
|
|
3177
|
-
}
|
|
3178
|
-
schema[input.name] = zodType;
|
|
3179
|
-
});
|
|
3180
|
-
return schema;
|
|
3181
|
-
}
|
|
3182
|
-
/**
|
|
3183
|
-
* Extract parameter names from URI template
|
|
3184
|
-
*
|
|
3185
|
-
* Parses a URI template string to extract parameter names enclosed in curly braces.
|
|
3186
|
-
* Used internally to identify dynamic parameters in resource templates and generate
|
|
3187
|
-
* appropriate validation schemas.
|
|
3188
|
-
*
|
|
3189
|
-
* @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
|
|
3190
|
-
* @returns Array of parameter names found in the template
|
|
3191
|
-
*
|
|
3192
|
-
* @example
|
|
3193
|
-
* ```typescript
|
|
3194
|
-
* const params = this.extractTemplateParams("/users/{id}/posts/{postId}")
|
|
3195
|
-
* // Returns: ["id", "postId"]
|
|
3196
|
-
* ```
|
|
3197
|
-
*/
|
|
3198
|
-
extractTemplateParams(uriTemplate) {
|
|
3199
|
-
const matches = uriTemplate.match(/\{([^}]+)\}/g);
|
|
3200
|
-
return matches ? matches.map((match) => match.slice(1, -1)) : [];
|
|
3201
|
-
}
|
|
3202
3072
|
/**
|
|
3203
3073
|
* Parse parameter values from a URI based on a template
|
|
3204
3074
|
*
|
|
@@ -3241,19 +3111,155 @@ function createMCPServer(name, config = {}) {
|
|
|
3241
3111
|
host: config.host,
|
|
3242
3112
|
baseUrl: config.baseUrl,
|
|
3243
3113
|
allowedOrigins: config.allowedOrigins,
|
|
3244
|
-
sessionIdleTimeoutMs: config.sessionIdleTimeoutMs
|
|
3114
|
+
sessionIdleTimeoutMs: config.sessionIdleTimeoutMs,
|
|
3115
|
+
autoCreateSessionOnInvalidId: config.autoCreateSessionOnInvalidId,
|
|
3116
|
+
oauth: config.oauth
|
|
3245
3117
|
});
|
|
3246
3118
|
return instance;
|
|
3247
3119
|
}
|
|
3248
3120
|
__name(createMCPServer, "createMCPServer");
|
|
3121
|
+
|
|
3122
|
+
// src/server/utils/response-helpers.ts
|
|
3123
|
+
function text(content) {
|
|
3124
|
+
return {
|
|
3125
|
+
content: [
|
|
3126
|
+
{
|
|
3127
|
+
type: "text",
|
|
3128
|
+
text: content
|
|
3129
|
+
}
|
|
3130
|
+
]
|
|
3131
|
+
};
|
|
3132
|
+
}
|
|
3133
|
+
__name(text, "text");
|
|
3134
|
+
function image(data, mimeType = "image/png") {
|
|
3135
|
+
return {
|
|
3136
|
+
content: [
|
|
3137
|
+
{
|
|
3138
|
+
type: "image",
|
|
3139
|
+
data,
|
|
3140
|
+
mimeType
|
|
3141
|
+
}
|
|
3142
|
+
]
|
|
3143
|
+
};
|
|
3144
|
+
}
|
|
3145
|
+
__name(image, "image");
|
|
3146
|
+
function resource(uri, mimeType, text2) {
|
|
3147
|
+
const resourceContent = {
|
|
3148
|
+
type: "resource",
|
|
3149
|
+
resource: {
|
|
3150
|
+
uri,
|
|
3151
|
+
...mimeType && { mimeType },
|
|
3152
|
+
...text2 && { text: text2 }
|
|
3153
|
+
}
|
|
3154
|
+
};
|
|
3155
|
+
return {
|
|
3156
|
+
content: [resourceContent]
|
|
3157
|
+
};
|
|
3158
|
+
}
|
|
3159
|
+
__name(resource, "resource");
|
|
3160
|
+
function error(message) {
|
|
3161
|
+
return {
|
|
3162
|
+
isError: true,
|
|
3163
|
+
content: [
|
|
3164
|
+
{
|
|
3165
|
+
type: "text",
|
|
3166
|
+
text: message
|
|
3167
|
+
}
|
|
3168
|
+
]
|
|
3169
|
+
};
|
|
3170
|
+
}
|
|
3171
|
+
__name(error, "error");
|
|
3172
|
+
function object(data) {
|
|
3173
|
+
return Array.isArray(data) ? array(data) : {
|
|
3174
|
+
content: [
|
|
3175
|
+
{
|
|
3176
|
+
type: "text",
|
|
3177
|
+
text: JSON.stringify(data, null, 2)
|
|
3178
|
+
}
|
|
3179
|
+
],
|
|
3180
|
+
structuredContent: data
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3183
|
+
__name(object, "object");
|
|
3184
|
+
function array(data) {
|
|
3185
|
+
return {
|
|
3186
|
+
content: [
|
|
3187
|
+
{
|
|
3188
|
+
type: "text",
|
|
3189
|
+
text: JSON.stringify(data, null, 2)
|
|
3190
|
+
}
|
|
3191
|
+
],
|
|
3192
|
+
structuredContent: { data }
|
|
3193
|
+
};
|
|
3194
|
+
}
|
|
3195
|
+
__name(array, "array");
|
|
3196
|
+
function widget(config) {
|
|
3197
|
+
const {
|
|
3198
|
+
name,
|
|
3199
|
+
data,
|
|
3200
|
+
message,
|
|
3201
|
+
invoking,
|
|
3202
|
+
invoked,
|
|
3203
|
+
widgetAccessible = true,
|
|
3204
|
+
resultCanProduceWidget = true,
|
|
3205
|
+
buildId
|
|
3206
|
+
} = config;
|
|
3207
|
+
const randomId = Math.random().toString(36).substring(2, 15);
|
|
3208
|
+
const buildIdPart = buildId ? `-${buildId}` : "";
|
|
3209
|
+
const uniqueUri = `ui://widget/${name}${buildIdPart}-${randomId}.html`;
|
|
3210
|
+
const metadata = {
|
|
3211
|
+
"openai/outputTemplate": uniqueUri,
|
|
3212
|
+
"openai/widgetAccessible": widgetAccessible,
|
|
3213
|
+
"openai/resultCanProduceWidget": resultCanProduceWidget
|
|
3214
|
+
};
|
|
3215
|
+
if (invoking) {
|
|
3216
|
+
metadata["openai/toolInvocation/invoking"] = invoking;
|
|
3217
|
+
}
|
|
3218
|
+
if (invoked) {
|
|
3219
|
+
metadata["openai/toolInvocation/invoked"] = invoked;
|
|
3220
|
+
}
|
|
3221
|
+
const displayMessage = message || `Displaying ${name}`;
|
|
3222
|
+
return {
|
|
3223
|
+
_meta: metadata,
|
|
3224
|
+
content: [
|
|
3225
|
+
{
|
|
3226
|
+
type: "text",
|
|
3227
|
+
text: displayMessage
|
|
3228
|
+
}
|
|
3229
|
+
],
|
|
3230
|
+
// structuredContent will be injected as window.openai.toolOutput by Apps SDK
|
|
3231
|
+
structuredContent: data
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
__name(widget, "widget");
|
|
3249
3235
|
export {
|
|
3250
3236
|
adaptConnectMiddleware,
|
|
3251
3237
|
adaptMiddleware,
|
|
3238
|
+
array,
|
|
3252
3239
|
buildWidgetUrl,
|
|
3253
3240
|
createExternalUrlResource,
|
|
3254
3241
|
createMCPServer,
|
|
3255
3242
|
createRawHtmlResource,
|
|
3256
3243
|
createRemoteDomResource,
|
|
3257
3244
|
createUIResourceFromDefinition,
|
|
3258
|
-
|
|
3245
|
+
error,
|
|
3246
|
+
getAuth,
|
|
3247
|
+
getRequestContext,
|
|
3248
|
+
hasAnyScope,
|
|
3249
|
+
hasRequestContext,
|
|
3250
|
+
hasScope,
|
|
3251
|
+
image,
|
|
3252
|
+
isExpressMiddleware,
|
|
3253
|
+
oauthAuth0Provider,
|
|
3254
|
+
oauthCustomProvider,
|
|
3255
|
+
oauthKeycloakProvider,
|
|
3256
|
+
oauthSupabaseProvider,
|
|
3257
|
+
oauthWorkOSProvider,
|
|
3258
|
+
object,
|
|
3259
|
+
requireAnyScope,
|
|
3260
|
+
requireScope,
|
|
3261
|
+
resource,
|
|
3262
|
+
runWithContext,
|
|
3263
|
+
text,
|
|
3264
|
+
widget
|
|
3259
3265
|
};
|