@mcp-ts/sdk 1.3.9 → 1.3.10

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.
@@ -1,4 +1,4 @@
1
- import { memo, useCallback, useRef, useState, useEffect } from 'react';
1
+ import { memo, useRef, useState, useEffect, useCallback, useMemo } from 'react';
2
2
  import { nanoid } from 'nanoid';
3
3
  import { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -275,6 +275,7 @@ function useMcp(options) {
275
275
  "disconnected"
276
276
  );
277
277
  const [isInitializing, setIsInitializing] = useState(false);
278
+ const [sseClient, setSseClient] = useState(null);
278
279
  useEffect(() => {
279
280
  isMountedRef.current = true;
280
281
  const clientOptions = {
@@ -297,6 +298,7 @@ function useMcp(options) {
297
298
  };
298
299
  const client = new SSEClient(clientOptions);
299
300
  clientRef.current = client;
301
+ setSseClient(client);
300
302
  if (autoConnect) {
301
303
  client.connect();
302
304
  if (autoInitialize) {
@@ -530,29 +532,54 @@ function useMcp(options) {
530
532
  },
531
533
  [getConnection]
532
534
  );
533
- return {
534
- connections,
535
- status,
536
- isInitializing,
537
- connect,
538
- disconnect,
539
- getConnection,
540
- getConnectionByServerId,
541
- isServerConnected,
542
- getTools,
543
- refresh,
544
- connectSSE,
545
- disconnectSSE,
546
- finishAuth,
547
- resumeAuth,
548
- callTool,
549
- listTools,
550
- listPrompts,
551
- getPrompt,
552
- listResources,
553
- readResource,
554
- sseClient: clientRef.current
555
- };
535
+ return useMemo(
536
+ () => ({
537
+ connections,
538
+ status,
539
+ isInitializing,
540
+ connect,
541
+ disconnect,
542
+ getConnection,
543
+ getConnectionByServerId,
544
+ isServerConnected,
545
+ getTools,
546
+ refresh,
547
+ connectSSE,
548
+ disconnectSSE,
549
+ finishAuth,
550
+ resumeAuth,
551
+ callTool,
552
+ listTools,
553
+ listPrompts,
554
+ getPrompt,
555
+ listResources,
556
+ readResource,
557
+ sseClient
558
+ }),
559
+ [
560
+ connections,
561
+ status,
562
+ isInitializing,
563
+ connect,
564
+ disconnect,
565
+ getConnection,
566
+ getConnectionByServerId,
567
+ isServerConnected,
568
+ getTools,
569
+ refresh,
570
+ connectSSE,
571
+ disconnectSSE,
572
+ finishAuth,
573
+ resumeAuth,
574
+ callTool,
575
+ listTools,
576
+ listPrompts,
577
+ getPrompt,
578
+ listResources,
579
+ readResource,
580
+ sseClient
581
+ ]
582
+ );
556
583
  }
557
584
  var HOST_INFO = { name: "mcp-ts-host", version: "1.0.0" };
558
585
  var SANDBOX_PERMISSIONS = [
@@ -884,37 +911,19 @@ function useAppHost(client, iframeRef, options) {
884
911
  }, [client, iframeRef]);
885
912
  return { host, error };
886
913
  }
887
- var McpAppRenderer = memo(function McpAppRenderer2({
888
- mcpClient,
914
+ var McpAppView = memo(function McpAppView2({
915
+ clientRef,
889
916
  name,
890
917
  input,
891
918
  result,
892
919
  status,
893
920
  className
894
921
  }) {
895
- const getAppMetadata = useCallback(() => {
896
- if (!mcpClient) return void 0;
897
- const extractedName = extractToolName(name);
898
- for (const conn of mcpClient.connections) {
899
- for (const tool of conn.tools) {
900
- const candidateName = extractToolName(tool.name);
901
- const resourceUri = tool.mcpApp?.resourceUri ?? tool._meta?.ui?.resourceUri ?? tool._meta?.["ui/resourceUri"];
902
- if (resourceUri && candidateName === extractedName) {
903
- return {
904
- toolName: candidateName,
905
- resourceUri,
906
- sessionId: conn.sessionId
907
- };
908
- }
909
- }
910
- }
911
- return void 0;
912
- }, [mcpClient, name]);
913
- const metadata = getAppMetadata();
922
+ const mcpClient = clientRef.current;
923
+ const metadata = getMcpAppMetadata(mcpClient, name);
914
924
  const sseClient = mcpClient?.sseClient ?? null;
915
- if (!metadata || !sseClient) {
916
- return null;
917
- }
925
+ const resourceUri = metadata?.resourceUri;
926
+ const appSessionId = metadata?.sessionId;
918
927
  const iframeRef = useRef(null);
919
928
  const { host, error: hostError } = useAppHost(sseClient, iframeRef);
920
929
  const [isLaunched, setIsLaunched] = useState(false);
@@ -925,19 +934,23 @@ var McpAppRenderer = memo(function McpAppRenderer2({
925
934
  const lastResultRef = useRef(result);
926
935
  const lastStatusRef = useRef(status);
927
936
  useEffect(() => {
928
- if (!host || !metadata.resourceUri || !metadata.sessionId) return;
929
- host.launch(metadata.resourceUri, metadata.sessionId).then(() => setIsLaunched(true)).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
930
- }, [host, metadata.resourceUri, metadata.sessionId]);
937
+ setIsLaunched(false);
938
+ setError(null);
939
+ }, [resourceUri, appSessionId]);
940
+ useEffect(() => {
941
+ if (!host || !resourceUri || !appSessionId) return;
942
+ host.launch(resourceUri, appSessionId).then(() => setIsLaunched(true)).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
943
+ }, [host, resourceUri, appSessionId]);
931
944
  useEffect(() => {
932
- if (!host || !isLaunched || !input) return;
945
+ if (!host || !isLaunched || !resourceUri || !appSessionId || !input) return;
933
946
  if (!sentInputRef.current || JSON.stringify(input) !== JSON.stringify(lastInputRef.current)) {
934
947
  sentInputRef.current = true;
935
948
  lastInputRef.current = input;
936
949
  host.sendToolInput(input);
937
950
  }
938
- }, [host, isLaunched, input]);
951
+ }, [host, isLaunched, input, resourceUri, appSessionId, name]);
939
952
  useEffect(() => {
940
- if (!host || !isLaunched || result === void 0) return;
953
+ if (!host || !isLaunched || !resourceUri || !appSessionId || result === void 0) return;
941
954
  if (status !== "complete") return;
942
955
  if (!sentResultRef.current || JSON.stringify(result) !== JSON.stringify(lastResultRef.current)) {
943
956
  sentResultRef.current = true;
@@ -945,7 +958,7 @@ var McpAppRenderer = memo(function McpAppRenderer2({
945
958
  const formattedResult = typeof result === "string" ? { content: [{ type: "text", text: result }] } : result;
946
959
  host.sendToolResult(formattedResult);
947
960
  }
948
- }, [host, isLaunched, result, status]);
961
+ }, [host, isLaunched, result, status, resourceUri, appSessionId, name]);
949
962
  useEffect(() => {
950
963
  if (status === "executing" && lastStatusRef.current !== "executing") {
951
964
  sentInputRef.current = false;
@@ -953,6 +966,9 @@ var McpAppRenderer = memo(function McpAppRenderer2({
953
966
  }
954
967
  lastStatusRef.current = status;
955
968
  }, [status]);
969
+ if (!metadata || !sseClient) {
970
+ return null;
971
+ }
956
972
  const displayError = error || hostError;
957
973
  if (displayError) {
958
974
  return /* @__PURE__ */ jsxs("div", { className: `p-4 bg-red-900/20 border border-red-700 rounded text-red-200 ${className || ""}`, children: [
@@ -975,33 +991,43 @@ var McpAppRenderer = memo(function McpAppRenderer2({
975
991
  ] });
976
992
  });
977
993
  function useMcpApps(mcpClient) {
994
+ const clientRef = useRef(mcpClient);
995
+ clientRef.current = mcpClient;
978
996
  const getAppMetadata = useCallback(
979
- (toolName) => {
980
- if (!mcpClient) return void 0;
981
- const extractedName = extractToolName(toolName);
982
- for (const conn of mcpClient.connections) {
983
- for (const tool of conn.tools) {
984
- const candidateName = extractToolName(tool.name);
985
- const resourceUri = tool.mcpApp?.resourceUri ?? tool._meta?.ui?.resourceUri ?? tool._meta?.["ui/resourceUri"];
986
- if (resourceUri && candidateName === extractedName) {
987
- return {
988
- toolName: candidateName,
989
- resourceUri,
990
- sessionId: conn.sessionId
991
- };
992
- }
993
- }
994
- }
995
- return void 0;
996
- },
997
- [mcpClient]
997
+ (toolName) => getMcpAppMetadata(clientRef.current, toolName),
998
+ []
998
999
  );
1000
+ const McpAppRenderer = useMemo(() => {
1001
+ const Renderer = memo(function McpAppRenderer2(props) {
1002
+ return /* @__PURE__ */ jsx(McpAppView, { clientRef, ...props });
1003
+ });
1004
+ Renderer.displayName = "McpAppRenderer";
1005
+ return Renderer;
1006
+ }, []);
999
1007
  return { getAppMetadata, McpAppRenderer };
1000
1008
  }
1001
1009
  function extractToolName(fullName) {
1002
1010
  const match = fullName.match(/(?:tool_[^_]+_)?(.+)$/);
1003
1011
  return match?.[1] || fullName;
1004
1012
  }
1013
+ function getMcpAppMetadata(mcpClient, toolName) {
1014
+ if (!mcpClient) return void 0;
1015
+ const extractedName = extractToolName(toolName);
1016
+ for (const conn of mcpClient.connections) {
1017
+ for (const tool of conn.tools) {
1018
+ const candidateName = extractToolName(tool.name);
1019
+ const resourceUri = tool.mcpApp?.resourceUri ?? tool._meta?.ui?.resourceUri ?? tool._meta?.["ui/resourceUri"];
1020
+ if (resourceUri && candidateName === extractedName) {
1021
+ return {
1022
+ toolName: candidateName,
1023
+ resourceUri,
1024
+ sessionId: conn.sessionId
1025
+ };
1026
+ }
1027
+ }
1028
+ }
1029
+ return void 0;
1030
+ }
1005
1031
 
1006
1032
  export { AppHost, SSEClient, useAppHost, useMcp, useMcpApps };
1007
1033
  //# sourceMappingURL=react.mjs.map