@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
@@ -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 nextState = existing.state === "READY" && isTransientReconnectState(event.state) ? existing.state : event.state;
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
- state: event.state,
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 metadata = getMcpAppMetadata(mcpClient, name);
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(input);
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 || !input) return;
1216
- if (!sentInputRef.current || JSON.stringify(input) !== JSON.stringify(lastInputRef.current)) {
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 = input;
1219
- host.sendToolInput(input);
1542
+ lastInputRef.current = resolvedInput;
1543
+ host.sendToolInput(resolvedInput);
1220
1544
  }
1221
- }, [host, isLaunched, input, resourceUri, appSessionId, name]);
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, name]);
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(clientRef.current, toolName),
1312
- []
1640
+ (toolName) => getMcpAppMetadata(mcpClient, toolName),
1641
+ [mcpClient]
1313
1642
  );
1314
- const McpAppRenderer = useMemo(() => {
1315
- const Inner = forwardRef(function McpAppRenderer2(props, ref) {
1316
- return /* @__PURE__ */ jsx(McpAppView2, { ref, clientRef, ...props });
1317
- });
1318
- const Renderer = memo(Inner);
1319
- Renderer.displayName = "McpAppRenderer";
1320
- return Renderer;
1321
- }, []);
1322
- return { getAppMetadata, McpAppRenderer };
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 extractedName = extractToolName(toolName);
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