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/index.cjs
CHANGED
|
@@ -335,13 +335,13 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
|
|
|
335
335
|
metadataProvider;
|
|
336
336
|
tagsProvider;
|
|
337
337
|
verbose;
|
|
338
|
-
constructor(
|
|
339
|
-
super(
|
|
338
|
+
constructor(config2, agentId2, metadata2, metadataProvider2, tagsProvider2) {
|
|
339
|
+
super(config2);
|
|
340
340
|
this.agentId = agentId2;
|
|
341
341
|
this.metadata = metadata2;
|
|
342
342
|
this.metadataProvider = metadataProvider2;
|
|
343
343
|
this.tagsProvider = tagsProvider2;
|
|
344
|
-
this.verbose =
|
|
344
|
+
this.verbose = config2?.verbose ?? false;
|
|
345
345
|
}
|
|
346
346
|
// Override to add custom metadata to traces
|
|
347
347
|
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata2, name, kwargs) {
|
|
@@ -466,7 +466,7 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
|
|
|
466
466
|
}
|
|
467
467
|
const initialMetadata = metadata || (metadataProvider ? metadataProvider() : {});
|
|
468
468
|
const initialTags = tagsProvider ? tagsProvider() : [];
|
|
469
|
-
const
|
|
469
|
+
const config = {
|
|
470
470
|
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
471
471
|
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
472
472
|
baseUrl: process.env.LANGFUSE_HOST || process.env.LANGFUSE_BASEURL || "https://cloud.langfuse.com",
|
|
@@ -491,17 +491,17 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
|
|
|
491
491
|
"Langfuse handler config:",
|
|
492
492
|
JSON.stringify(
|
|
493
493
|
{
|
|
494
|
-
traceName:
|
|
495
|
-
sessionId:
|
|
496
|
-
userId:
|
|
497
|
-
tags:
|
|
494
|
+
traceName: config.traceName,
|
|
495
|
+
sessionId: config.sessionId,
|
|
496
|
+
userId: config.userId,
|
|
497
|
+
tags: config.tags
|
|
498
498
|
},
|
|
499
499
|
null,
|
|
500
500
|
2
|
|
501
501
|
)
|
|
502
502
|
);
|
|
503
503
|
langfuseState.handler = new LoggingCallbackHandler(
|
|
504
|
-
|
|
504
|
+
config,
|
|
505
505
|
agentId,
|
|
506
506
|
metadata,
|
|
507
507
|
metadataProvider,
|
|
@@ -528,13 +528,11 @@ async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvi
|
|
|
528
528
|
logger.debug(`Langfuse initialization error: ${error}`);
|
|
529
529
|
}
|
|
530
530
|
}
|
|
531
|
-
var
|
|
531
|
+
var langfuseDisabled, langfuseState, langfuseHandler, langfuseClient, langfuseInitPromise;
|
|
532
532
|
var init_langfuse = __esm({
|
|
533
533
|
"src/observability/langfuse.ts"() {
|
|
534
534
|
"use strict";
|
|
535
|
-
import_dotenv = require("dotenv");
|
|
536
535
|
init_logging();
|
|
537
|
-
(0, import_dotenv.config)();
|
|
538
536
|
langfuseDisabled = process.env.MCP_USE_LANGFUSE?.toLowerCase() === "false";
|
|
539
537
|
langfuseState = {
|
|
540
538
|
handler: null,
|
|
@@ -573,8 +571,24 @@ __export(display_exports, {
|
|
|
573
571
|
renderContent: () => renderContent,
|
|
574
572
|
unwrapToolInput: () => unwrapToolInput
|
|
575
573
|
});
|
|
574
|
+
function highlightCode(content, language) {
|
|
575
|
+
if (!highlight) {
|
|
576
|
+
return content;
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
return highlight(content, {
|
|
580
|
+
language: language ?? "javascript",
|
|
581
|
+
ignoreIllegals: true
|
|
582
|
+
});
|
|
583
|
+
} catch {
|
|
584
|
+
return content;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
576
587
|
function stripAnsi(str) {
|
|
577
|
-
|
|
588
|
+
if (stripVTControlCharacters) {
|
|
589
|
+
return stripVTControlCharacters(str);
|
|
590
|
+
}
|
|
591
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
578
592
|
}
|
|
579
593
|
function wrapAnsiLine(line, maxWidth) {
|
|
580
594
|
const stripped = stripAnsi(line);
|
|
@@ -614,28 +628,28 @@ function printBox(content, title, language, bgColor = false) {
|
|
|
614
628
|
let displayContent = content;
|
|
615
629
|
if (language) {
|
|
616
630
|
try {
|
|
617
|
-
displayContent = (
|
|
631
|
+
displayContent = highlightCode(content, language);
|
|
618
632
|
} catch {
|
|
619
633
|
}
|
|
620
634
|
}
|
|
621
635
|
const lines = displayContent.split("\n").flatMap((line) => wrapAnsiLine(line, width - 4));
|
|
622
|
-
console.log(
|
|
636
|
+
console.log(chalkHelper.gray("\u250C" + "\u2500".repeat(width - 2) + "\u2510"));
|
|
623
637
|
if (title) {
|
|
624
638
|
const stripped = stripAnsi(title);
|
|
625
639
|
const lineText = `${title} `;
|
|
626
640
|
const padding = Math.max(0, width - 4 - stripped.length - 2);
|
|
627
641
|
console.log(
|
|
628
|
-
|
|
642
|
+
chalkHelper.gray("\u2502 ") + chalkHelper.bold.white(lineText) + " ".repeat(padding) + chalkHelper.gray(" \u2502")
|
|
629
643
|
);
|
|
630
|
-
console.log(
|
|
644
|
+
console.log(chalkHelper.gray("\u251C" + "\u2500".repeat(width - 2) + "\u2524"));
|
|
631
645
|
}
|
|
632
646
|
lines.forEach((line) => {
|
|
633
647
|
const stripped = stripAnsi(line);
|
|
634
648
|
const padding = Math.max(0, width - 4 - stripped.length);
|
|
635
|
-
const finalLine = bgColor ?
|
|
636
|
-
console.log(
|
|
649
|
+
const finalLine = bgColor ? chalkHelper.bgGray(line + " ".repeat(padding)) : line + " ".repeat(padding);
|
|
650
|
+
console.log(chalkHelper.gray("\u2502 ") + finalLine + chalkHelper.gray(" \u2502"));
|
|
637
651
|
});
|
|
638
|
-
console.log(
|
|
652
|
+
console.log(chalkHelper.gray("\u2514" + "\u2500".repeat(width - 2) + "\u2518"));
|
|
639
653
|
}
|
|
640
654
|
function extractCodeFromToolInput(input) {
|
|
641
655
|
if (typeof input === "object" && input !== null && "code" in input) {
|
|
@@ -774,7 +788,7 @@ ${noResultsMsg}`;
|
|
|
774
788
|
const isLastServer = i === servers.length - 1;
|
|
775
789
|
const serverPrefix = isLastServer ? "\u2514\u2500" : "\u251C\u2500";
|
|
776
790
|
lines.push(
|
|
777
|
-
`${serverPrefix} ${
|
|
791
|
+
`${serverPrefix} ${chalkHelper.cyan(server)} (${serverTools.length} tools)`
|
|
778
792
|
);
|
|
779
793
|
for (let j = 0; j < serverTools.length; j++) {
|
|
780
794
|
const tool = serverTools[j];
|
|
@@ -806,7 +820,7 @@ ${noResultsMsg}`;
|
|
|
806
820
|
wrappedLines.push(currentLine.trimEnd());
|
|
807
821
|
}
|
|
808
822
|
for (const descLine of wrappedLines) {
|
|
809
|
-
lines.push(`${descriptionIndent}${
|
|
823
|
+
lines.push(`${descriptionIndent}${chalkHelper.dim(descLine)}`);
|
|
810
824
|
}
|
|
811
825
|
}
|
|
812
826
|
}
|
|
@@ -833,7 +847,7 @@ function handleToolEnd(event) {
|
|
|
833
847
|
const timeMs = execResult2.execution_time ? Math.round(execResult2.execution_time * 1e3) : 0;
|
|
834
848
|
const timeStr = `${timeMs}ms`;
|
|
835
849
|
const isError2 = execResult2.error !== null && execResult2.error !== void 0 && execResult2.error !== "";
|
|
836
|
-
const statusText = isError2 ?
|
|
850
|
+
const statusText = isError2 ? chalkHelper.red("error") : chalkHelper.green("success");
|
|
837
851
|
const title2 = `${toolName} - ${statusText} - ${timeStr}`;
|
|
838
852
|
if (execResult2.result !== null && execResult2.result !== void 0) {
|
|
839
853
|
const resultStr = renderContent(execResult2.result);
|
|
@@ -846,7 +860,12 @@ function handleToolEnd(event) {
|
|
|
846
860
|
printBox(execResult2.logs.join("\n"), `Logs`, void 0, false);
|
|
847
861
|
}
|
|
848
862
|
if (execResult2.error) {
|
|
849
|
-
printBox(
|
|
863
|
+
printBox(
|
|
864
|
+
execResult2.error,
|
|
865
|
+
chalkHelper.red("Error"),
|
|
866
|
+
void 0,
|
|
867
|
+
false
|
|
868
|
+
);
|
|
850
869
|
}
|
|
851
870
|
return;
|
|
852
871
|
}
|
|
@@ -872,7 +891,7 @@ function handleToolEnd(event) {
|
|
|
872
891
|
const contentWithMeta = actualContent;
|
|
873
892
|
const meta = contentWithMeta.meta;
|
|
874
893
|
const treeStr = formatSearchToolsAsTree(results, meta, query);
|
|
875
|
-
const statusText = status === "success" ?
|
|
894
|
+
const statusText = status === "success" ? chalk.green("Success") : chalk.red("Error");
|
|
876
895
|
const title2 = `${statusText}: ${toolName} - Result`;
|
|
877
896
|
printBox(treeStr, title2, void 0, false);
|
|
878
897
|
return;
|
|
@@ -883,7 +902,7 @@ function handleToolEnd(event) {
|
|
|
883
902
|
void 0,
|
|
884
903
|
query
|
|
885
904
|
);
|
|
886
|
-
const statusText = status === "success" ?
|
|
905
|
+
const statusText = status === "success" ? chalk.green("Success") : chalk.red("Error");
|
|
887
906
|
const title2 = `${statusText}: ${toolName} - Result`;
|
|
888
907
|
printBox(treeStr, title2, void 0, false);
|
|
889
908
|
return;
|
|
@@ -902,7 +921,7 @@ function handleToolEnd(event) {
|
|
|
902
921
|
}
|
|
903
922
|
const contentStr = renderContent(displayContent);
|
|
904
923
|
const language2 = typeof displayContent === "object" ? "json" : void 0;
|
|
905
|
-
const statusLabel = status === "success" ?
|
|
924
|
+
const statusLabel = status === "success" ? chalkHelper.green("Success") : isError ? chalkHelper.red("Error") : "Result";
|
|
906
925
|
const title = `${statusLabel}: ${toolName} - Result`;
|
|
907
926
|
printBox(contentStr, title, language2, false);
|
|
908
927
|
return;
|
|
@@ -920,7 +939,7 @@ function handleToolEnd(event) {
|
|
|
920
939
|
printBox(execResult.logs.join("\n"), `Logs`, void 0, false);
|
|
921
940
|
}
|
|
922
941
|
if (execResult.error) {
|
|
923
|
-
printBox(execResult.error,
|
|
942
|
+
printBox(execResult.error, chalkHelper.red("Error"), void 0, false);
|
|
924
943
|
}
|
|
925
944
|
return;
|
|
926
945
|
}
|
|
@@ -960,14 +979,55 @@ async function* prettyStreamEvents(streamEventsGenerator) {
|
|
|
960
979
|
}
|
|
961
980
|
return finalResponse;
|
|
962
981
|
}
|
|
963
|
-
var
|
|
982
|
+
var chalk, highlight, stripVTControlCharacters, displayPackagesWarned, isNode, TERMINAL_WIDTH, chalkHelper;
|
|
964
983
|
var init_display = __esm({
|
|
965
984
|
"src/agents/display.ts"() {
|
|
966
985
|
"use strict";
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
986
|
+
chalk = null;
|
|
987
|
+
highlight = null;
|
|
988
|
+
stripVTControlCharacters = null;
|
|
989
|
+
displayPackagesWarned = false;
|
|
990
|
+
isNode = typeof process !== "undefined" && process.versions?.node;
|
|
991
|
+
(async () => {
|
|
992
|
+
if (isNode) {
|
|
993
|
+
try {
|
|
994
|
+
const utilModule = await import("util");
|
|
995
|
+
stripVTControlCharacters = utilModule.stripVTControlCharacters;
|
|
996
|
+
} catch {
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
try {
|
|
1000
|
+
const chalkModule = await import("chalk");
|
|
1001
|
+
chalk = chalkModule.default;
|
|
1002
|
+
} catch {
|
|
1003
|
+
}
|
|
1004
|
+
try {
|
|
1005
|
+
const cliHighlightModule = await import("cli-highlight");
|
|
1006
|
+
highlight = cliHighlightModule.highlight;
|
|
1007
|
+
} catch {
|
|
1008
|
+
}
|
|
1009
|
+
if (isNode && (!chalk || !highlight)) {
|
|
1010
|
+
if (!displayPackagesWarned) {
|
|
1011
|
+
displayPackagesWarned = true;
|
|
1012
|
+
console.warn(
|
|
1013
|
+
"\n\u2728 For enhanced console output with colors and syntax highlighting, install:\n\n npm install chalk cli-highlight\n # or\n pnpm add chalk cli-highlight\n"
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
})();
|
|
970
1018
|
TERMINAL_WIDTH = process.stdout.columns || 120;
|
|
1019
|
+
chalkHelper = {
|
|
1020
|
+
gray: /* @__PURE__ */ __name((str) => chalk?.gray(str) ?? str, "gray"),
|
|
1021
|
+
bold: {
|
|
1022
|
+
white: /* @__PURE__ */ __name((str) => chalk?.bold?.white(str) ?? str, "white")
|
|
1023
|
+
},
|
|
1024
|
+
bgGray: /* @__PURE__ */ __name((str) => chalk?.bgGray(str) ?? str, "bgGray"),
|
|
1025
|
+
cyan: /* @__PURE__ */ __name((str) => chalk?.cyan(str) ?? str, "cyan"),
|
|
1026
|
+
dim: /* @__PURE__ */ __name((str) => chalk?.dim(str) ?? str, "dim"),
|
|
1027
|
+
red: /* @__PURE__ */ __name((str) => chalk?.red(str) ?? str, "red"),
|
|
1028
|
+
green: /* @__PURE__ */ __name((str) => chalk?.green(str) ?? str, "green")
|
|
1029
|
+
};
|
|
1030
|
+
__name(highlightCode, "highlightCode");
|
|
971
1031
|
__name(stripAnsi, "stripAnsi");
|
|
972
1032
|
__name(wrapAnsiLine, "wrapAnsiLine");
|
|
973
1033
|
__name(printBox, "printBox");
|
|
@@ -1037,12 +1097,699 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1037
1097
|
|
|
1038
1098
|
// src/agents/mcp_agent.ts
|
|
1039
1099
|
var import_langchain2 = require("langchain");
|
|
1040
|
-
var
|
|
1100
|
+
var import_zod9 = require("zod");
|
|
1101
|
+
|
|
1102
|
+
// src/utils/json-schema-to-zod/JSONSchemaToZod.ts
|
|
1103
|
+
var import_zod = require("zod");
|
|
1104
|
+
var JSONSchemaToZod = class {
|
|
1105
|
+
static {
|
|
1106
|
+
__name(this, "JSONSchemaToZod");
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Converts a JSON schema to a Zod schema.
|
|
1110
|
+
*
|
|
1111
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1112
|
+
* @returns {ZodSchema} - The Zod schema.
|
|
1113
|
+
*/
|
|
1114
|
+
static convert(schema) {
|
|
1115
|
+
return this.parseSchema(schema);
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Checks if data matches a condition schema.
|
|
1119
|
+
*
|
|
1120
|
+
* @param {JSONValue} data - The data to check.
|
|
1121
|
+
* @param {JSONSchema} condition - The condition schema.
|
|
1122
|
+
* @returns {boolean} - Whether the data matches the condition.
|
|
1123
|
+
*/
|
|
1124
|
+
static matchesCondition(data, condition) {
|
|
1125
|
+
if (!condition.properties) {
|
|
1126
|
+
return true;
|
|
1127
|
+
}
|
|
1128
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
const objectData = data;
|
|
1132
|
+
for (const [key, propCondition] of Object.entries(condition.properties)) {
|
|
1133
|
+
if (!(key in objectData)) {
|
|
1134
|
+
if ("const" in propCondition) {
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
continue;
|
|
1138
|
+
}
|
|
1139
|
+
const value = objectData[key];
|
|
1140
|
+
if ("const" in propCondition && value !== propCondition["const"]) {
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
if ("minimum" in propCondition && typeof value === "number" && value < propCondition["minimum"]) {
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
if ("maximum" in propCondition && typeof value === "number" && value > propCondition["maximum"]) {
|
|
1147
|
+
return false;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return true;
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Validates data against a conditional schema and adds issues to context if validation fails.
|
|
1154
|
+
*
|
|
1155
|
+
* @param {JSONValue} data - The data to validate.
|
|
1156
|
+
* @param {JSONSchema} schema - The conditional schema.
|
|
1157
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1158
|
+
*/
|
|
1159
|
+
static validateConditionalSchema(data, schema, ctx) {
|
|
1160
|
+
this.validateRequiredProperties(data, schema, ctx);
|
|
1161
|
+
this.validatePropertyPatterns(data, schema, ctx);
|
|
1162
|
+
this.validateNestedConditions(data, schema, ctx);
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Validates that all required properties are present in the data.
|
|
1166
|
+
*
|
|
1167
|
+
* @param {JSONValue} data - The data to validate.
|
|
1168
|
+
* @param {JSONSchema} schema - The schema containing required properties.
|
|
1169
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1170
|
+
*/
|
|
1171
|
+
static validateRequiredProperties(data, schema, ctx) {
|
|
1172
|
+
if (!schema.required) {
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
if (typeof data !== "object" || data === null) {
|
|
1176
|
+
for (const requiredProp of schema.required) {
|
|
1177
|
+
ctx.addIssue({
|
|
1178
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
1179
|
+
message: `Required property '${requiredProp}' is missing`,
|
|
1180
|
+
path: [requiredProp]
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
for (const requiredProp of schema.required) {
|
|
1186
|
+
if (!(requiredProp in data)) {
|
|
1187
|
+
ctx.addIssue({
|
|
1188
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
1189
|
+
message: `Required property '${requiredProp}' is missing`,
|
|
1190
|
+
path: [requiredProp]
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Validates property patterns for string properties.
|
|
1197
|
+
*
|
|
1198
|
+
* @param {JSONValue} data - The data to validate.
|
|
1199
|
+
* @param {JSONSchema} schema - The schema containing property patterns.
|
|
1200
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1201
|
+
*/
|
|
1202
|
+
static validatePropertyPatterns(data, schema, ctx) {
|
|
1203
|
+
if (!schema.properties) {
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
if (typeof data !== "object" || data === null) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
if (Array.isArray(data)) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const objectData = data;
|
|
1213
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1214
|
+
if (!(key in objectData)) {
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
const value = objectData[key];
|
|
1218
|
+
if (propSchema["pattern"] && typeof value === "string") {
|
|
1219
|
+
const regex = new RegExp(propSchema["pattern"]);
|
|
1220
|
+
if (!regex.test(value)) {
|
|
1221
|
+
ctx.addIssue({
|
|
1222
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
1223
|
+
message: `String '${value}' does not match pattern '${propSchema["pattern"]}'`,
|
|
1224
|
+
path: [key]
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Validates nested if-then-else conditions.
|
|
1232
|
+
*
|
|
1233
|
+
* @param {JSONValue} data - The data to validate.
|
|
1234
|
+
* @param {JSONSchema} schema - The schema containing if-then-else conditions.
|
|
1235
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1236
|
+
*/
|
|
1237
|
+
static validateNestedConditions(data, schema, ctx) {
|
|
1238
|
+
if (!schema["if"] || !schema["then"]) {
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
const matchesIf = this.matchesCondition(data, schema["if"]);
|
|
1242
|
+
if (matchesIf) {
|
|
1243
|
+
this.validateConditionalSchema(data, schema["then"], ctx);
|
|
1244
|
+
} else if (schema["else"]) {
|
|
1245
|
+
this.validateConditionalSchema(data, schema["else"], ctx);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Parses a JSON schema and returns the corresponding Zod schema.
|
|
1250
|
+
* This is the main entry point for schema conversion.
|
|
1251
|
+
*
|
|
1252
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1253
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1254
|
+
*/
|
|
1255
|
+
static parseSchema(schema) {
|
|
1256
|
+
if (Array.isArray(schema.type)) {
|
|
1257
|
+
return this.handleTypeArray(schema);
|
|
1258
|
+
}
|
|
1259
|
+
if (schema.oneOf || schema.anyOf || schema.allOf) {
|
|
1260
|
+
return this.parseCombinator(schema);
|
|
1261
|
+
}
|
|
1262
|
+
if (schema["if"] && schema["then"]) {
|
|
1263
|
+
return this.parseObject(schema);
|
|
1264
|
+
}
|
|
1265
|
+
if (schema.properties && (!schema.type || schema.type === "object")) {
|
|
1266
|
+
return this.parseObject(schema);
|
|
1267
|
+
}
|
|
1268
|
+
return this.handleSingleType(schema);
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Handles schemas with an array of types.
|
|
1272
|
+
*
|
|
1273
|
+
* @param {JSONSchema} schema - The JSON schema with type array.
|
|
1274
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1275
|
+
*/
|
|
1276
|
+
static handleTypeArray(schema) {
|
|
1277
|
+
if (!Array.isArray(schema.type)) {
|
|
1278
|
+
throw new Error("Expected schema.type to be an array");
|
|
1279
|
+
}
|
|
1280
|
+
if (schema.type.includes("null")) {
|
|
1281
|
+
return this.handleNullableType(schema);
|
|
1282
|
+
}
|
|
1283
|
+
return this.createUnionFromTypes(schema.type, schema);
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Handles nullable types by creating a nullable schema.
|
|
1287
|
+
*
|
|
1288
|
+
* @param {JSONSchema} schema - The JSON schema with nullable type.
|
|
1289
|
+
* @returns {ZodTypeAny} - The nullable Zod schema.
|
|
1290
|
+
*/
|
|
1291
|
+
static handleNullableType(schema) {
|
|
1292
|
+
if (!Array.isArray(schema.type)) {
|
|
1293
|
+
throw new Error("Expected schema.type to be an array");
|
|
1294
|
+
}
|
|
1295
|
+
const nonNullSchema = { ...schema };
|
|
1296
|
+
nonNullSchema.type = schema.type.filter((t) => t !== "null");
|
|
1297
|
+
if (nonNullSchema.type.length === 1) {
|
|
1298
|
+
const singleTypeSchema = this.handleSingleType({
|
|
1299
|
+
...schema,
|
|
1300
|
+
type: nonNullSchema.type[0]
|
|
1301
|
+
});
|
|
1302
|
+
return singleTypeSchema.nullable();
|
|
1303
|
+
}
|
|
1304
|
+
const unionSchema = this.parseSchema(nonNullSchema);
|
|
1305
|
+
return unionSchema.nullable();
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Creates a union type from an array of types.
|
|
1309
|
+
*
|
|
1310
|
+
* @param {string[]} types - Array of type strings.
|
|
1311
|
+
* @param {JSONSchema} baseSchema - The base schema to apply to each type.
|
|
1312
|
+
* @returns {ZodTypeAny} - The union Zod schema.
|
|
1313
|
+
*/
|
|
1314
|
+
static createUnionFromTypes(types, baseSchema) {
|
|
1315
|
+
const schemas = types.map((type) => {
|
|
1316
|
+
const singleTypeSchema = { ...baseSchema, type };
|
|
1317
|
+
return this.parseSchema(singleTypeSchema);
|
|
1318
|
+
});
|
|
1319
|
+
return import_zod.z.union(schemas);
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Handles schemas with a single type.
|
|
1323
|
+
*
|
|
1324
|
+
* @param {JSONSchema} schema - The JSON schema with single type.
|
|
1325
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1326
|
+
*/
|
|
1327
|
+
static handleSingleType(schema) {
|
|
1328
|
+
if (schema.type === void 0) {
|
|
1329
|
+
if (schema.oneOf || schema.anyOf || schema.allOf) {
|
|
1330
|
+
return this.parseCombinator(schema);
|
|
1331
|
+
}
|
|
1332
|
+
if (schema.properties) {
|
|
1333
|
+
return this.parseObject(schema);
|
|
1334
|
+
}
|
|
1335
|
+
return import_zod.z.any();
|
|
1336
|
+
}
|
|
1337
|
+
switch (schema.type) {
|
|
1338
|
+
case "string":
|
|
1339
|
+
return this.parseString(schema);
|
|
1340
|
+
case "number":
|
|
1341
|
+
case "integer":
|
|
1342
|
+
return this.parseNumberSchema(schema);
|
|
1343
|
+
case "boolean":
|
|
1344
|
+
return import_zod.z.boolean();
|
|
1345
|
+
case "array":
|
|
1346
|
+
return this.parseArray(schema);
|
|
1347
|
+
case "object":
|
|
1348
|
+
return this.parseObject(schema);
|
|
1349
|
+
default:
|
|
1350
|
+
throw new Error("Unsupported schema type");
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Parses a number schema.
|
|
1355
|
+
*
|
|
1356
|
+
* @param {JSONSchema} schema - The JSON schema for a number.
|
|
1357
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1358
|
+
*/
|
|
1359
|
+
static parseNumberSchema(schema) {
|
|
1360
|
+
const numberSchema = import_zod.z.number();
|
|
1361
|
+
let result = numberSchema;
|
|
1362
|
+
result = this.applyNumberBounds(numberSchema, schema);
|
|
1363
|
+
result = this.applyNumberMultipleOf(numberSchema, schema);
|
|
1364
|
+
result = this.applyNumberEnum(numberSchema, schema);
|
|
1365
|
+
result = this.applyIntegerConstraint(numberSchema, schema);
|
|
1366
|
+
return result;
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Applies bounds validation to a number schema.
|
|
1370
|
+
*
|
|
1371
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1372
|
+
* @param {JSONSchema} schema - The JSON schema with bounds.
|
|
1373
|
+
* @returns {z.ZodNumber} - The updated schema with bounds validation.
|
|
1374
|
+
*/
|
|
1375
|
+
static applyNumberBounds(numberSchema, schema) {
|
|
1376
|
+
let result = numberSchema;
|
|
1377
|
+
if (schema["minimum"] !== void 0) {
|
|
1378
|
+
result = schema["exclusiveMinimum"] ? result.gt(schema["minimum"]) : result.gte(schema["minimum"]);
|
|
1379
|
+
}
|
|
1380
|
+
if (schema["maximum"] !== void 0) {
|
|
1381
|
+
result = schema["exclusiveMaximum"] ? result.lt(schema["maximum"]) : result.lte(schema["maximum"]);
|
|
1382
|
+
}
|
|
1383
|
+
return result;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Applies multipleOf validation to a number schema.
|
|
1387
|
+
*
|
|
1388
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1389
|
+
* @param {JSONSchema} schema - The JSON schema with multipleOf.
|
|
1390
|
+
* @returns {z.ZodNumber} - The updated schema with multipleOf validation.
|
|
1391
|
+
*/
|
|
1392
|
+
static applyNumberMultipleOf(numberSchema, schema) {
|
|
1393
|
+
if (schema["multipleOf"] === void 0) {
|
|
1394
|
+
return numberSchema;
|
|
1395
|
+
}
|
|
1396
|
+
return numberSchema.refine((val) => val % schema["multipleOf"] === 0, {
|
|
1397
|
+
message: `Number must be a multiple of ${schema["multipleOf"]}`
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Applies enum validation to a number schema.
|
|
1402
|
+
*
|
|
1403
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1404
|
+
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
1405
|
+
* @returns {z.ZodNumber} - The updated schema with enum validation.
|
|
1406
|
+
*/
|
|
1407
|
+
static applyNumberEnum(numberSchema, schema) {
|
|
1408
|
+
if (!schema.enum) {
|
|
1409
|
+
return numberSchema;
|
|
1410
|
+
}
|
|
1411
|
+
const numberEnums = schema.enum.filter(
|
|
1412
|
+
(val) => typeof val === "number"
|
|
1413
|
+
);
|
|
1414
|
+
if (numberEnums.length === 0) {
|
|
1415
|
+
return numberSchema;
|
|
1416
|
+
}
|
|
1417
|
+
return numberSchema.refine((val) => numberEnums.includes(val), {
|
|
1418
|
+
message: `Number must be one of: ${numberEnums.join(", ")}`
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* Applies integer constraint to a number schema if needed.
|
|
1423
|
+
*
|
|
1424
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1425
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1426
|
+
* @returns {z.ZodNumber} - The updated schema with integer validation if needed.
|
|
1427
|
+
*/
|
|
1428
|
+
static applyIntegerConstraint(numberSchema, schema) {
|
|
1429
|
+
if (schema.type !== "integer") {
|
|
1430
|
+
return numberSchema;
|
|
1431
|
+
}
|
|
1432
|
+
return numberSchema.refine((val) => Number.isInteger(val), {
|
|
1433
|
+
message: "Number must be an integer"
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Parses a string schema.
|
|
1438
|
+
*
|
|
1439
|
+
* @param {JSONSchema} schema - The JSON schema for a string.
|
|
1440
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1441
|
+
*/
|
|
1442
|
+
static parseString(schema) {
|
|
1443
|
+
const stringSchema = import_zod.z.string();
|
|
1444
|
+
let result = stringSchema;
|
|
1445
|
+
if (schema.format) {
|
|
1446
|
+
return this.applyStringFormat(stringSchema, schema);
|
|
1447
|
+
} else {
|
|
1448
|
+
result = this.applyStringPattern(stringSchema, schema);
|
|
1449
|
+
result = this.applyStringLength(stringSchema, schema);
|
|
1450
|
+
result = this.applyStringEnum(stringSchema, schema);
|
|
1451
|
+
}
|
|
1452
|
+
return result;
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Applies format validation to a string schema.
|
|
1456
|
+
*
|
|
1457
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1458
|
+
* @param {JSONSchema} schema - The JSON schema with format.
|
|
1459
|
+
* @returns {ZodTypeAny} - The updated schema with format validation.
|
|
1460
|
+
*/
|
|
1461
|
+
static applyStringFormat(stringSchema, schema) {
|
|
1462
|
+
if (!schema.format) {
|
|
1463
|
+
return stringSchema;
|
|
1464
|
+
}
|
|
1465
|
+
switch (schema.format) {
|
|
1466
|
+
case "email":
|
|
1467
|
+
return stringSchema.email();
|
|
1468
|
+
case "date-time":
|
|
1469
|
+
return stringSchema.datetime();
|
|
1470
|
+
case "uri":
|
|
1471
|
+
return stringSchema.url();
|
|
1472
|
+
case "uuid":
|
|
1473
|
+
return stringSchema.uuid();
|
|
1474
|
+
case "date":
|
|
1475
|
+
return stringSchema.date();
|
|
1476
|
+
default:
|
|
1477
|
+
return stringSchema;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Applies pattern validation to a string schema.
|
|
1482
|
+
*
|
|
1483
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1484
|
+
* @param {JSONSchema} schema - The JSON schema with pattern.
|
|
1485
|
+
* @returns {z.ZodString} - The updated schema with pattern validation.
|
|
1486
|
+
*/
|
|
1487
|
+
static applyStringPattern(stringSchema, schema) {
|
|
1488
|
+
if (!schema["pattern"]) {
|
|
1489
|
+
return stringSchema;
|
|
1490
|
+
}
|
|
1491
|
+
const regex = new RegExp(schema["pattern"]);
|
|
1492
|
+
return stringSchema.regex(regex, {
|
|
1493
|
+
message: `String must match pattern: ${schema["pattern"]}`
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Applies length constraints to a string schema.
|
|
1498
|
+
*
|
|
1499
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1500
|
+
* @param {JSONSchema} schema - The JSON schema with length constraints.
|
|
1501
|
+
* @returns {z.ZodString} - The updated schema with length validation.
|
|
1502
|
+
*/
|
|
1503
|
+
static applyStringLength(stringSchema, schema) {
|
|
1504
|
+
const result = stringSchema;
|
|
1505
|
+
if (schema["minLength"] !== void 0) {
|
|
1506
|
+
stringSchema = stringSchema.min(schema["minLength"]);
|
|
1507
|
+
}
|
|
1508
|
+
if (schema["maxLength"] !== void 0) {
|
|
1509
|
+
stringSchema = stringSchema.max(schema["maxLength"]);
|
|
1510
|
+
}
|
|
1511
|
+
return result;
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Applies enum validation to a string schema.
|
|
1515
|
+
*
|
|
1516
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1517
|
+
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
1518
|
+
* @returns {ZodTypeAny} - The updated schema with enum validation.
|
|
1519
|
+
*/
|
|
1520
|
+
static applyStringEnum(stringSchema, schema) {
|
|
1521
|
+
if (!schema.enum) {
|
|
1522
|
+
return stringSchema;
|
|
1523
|
+
}
|
|
1524
|
+
return stringSchema.refine((val) => schema.enum?.includes(val), {
|
|
1525
|
+
message: `Value must be one of: ${schema.enum?.join(", ")}`
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Parses a JSON schema of type array and returns the corresponding Zod schema.
|
|
1530
|
+
*
|
|
1531
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1532
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1533
|
+
*/
|
|
1534
|
+
static parseArray(schema) {
|
|
1535
|
+
if (Array.isArray(schema.items)) {
|
|
1536
|
+
const tupleSchemas = schema.items.map((item) => this.parseSchema(item));
|
|
1537
|
+
return import_zod.z.union(tupleSchemas);
|
|
1538
|
+
}
|
|
1539
|
+
const itemSchema = schema.items ? this.parseSchema(schema.items) : import_zod.z.any();
|
|
1540
|
+
const arraySchema = import_zod.z.array(itemSchema);
|
|
1541
|
+
let result = arraySchema;
|
|
1542
|
+
result = this.applyArrayConstraints(arraySchema, schema);
|
|
1543
|
+
return result;
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Applies constraints to an array schema.
|
|
1547
|
+
*
|
|
1548
|
+
* @param {z.ZodArray<any>} arraySchema - The base array schema.
|
|
1549
|
+
* @param {JSONSchema} schema - The JSON schema with array constraints.
|
|
1550
|
+
* @returns {z.ZodTypeAny} - The updated array schema with constraints.
|
|
1551
|
+
*/
|
|
1552
|
+
static applyArrayConstraints(arraySchema, schema) {
|
|
1553
|
+
if (schema["minItems"] !== void 0) {
|
|
1554
|
+
arraySchema = arraySchema.min(schema["minItems"]);
|
|
1555
|
+
}
|
|
1556
|
+
if (schema["maxItems"] !== void 0) {
|
|
1557
|
+
arraySchema = arraySchema.max(schema["maxItems"]);
|
|
1558
|
+
}
|
|
1559
|
+
if (schema["uniqueItems"]) {
|
|
1560
|
+
return arraySchema.refine(
|
|
1561
|
+
(items) => new Set(items).size === items.length,
|
|
1562
|
+
{ message: "Array items must be unique" }
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
return arraySchema;
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Parses an object schema.
|
|
1569
|
+
*
|
|
1570
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
1571
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1572
|
+
*/
|
|
1573
|
+
static parseObject(schema) {
|
|
1574
|
+
if (schema["if"] && schema["then"]) {
|
|
1575
|
+
return this.parseConditional(schema);
|
|
1576
|
+
}
|
|
1577
|
+
const shape = {};
|
|
1578
|
+
this.processObjectProperties(schema, shape);
|
|
1579
|
+
return this.processAdditionalProperties(schema, import_zod.z.object(shape));
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Processes object properties and builds the shape object.
|
|
1583
|
+
*
|
|
1584
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
1585
|
+
* @param {Record<string, ZodTypeAny>} shape - The shape object to populate.
|
|
1586
|
+
*/
|
|
1587
|
+
static processObjectProperties(schema, shape) {
|
|
1588
|
+
const required = new Set(schema.required || []);
|
|
1589
|
+
if (!schema.properties) {
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1593
|
+
const zodSchema = this.parseSchema(propSchema);
|
|
1594
|
+
shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* Processes additionalProperties configuration.
|
|
1599
|
+
*
|
|
1600
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
1601
|
+
* @param {z.ZodObject<any, any>} objectSchema - The Zod object schema.
|
|
1602
|
+
* @returns {z.ZodObject<any, any>} - The updated Zod object schema.
|
|
1603
|
+
*/
|
|
1604
|
+
static processAdditionalProperties(schema, objectSchema) {
|
|
1605
|
+
if (schema.additionalProperties === true) {
|
|
1606
|
+
return objectSchema.passthrough();
|
|
1607
|
+
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
1608
|
+
const additionalPropSchema = this.parseSchema(
|
|
1609
|
+
schema.additionalProperties
|
|
1610
|
+
);
|
|
1611
|
+
return objectSchema.catchall(additionalPropSchema);
|
|
1612
|
+
} else {
|
|
1613
|
+
return objectSchema.strict();
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Parses a conditional schema with if-then-else.
|
|
1618
|
+
*
|
|
1619
|
+
* @param {JSONSchema} schema - The JSON schema with conditional validation.
|
|
1620
|
+
* @returns {ZodTypeAny} - The conditional Zod schema.
|
|
1621
|
+
*/
|
|
1622
|
+
static parseConditional(schema) {
|
|
1623
|
+
const zodObject = this.createBaseObjectSchema(schema);
|
|
1624
|
+
const ifCondition = schema["if"];
|
|
1625
|
+
const thenSchema = schema["then"];
|
|
1626
|
+
const elseSchema = schema["else"];
|
|
1627
|
+
return zodObject.superRefine((data, ctx) => {
|
|
1628
|
+
const dataWithDefaults = this.applyDefaultValues(
|
|
1629
|
+
data,
|
|
1630
|
+
schema
|
|
1631
|
+
);
|
|
1632
|
+
if (this.matchesCondition(dataWithDefaults, ifCondition)) {
|
|
1633
|
+
this.validateConditionalSchema(dataWithDefaults, thenSchema, ctx);
|
|
1634
|
+
} else if (elseSchema) {
|
|
1635
|
+
this.validateConditionalSchema(dataWithDefaults, elseSchema, ctx);
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
/**
|
|
1640
|
+
* Creates a base object schema from the given JSON schema.
|
|
1641
|
+
*
|
|
1642
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1643
|
+
* @returns {z.ZodObject<any, any>} - The base Zod object schema.
|
|
1644
|
+
*/
|
|
1645
|
+
static createBaseObjectSchema(schema) {
|
|
1646
|
+
const shape = {};
|
|
1647
|
+
const required = new Set(schema.required || []);
|
|
1648
|
+
for (const [key, value] of Object.entries(schema.properties || {})) {
|
|
1649
|
+
const zodSchema = this.parseSchema(value);
|
|
1650
|
+
shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
|
|
1651
|
+
}
|
|
1652
|
+
const zodObject = import_zod.z.object(shape);
|
|
1653
|
+
return this.processAdditionalProperties(schema, zodObject);
|
|
1654
|
+
}
|
|
1655
|
+
/**
|
|
1656
|
+
* Applies default values from schema properties to data object.
|
|
1657
|
+
*
|
|
1658
|
+
* @param {JSONValue} data - The original data object.
|
|
1659
|
+
* @param {JSONSchema} schema - The schema with default values.
|
|
1660
|
+
* @returns {JSONValue} - The data object with defaults applied.
|
|
1661
|
+
*/
|
|
1662
|
+
static applyDefaultValues(data, schema) {
|
|
1663
|
+
if (typeof data !== "object" || data === null) {
|
|
1664
|
+
return data;
|
|
1665
|
+
}
|
|
1666
|
+
if (Array.isArray(data)) {
|
|
1667
|
+
return data;
|
|
1668
|
+
}
|
|
1669
|
+
const objectData = data;
|
|
1670
|
+
const dataWithDefaults = { ...objectData };
|
|
1671
|
+
if (!schema.properties) {
|
|
1672
|
+
return dataWithDefaults;
|
|
1673
|
+
}
|
|
1674
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1675
|
+
if (!(key in dataWithDefaults) && "default" in propSchema) {
|
|
1676
|
+
dataWithDefaults[key] = propSchema["default"];
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return dataWithDefaults;
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Parses a schema with combinators (oneOf, anyOf, allOf).
|
|
1683
|
+
* Delegates to the appropriate combinator parser based on which combinator is present.
|
|
1684
|
+
*
|
|
1685
|
+
* @param {JSONSchema} schema - The JSON schema with combinators.
|
|
1686
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1687
|
+
*/
|
|
1688
|
+
static parseCombinator(schema) {
|
|
1689
|
+
if (schema.oneOf) {
|
|
1690
|
+
return this.parseOneOf(schema.oneOf);
|
|
1691
|
+
}
|
|
1692
|
+
if (schema.anyOf) {
|
|
1693
|
+
return this.parseAnyOf(schema.anyOf);
|
|
1694
|
+
}
|
|
1695
|
+
if (schema.allOf) {
|
|
1696
|
+
return this.parseAllOf(schema.allOf);
|
|
1697
|
+
}
|
|
1698
|
+
throw new Error("Unsupported schema type");
|
|
1699
|
+
}
|
|
1700
|
+
/**
|
|
1701
|
+
* Parses a oneOf combinator schema.
|
|
1702
|
+
*
|
|
1703
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the oneOf.
|
|
1704
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1705
|
+
*/
|
|
1706
|
+
static parseOneOf(schemas) {
|
|
1707
|
+
return this.createUnionFromSchemas(schemas);
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Parses an anyOf combinator schema.
|
|
1711
|
+
*
|
|
1712
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the anyOf.
|
|
1713
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1714
|
+
*/
|
|
1715
|
+
static parseAnyOf(schemas) {
|
|
1716
|
+
return this.createUnionFromSchemas(schemas);
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
* Creates a union from an array of schemas, handling special cases.
|
|
1720
|
+
*
|
|
1721
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas to create a union from.
|
|
1722
|
+
* @returns {ZodTypeAny} - The union Zod schema.
|
|
1723
|
+
*/
|
|
1724
|
+
static createUnionFromSchemas(schemas) {
|
|
1725
|
+
if (schemas.length === 0) {
|
|
1726
|
+
return import_zod.z.any();
|
|
1727
|
+
}
|
|
1728
|
+
if (schemas.length === 1) {
|
|
1729
|
+
return this.parseSchema(schemas[0]);
|
|
1730
|
+
}
|
|
1731
|
+
const zodSchemas = [];
|
|
1732
|
+
for (const subSchema of schemas) {
|
|
1733
|
+
if (subSchema.type === "null") {
|
|
1734
|
+
zodSchemas.push(import_zod.z.null());
|
|
1735
|
+
} else {
|
|
1736
|
+
zodSchemas.push(this.parseSchema(subSchema));
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
if (zodSchemas.length >= 2) {
|
|
1740
|
+
return import_zod.z.union(zodSchemas);
|
|
1741
|
+
} else if (zodSchemas.length === 1) {
|
|
1742
|
+
return zodSchemas[0];
|
|
1743
|
+
}
|
|
1744
|
+
return import_zod.z.any();
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Parses an allOf combinator schema by merging all schemas.
|
|
1748
|
+
*
|
|
1749
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the allOf.
|
|
1750
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1751
|
+
*/
|
|
1752
|
+
static parseAllOf(schemas) {
|
|
1753
|
+
if (schemas.length === 0) {
|
|
1754
|
+
return import_zod.z.any();
|
|
1755
|
+
}
|
|
1756
|
+
if (schemas.length === 1) {
|
|
1757
|
+
return this.parseSchema(schemas[0]);
|
|
1758
|
+
}
|
|
1759
|
+
const mergedSchema = schemas.reduce(
|
|
1760
|
+
(acc, currentSchema) => this.mergeSchemas(acc, currentSchema)
|
|
1761
|
+
);
|
|
1762
|
+
return this.parseSchema(mergedSchema);
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Merges two JSON schemas together.
|
|
1766
|
+
*
|
|
1767
|
+
* @param {JSONSchema} baseSchema - The base JSON schema.
|
|
1768
|
+
* @param {JSONSchema} addSchema - The JSON schema to add.
|
|
1769
|
+
* @returns {JSONSchema} - The merged JSON schema
|
|
1770
|
+
*/
|
|
1771
|
+
static mergeSchemas(baseSchema, addSchema) {
|
|
1772
|
+
const merged = { ...baseSchema, ...addSchema };
|
|
1773
|
+
if (baseSchema.properties && addSchema.properties) {
|
|
1774
|
+
const mergedProperties = {
|
|
1775
|
+
...baseSchema.properties,
|
|
1776
|
+
...addSchema.properties
|
|
1777
|
+
};
|
|
1778
|
+
merged.properties = mergedProperties;
|
|
1779
|
+
}
|
|
1780
|
+
if (baseSchema.required && addSchema.required) {
|
|
1781
|
+
const mergedRequired = [
|
|
1782
|
+
.../* @__PURE__ */ new Set([...baseSchema.required, ...addSchema.required])
|
|
1783
|
+
];
|
|
1784
|
+
merged.required = mergedRequired;
|
|
1785
|
+
}
|
|
1786
|
+
return merged;
|
|
1787
|
+
}
|
|
1788
|
+
};
|
|
1041
1789
|
|
|
1042
1790
|
// src/adapters/langchain_adapter.ts
|
|
1043
|
-
var import_json_schema_to_zod = require("@dmitryrechkin/json-schema-to-zod");
|
|
1044
1791
|
var import_tools = require("@langchain/core/tools");
|
|
1045
|
-
var
|
|
1792
|
+
var import_zod2 = require("zod");
|
|
1046
1793
|
init_logging();
|
|
1047
1794
|
|
|
1048
1795
|
// src/adapters/base.ts
|
|
@@ -1162,10 +1909,10 @@ var BaseAdapter = class {
|
|
|
1162
1909
|
// src/adapters/langchain_adapter.ts
|
|
1163
1910
|
function schemaToZod(schema) {
|
|
1164
1911
|
try {
|
|
1165
|
-
return
|
|
1912
|
+
return JSONSchemaToZod.convert(schema);
|
|
1166
1913
|
} catch (err) {
|
|
1167
1914
|
logger.warn(`Failed to convert JSON schema to Zod: ${err}`);
|
|
1168
|
-
return
|
|
1915
|
+
return import_zod2.z.any();
|
|
1169
1916
|
}
|
|
1170
1917
|
}
|
|
1171
1918
|
__name(schemaToZod, "schemaToZod");
|
|
@@ -1183,7 +1930,7 @@ var LangChainAdapter = class extends BaseAdapter {
|
|
|
1183
1930
|
if (this.disallowedTools.includes(mcpTool.name)) {
|
|
1184
1931
|
return null;
|
|
1185
1932
|
}
|
|
1186
|
-
const argsSchema = mcpTool.inputSchema ? schemaToZod(mcpTool.inputSchema) :
|
|
1933
|
+
const argsSchema = mcpTool.inputSchema ? schemaToZod(mcpTool.inputSchema) : import_zod2.z.object({}).optional();
|
|
1187
1934
|
const tool = new import_tools.DynamicStructuredTool({
|
|
1188
1935
|
name: mcpTool.name ?? "NO NAME",
|
|
1189
1936
|
description: mcpTool.description ?? "",
|
|
@@ -1213,11 +1960,10 @@ var LangChainAdapter = class extends BaseAdapter {
|
|
|
1213
1960
|
init_logging();
|
|
1214
1961
|
|
|
1215
1962
|
// src/managers/server_manager.ts
|
|
1216
|
-
var import_lodash_es = require("lodash-es");
|
|
1217
1963
|
init_logging();
|
|
1218
1964
|
|
|
1219
1965
|
// src/managers/tools/acquire_active_mcp_server.ts
|
|
1220
|
-
var
|
|
1966
|
+
var import_zod3 = require("zod");
|
|
1221
1967
|
|
|
1222
1968
|
// src/managers/tools/base.ts
|
|
1223
1969
|
var import_tools2 = require("@langchain/core/tools");
|
|
@@ -1242,7 +1988,7 @@ var MCPServerTool = class extends import_tools2.StructuredTool {
|
|
|
1242
1988
|
};
|
|
1243
1989
|
|
|
1244
1990
|
// src/managers/tools/acquire_active_mcp_server.ts
|
|
1245
|
-
var PresentActiveServerSchema =
|
|
1991
|
+
var PresentActiveServerSchema = import_zod3.z.object({});
|
|
1246
1992
|
var AcquireActiveMCPServerTool = class extends MCPServerTool {
|
|
1247
1993
|
static {
|
|
1248
1994
|
__name(this, "AcquireActiveMCPServerTool");
|
|
@@ -1263,7 +2009,7 @@ var AcquireActiveMCPServerTool = class extends MCPServerTool {
|
|
|
1263
2009
|
|
|
1264
2010
|
// src/managers/tools/add_server_from_config.ts
|
|
1265
2011
|
var import_tools3 = require("@langchain/core/tools");
|
|
1266
|
-
var
|
|
2012
|
+
var import_zod4 = require("zod");
|
|
1267
2013
|
init_logging();
|
|
1268
2014
|
var AddMCPServerFromConfigTool = class extends import_tools3.StructuredTool {
|
|
1269
2015
|
static {
|
|
@@ -1271,9 +2017,9 @@ var AddMCPServerFromConfigTool = class extends import_tools3.StructuredTool {
|
|
|
1271
2017
|
}
|
|
1272
2018
|
name = "add_mcp_server_from_config";
|
|
1273
2019
|
description = "Adds a new MCP server to the client from a configuration object and connects to it, making its tools available.";
|
|
1274
|
-
schema =
|
|
1275
|
-
serverName:
|
|
1276
|
-
serverConfig:
|
|
2020
|
+
schema = import_zod4.z.object({
|
|
2021
|
+
serverName: import_zod4.z.string().describe("The name for the new MCP server."),
|
|
2022
|
+
serverConfig: import_zod4.z.any().describe(
|
|
1277
2023
|
'The configuration object for the server. This should not include the top-level "mcpServers" key.'
|
|
1278
2024
|
)
|
|
1279
2025
|
});
|
|
@@ -1315,10 +2061,10 @@ ${tools.map((t) => t.name).join("\n")}`;
|
|
|
1315
2061
|
};
|
|
1316
2062
|
|
|
1317
2063
|
// src/managers/tools/connect_mcp_server.ts
|
|
1318
|
-
var
|
|
2064
|
+
var import_zod5 = require("zod");
|
|
1319
2065
|
init_logging();
|
|
1320
|
-
var ConnectMCPServerSchema =
|
|
1321
|
-
serverName:
|
|
2066
|
+
var ConnectMCPServerSchema = import_zod5.z.object({
|
|
2067
|
+
serverName: import_zod5.z.string().describe("The name of the MCP server.")
|
|
1322
2068
|
});
|
|
1323
2069
|
var ConnectMCPServerTool = class extends MCPServerTool {
|
|
1324
2070
|
static {
|
|
@@ -1366,9 +2112,9 @@ var ConnectMCPServerTool = class extends MCPServerTool {
|
|
|
1366
2112
|
};
|
|
1367
2113
|
|
|
1368
2114
|
// src/managers/tools/list_mcp_servers.ts
|
|
1369
|
-
var
|
|
2115
|
+
var import_zod6 = require("zod");
|
|
1370
2116
|
init_logging();
|
|
1371
|
-
var EnumerateServersSchema =
|
|
2117
|
+
var EnumerateServersSchema = import_zod6.z.object({});
|
|
1372
2118
|
var ListMCPServersTool = class extends MCPServerTool {
|
|
1373
2119
|
static {
|
|
1374
2120
|
__name(this, "ListMCPServersTool");
|
|
@@ -1405,8 +2151,8 @@ var ListMCPServersTool = class extends MCPServerTool {
|
|
|
1405
2151
|
};
|
|
1406
2152
|
|
|
1407
2153
|
// src/managers/tools/release_mcp_server_connection.ts
|
|
1408
|
-
var
|
|
1409
|
-
var ReleaseConnectionSchema =
|
|
2154
|
+
var import_zod7 = require("zod");
|
|
2155
|
+
var ReleaseConnectionSchema = import_zod7.z.object({});
|
|
1410
2156
|
var ReleaseMCPServerConnectionTool = class extends MCPServerTool {
|
|
1411
2157
|
static {
|
|
1412
2158
|
__name(this, "ReleaseMCPServerConnectionTool");
|
|
@@ -1428,6 +2174,28 @@ var ReleaseMCPServerConnectionTool = class extends MCPServerTool {
|
|
|
1428
2174
|
};
|
|
1429
2175
|
|
|
1430
2176
|
// src/managers/server_manager.ts
|
|
2177
|
+
function isEqual(a, b) {
|
|
2178
|
+
if (a === b) return true;
|
|
2179
|
+
if (a == null || b == null) return false;
|
|
2180
|
+
if (typeof a !== typeof b) return false;
|
|
2181
|
+
if (a instanceof Date && b instanceof Date) {
|
|
2182
|
+
return a.getTime() === b.getTime();
|
|
2183
|
+
}
|
|
2184
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
2185
|
+
if (a.length !== b.length) return false;
|
|
2186
|
+
return a.every((item, index) => isEqual(item, b[index]));
|
|
2187
|
+
}
|
|
2188
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
2189
|
+
const keysA = Object.keys(a);
|
|
2190
|
+
const keysB = Object.keys(b);
|
|
2191
|
+
if (keysA.length !== keysB.length) return false;
|
|
2192
|
+
return keysA.every((key) => {
|
|
2193
|
+
return Object.prototype.hasOwnProperty.call(b, key) && isEqual(a[key], b[key]);
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
return false;
|
|
2197
|
+
}
|
|
2198
|
+
__name(isEqual, "isEqual");
|
|
1431
2199
|
var ServerManager = class {
|
|
1432
2200
|
static {
|
|
1433
2201
|
__name(this, "ServerManager");
|
|
@@ -1504,7 +2272,7 @@ var ServerManager = class {
|
|
|
1504
2272
|
continue;
|
|
1505
2273
|
}
|
|
1506
2274
|
const cachedTools = this.serverTools[serverName];
|
|
1507
|
-
const toolsChanged = !cachedTools || !
|
|
2275
|
+
const toolsChanged = !cachedTools || !isEqual(cachedTools, tools);
|
|
1508
2276
|
if (toolsChanged) {
|
|
1509
2277
|
this.serverTools[serverName] = tools;
|
|
1510
2278
|
this.initializedServers[serverName] = true;
|
|
@@ -1566,14 +2334,14 @@ var ObservabilityManager = class {
|
|
|
1566
2334
|
metadata;
|
|
1567
2335
|
metadataProvider;
|
|
1568
2336
|
tagsProvider;
|
|
1569
|
-
constructor(
|
|
1570
|
-
this.customCallbacks =
|
|
1571
|
-
this.verbose =
|
|
1572
|
-
this.observe =
|
|
1573
|
-
this.agentId =
|
|
1574
|
-
this.metadata =
|
|
1575
|
-
this.metadataProvider =
|
|
1576
|
-
this.tagsProvider =
|
|
2337
|
+
constructor(config = {}) {
|
|
2338
|
+
this.customCallbacks = config.customCallbacks;
|
|
2339
|
+
this.verbose = config.verbose ?? false;
|
|
2340
|
+
this.observe = config.observe ?? true;
|
|
2341
|
+
this.agentId = config.agentId;
|
|
2342
|
+
this.metadata = config.metadata;
|
|
2343
|
+
this.metadataProvider = config.metadataProvider;
|
|
2344
|
+
this.tagsProvider = config.tagsProvider;
|
|
1577
2345
|
}
|
|
1578
2346
|
/**
|
|
1579
2347
|
* Collect all available observability handlers from configured platforms.
|
|
@@ -1746,7 +2514,15 @@ var fs2 = __toESM(require("fs"), 1);
|
|
|
1746
2514
|
var os = __toESM(require("os"), 1);
|
|
1747
2515
|
var path2 = __toESM(require("path"), 1);
|
|
1748
2516
|
var import_posthog_node = require("posthog-node");
|
|
1749
|
-
|
|
2517
|
+
|
|
2518
|
+
// src/server/utils/runtime.ts
|
|
2519
|
+
var isDeno = typeof globalThis.Deno !== "undefined";
|
|
2520
|
+
function generateUUID() {
|
|
2521
|
+
return globalThis.crypto.randomUUID();
|
|
2522
|
+
}
|
|
2523
|
+
__name(generateUUID, "generateUUID");
|
|
2524
|
+
|
|
2525
|
+
// src/telemetry/telemetry.ts
|
|
1750
2526
|
init_logging();
|
|
1751
2527
|
|
|
1752
2528
|
// src/telemetry/events.ts
|
|
@@ -2010,7 +2786,7 @@ var Telemetry = class _Telemetry {
|
|
|
2010
2786
|
if (isFirstTime) {
|
|
2011
2787
|
logger.debug(`Creating user ID path: ${this.USER_ID_PATH}`);
|
|
2012
2788
|
fs2.mkdirSync(path2.dirname(this.USER_ID_PATH), { recursive: true });
|
|
2013
|
-
const newUserId = (
|
|
2789
|
+
const newUserId = generateUUID();
|
|
2014
2790
|
fs2.writeFileSync(this.USER_ID_PATH, newUserId);
|
|
2015
2791
|
this._currUserId = newUserId;
|
|
2016
2792
|
logger.debug(`User ID path created: ${this.USER_ID_PATH}`);
|
|
@@ -2232,7 +3008,7 @@ Here are the tools *currently* available to you (this list includes server manag
|
|
|
2232
3008
|
`;
|
|
2233
3009
|
|
|
2234
3010
|
// src/agents/remote.ts
|
|
2235
|
-
var
|
|
3011
|
+
var import_zod8 = require("zod");
|
|
2236
3012
|
init_logging();
|
|
2237
3013
|
var API_CHATS_ENDPOINT = "/api/v1/chats";
|
|
2238
3014
|
var API_CHAT_EXECUTE_ENDPOINT = "/api/v1/chats/{chat_id}/execute";
|
|
@@ -2256,7 +3032,7 @@ var RemoteAgent = class {
|
|
|
2256
3032
|
this.apiKey = apiKey;
|
|
2257
3033
|
}
|
|
2258
3034
|
pydanticToJsonSchema(schema) {
|
|
2259
|
-
return (0,
|
|
3035
|
+
return (0, import_zod8.toJSONSchema)(schema);
|
|
2260
3036
|
}
|
|
2261
3037
|
parseStructuredResponse(responseData, outputSchema) {
|
|
2262
3038
|
let resultData;
|
|
@@ -2858,24 +3634,24 @@ var MCPAgent = class {
|
|
|
2858
3634
|
const serverConfigs = {};
|
|
2859
3635
|
for (const serverName of serverNames) {
|
|
2860
3636
|
try {
|
|
2861
|
-
const
|
|
2862
|
-
if (
|
|
3637
|
+
const config = this.client.getServerConfig(serverName);
|
|
3638
|
+
if (config) {
|
|
2863
3639
|
let serverType = "unknown";
|
|
2864
|
-
if (
|
|
3640
|
+
if (config.command) {
|
|
2865
3641
|
serverType = "command";
|
|
2866
|
-
} else if (
|
|
3642
|
+
} else if (config.url) {
|
|
2867
3643
|
serverType = "http";
|
|
2868
|
-
} else if (
|
|
3644
|
+
} else if (config.ws_url) {
|
|
2869
3645
|
serverType = "websocket";
|
|
2870
3646
|
}
|
|
2871
3647
|
serverConfigs[serverName] = {
|
|
2872
3648
|
type: serverType,
|
|
2873
3649
|
// Include safe configuration details (avoid sensitive data)
|
|
2874
|
-
has_args: !!
|
|
2875
|
-
has_env: !!
|
|
2876
|
-
has_headers: !!
|
|
2877
|
-
url:
|
|
2878
|
-
command:
|
|
3650
|
+
has_args: !!config.args,
|
|
3651
|
+
has_env: !!config.env,
|
|
3652
|
+
has_headers: !!config.headers,
|
|
3653
|
+
url: config.url || null,
|
|
3654
|
+
command: config.command || null
|
|
2879
3655
|
};
|
|
2880
3656
|
}
|
|
2881
3657
|
} catch (error) {
|
|
@@ -3691,7 +4467,7 @@ var MCPAgent = class {
|
|
|
3691
4467
|
let structuredLlm = null;
|
|
3692
4468
|
let schemaDescription = "";
|
|
3693
4469
|
logger.debug(
|
|
3694
|
-
`\u{1F504} Structured output requested, schema: ${JSON.stringify((0,
|
|
4470
|
+
`\u{1F504} Structured output requested, schema: ${JSON.stringify((0, import_zod9.toJSONSchema)(outputSchema), null, 2)}`
|
|
3695
4471
|
);
|
|
3696
4472
|
if (llm && "withStructuredOutput" in llm && typeof llm.withStructuredOutput === "function") {
|
|
3697
4473
|
structuredLlm = llm.withStructuredOutput(outputSchema);
|
|
@@ -3700,7 +4476,7 @@ var MCPAgent = class {
|
|
|
3700
4476
|
} else {
|
|
3701
4477
|
throw new Error("LLM is required for structured output");
|
|
3702
4478
|
}
|
|
3703
|
-
const jsonSchema = (0,
|
|
4479
|
+
const jsonSchema = (0, import_zod9.toJSONSchema)(outputSchema);
|
|
3704
4480
|
const { $schema, additionalProperties, ...cleanSchema } = jsonSchema;
|
|
3705
4481
|
schemaDescription = JSON.stringify(cleanSchema, null, 2);
|
|
3706
4482
|
logger.info(`\u{1F504} Schema description: ${schemaDescription}`);
|
|
@@ -3845,7 +4621,7 @@ ${formatPrompt}`
|
|
|
3845
4621
|
*/
|
|
3846
4622
|
_enhanceQueryWithSchema(query, outputSchema) {
|
|
3847
4623
|
try {
|
|
3848
|
-
const jsonSchema = (0,
|
|
4624
|
+
const jsonSchema = (0, import_zod9.toJSONSchema)(outputSchema);
|
|
3849
4625
|
const { $schema, additionalProperties, ...cleanSchema } = jsonSchema;
|
|
3850
4626
|
const schemaDescription = JSON.stringify(cleanSchema, null, 2);
|
|
3851
4627
|
const enhancedQuery = `
|
|
@@ -3954,9 +4730,9 @@ var BaseMCPClient = class {
|
|
|
3954
4730
|
config = {};
|
|
3955
4731
|
sessions = {};
|
|
3956
4732
|
activeSessions = [];
|
|
3957
|
-
constructor(
|
|
3958
|
-
if (
|
|
3959
|
-
this.config =
|
|
4733
|
+
constructor(config) {
|
|
4734
|
+
if (config) {
|
|
4735
|
+
this.config = config;
|
|
3960
4736
|
}
|
|
3961
4737
|
}
|
|
3962
4738
|
static fromDict(_cfg) {
|
|
@@ -5645,6 +6421,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
5645
6421
|
stop: /* @__PURE__ */ __name(async () => {
|
|
5646
6422
|
if (this.streamableTransport) {
|
|
5647
6423
|
try {
|
|
6424
|
+
await this.streamableTransport.terminateSession();
|
|
5648
6425
|
await this.streamableTransport.close();
|
|
5649
6426
|
} catch (e) {
|
|
5650
6427
|
logger.warn(`Error closing Streamable HTTP transport: ${e}`);
|
|
@@ -5669,6 +6446,8 @@ var HttpConnector = class extends BaseConnector {
|
|
|
5669
6446
|
async connectWithSse(baseUrl) {
|
|
5670
6447
|
try {
|
|
5671
6448
|
this.connectionManager = new SseConnectionManager(baseUrl, {
|
|
6449
|
+
authProvider: this.opts.authProvider,
|
|
6450
|
+
// ← Pass OAuth provider to SDK (same as streamable HTTP)
|
|
5672
6451
|
requestInit: {
|
|
5673
6452
|
headers: this.headers
|
|
5674
6453
|
}
|
|
@@ -5870,7 +6649,6 @@ var StdioConnector = class extends BaseConnector {
|
|
|
5870
6649
|
};
|
|
5871
6650
|
|
|
5872
6651
|
// src/connectors/websocket.ts
|
|
5873
|
-
var import_uuid2 = require("uuid");
|
|
5874
6652
|
init_logging();
|
|
5875
6653
|
|
|
5876
6654
|
// src/task_managers/websocket.ts
|
|
@@ -5992,7 +6770,7 @@ var WebSocketConnector = class extends BaseConnector {
|
|
|
5992
6770
|
}
|
|
5993
6771
|
sendRequest(method, params = null) {
|
|
5994
6772
|
if (!this.ws) throw new Error("WebSocket is not connected");
|
|
5995
|
-
const id = (
|
|
6773
|
+
const id = generateUUID();
|
|
5996
6774
|
const payload = JSON.stringify({ id, method, params: params ?? {} });
|
|
5997
6775
|
return new Promise((resolve, reject) => {
|
|
5998
6776
|
this.pending.set(id, { resolve, reject });
|
|
@@ -6195,12 +6973,12 @@ var MCPClient = class _MCPClient extends BaseMCPClient {
|
|
|
6195
6973
|
_codeExecutorConfig = "vm";
|
|
6196
6974
|
_executorOptions;
|
|
6197
6975
|
_samplingCallback;
|
|
6198
|
-
constructor(
|
|
6199
|
-
if (
|
|
6200
|
-
if (typeof
|
|
6201
|
-
super(loadConfigFile(
|
|
6976
|
+
constructor(config, options) {
|
|
6977
|
+
if (config) {
|
|
6978
|
+
if (typeof config === "string") {
|
|
6979
|
+
super(loadConfigFile(config));
|
|
6202
6980
|
} else {
|
|
6203
|
-
super(
|
|
6981
|
+
super(config);
|
|
6204
6982
|
}
|
|
6205
6983
|
} else {
|
|
6206
6984
|
super();
|
|
@@ -6259,15 +7037,15 @@ var MCPClient = class _MCPClient extends BaseMCPClient {
|
|
|
6259
7037
|
}
|
|
6260
7038
|
_ensureCodeExecutor() {
|
|
6261
7039
|
if (!this._codeExecutor) {
|
|
6262
|
-
const
|
|
6263
|
-
if (
|
|
6264
|
-
this._codeExecutor =
|
|
6265
|
-
} else if (typeof
|
|
6266
|
-
this._customCodeExecutor =
|
|
7040
|
+
const config = this._codeExecutorConfig;
|
|
7041
|
+
if (config instanceof BaseCodeExecutor) {
|
|
7042
|
+
this._codeExecutor = config;
|
|
7043
|
+
} else if (typeof config === "function") {
|
|
7044
|
+
this._customCodeExecutor = config;
|
|
6267
7045
|
throw new Error(
|
|
6268
7046
|
"Custom executor function should be handled in executeCode"
|
|
6269
7047
|
);
|
|
6270
|
-
} else if (
|
|
7048
|
+
} else if (config === "e2b") {
|
|
6271
7049
|
const opts = this._executorOptions;
|
|
6272
7050
|
if (!opts?.apiKey) {
|
|
6273
7051
|
logger.warn("E2B executor requires apiKey. Falling back to VM.");
|
|
@@ -6424,8 +7202,8 @@ var OAuthHelper = class {
|
|
|
6424
7202
|
discovery;
|
|
6425
7203
|
state;
|
|
6426
7204
|
clientRegistration;
|
|
6427
|
-
constructor(
|
|
6428
|
-
this.config =
|
|
7205
|
+
constructor(config) {
|
|
7206
|
+
this.config = config;
|
|
6429
7207
|
this.state = {
|
|
6430
7208
|
isRequired: false,
|
|
6431
7209
|
isAuthenticated: false,
|
|
@@ -6820,8 +7598,33 @@ function createOAuthMCPConfig(serverUrl, accessToken) {
|
|
|
6820
7598
|
}
|
|
6821
7599
|
__name(createOAuthMCPConfig, "createOAuthMCPConfig");
|
|
6822
7600
|
|
|
7601
|
+
// src/utils/url-sanitize.ts
|
|
7602
|
+
function sanitizeUrl(raw) {
|
|
7603
|
+
const abort = /* @__PURE__ */ __name(() => {
|
|
7604
|
+
throw new Error(`Invalid url to pass to open(): ${raw}`);
|
|
7605
|
+
}, "abort");
|
|
7606
|
+
let url;
|
|
7607
|
+
try {
|
|
7608
|
+
url = new URL(raw);
|
|
7609
|
+
} catch (_) {
|
|
7610
|
+
abort();
|
|
7611
|
+
}
|
|
7612
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") abort();
|
|
7613
|
+
if (url.hostname !== encodeURIComponent(url.hostname)) abort();
|
|
7614
|
+
if (url.username) url.username = encodeURIComponent(url.username);
|
|
7615
|
+
if (url.password) url.password = encodeURIComponent(url.password);
|
|
7616
|
+
url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/gi, "/");
|
|
7617
|
+
url.search = url.search.slice(0, 1) + Array.from(url.searchParams.entries()).map(sanitizeParam).join("&");
|
|
7618
|
+
url.hash = url.hash.slice(0, 1) + encodeURIComponent(url.hash.slice(1));
|
|
7619
|
+
return url.href;
|
|
7620
|
+
}
|
|
7621
|
+
__name(sanitizeUrl, "sanitizeUrl");
|
|
7622
|
+
function sanitizeParam([k, v]) {
|
|
7623
|
+
return `${encodeURIComponent(k)}${v.length > 0 ? `=${encodeURIComponent(v)}` : ""}`;
|
|
7624
|
+
}
|
|
7625
|
+
__name(sanitizeParam, "sanitizeParam");
|
|
7626
|
+
|
|
6823
7627
|
// src/auth/browser-provider.ts
|
|
6824
|
-
var import_strict_url_sanitise = require("strict-url-sanitise");
|
|
6825
7628
|
var BrowserOAuthClientProvider = class {
|
|
6826
7629
|
static {
|
|
6827
7630
|
__name(this, "BrowserOAuthClientProvider");
|
|
@@ -6833,6 +7636,7 @@ var BrowserOAuthClientProvider = class {
|
|
|
6833
7636
|
clientUri;
|
|
6834
7637
|
callbackUrl;
|
|
6835
7638
|
preventAutoAuth;
|
|
7639
|
+
useRedirectFlow;
|
|
6836
7640
|
onPopupWindow;
|
|
6837
7641
|
constructor(serverUrl, options = {}) {
|
|
6838
7642
|
this.serverUrl = serverUrl;
|
|
@@ -6840,15 +7644,16 @@ var BrowserOAuthClientProvider = class {
|
|
|
6840
7644
|
this.serverUrlHash = this.hashString(serverUrl);
|
|
6841
7645
|
this.clientName = options.clientName || "mcp-use";
|
|
6842
7646
|
this.clientUri = options.clientUri || (typeof window !== "undefined" ? window.location.origin : "");
|
|
6843
|
-
this.callbackUrl =
|
|
7647
|
+
this.callbackUrl = sanitizeUrl(
|
|
6844
7648
|
options.callbackUrl || (typeof window !== "undefined" ? new URL("/oauth/callback", window.location.origin).toString() : "/oauth/callback")
|
|
6845
7649
|
);
|
|
6846
7650
|
this.preventAutoAuth = options.preventAutoAuth;
|
|
7651
|
+
this.useRedirectFlow = options.useRedirectFlow;
|
|
6847
7652
|
this.onPopupWindow = options.onPopupWindow;
|
|
6848
7653
|
}
|
|
6849
7654
|
// --- SDK Interface Methods ---
|
|
6850
7655
|
get redirectUrl() {
|
|
6851
|
-
return
|
|
7656
|
+
return sanitizeUrl(this.callbackUrl);
|
|
6852
7657
|
}
|
|
6853
7658
|
get clientMetadata() {
|
|
6854
7659
|
return {
|
|
@@ -6935,12 +7740,16 @@ var BrowserOAuthClientProvider = class {
|
|
|
6935
7740
|
clientName: this.clientName,
|
|
6936
7741
|
clientUri: this.clientUri,
|
|
6937
7742
|
callbackUrl: this.callbackUrl
|
|
6938
|
-
}
|
|
7743
|
+
},
|
|
7744
|
+
// Store flow type so callback knows how to handle the response
|
|
7745
|
+
flowType: this.useRedirectFlow ? "redirect" : "popup",
|
|
7746
|
+
// Store current URL for redirect flow so we can return to it
|
|
7747
|
+
returnUrl: this.useRedirectFlow && typeof window !== "undefined" ? window.location.href : void 0
|
|
6939
7748
|
};
|
|
6940
7749
|
localStorage.setItem(stateKey, JSON.stringify(stateData));
|
|
6941
7750
|
authorizationUrl.searchParams.set("state", state);
|
|
6942
7751
|
const authUrlString = authorizationUrl.toString();
|
|
6943
|
-
const sanitizedAuthUrl =
|
|
7752
|
+
const sanitizedAuthUrl = sanitizeUrl(authUrlString);
|
|
6944
7753
|
localStorage.setItem(this.getKey("last_auth_url"), sanitizedAuthUrl);
|
|
6945
7754
|
return sanitizedAuthUrl;
|
|
6946
7755
|
}
|
|
@@ -6950,8 +7759,20 @@ var BrowserOAuthClientProvider = class {
|
|
|
6950
7759
|
* @param authorizationUrl The fully constructed authorization URL from the SDK.
|
|
6951
7760
|
*/
|
|
6952
7761
|
async redirectToAuthorization(authorizationUrl) {
|
|
6953
|
-
if (this.preventAutoAuth) return;
|
|
6954
7762
|
const sanitizedAuthUrl = await this.prepareAuthorizationUrl(authorizationUrl);
|
|
7763
|
+
if (this.preventAutoAuth) {
|
|
7764
|
+
console.info(
|
|
7765
|
+
`[${this.storageKeyPrefix}] Auto-auth prevented. Authorization URL stored for manual trigger.`
|
|
7766
|
+
);
|
|
7767
|
+
return;
|
|
7768
|
+
}
|
|
7769
|
+
if (this.useRedirectFlow) {
|
|
7770
|
+
console.info(
|
|
7771
|
+
`[${this.storageKeyPrefix}] Redirecting to authorization URL (full-page redirect).`
|
|
7772
|
+
);
|
|
7773
|
+
window.location.href = sanitizedAuthUrl;
|
|
7774
|
+
return;
|
|
7775
|
+
}
|
|
6955
7776
|
const popupFeatures = "width=600,height=700,resizable=yes,scrollbars=yes,status=yes";
|
|
6956
7777
|
try {
|
|
6957
7778
|
const popup = window.open(
|
|
@@ -6985,7 +7806,7 @@ var BrowserOAuthClientProvider = class {
|
|
|
6985
7806
|
*/
|
|
6986
7807
|
getLastAttemptedAuthUrl() {
|
|
6987
7808
|
const storedUrl = localStorage.getItem(this.getKey("last_auth_url"));
|
|
6988
|
-
return storedUrl ?
|
|
7809
|
+
return storedUrl ? sanitizeUrl(storedUrl) : null;
|
|
6989
7810
|
}
|
|
6990
7811
|
clearStorage() {
|
|
6991
7812
|
const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;
|
|
@@ -7101,24 +7922,31 @@ async function onMcpAuthorization() {
|
|
|
7101
7922
|
authorizationCode: code
|
|
7102
7923
|
});
|
|
7103
7924
|
if (authResult === "AUTHORIZED") {
|
|
7104
|
-
console.log(
|
|
7105
|
-
|
|
7106
|
-
)
|
|
7107
|
-
|
|
7925
|
+
console.log(`${logPrefix} Authorization successful via SDK auth().`);
|
|
7926
|
+
const isRedirectFlow = storedStateData.flowType === "redirect";
|
|
7927
|
+
if (isRedirectFlow && storedStateData.returnUrl) {
|
|
7928
|
+
console.log(
|
|
7929
|
+
`${logPrefix} Redirect flow complete. Returning to: ${storedStateData.returnUrl}`
|
|
7930
|
+
);
|
|
7931
|
+
localStorage.removeItem(stateKey);
|
|
7932
|
+
window.location.href = storedStateData.returnUrl;
|
|
7933
|
+
} else if (window.opener && !window.opener.closed) {
|
|
7934
|
+
console.log(`${logPrefix} Popup flow complete. Notifying opener...`);
|
|
7108
7935
|
window.opener.postMessage(
|
|
7109
7936
|
{ type: "mcp_auth_callback", success: true },
|
|
7110
7937
|
window.location.origin
|
|
7111
7938
|
);
|
|
7939
|
+
localStorage.removeItem(stateKey);
|
|
7112
7940
|
window.close();
|
|
7113
7941
|
} else {
|
|
7114
7942
|
console.warn(
|
|
7115
|
-
`${logPrefix} No opener window detected. Redirecting to root.`
|
|
7943
|
+
`${logPrefix} No opener window or return URL detected. Redirecting to root.`
|
|
7116
7944
|
);
|
|
7945
|
+
localStorage.removeItem(stateKey);
|
|
7117
7946
|
const pathParts = window.location.pathname.split("/").filter(Boolean);
|
|
7118
7947
|
const basePath = pathParts.length > 0 && pathParts[pathParts.length - 1] === "callback" ? "/" + pathParts.slice(0, -2).join("/") : "/";
|
|
7119
7948
|
window.location.href = basePath || "/";
|
|
7120
7949
|
}
|
|
7121
|
-
localStorage.removeItem(stateKey);
|
|
7122
7950
|
} else {
|
|
7123
7951
|
console.warn(
|
|
7124
7952
|
`${logPrefix} SDK auth() returned unexpected status: ${authResult}`
|
|
@@ -7166,15 +7994,14 @@ __name(onMcpAuthorization, "onMcpAuthorization");
|
|
|
7166
7994
|
|
|
7167
7995
|
// src/react/useMcp.ts
|
|
7168
7996
|
var import_react = require("react");
|
|
7169
|
-
var import_strict_url_sanitise2 = require("strict-url-sanitise");
|
|
7170
7997
|
|
|
7171
7998
|
// src/client/browser.ts
|
|
7172
7999
|
var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
|
|
7173
8000
|
static {
|
|
7174
8001
|
__name(this, "BrowserMCPClient");
|
|
7175
8002
|
}
|
|
7176
|
-
constructor(
|
|
7177
|
-
super(
|
|
8003
|
+
constructor(config) {
|
|
8004
|
+
super(config);
|
|
7178
8005
|
}
|
|
7179
8006
|
static fromDict(cfg) {
|
|
7180
8007
|
return new _BrowserMCPClient(cfg);
|
|
@@ -7240,14 +8067,13 @@ __name(assert, "assert");
|
|
|
7240
8067
|
// src/react/useMcp.ts
|
|
7241
8068
|
var DEFAULT_RECONNECT_DELAY = 3e3;
|
|
7242
8069
|
var DEFAULT_RETRY_DELAY = 5e3;
|
|
7243
|
-
var AUTH_TIMEOUT = 5 * 60 * 1e3;
|
|
7244
8070
|
function useMcp(options) {
|
|
7245
8071
|
const {
|
|
7246
8072
|
url,
|
|
7247
8073
|
enabled = true,
|
|
7248
8074
|
clientName,
|
|
7249
8075
|
clientUri,
|
|
7250
|
-
callbackUrl = typeof window !== "undefined" ?
|
|
8076
|
+
callbackUrl = typeof window !== "undefined" ? sanitizeUrl(
|
|
7251
8077
|
new URL("/oauth/callback", window.location.origin).toString()
|
|
7252
8078
|
) : "/oauth/callback",
|
|
7253
8079
|
storageKeyPrefix = "mcp:auth",
|
|
@@ -7258,6 +8084,9 @@ function useMcp(options) {
|
|
|
7258
8084
|
autoReconnect = DEFAULT_RECONNECT_DELAY,
|
|
7259
8085
|
transportType = "auto",
|
|
7260
8086
|
preventAutoAuth = false,
|
|
8087
|
+
// Default to false for backward compatibility (auto-trigger OAuth)
|
|
8088
|
+
useRedirectFlow = false,
|
|
8089
|
+
// Default to false for backward compatibility (use popup)
|
|
7261
8090
|
onPopupWindow,
|
|
7262
8091
|
timeout = 3e4,
|
|
7263
8092
|
// 30 seconds default for connection timeout
|
|
@@ -7383,6 +8212,7 @@ function useMcp(options) {
|
|
|
7383
8212
|
clientUri,
|
|
7384
8213
|
callbackUrl,
|
|
7385
8214
|
preventAutoAuth,
|
|
8215
|
+
useRedirectFlow,
|
|
7386
8216
|
onPopupWindow
|
|
7387
8217
|
});
|
|
7388
8218
|
addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
|
|
@@ -7473,6 +8303,42 @@ function useMcp(options) {
|
|
|
7473
8303
|
} catch (err) {
|
|
7474
8304
|
const errorMessage = err?.message || String(err);
|
|
7475
8305
|
if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
|
|
8306
|
+
if (authProviderRef.current) {
|
|
8307
|
+
addLog(
|
|
8308
|
+
"info",
|
|
8309
|
+
"Authentication required. OAuth provider available."
|
|
8310
|
+
);
|
|
8311
|
+
try {
|
|
8312
|
+
const { auth: auth2 } = await import("@modelcontextprotocol/sdk/client/auth.js");
|
|
8313
|
+
const baseUrl = new URL(url).origin;
|
|
8314
|
+
auth2(authProviderRef.current, { serverUrl: baseUrl }).catch(
|
|
8315
|
+
() => {
|
|
8316
|
+
}
|
|
8317
|
+
);
|
|
8318
|
+
setTimeout(() => {
|
|
8319
|
+
if (isMountedRef.current) {
|
|
8320
|
+
const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl();
|
|
8321
|
+
if (manualUrl) {
|
|
8322
|
+
setAuthUrl(manualUrl);
|
|
8323
|
+
addLog(
|
|
8324
|
+
"info",
|
|
8325
|
+
"Manual authentication URL available:",
|
|
8326
|
+
manualUrl
|
|
8327
|
+
);
|
|
8328
|
+
} else {
|
|
8329
|
+
addLog("warn", "Could not generate authentication URL");
|
|
8330
|
+
}
|
|
8331
|
+
}
|
|
8332
|
+
}, 100);
|
|
8333
|
+
} catch (authGenError) {
|
|
8334
|
+
addLog("warn", "Error generating auth URL:", authGenError);
|
|
8335
|
+
}
|
|
8336
|
+
if (isMountedRef.current) {
|
|
8337
|
+
setState("pending_auth");
|
|
8338
|
+
}
|
|
8339
|
+
connectingRef.current = false;
|
|
8340
|
+
return "auth_redirect";
|
|
8341
|
+
}
|
|
7476
8342
|
if (customHeaders && Object.keys(customHeaders).length > 0) {
|
|
7477
8343
|
failConnection(
|
|
7478
8344
|
"Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
|
|
@@ -7524,6 +8390,7 @@ function useMcp(options) {
|
|
|
7524
8390
|
customHeaders,
|
|
7525
8391
|
transportType,
|
|
7526
8392
|
preventAutoAuth,
|
|
8393
|
+
useRedirectFlow,
|
|
7527
8394
|
onPopupWindow,
|
|
7528
8395
|
enabled,
|
|
7529
8396
|
timeout,
|
|
@@ -7576,32 +8443,54 @@ function useMcp(options) {
|
|
|
7576
8443
|
retry();
|
|
7577
8444
|
} else if (currentState === "pending_auth") {
|
|
7578
8445
|
addLog("info", "Proceeding with authentication from pending state...");
|
|
7579
|
-
setState("authenticating");
|
|
7580
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
7581
|
-
authTimeoutRef.current = setTimeout(() => {
|
|
7582
|
-
if (isMountedRef.current) {
|
|
7583
|
-
const currentStateValue = stateRef.current;
|
|
7584
|
-
if (currentStateValue === "authenticating") {
|
|
7585
|
-
failConnection("Authentication timed out. Please try again.");
|
|
7586
|
-
}
|
|
7587
|
-
}
|
|
7588
|
-
}, AUTH_TIMEOUT);
|
|
7589
8446
|
try {
|
|
7590
8447
|
assert(
|
|
7591
8448
|
authProviderRef.current,
|
|
7592
8449
|
"Auth Provider not available for manual auth"
|
|
7593
8450
|
);
|
|
7594
8451
|
assert(url, "Server URL is required for authentication");
|
|
7595
|
-
addLog(
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
8452
|
+
addLog("info", "Clearing all OAuth state and initiating fresh flow...");
|
|
8453
|
+
const hashPrefix = `${storageKeyPrefix}:${authProviderRef.current.serverUrlHash}`;
|
|
8454
|
+
Object.keys(localStorage).forEach((key) => {
|
|
8455
|
+
if (key.startsWith(hashPrefix)) {
|
|
8456
|
+
addLog("debug", `Removing stale OAuth key: ${key}`);
|
|
8457
|
+
localStorage.removeItem(key);
|
|
8458
|
+
}
|
|
8459
|
+
if (key.startsWith(`${storageKeyPrefix}:state_`)) {
|
|
8460
|
+
addLog("debug", `Removing orphaned state: ${key}`);
|
|
8461
|
+
localStorage.removeItem(key);
|
|
8462
|
+
}
|
|
8463
|
+
});
|
|
8464
|
+
setState("authenticating");
|
|
8465
|
+
const freshAuthProvider = new BrowserOAuthClientProvider(url, {
|
|
8466
|
+
storageKeyPrefix,
|
|
8467
|
+
clientName,
|
|
8468
|
+
clientUri,
|
|
8469
|
+
callbackUrl,
|
|
8470
|
+
preventAutoAuth: false,
|
|
8471
|
+
// ← Allow OAuth to proceed
|
|
8472
|
+
useRedirectFlow,
|
|
8473
|
+
onPopupWindow
|
|
8474
|
+
});
|
|
8475
|
+
authProviderRef.current = freshAuthProvider;
|
|
8476
|
+
addLog("info", "Triggering fresh OAuth authorization...");
|
|
8477
|
+
const { auth: auth2 } = await import("@modelcontextprotocol/sdk/client/auth.js");
|
|
8478
|
+
const baseUrl = new URL(url).origin;
|
|
8479
|
+
auth2(freshAuthProvider, {
|
|
8480
|
+
serverUrl: baseUrl
|
|
8481
|
+
}).catch((err) => {
|
|
8482
|
+
addLog(
|
|
8483
|
+
"info",
|
|
8484
|
+
"OAuth flow initiated:",
|
|
8485
|
+
err?.message || "Redirecting..."
|
|
8486
|
+
);
|
|
8487
|
+
});
|
|
7599
8488
|
} catch (authError) {
|
|
7600
8489
|
if (!isMountedRef.current) return;
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
authError instanceof Error ? authError :
|
|
8490
|
+
setState("pending_auth");
|
|
8491
|
+
addLog(
|
|
8492
|
+
"error",
|
|
8493
|
+
`Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`
|
|
7605
8494
|
);
|
|
7606
8495
|
}
|
|
7607
8496
|
} else if (currentState === "authenticating") {
|
|
@@ -7620,7 +8509,18 @@ function useMcp(options) {
|
|
|
7620
8509
|
`Client not in a state requiring manual authentication trigger (state: ${currentState}). If needed, try disconnecting and reconnecting.`
|
|
7621
8510
|
);
|
|
7622
8511
|
}
|
|
7623
|
-
}, [
|
|
8512
|
+
}, [
|
|
8513
|
+
addLog,
|
|
8514
|
+
retry,
|
|
8515
|
+
authUrl,
|
|
8516
|
+
url,
|
|
8517
|
+
useRedirectFlow,
|
|
8518
|
+
onPopupWindow,
|
|
8519
|
+
storageKeyPrefix,
|
|
8520
|
+
clientName,
|
|
8521
|
+
clientUri,
|
|
8522
|
+
callbackUrl
|
|
8523
|
+
]);
|
|
7624
8524
|
const clearStorage = (0, import_react.useCallback)(() => {
|
|
7625
8525
|
if (authProviderRef.current) {
|
|
7626
8526
|
const count = authProviderRef.current.clearStorage();
|
|
@@ -7791,6 +8691,7 @@ function useMcp(options) {
|
|
|
7791
8691
|
clientUri,
|
|
7792
8692
|
callbackUrl,
|
|
7793
8693
|
preventAutoAuth,
|
|
8694
|
+
useRedirectFlow,
|
|
7794
8695
|
onPopupWindow
|
|
7795
8696
|
});
|
|
7796
8697
|
addLog(
|
|
@@ -7812,7 +8713,8 @@ function useMcp(options) {
|
|
|
7812
8713
|
clientName,
|
|
7813
8714
|
clientUri,
|
|
7814
8715
|
clientConfig.name,
|
|
7815
|
-
clientConfig.version
|
|
8716
|
+
clientConfig.version,
|
|
8717
|
+
useRedirectFlow
|
|
7816
8718
|
]);
|
|
7817
8719
|
(0, import_react.useEffect)(() => {
|
|
7818
8720
|
let retryTimeoutId = null;
|
|
@@ -8627,7 +9529,18 @@ __name(WidgetControls, "WidgetControls");
|
|
|
8627
9529
|
|
|
8628
9530
|
// src/react/McpUseProvider.tsx
|
|
8629
9531
|
var import_react7 = __toESM(require("react"), 1);
|
|
8630
|
-
var
|
|
9532
|
+
var BrowserRouter = null;
|
|
9533
|
+
var routerError = null;
|
|
9534
|
+
(async () => {
|
|
9535
|
+
try {
|
|
9536
|
+
const routerModule = await import("react-router-dom");
|
|
9537
|
+
BrowserRouter = routerModule.BrowserRouter;
|
|
9538
|
+
} catch (error) {
|
|
9539
|
+
routerError = new Error(
|
|
9540
|
+
"\u274C react-router-dom not installed!\n\nTo use MCP widgets with McpUseProvider, you need to install:\n\n npm install react-router-dom\n # or\n pnpm add react-router-dom\n\nThis dependency is automatically included in projects created with 'create-mcp-use-app'."
|
|
9541
|
+
);
|
|
9542
|
+
}
|
|
9543
|
+
})();
|
|
8631
9544
|
function getBasename() {
|
|
8632
9545
|
if (typeof window === "undefined") return "/";
|
|
8633
9546
|
const path4 = window.location.pathname;
|
|
@@ -8721,7 +9634,13 @@ function McpUseProvider({
|
|
|
8721
9634
|
if (enableDebugger || viewControls) {
|
|
8722
9635
|
content = /* @__PURE__ */ import_react7.default.createElement(WidgetControls, { debugger: enableDebugger, viewControls }, content);
|
|
8723
9636
|
}
|
|
8724
|
-
|
|
9637
|
+
if (routerError) {
|
|
9638
|
+
throw routerError;
|
|
9639
|
+
}
|
|
9640
|
+
if (!BrowserRouter) {
|
|
9641
|
+
throw new Error("react-router-dom is still loading, please try again.");
|
|
9642
|
+
}
|
|
9643
|
+
content = /* @__PURE__ */ import_react7.default.createElement(BrowserRouter, { basename }, content);
|
|
8725
9644
|
content = /* @__PURE__ */ import_react7.default.createElement(ThemeProvider, null, content);
|
|
8726
9645
|
if (autoSize) {
|
|
8727
9646
|
const containerStyle = {
|