@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.
Files changed (80) hide show
  1. package/README.md +20 -27
  2. package/dist/adapters/agui-adapter.d.mts +16 -0
  3. package/dist/adapters/agui-adapter.d.ts +16 -0
  4. package/dist/adapters/agui-adapter.js +185 -0
  5. package/dist/adapters/agui-adapter.js.map +1 -1
  6. package/dist/adapters/agui-adapter.mjs +185 -0
  7. package/dist/adapters/agui-adapter.mjs.map +1 -1
  8. package/dist/adapters/agui-middleware.d.mts +2 -0
  9. package/dist/adapters/agui-middleware.d.ts +2 -0
  10. package/dist/adapters/agui-middleware.js.map +1 -1
  11. package/dist/adapters/agui-middleware.mjs.map +1 -1
  12. package/dist/adapters/ai-adapter.d.mts +21 -0
  13. package/dist/adapters/ai-adapter.d.ts +21 -0
  14. package/dist/adapters/ai-adapter.js +175 -0
  15. package/dist/adapters/ai-adapter.js.map +1 -1
  16. package/dist/adapters/ai-adapter.mjs +175 -0
  17. package/dist/adapters/ai-adapter.mjs.map +1 -1
  18. package/dist/adapters/langchain-adapter.d.mts +16 -0
  19. package/dist/adapters/langchain-adapter.d.ts +16 -0
  20. package/dist/adapters/langchain-adapter.js +179 -0
  21. package/dist/adapters/langchain-adapter.js.map +1 -1
  22. package/dist/adapters/langchain-adapter.mjs +179 -0
  23. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  24. package/dist/client/index.d.mts +2 -2
  25. package/dist/client/index.d.ts +2 -2
  26. package/dist/client/react.d.mts +94 -8
  27. package/dist/client/react.d.ts +94 -8
  28. package/dist/client/react.js +364 -26
  29. package/dist/client/react.js.map +1 -1
  30. package/dist/client/react.mjs +358 -27
  31. package/dist/client/react.mjs.map +1 -1
  32. package/dist/client/vue.d.mts +4 -4
  33. package/dist/client/vue.d.ts +4 -4
  34. package/dist/client/vue.js +11 -2
  35. package/dist/client/vue.js.map +1 -1
  36. package/dist/client/vue.mjs +11 -2
  37. package/dist/client/vue.mjs.map +1 -1
  38. package/dist/{index-CQr9q0bF.d.mts → index-DcYfpY3H.d.mts} +1 -1
  39. package/dist/{index-nE_7Io0I.d.ts → index-GfC_eNEv.d.ts} +1 -1
  40. package/dist/index.d.mts +4 -3
  41. package/dist/index.d.ts +4 -3
  42. package/dist/index.js +938 -12
  43. package/dist/index.js.map +1 -1
  44. package/dist/index.mjs +923 -13
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/server/index.d.mts +2 -2
  47. package/dist/server/index.d.ts +2 -2
  48. package/dist/server/index.js +58 -12
  49. package/dist/server/index.js.map +1 -1
  50. package/dist/server/index.mjs +58 -12
  51. package/dist/server/index.mjs.map +1 -1
  52. package/dist/shared/index.d.mts +86 -4
  53. package/dist/shared/index.d.ts +86 -4
  54. package/dist/shared/index.js +874 -0
  55. package/dist/shared/index.js.map +1 -1
  56. package/dist/shared/index.mjs +865 -1
  57. package/dist/shared/index.mjs.map +1 -1
  58. package/dist/tool-router-Bo8qZbsD.d.ts +325 -0
  59. package/dist/tool-router-XnWVxPzv.d.mts +325 -0
  60. package/dist/{types-CW6lghof.d.mts → types-CfCoIsWI.d.mts} +27 -1
  61. package/dist/{types-CW6lghof.d.ts → types-CfCoIsWI.d.ts} +27 -1
  62. package/package.json +3 -2
  63. package/src/adapters/agui-adapter.ts +79 -0
  64. package/src/adapters/ai-adapter.ts +75 -0
  65. package/src/adapters/langchain-adapter.ts +74 -0
  66. package/src/client/react/index.ts +16 -0
  67. package/src/client/react/oauth-popup.tsx +446 -0
  68. package/src/client/react/use-mcp-apps.tsx +50 -32
  69. package/src/client/react/use-mcp.ts +36 -3
  70. package/src/client/vue/use-mcp.ts +38 -3
  71. package/src/server/handlers/sse-handler.ts +39 -0
  72. package/src/server/index.ts +2 -0
  73. package/src/server/mcp/oauth-client.ts +35 -15
  74. package/src/shared/index.ts +36 -0
  75. package/src/shared/meta-tools.ts +387 -0
  76. package/src/shared/schema-compressor.ts +124 -0
  77. package/src/shared/tool-index.ts +499 -0
  78. package/src/shared/tool-router.ts +469 -0
  79. package/src/shared/types.ts +30 -0
  80. package/supabase/migrations/20260421010000_add_session_cleanup_cron.sql +32 -0
@@ -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 nextState = existing.state === "READY" && isTransientReconnectState(event.state) ? existing.state : event.state;
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
- state: event.state,
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 metadata = getMcpAppMetadata(mcpClient, name);
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(input);
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 || !input) return;
1218
- if (!sentInputRef.current || JSON.stringify(input) !== JSON.stringify(lastInputRef.current)) {
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 = input;
1221
- host.sendToolInput(input);
1544
+ lastInputRef.current = resolvedInput;
1545
+ host.sendToolInput(resolvedInput);
1222
1546
  }
1223
- }, [host, isLaunched, input, resourceUri, appSessionId, name]);
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, name]);
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(clientRef.current, toolName),
1314
- []
1642
+ (toolName) => getMcpAppMetadata(mcpClient, toolName),
1643
+ [mcpClient]
1315
1644
  );
1316
- const McpAppRenderer = react.useMemo(() => {
1317
- const Inner = react.forwardRef(function McpAppRenderer2(props, ref) {
1318
- return /* @__PURE__ */ jsxRuntime.jsx(McpAppView2, { ref, clientRef, ...props });
1319
- });
1320
- const Renderer = react.memo(Inner);
1321
- Renderer.displayName = "McpAppRenderer";
1322
- return Renderer;
1323
- }, []);
1324
- return { getAppMetadata, McpAppRenderer };
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 extractedName = extractToolName(toolName);
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