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