@mcp-ts/sdk 1.4.0 → 1.5.1
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/README.md +20 -27
- package/dist/adapters/agui-adapter.d.mts +16 -0
- package/dist/adapters/agui-adapter.d.ts +16 -0
- package/dist/adapters/agui-adapter.js +185 -0
- package/dist/adapters/agui-adapter.js.map +1 -1
- package/dist/adapters/agui-adapter.mjs +185 -0
- package/dist/adapters/agui-adapter.mjs.map +1 -1
- package/dist/adapters/agui-middleware.d.mts +2 -0
- package/dist/adapters/agui-middleware.d.ts +2 -0
- package/dist/adapters/agui-middleware.js.map +1 -1
- package/dist/adapters/agui-middleware.mjs.map +1 -1
- package/dist/adapters/ai-adapter.d.mts +21 -0
- package/dist/adapters/ai-adapter.d.ts +21 -0
- package/dist/adapters/ai-adapter.js +175 -0
- package/dist/adapters/ai-adapter.js.map +1 -1
- package/dist/adapters/ai-adapter.mjs +175 -0
- package/dist/adapters/ai-adapter.mjs.map +1 -1
- package/dist/adapters/langchain-adapter.d.mts +16 -0
- package/dist/adapters/langchain-adapter.d.ts +16 -0
- package/dist/adapters/langchain-adapter.js +179 -0
- package/dist/adapters/langchain-adapter.js.map +1 -1
- package/dist/adapters/langchain-adapter.mjs +179 -0
- package/dist/adapters/langchain-adapter.mjs.map +1 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/react.d.mts +94 -8
- package/dist/client/react.d.ts +94 -8
- package/dist/client/react.js +364 -26
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +358 -27
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +4 -4
- package/dist/client/vue.d.ts +4 -4
- package/dist/client/vue.js +11 -2
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +11 -2
- package/dist/client/vue.mjs.map +1 -1
- package/dist/{index-CQr9q0bF.d.mts → index-DcYfpY3H.d.mts} +1 -1
- package/dist/{index-nE_7Io0I.d.ts → index-GfC_eNEv.d.ts} +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +938 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +923 -13
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +58 -12
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +58 -12
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +86 -4
- package/dist/shared/index.d.ts +86 -4
- package/dist/shared/index.js +874 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +865 -1
- package/dist/shared/index.mjs.map +1 -1
- package/dist/tool-router-Bo8qZbsD.d.ts +325 -0
- package/dist/tool-router-XnWVxPzv.d.mts +325 -0
- package/dist/{types-CW6lghof.d.mts → types-CfCoIsWI.d.mts} +27 -1
- package/dist/{types-CW6lghof.d.ts → types-CfCoIsWI.d.ts} +27 -1
- package/package.json +3 -2
- package/src/adapters/agui-adapter.ts +79 -0
- package/src/adapters/ai-adapter.ts +75 -0
- package/src/adapters/langchain-adapter.ts +74 -0
- package/src/client/react/index.ts +16 -0
- package/src/client/react/oauth-popup.tsx +446 -0
- package/src/client/react/use-mcp-apps.tsx +50 -32
- package/src/client/react/use-mcp.ts +36 -3
- package/src/client/vue/use-mcp.ts +38 -3
- package/src/server/handlers/sse-handler.ts +39 -0
- package/src/server/index.ts +2 -0
- package/src/server/mcp/oauth-client.ts +35 -15
- package/src/shared/index.ts +36 -0
- package/src/shared/meta-tools.ts +387 -0
- package/src/shared/schema-compressor.ts +124 -0
- package/src/shared/tool-index.ts +499 -0
- package/src/shared/tool-router.ts +469 -0
- package/src/shared/types.ts +30 -0
- package/supabase/migrations/20260421010000_add_session_cleanup_cron.sql +32 -0
package/dist/client/react.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var nanoid = require('nanoid');
|
|
5
|
-
var appBridge = require('@modelcontextprotocol/ext-apps/app-bridge');
|
|
6
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var appBridge = require('@modelcontextprotocol/ext-apps/app-bridge');
|
|
7
7
|
|
|
8
8
|
var __defProp = Object.defineProperty;
|
|
9
9
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -315,12 +315,19 @@ function useMcp(options) {
|
|
|
315
315
|
const updateConnectionsFromEvent = react.useCallback((event) => {
|
|
316
316
|
if (!isMountedRef.current) return;
|
|
317
317
|
const isTransientReconnectState = (state) => state === "INITIALIZING" || state === "VALIDATING" || state === "RECONNECTING" || state === "CONNECTING" || state === "CONNECTED" || state === "DISCOVERING";
|
|
318
|
+
const getVisibleState = (incomingState, existingState, previousState) => {
|
|
319
|
+
if (incomingState === "INITIALIZING" && (existingState === "AUTHENTICATING" || existingState === "AUTHENTICATED" || previousState === "AUTHENTICATING" || previousState === "AUTHENTICATED")) {
|
|
320
|
+
return existingState === "AUTHENTICATED" || previousState === "AUTHENTICATED" ? "AUTHENTICATED" : "AUTHENTICATING";
|
|
321
|
+
}
|
|
322
|
+
return incomingState;
|
|
323
|
+
};
|
|
318
324
|
setConnections((prev) => {
|
|
319
325
|
switch (event.type) {
|
|
320
326
|
case "state_changed": {
|
|
321
327
|
const existing = prev.find((c) => c.sessionId === event.sessionId);
|
|
322
328
|
if (existing) {
|
|
323
|
-
const
|
|
329
|
+
const normalizedState = getVisibleState(event.state, existing.state, event.previousState);
|
|
330
|
+
const nextState = existing.state === "READY" && isTransientReconnectState(normalizedState) ? existing.state : normalizedState;
|
|
324
331
|
return prev.map(
|
|
325
332
|
(c) => c.sessionId === event.sessionId ? {
|
|
326
333
|
...c,
|
|
@@ -340,7 +347,9 @@ function useMcp(options) {
|
|
|
340
347
|
serverId: event.serverId,
|
|
341
348
|
serverName: event.serverName,
|
|
342
349
|
serverUrl: event.serverUrl,
|
|
343
|
-
|
|
350
|
+
// New connections do not have prior local state, so we normalize
|
|
351
|
+
// only against the server-reported previous state.
|
|
352
|
+
state: getVisibleState(event.state, void 0, event.previousState),
|
|
344
353
|
createdAt: event.createdAt ? new Date(event.createdAt) : void 0,
|
|
345
354
|
tools: []
|
|
346
355
|
}
|
|
@@ -593,6 +602,305 @@ function useMcp(options) {
|
|
|
593
602
|
]
|
|
594
603
|
);
|
|
595
604
|
}
|
|
605
|
+
var AUTH_CODE_MESSAGE = "MCP_AUTH_CODE";
|
|
606
|
+
var AUTH_RESULT_MESSAGE = "MCP_AUTH_RESULT";
|
|
607
|
+
function postPopupResult(popupWindow, result) {
|
|
608
|
+
popupWindow?.postMessage(
|
|
609
|
+
{
|
|
610
|
+
type: AUTH_RESULT_MESSAGE,
|
|
611
|
+
...result
|
|
612
|
+
},
|
|
613
|
+
window.location.origin
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
function openCenteredPopup(url, options = {}) {
|
|
617
|
+
const {
|
|
618
|
+
width = 600,
|
|
619
|
+
height = 700,
|
|
620
|
+
windowName = "mcp-auth-popup",
|
|
621
|
+
features = [],
|
|
622
|
+
onBlocked
|
|
623
|
+
} = options;
|
|
624
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
625
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
626
|
+
const featureList = [
|
|
627
|
+
`width=${width}`,
|
|
628
|
+
`height=${height}`,
|
|
629
|
+
`left=${left}`,
|
|
630
|
+
`top=${top}`,
|
|
631
|
+
"resizable=yes",
|
|
632
|
+
"scrollbars=yes",
|
|
633
|
+
"status=yes",
|
|
634
|
+
...features
|
|
635
|
+
].join(",");
|
|
636
|
+
const popup = window.open(url, windowName, featureList);
|
|
637
|
+
if (!popup) {
|
|
638
|
+
onBlocked?.(url);
|
|
639
|
+
}
|
|
640
|
+
return popup;
|
|
641
|
+
}
|
|
642
|
+
function createOAuthPopupRedirectHandler(options = {}) {
|
|
643
|
+
return (url) => {
|
|
644
|
+
openCenteredPopup(url, {
|
|
645
|
+
...options,
|
|
646
|
+
onBlocked: options.onBlocked ?? ((blockedUrl) => {
|
|
647
|
+
window.alert("Popup blocked! Allow popups for this site to complete authentication.");
|
|
648
|
+
window.location.href = blockedUrl;
|
|
649
|
+
})
|
|
650
|
+
});
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
function useMcpOAuthPopup(connections, finishAuth) {
|
|
654
|
+
const pendingPopupsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
655
|
+
react.useEffect(() => {
|
|
656
|
+
const handleMessage = async (event) => {
|
|
657
|
+
if (event.origin !== window.location.origin) {
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (event.data?.type !== AUTH_CODE_MESSAGE || !event.data.code) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const popupWindow = event.source && "postMessage" in event.source ? event.source : null;
|
|
664
|
+
const targetSessionId = typeof event.data.sessionId === "string" ? event.data.sessionId : "";
|
|
665
|
+
if (!targetSessionId) {
|
|
666
|
+
postPopupResult(popupWindow, {
|
|
667
|
+
success: false,
|
|
668
|
+
error: "Missing OAuth session identifier"
|
|
669
|
+
});
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
const targetSession = connections.find((connection) => connection.sessionId === targetSessionId);
|
|
673
|
+
if (!targetSession) {
|
|
674
|
+
postPopupResult(popupWindow, {
|
|
675
|
+
sessionId: targetSessionId,
|
|
676
|
+
success: false,
|
|
677
|
+
error: "OAuth session not found in the current client state"
|
|
678
|
+
});
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (popupWindow) {
|
|
682
|
+
pendingPopupsRef.current.set(targetSession.sessionId, popupWindow);
|
|
683
|
+
}
|
|
684
|
+
try {
|
|
685
|
+
await finishAuth(targetSession.sessionId, event.data.code);
|
|
686
|
+
} catch (error) {
|
|
687
|
+
pendingPopupsRef.current.delete(targetSession.sessionId);
|
|
688
|
+
postPopupResult(popupWindow, {
|
|
689
|
+
sessionId: targetSession.sessionId,
|
|
690
|
+
success: false,
|
|
691
|
+
error: error instanceof Error ? error.message : "Failed to finish auth"
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
window.addEventListener("message", handleMessage);
|
|
696
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
697
|
+
}, [connections, finishAuth]);
|
|
698
|
+
react.useEffect(() => {
|
|
699
|
+
for (const connection of connections) {
|
|
700
|
+
const popupWindow = pendingPopupsRef.current.get(connection.sessionId);
|
|
701
|
+
if (!popupWindow) {
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (connection.state === "AUTHENTICATED") {
|
|
705
|
+
postPopupResult(popupWindow, {
|
|
706
|
+
sessionId: connection.sessionId,
|
|
707
|
+
success: true
|
|
708
|
+
});
|
|
709
|
+
pendingPopupsRef.current.delete(connection.sessionId);
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
if (connection.state === "FAILED") {
|
|
713
|
+
postPopupResult(popupWindow, {
|
|
714
|
+
sessionId: connection.sessionId,
|
|
715
|
+
success: false,
|
|
716
|
+
error: connection.error || "Failed to complete authorization"
|
|
717
|
+
});
|
|
718
|
+
pendingPopupsRef.current.delete(connection.sessionId);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}, [connections]);
|
|
722
|
+
}
|
|
723
|
+
function McpOAuthCallbackContent({
|
|
724
|
+
code,
|
|
725
|
+
sessionId,
|
|
726
|
+
title = "Verifying Authorization",
|
|
727
|
+
initialStatus = "Completing your authorization...",
|
|
728
|
+
loadingFallback = "Loading...",
|
|
729
|
+
rootStyle,
|
|
730
|
+
cardStyle,
|
|
731
|
+
titleStyle,
|
|
732
|
+
messageStyle,
|
|
733
|
+
renderContainer,
|
|
734
|
+
debugPhase
|
|
735
|
+
}) {
|
|
736
|
+
const [phase, setPhase] = react.useState(debugPhase || "loading");
|
|
737
|
+
const [errorMessage, setErrorMessage] = react.useState("");
|
|
738
|
+
const openerMissing = typeof window !== "undefined" ? !window.opener : false;
|
|
739
|
+
const missingCode = !code;
|
|
740
|
+
const missingSessionId = !sessionId;
|
|
741
|
+
const blockingError = openerMissing ? "Error: No opener window found. This window should be opened from the app." : missingCode ? "Error: No authorization code received." : missingSessionId ? "Error: No OAuth state received." : null;
|
|
742
|
+
react.useEffect(() => {
|
|
743
|
+
if (debugPhase) {
|
|
744
|
+
setPhase(debugPhase);
|
|
745
|
+
if (debugPhase === "error") setErrorMessage("Test error message representing a real failure.");
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (blockingError) {
|
|
749
|
+
setPhase("error");
|
|
750
|
+
setErrorMessage(blockingError);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
let closed = false;
|
|
754
|
+
const handleResult = (event) => {
|
|
755
|
+
if (event.origin !== window.location.origin) {
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
if (event.data?.type !== AUTH_RESULT_MESSAGE) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (event.data.sessionId !== sessionId) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (event.data.success) {
|
|
765
|
+
setPhase("success");
|
|
766
|
+
window.removeEventListener("message", handleResult);
|
|
767
|
+
closed = true;
|
|
768
|
+
window.setTimeout(() => window.close(), 1200);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
const message = typeof event.data.error === "string" && event.data.error.length > 0 ? event.data.error : "Failed to complete authorization.";
|
|
772
|
+
setPhase("error");
|
|
773
|
+
setErrorMessage(message);
|
|
774
|
+
};
|
|
775
|
+
window.addEventListener("message", handleResult);
|
|
776
|
+
try {
|
|
777
|
+
window.opener.postMessage(
|
|
778
|
+
{ type: AUTH_CODE_MESSAGE, code, sessionId },
|
|
779
|
+
window.location.origin
|
|
780
|
+
);
|
|
781
|
+
} catch (error) {
|
|
782
|
+
console.error("Failed to communicate with opener:", error);
|
|
783
|
+
window.setTimeout(() => {
|
|
784
|
+
setPhase("error");
|
|
785
|
+
setErrorMessage("Error: Could not communicate with main window.");
|
|
786
|
+
}, 0);
|
|
787
|
+
}
|
|
788
|
+
return () => {
|
|
789
|
+
if (!closed) {
|
|
790
|
+
window.removeEventListener("message", handleResult);
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
}, [blockingError, code, sessionId, debugPhase]);
|
|
794
|
+
const loadingBubbles = /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "8px", justifyContent: "center", height: "12px", alignItems: "center" }, children: [0, 150, 300].map((delay) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
795
|
+
"span",
|
|
796
|
+
{
|
|
797
|
+
style: {
|
|
798
|
+
width: "8px",
|
|
799
|
+
height: "8px",
|
|
800
|
+
borderRadius: "50%",
|
|
801
|
+
backgroundColor: "currentColor",
|
|
802
|
+
opacity: 0.3,
|
|
803
|
+
animation: `mcp-pulse 1.2s ease-in-out infinite`,
|
|
804
|
+
animationDelay: `${delay}ms`
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
delay
|
|
808
|
+
)) });
|
|
809
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
810
|
+
"div",
|
|
811
|
+
{
|
|
812
|
+
style: {
|
|
813
|
+
display: "flex",
|
|
814
|
+
justifyContent: "center",
|
|
815
|
+
alignItems: "center",
|
|
816
|
+
minHeight: "100vh",
|
|
817
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
818
|
+
flexDirection: "column",
|
|
819
|
+
backgroundColor: "#fafafa",
|
|
820
|
+
color: "#18181b",
|
|
821
|
+
boxSizing: "border-box",
|
|
822
|
+
padding: "1.5rem",
|
|
823
|
+
...rootStyle
|
|
824
|
+
},
|
|
825
|
+
children: [
|
|
826
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
827
|
+
@keyframes mcp-pulse { 0%, 100% { transform: scale(0.8); opacity: 0.4; } 50% { transform: scale(1.2); opacity: 1; } }
|
|
828
|
+
@keyframes mcp-fade-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
829
|
+
` }),
|
|
830
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
831
|
+
"div",
|
|
832
|
+
{
|
|
833
|
+
style: {
|
|
834
|
+
backgroundColor: "#fff",
|
|
835
|
+
borderRadius: "20px",
|
|
836
|
+
boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.05)",
|
|
837
|
+
width: "100%",
|
|
838
|
+
maxWidth: "400px",
|
|
839
|
+
overflow: "hidden",
|
|
840
|
+
border: "1px solid #f4f4f5",
|
|
841
|
+
display: "flex",
|
|
842
|
+
flexDirection: "column",
|
|
843
|
+
...cardStyle
|
|
844
|
+
},
|
|
845
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "3rem 2rem", textAlign: "center", animation: "mcp-fade-up 0.4s ease-out" }, children: [
|
|
846
|
+
phase === "loading" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem", alignItems: "center" }, children: [
|
|
847
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "48px", width: "48px", background: "#f8fafc", borderRadius: "12px", border: "1px solid #f1f5f9", color: "#64748b" }, children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }) }) }),
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
849
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "1.125rem", fontWeight: 600, ...titleStyle }, children: title }),
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "0.9rem", color: "#71717a", lineHeight: 1.5, ...messageStyle }, children: initialStatus })
|
|
851
|
+
] }),
|
|
852
|
+
loadingBubbles
|
|
853
|
+
] }),
|
|
854
|
+
phase === "success" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem", alignItems: "center" }, children: [
|
|
855
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { style: { color: "#10b981" }, width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
857
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 12l3 3 5-5" })
|
|
858
|
+
] }),
|
|
859
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 600, ...titleStyle }, children: "Connected" }),
|
|
860
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "0.9rem", color: "#71717a", lineHeight: 1.5, ...messageStyle }, children: "Authorization complete. This window will close automatically." })
|
|
861
|
+
] }),
|
|
862
|
+
phase === "error" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem", alignItems: "center" }, children: [
|
|
863
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { style: { color: "#ef4444" }, width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
864
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
865
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 9l-6 6M9 9l6 6" })
|
|
866
|
+
] }),
|
|
867
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 600, ...titleStyle }, children: "Connection Failed" }),
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "0.9rem", color: "#ef4444", fontWeight: 500, ...messageStyle }, children: errorMessage }),
|
|
869
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
870
|
+
"button",
|
|
871
|
+
{
|
|
872
|
+
onClick: () => window.close(),
|
|
873
|
+
style: {
|
|
874
|
+
marginTop: "0.5rem",
|
|
875
|
+
padding: "0.625rem 1.25rem",
|
|
876
|
+
border: "none",
|
|
877
|
+
borderRadius: "8px",
|
|
878
|
+
backgroundColor: "#fef2f2",
|
|
879
|
+
color: "#ef4444",
|
|
880
|
+
cursor: "pointer",
|
|
881
|
+
fontWeight: 600,
|
|
882
|
+
fontSize: "0.875rem"
|
|
883
|
+
},
|
|
884
|
+
children: "Close Window"
|
|
885
|
+
}
|
|
886
|
+
)
|
|
887
|
+
] })
|
|
888
|
+
] })
|
|
889
|
+
}
|
|
890
|
+
)
|
|
891
|
+
]
|
|
892
|
+
}
|
|
893
|
+
);
|
|
894
|
+
if (renderContainer) {
|
|
895
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderContainer(content) });
|
|
896
|
+
}
|
|
897
|
+
return content;
|
|
898
|
+
}
|
|
899
|
+
function McpOAuthCallbackFallback({
|
|
900
|
+
children = "Loading..."
|
|
901
|
+
}) {
|
|
902
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children || "Loading..." });
|
|
903
|
+
}
|
|
596
904
|
|
|
597
905
|
// src/client/core/constants.ts
|
|
598
906
|
var SANDBOX_PROXY_READY_METHOD = "ui/notifications/sandbox-proxy-ready";
|
|
@@ -1080,6 +1388,21 @@ function useAppHost(client, iframeRef, options) {
|
|
|
1080
1388
|
}, [client, iframeRef]);
|
|
1081
1389
|
return { host, error };
|
|
1082
1390
|
}
|
|
1391
|
+
|
|
1392
|
+
// src/shared/meta-tools.ts
|
|
1393
|
+
function resolveMetaToolProxy(toolName, args) {
|
|
1394
|
+
if (toolName === "mcp_execute_tool") {
|
|
1395
|
+
const innerName = args?.toolName;
|
|
1396
|
+
const innerArgs = args?.args;
|
|
1397
|
+
return {
|
|
1398
|
+
toolName: typeof innerName === "string" && innerName ? innerName : toolName,
|
|
1399
|
+
args: innerArgs && typeof innerArgs === "object" && !Array.isArray(innerArgs) ? innerArgs : {}
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
const match = toolName.match(/(?:tool_[^_]+_)?(.+)$/);
|
|
1403
|
+
const resolvedName = match?.[1] ?? toolName;
|
|
1404
|
+
return { toolName: resolvedName, args: args ?? {} };
|
|
1405
|
+
}
|
|
1083
1406
|
var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
1084
1407
|
clientRef,
|
|
1085
1408
|
name,
|
|
@@ -1104,7 +1427,8 @@ var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
|
1104
1427
|
loader
|
|
1105
1428
|
}, ref) {
|
|
1106
1429
|
const mcpClient = clientRef.current;
|
|
1107
|
-
const
|
|
1430
|
+
const { toolName: resolvedToolName, args: resolvedInput } = resolveMetaToolProxy(name, input);
|
|
1431
|
+
const metadata = getMcpAppMetadata(mcpClient, resolvedToolName, resolvedInput);
|
|
1108
1432
|
const sseClient = mcpClient?.sseClient ?? null;
|
|
1109
1433
|
const resourceUri = toolResourceUri || metadata?.resourceUri;
|
|
1110
1434
|
const appSessionId = metadata?.sessionId;
|
|
@@ -1184,7 +1508,7 @@ var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
|
1184
1508
|
const [error, setError] = react.useState(null);
|
|
1185
1509
|
const sentInputRef = react.useRef(false);
|
|
1186
1510
|
const sentResultRef = react.useRef(false);
|
|
1187
|
-
const lastInputRef = react.useRef(
|
|
1511
|
+
const lastInputRef = react.useRef(resolvedInput);
|
|
1188
1512
|
const lastResultRef = react.useRef(result);
|
|
1189
1513
|
const lastStatusRef = react.useRef(status);
|
|
1190
1514
|
react.useEffect(() => {
|
|
@@ -1214,13 +1538,13 @@ var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
|
1214
1538
|
host.launch({ uri: resourceUri, html }, appSessionId).then(() => setIsLaunched(true)).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
1215
1539
|
}, [host, resourceUri, html, appSessionId]);
|
|
1216
1540
|
react.useEffect(() => {
|
|
1217
|
-
if (!host || !isLaunched || !resourceUri || !appSessionId || !
|
|
1218
|
-
if (!sentInputRef.current || JSON.stringify(
|
|
1541
|
+
if (!host || !isLaunched || !resourceUri || !appSessionId || !resolvedInput) return;
|
|
1542
|
+
if (!sentInputRef.current || JSON.stringify(resolvedInput) !== JSON.stringify(lastInputRef.current)) {
|
|
1219
1543
|
sentInputRef.current = true;
|
|
1220
|
-
lastInputRef.current =
|
|
1221
|
-
host.sendToolInput(
|
|
1544
|
+
lastInputRef.current = resolvedInput;
|
|
1545
|
+
host.sendToolInput(resolvedInput);
|
|
1222
1546
|
}
|
|
1223
|
-
}, [host, isLaunched,
|
|
1547
|
+
}, [host, isLaunched, resolvedInput, resourceUri, appSessionId, resolvedToolName]);
|
|
1224
1548
|
react.useEffect(() => {
|
|
1225
1549
|
if (!host || !isLaunched || !resourceUri || !appSessionId || result === void 0) return;
|
|
1226
1550
|
if (status !== "complete") return;
|
|
@@ -1230,7 +1554,7 @@ var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
|
1230
1554
|
const formattedResult = typeof result === "string" ? { content: [{ type: "text", text: result }] } : result;
|
|
1231
1555
|
host.sendToolResult(formattedResult);
|
|
1232
1556
|
}
|
|
1233
|
-
}, [host, isLaunched, result, status, resourceUri, appSessionId,
|
|
1557
|
+
}, [host, isLaunched, result, status, resourceUri, appSessionId, resolvedToolName]);
|
|
1234
1558
|
react.useEffect(() => {
|
|
1235
1559
|
if (status === "executing" && lastStatusRef.current !== "executing") {
|
|
1236
1560
|
sentInputRef.current = false;
|
|
@@ -1306,30 +1630,37 @@ var McpAppViewInner = react.forwardRef(function McpAppView({
|
|
|
1306
1630
|
});
|
|
1307
1631
|
var McpAppView2 = react.memo(McpAppViewInner);
|
|
1308
1632
|
McpAppView2.displayName = "McpAppView";
|
|
1633
|
+
var McpAppRenderer = react.memo(
|
|
1634
|
+
react.forwardRef(function McpAppRenderer2({ client, ...props }, ref) {
|
|
1635
|
+
const clientRef = react.useRef(client || null);
|
|
1636
|
+
clientRef.current = client || null;
|
|
1637
|
+
return /* @__PURE__ */ jsxRuntime.jsx(McpAppView2, { ref, clientRef, ...props });
|
|
1638
|
+
})
|
|
1639
|
+
);
|
|
1309
1640
|
function useMcpApps(mcpClient) {
|
|
1310
|
-
const clientRef = react.useRef(mcpClient);
|
|
1311
|
-
clientRef.current = mcpClient;
|
|
1312
1641
|
const getAppMetadata = react.useCallback(
|
|
1313
|
-
(toolName) => getMcpAppMetadata(
|
|
1314
|
-
[]
|
|
1642
|
+
(toolName) => getMcpAppMetadata(mcpClient, toolName),
|
|
1643
|
+
[mcpClient]
|
|
1315
1644
|
);
|
|
1316
|
-
const
|
|
1317
|
-
const
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1645
|
+
const BoundMcpAppRenderer = react.useMemo(() => {
|
|
1646
|
+
const Renderer = react.forwardRef(
|
|
1647
|
+
function BoundMcpAppRenderer2(props, ref) {
|
|
1648
|
+
return /* @__PURE__ */ jsxRuntime.jsx(McpAppRenderer, { ref, client: mcpClient, ...props });
|
|
1649
|
+
}
|
|
1650
|
+
);
|
|
1651
|
+
Renderer.displayName = "BoundMcpAppRenderer";
|
|
1652
|
+
return react.memo(Renderer);
|
|
1653
|
+
}, [mcpClient]);
|
|
1654
|
+
return { getAppMetadata, McpAppRenderer: BoundMcpAppRenderer };
|
|
1325
1655
|
}
|
|
1326
1656
|
function extractToolName(fullName) {
|
|
1327
1657
|
const match = fullName.match(/(?:tool_[^_]+_)?(.+)$/);
|
|
1328
1658
|
return match?.[1] || fullName;
|
|
1329
1659
|
}
|
|
1330
|
-
function getMcpAppMetadata(mcpClient, toolName) {
|
|
1660
|
+
function getMcpAppMetadata(mcpClient, toolName, input) {
|
|
1331
1661
|
if (!mcpClient) return void 0;
|
|
1332
|
-
const
|
|
1662
|
+
const { toolName: proxyToolName } = resolveMetaToolProxy(toolName, input);
|
|
1663
|
+
const extractedName = extractToolName(proxyToolName);
|
|
1333
1664
|
for (const conn of mcpClient.connections) {
|
|
1334
1665
|
for (const tool of conn.tools) {
|
|
1335
1666
|
const candidateName = extractToolName(tool.name);
|
|
@@ -1349,11 +1680,18 @@ function getMcpAppMetadata(mcpClient, toolName) {
|
|
|
1349
1680
|
exports.APP_HOST_DEFAULTS = APP_HOST_DEFAULTS;
|
|
1350
1681
|
exports.AppHost = AppHost;
|
|
1351
1682
|
exports.DEFAULT_MCP_APP_CSP = DEFAULT_MCP_APP_CSP;
|
|
1683
|
+
exports.McpAppRenderer = McpAppRenderer;
|
|
1684
|
+
exports.McpOAuthCallbackContent = McpOAuthCallbackContent;
|
|
1685
|
+
exports.McpOAuthCallbackFallback = McpOAuthCallbackFallback;
|
|
1352
1686
|
exports.SANDBOX_PROXY_READY_METHOD = SANDBOX_PROXY_READY_METHOD;
|
|
1353
1687
|
exports.SANDBOX_RESOURCE_READY_METHOD = SANDBOX_RESOURCE_READY_METHOD;
|
|
1354
1688
|
exports.SSEClient = SSEClient;
|
|
1689
|
+
exports.createOAuthPopupRedirectHandler = createOAuthPopupRedirectHandler;
|
|
1690
|
+
exports.getMcpAppMetadata = getMcpAppMetadata;
|
|
1691
|
+
exports.openCenteredPopup = openCenteredPopup;
|
|
1355
1692
|
exports.useAppHost = useAppHost;
|
|
1356
1693
|
exports.useMcp = useMcp;
|
|
1357
1694
|
exports.useMcpApps = useMcpApps;
|
|
1695
|
+
exports.useMcpOAuthPopup = useMcpOAuthPopup;
|
|
1358
1696
|
//# sourceMappingURL=react.js.map
|
|
1359
1697
|
//# sourceMappingURL=react.js.map
|