mcp-use 1.2.1 → 1.2.2-canary.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 (155) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/chunk-3RJENWH4.js +248 -0
  3. package/dist/{chunk-MGUO7HXB.js → chunk-7UX634PO.js} +307 -1066
  4. package/dist/chunk-KLIBVJ3Z.js +759 -0
  5. package/dist/chunk-MZLETWQQ.js +250 -0
  6. package/dist/chunk-RSGKBEHH.js +1411 -0
  7. package/dist/index.cjs +880 -541
  8. package/dist/index.d.ts +24 -24
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +92 -33
  11. package/dist/{langfuse-6AJGHMAV.js → langfuse-LCJ6VJEP.js} +2 -1
  12. package/dist/src/adapters/base.d.ts +2 -2
  13. package/dist/src/adapters/base.d.ts.map +1 -1
  14. package/dist/src/adapters/index.d.ts +2 -2
  15. package/dist/src/adapters/index.d.ts.map +1 -1
  16. package/dist/src/adapters/langchain_adapter.d.ts +4 -4
  17. package/dist/src/adapters/langchain_adapter.d.ts.map +1 -1
  18. package/dist/src/agents/base.d.ts +1 -1
  19. package/dist/src/agents/base.d.ts.map +1 -1
  20. package/dist/src/agents/index.d.ts +3 -3
  21. package/dist/src/agents/index.d.ts.map +1 -1
  22. package/dist/src/agents/mcp_agent.d.ts +12 -12
  23. package/dist/src/agents/mcp_agent.d.ts.map +1 -1
  24. package/dist/src/agents/prompts/system_prompt_builder.d.ts +2 -2
  25. package/dist/src/agents/prompts/system_prompt_builder.d.ts.map +1 -1
  26. package/dist/src/agents/prompts/templates.d.ts.map +1 -1
  27. package/dist/src/agents/remote.d.ts +2 -2
  28. package/dist/src/agents/remote.d.ts.map +1 -1
  29. package/dist/src/agents/types.d.ts +1 -1
  30. package/dist/src/agents/types.d.ts.map +1 -1
  31. package/dist/src/agents/utils/ai_sdk.d.ts +1 -1
  32. package/dist/src/agents/utils/ai_sdk.d.ts.map +1 -1
  33. package/dist/src/agents/utils/index.d.ts +1 -1
  34. package/dist/src/agents/utils/index.d.ts.map +1 -1
  35. package/dist/src/auth/browser-provider.d.ts +2 -2
  36. package/dist/src/auth/browser-provider.d.ts.map +1 -1
  37. package/dist/src/auth/callback.d.ts.map +1 -1
  38. package/dist/src/auth/index.d.ts +3 -3
  39. package/dist/src/auth/index.d.ts.map +1 -1
  40. package/dist/src/auth/types.d.ts +1 -1
  41. package/dist/src/auth/types.d.ts.map +1 -1
  42. package/dist/src/browser.cjs +573 -219
  43. package/dist/src/browser.d.ts +17 -17
  44. package/dist/src/browser.d.ts.map +1 -1
  45. package/dist/src/browser.js +17 -46
  46. package/dist/src/client/base.d.ts +2 -2
  47. package/dist/src/client/base.d.ts.map +1 -1
  48. package/dist/src/client/browser.d.ts +2 -2
  49. package/dist/src/client/browser.d.ts.map +1 -1
  50. package/dist/src/client.d.ts +2 -2
  51. package/dist/src/client.d.ts.map +1 -1
  52. package/dist/src/config.d.ts +1 -1
  53. package/dist/src/config.d.ts.map +1 -1
  54. package/dist/src/connectors/base.d.ts +51 -9
  55. package/dist/src/connectors/base.d.ts.map +1 -1
  56. package/dist/src/connectors/http.d.ts +3 -3
  57. package/dist/src/connectors/http.d.ts.map +1 -1
  58. package/dist/src/connectors/index.d.ts +4 -4
  59. package/dist/src/connectors/index.d.ts.map +1 -1
  60. package/dist/src/connectors/stdio.d.ts +3 -3
  61. package/dist/src/connectors/stdio.d.ts.map +1 -1
  62. package/dist/src/connectors/websocket.d.ts +4 -7
  63. package/dist/src/connectors/websocket.d.ts.map +1 -1
  64. package/dist/src/logging.d.ts +4 -4
  65. package/dist/src/logging.d.ts.map +1 -1
  66. package/dist/src/managers/index.d.ts +2 -2
  67. package/dist/src/managers/index.d.ts.map +1 -1
  68. package/dist/src/managers/server_manager.d.ts +4 -4
  69. package/dist/src/managers/server_manager.d.ts.map +1 -1
  70. package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +3 -3
  71. package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
  72. package/dist/src/managers/tools/add_server_from_config.d.ts +3 -3
  73. package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
  74. package/dist/src/managers/tools/base.d.ts +6 -6
  75. package/dist/src/managers/tools/base.d.ts.map +1 -1
  76. package/dist/src/managers/tools/connect_mcp_server.d.ts +4 -4
  77. package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
  78. package/dist/src/managers/tools/index.d.ts +5 -5
  79. package/dist/src/managers/tools/index.d.ts.map +1 -1
  80. package/dist/src/managers/tools/list_mcp_servers.d.ts +3 -3
  81. package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
  82. package/dist/src/managers/tools/release_mcp_server_connection.d.ts +3 -3
  83. package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
  84. package/dist/src/managers/types.d.ts +3 -3
  85. package/dist/src/managers/types.d.ts.map +1 -1
  86. package/dist/src/oauth-helper.d.ts.map +1 -1
  87. package/dist/src/observability/index.d.ts +3 -3
  88. package/dist/src/observability/index.d.ts.map +1 -1
  89. package/dist/src/observability/langfuse.d.ts +1 -1
  90. package/dist/src/observability/langfuse.d.ts.map +1 -1
  91. package/dist/src/observability/manager.d.ts +1 -1
  92. package/dist/src/observability/manager.d.ts.map +1 -1
  93. package/dist/src/observability/types.d.ts +1 -1
  94. package/dist/src/observability/types.d.ts.map +1 -1
  95. package/dist/src/react/index.cjs +1571 -321
  96. package/dist/src/react/index.d.ts +6 -6
  97. package/dist/src/react/index.d.ts.map +1 -1
  98. package/dist/src/react/index.js +3 -2
  99. package/dist/src/react/types.d.ts +27 -5
  100. package/dist/src/react/types.d.ts.map +1 -1
  101. package/dist/src/react/useMcp.d.ts +32 -1
  102. package/dist/src/react/useMcp.d.ts.map +1 -1
  103. package/dist/src/react/useWidget.d.ts +5 -2
  104. package/dist/src/react/useWidget.d.ts.map +1 -1
  105. package/dist/src/react/widget-types.d.ts +3 -3
  106. package/dist/src/react/widget-types.d.ts.map +1 -1
  107. package/dist/src/server/adapters/mcp-ui-adapter.d.ts +3 -3
  108. package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -1
  109. package/dist/src/server/index.cjs +170 -50
  110. package/dist/src/server/index.d.ts +4 -4
  111. package/dist/src/server/index.d.ts.map +1 -1
  112. package/dist/src/server/index.js +174 -51
  113. package/dist/src/server/logging.d.ts +1 -1
  114. package/dist/src/server/logging.d.ts.map +1 -1
  115. package/dist/src/server/mcp-server.d.ts +29 -29
  116. package/dist/src/server/mcp-server.d.ts.map +1 -1
  117. package/dist/src/server/types/common.d.ts +2 -2
  118. package/dist/src/server/types/common.d.ts.map +1 -1
  119. package/dist/src/server/types/index.d.ts +4 -4
  120. package/dist/src/server/types/index.d.ts.map +1 -1
  121. package/dist/src/server/types/prompt.d.ts +2 -2
  122. package/dist/src/server/types/prompt.d.ts.map +1 -1
  123. package/dist/src/server/types/resource.d.ts +24 -24
  124. package/dist/src/server/types/resource.d.ts.map +1 -1
  125. package/dist/src/server/types/tool.d.ts +3 -3
  126. package/dist/src/server/types/tool.d.ts.map +1 -1
  127. package/dist/src/server/types/widget.d.ts +1 -1
  128. package/dist/src/server/types.d.ts +1 -1
  129. package/dist/src/server/types.d.ts.map +1 -1
  130. package/dist/src/session.d.ts +1 -1
  131. package/dist/src/session.d.ts.map +1 -1
  132. package/dist/src/task_managers/base.d.ts.map +1 -1
  133. package/dist/src/task_managers/index.d.ts +5 -5
  134. package/dist/src/task_managers/index.d.ts.map +1 -1
  135. package/dist/src/task_managers/sse.d.ts +3 -3
  136. package/dist/src/task_managers/sse.d.ts.map +1 -1
  137. package/dist/src/task_managers/stdio.d.ts +4 -4
  138. package/dist/src/task_managers/stdio.d.ts.map +1 -1
  139. package/dist/src/task_managers/streamable_http.d.ts +3 -3
  140. package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
  141. package/dist/src/task_managers/websocket.d.ts +2 -2
  142. package/dist/src/task_managers/websocket.d.ts.map +1 -1
  143. package/dist/src/telemetry/events.d.ts.map +1 -1
  144. package/dist/src/telemetry/index.d.ts +4 -4
  145. package/dist/src/telemetry/index.d.ts.map +1 -1
  146. package/dist/src/telemetry/telemetry.d.ts +1 -1
  147. package/dist/src/telemetry/telemetry.d.ts.map +1 -1
  148. package/dist/src/telemetry/utils.d.ts +1 -1
  149. package/dist/src/telemetry/utils.d.ts.map +1 -1
  150. package/dist/tsup.config.d.ts.map +1 -1
  151. package/dist/vitest.config.d.ts.map +1 -1
  152. package/package.json +3 -3
  153. package/dist/chunk-62GFHYCL.js +0 -300
  154. package/dist/chunk-JV7HAYUT.js +0 -860
  155. package/dist/chunk-ZUEQQ6YK.js +0 -444
@@ -0,0 +1,759 @@
1
+ import {
2
+ BrowserMCPClient,
3
+ BrowserOAuthClientProvider
4
+ } from "./chunk-RSGKBEHH.js";
5
+ import {
6
+ __name
7
+ } from "./chunk-SHUYVCID.js";
8
+
9
+ // src/react/useMcp.ts
10
+ import { useCallback, useEffect, useRef, useState } from "react";
11
+ import { sanitizeUrl } from "strict-url-sanitise";
12
+
13
+ // src/utils/assert.ts
14
+ function assert(condition, message) {
15
+ if (!condition) {
16
+ throw new Error(message);
17
+ }
18
+ }
19
+ __name(assert, "assert");
20
+
21
+ // src/react/useMcp.ts
22
+ var DEFAULT_RECONNECT_DELAY = 3e3;
23
+ var DEFAULT_RETRY_DELAY = 5e3;
24
+ var AUTH_TIMEOUT = 5 * 60 * 1e3;
25
+ function useMcp(options) {
26
+ const {
27
+ url,
28
+ enabled = true,
29
+ clientName,
30
+ clientUri,
31
+ callbackUrl = typeof window !== "undefined" ? sanitizeUrl(
32
+ new URL("/oauth/callback", window.location.origin).toString()
33
+ ) : "/oauth/callback",
34
+ storageKeyPrefix = "mcp:auth",
35
+ clientConfig = {},
36
+ customHeaders = {},
37
+ debug: _debug = false,
38
+ autoRetry = false,
39
+ autoReconnect = DEFAULT_RECONNECT_DELAY,
40
+ transportType = "auto",
41
+ preventAutoAuth = false,
42
+ onPopupWindow,
43
+ timeout = 3e4,
44
+ // 30 seconds default for connection timeout
45
+ sseReadTimeout = 3e5
46
+ // 5 minutes default for SSE read timeout
47
+ } = options;
48
+ const [state, setState] = useState("discovering");
49
+ const [tools, setTools] = useState([]);
50
+ const [resources, setResources] = useState([]);
51
+ const [resourceTemplates, setResourceTemplates] = useState([]);
52
+ const [prompts, setPrompts] = useState([]);
53
+ const [error, setError] = useState(void 0);
54
+ const [log, setLog] = useState([]);
55
+ const [authUrl, setAuthUrl] = useState(void 0);
56
+ const clientRef = useRef(null);
57
+ const authProviderRef = useRef(null);
58
+ const connectingRef = useRef(false);
59
+ const isMountedRef = useRef(true);
60
+ const connectAttemptRef = useRef(0);
61
+ const authTimeoutRef = useRef(null);
62
+ const stateRef = useRef(state);
63
+ const autoReconnectRef = useRef(autoReconnect);
64
+ const successfulTransportRef = useRef(null);
65
+ useEffect(() => {
66
+ stateRef.current = state;
67
+ autoReconnectRef.current = autoReconnect;
68
+ }, [state, autoReconnect]);
69
+ const addLog = useCallback(
70
+ (level, message, ...args) => {
71
+ const fullMessage = args.length > 0 ? `${message} ${args.map((arg) => JSON.stringify(arg)).join(" ")}` : message;
72
+ console[level](`[useMcp] ${fullMessage}`);
73
+ if (isMountedRef.current) {
74
+ setLog((prevLog) => [
75
+ ...prevLog.slice(-100),
76
+ { level, message: fullMessage, timestamp: Date.now() }
77
+ ]);
78
+ }
79
+ },
80
+ []
81
+ );
82
+ const disconnect = useCallback(
83
+ async (quiet = false) => {
84
+ if (!quiet) addLog("info", "Disconnecting...");
85
+ connectingRef.current = false;
86
+ if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
87
+ authTimeoutRef.current = null;
88
+ if (clientRef.current) {
89
+ try {
90
+ const serverName = "inspector-server";
91
+ await clientRef.current.closeSession(serverName);
92
+ } catch (err) {
93
+ if (!quiet) addLog("warn", "Error closing session:", err);
94
+ }
95
+ }
96
+ clientRef.current = null;
97
+ if (isMountedRef.current && !quiet) {
98
+ setState("discovering");
99
+ setTools([]);
100
+ setResources([]);
101
+ setResourceTemplates([]);
102
+ setPrompts([]);
103
+ setError(void 0);
104
+ setAuthUrl(void 0);
105
+ }
106
+ },
107
+ [addLog]
108
+ );
109
+ const failConnection = useCallback(
110
+ (errorMessage, connectionError) => {
111
+ addLog("error", errorMessage, connectionError ?? "");
112
+ if (isMountedRef.current) {
113
+ setState("failed");
114
+ setError(errorMessage);
115
+ const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl();
116
+ if (manualUrl) {
117
+ setAuthUrl(manualUrl);
118
+ addLog(
119
+ "info",
120
+ "Manual authentication URL may be available.",
121
+ manualUrl
122
+ );
123
+ }
124
+ }
125
+ connectingRef.current = false;
126
+ },
127
+ [addLog]
128
+ );
129
+ const connect = useCallback(async () => {
130
+ if (!enabled || !url) {
131
+ addLog(
132
+ "debug",
133
+ enabled ? "No server URL provided, skipping connection." : "Connection disabled via enabled flag."
134
+ );
135
+ return;
136
+ }
137
+ if (connectingRef.current) {
138
+ addLog("debug", "Connection attempt already in progress.");
139
+ return;
140
+ }
141
+ if (!isMountedRef.current) {
142
+ addLog("debug", "Connect called after unmount, aborting.");
143
+ return;
144
+ }
145
+ connectingRef.current = true;
146
+ connectAttemptRef.current += 1;
147
+ setError(void 0);
148
+ setAuthUrl(void 0);
149
+ successfulTransportRef.current = null;
150
+ setState("discovering");
151
+ addLog(
152
+ "info",
153
+ `Connecting attempt #${connectAttemptRef.current} to ${url}...`
154
+ );
155
+ if (!authProviderRef.current) {
156
+ authProviderRef.current = new BrowserOAuthClientProvider(url, {
157
+ storageKeyPrefix,
158
+ clientName,
159
+ clientUri,
160
+ callbackUrl,
161
+ preventAutoAuth,
162
+ onPopupWindow
163
+ });
164
+ addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
165
+ }
166
+ if (!clientRef.current) {
167
+ clientRef.current = new BrowserMCPClient();
168
+ addLog("debug", "BrowserMCPClient initialized in connect.");
169
+ }
170
+ const tryConnectWithTransport = /* @__PURE__ */ __name(async (transportTypeParam, isAuthRetry = false) => {
171
+ addLog(
172
+ "info",
173
+ `Attempting connection with transport: ${transportTypeParam}`
174
+ );
175
+ try {
176
+ const serverName = "inspector-server";
177
+ const serverConfig = {
178
+ url,
179
+ transport: transportTypeParam === "sse" ? "http" : transportTypeParam
180
+ };
181
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
182
+ serverConfig.headers = customHeaders;
183
+ }
184
+ if (authProviderRef.current) {
185
+ const tokens = await authProviderRef.current.tokens();
186
+ if (tokens?.access_token) {
187
+ serverConfig.headers = {
188
+ ...serverConfig.headers,
189
+ Authorization: `Bearer ${tokens.access_token}`
190
+ };
191
+ }
192
+ }
193
+ clientRef.current.addServer(serverName, {
194
+ ...serverConfig,
195
+ authProvider: authProviderRef.current
196
+ // ← SDK handles OAuth automatically!
197
+ });
198
+ const session = await clientRef.current.createSession(serverName);
199
+ await session.initialize();
200
+ addLog("info", "\u2705 Successfully connected to MCP server");
201
+ setState("ready");
202
+ successfulTransportRef.current = transportTypeParam;
203
+ setTools(session.connector.tools || []);
204
+ const resourcesResult = await session.connector.listAllResources();
205
+ setResources(resourcesResult.resources || []);
206
+ const promptsResult = await session.connector.listPrompts();
207
+ setPrompts(promptsResult.prompts || []);
208
+ return "success";
209
+ } catch (err) {
210
+ const errorMessage = err?.message || String(err);
211
+ if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
212
+ if (customHeaders && Object.keys(customHeaders).length > 0) {
213
+ failConnection(
214
+ "Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
215
+ );
216
+ return "failed";
217
+ }
218
+ failConnection(
219
+ "Authentication required: Server returned 401 Unauthorized. Add an Authorization header in the Custom Headers section (e.g., Authorization: Bearer YOUR_API_KEY)."
220
+ );
221
+ return "failed";
222
+ }
223
+ failConnection(errorMessage, err);
224
+ return "failed";
225
+ }
226
+ }, "tryConnectWithTransport");
227
+ let finalStatus = "failed";
228
+ if (transportType === "sse") {
229
+ addLog("debug", "Using SSE-only transport mode");
230
+ finalStatus = await tryConnectWithTransport("sse");
231
+ } else if (transportType === "http") {
232
+ addLog("debug", "Using HTTP-only transport mode");
233
+ finalStatus = await tryConnectWithTransport("http");
234
+ } else {
235
+ addLog("debug", "Using auto transport mode (HTTP with SSE fallback)");
236
+ const httpResult = await tryConnectWithTransport("http");
237
+ if (httpResult === "fallback" && isMountedRef.current && stateRef.current !== "authenticating") {
238
+ addLog("info", "HTTP failed, attempting SSE fallback...");
239
+ const sseResult = await tryConnectWithTransport("sse");
240
+ finalStatus = sseResult;
241
+ } else {
242
+ finalStatus = httpResult;
243
+ }
244
+ }
245
+ if (finalStatus === "success" || finalStatus === "failed" || finalStatus === "auth_redirect") {
246
+ connectingRef.current = false;
247
+ }
248
+ addLog("debug", `Connection sequence finished with status: ${finalStatus}`);
249
+ }, [
250
+ addLog,
251
+ failConnection,
252
+ disconnect,
253
+ url,
254
+ storageKeyPrefix,
255
+ clientName,
256
+ clientUri,
257
+ callbackUrl,
258
+ clientConfig.name,
259
+ clientConfig.version,
260
+ customHeaders,
261
+ transportType,
262
+ preventAutoAuth,
263
+ onPopupWindow,
264
+ enabled,
265
+ timeout,
266
+ sseReadTimeout
267
+ ]);
268
+ const callTool = useCallback(
269
+ async (name, args) => {
270
+ if (stateRef.current !== "ready" || !clientRef.current) {
271
+ throw new Error(
272
+ `MCP client is not ready (current state: ${state}). Cannot call tool "${name}".`
273
+ );
274
+ }
275
+ addLog("info", `Calling tool: ${name}`, args);
276
+ try {
277
+ const serverName = "inspector-server";
278
+ const session = clientRef.current.getSession(serverName);
279
+ if (!session) {
280
+ throw new Error("No active session found");
281
+ }
282
+ const result = await session.connector.callTool(name, args || {});
283
+ addLog("info", `Tool "${name}" call successful:`, result);
284
+ return result;
285
+ } catch (err) {
286
+ addLog("error", `Tool "${name}" call failed:`, err);
287
+ throw err;
288
+ }
289
+ },
290
+ [state]
291
+ );
292
+ const retry = useCallback(() => {
293
+ if (stateRef.current === "failed") {
294
+ addLog("info", "Retry requested...");
295
+ connect();
296
+ } else {
297
+ addLog(
298
+ "warn",
299
+ `Retry called but state is not 'failed' (state: ${stateRef.current}). Ignoring.`
300
+ );
301
+ }
302
+ }, [addLog, connect]);
303
+ const authenticate = useCallback(async () => {
304
+ addLog("info", "Manual authentication requested...");
305
+ const currentState = stateRef.current;
306
+ if (currentState === "failed") {
307
+ addLog("info", "Attempting to reconnect and authenticate via retry...");
308
+ retry();
309
+ } else if (currentState === "pending_auth") {
310
+ addLog("info", "Proceeding with authentication from pending state...");
311
+ setState("authenticating");
312
+ if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
313
+ authTimeoutRef.current = setTimeout(() => {
314
+ if (isMountedRef.current) {
315
+ const currentStateValue = stateRef.current;
316
+ if (currentStateValue === "authenticating") {
317
+ failConnection("Authentication timed out. Please try again.");
318
+ }
319
+ }
320
+ }, AUTH_TIMEOUT);
321
+ try {
322
+ assert(
323
+ authProviderRef.current,
324
+ "Auth Provider not available for manual auth"
325
+ );
326
+ assert(url, "Server URL is required for authentication");
327
+ addLog(
328
+ "info",
329
+ "Redirecting for manual authentication. Waiting for callback..."
330
+ );
331
+ } catch (authError) {
332
+ if (!isMountedRef.current) return;
333
+ if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
334
+ failConnection(
335
+ `Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`,
336
+ authError instanceof Error ? authError : void 0
337
+ );
338
+ }
339
+ } else if (currentState === "authenticating") {
340
+ addLog(
341
+ "warn",
342
+ "Already attempting authentication. Check for blocked popups or wait for timeout."
343
+ );
344
+ const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl();
345
+ if (manualUrl && !authUrl) {
346
+ setAuthUrl(manualUrl);
347
+ addLog("info", "Manual authentication URL retrieved:", manualUrl);
348
+ }
349
+ } else {
350
+ addLog(
351
+ "info",
352
+ `Client not in a state requiring manual authentication trigger (state: ${currentState}). If needed, try disconnecting and reconnecting.`
353
+ );
354
+ }
355
+ }, [addLog, retry, authUrl, url, failConnection, connect]);
356
+ const clearStorage = useCallback(() => {
357
+ if (authProviderRef.current) {
358
+ const count = authProviderRef.current.clearStorage();
359
+ addLog("info", `Cleared ${count} item(s) from localStorage for ${url}.`);
360
+ setAuthUrl(void 0);
361
+ disconnect();
362
+ } else {
363
+ addLog("warn", "Auth provider not initialized, cannot clear storage.");
364
+ }
365
+ }, [url, addLog, disconnect]);
366
+ const listResources = useCallback(async () => {
367
+ if (stateRef.current !== "ready" || !clientRef.current) {
368
+ throw new Error(
369
+ `MCP client is not ready (current state: ${state}). Cannot list resources.`
370
+ );
371
+ }
372
+ addLog("info", "Listing resources");
373
+ try {
374
+ const serverName = "inspector-server";
375
+ const session = clientRef.current.getSession(serverName);
376
+ if (!session) {
377
+ throw new Error("No active session found");
378
+ }
379
+ const resourcesResult = await session.connector.listAllResources();
380
+ setResources(resourcesResult.resources || []);
381
+ addLog("info", "Resources listed successfully");
382
+ } catch (err) {
383
+ addLog("error", "List resources failed:", err);
384
+ throw err;
385
+ }
386
+ }, [state]);
387
+ const readResource = useCallback(
388
+ async (uri) => {
389
+ if (stateRef.current !== "ready" || !clientRef.current) {
390
+ throw new Error(
391
+ `MCP client is not ready (current state: ${state}). Cannot read resource.`
392
+ );
393
+ }
394
+ addLog("info", `Reading resource: ${uri}`);
395
+ try {
396
+ const serverName = "inspector-server";
397
+ const session = clientRef.current.getSession(serverName);
398
+ if (!session) {
399
+ throw new Error("No active session found");
400
+ }
401
+ const result = await session.connector.readResource(uri);
402
+ addLog("info", "Resource read successful:", result);
403
+ return result;
404
+ } catch (err) {
405
+ addLog("error", "Resource read failed:", err);
406
+ throw err;
407
+ }
408
+ },
409
+ [state]
410
+ );
411
+ const listPrompts = useCallback(async () => {
412
+ if (stateRef.current !== "ready" || !clientRef.current) {
413
+ throw new Error(
414
+ `MCP client is not ready (current state: ${state}). Cannot list prompts.`
415
+ );
416
+ }
417
+ addLog("info", "Listing prompts");
418
+ try {
419
+ const serverName = "inspector-server";
420
+ const session = clientRef.current.getSession(serverName);
421
+ if (!session) {
422
+ throw new Error("No active session found");
423
+ }
424
+ const promptsResult = await session.connector.listPrompts();
425
+ setPrompts(promptsResult.prompts || []);
426
+ addLog("info", "Prompts listed successfully");
427
+ } catch (err) {
428
+ addLog("error", "List prompts failed:", err);
429
+ throw err;
430
+ }
431
+ }, [state]);
432
+ const getPrompt = useCallback(
433
+ async (name, args) => {
434
+ if (stateRef.current !== "ready" || !clientRef.current) {
435
+ throw new Error(
436
+ `MCP client is not ready (current state: ${state}). Cannot get prompt.`
437
+ );
438
+ }
439
+ addLog("info", `Getting prompt: ${name}`, args);
440
+ try {
441
+ const serverName = "inspector-server";
442
+ const session = clientRef.current.getSession(serverName);
443
+ if (!session) {
444
+ throw new Error("No active session found");
445
+ }
446
+ const result = await session.connector.getPrompt(name, args || {});
447
+ addLog("info", `Prompt "${name}" retrieved successfully:`, result);
448
+ return result;
449
+ } catch (err) {
450
+ addLog("error", `Prompt "${name}" retrieval failed:`, err);
451
+ throw err;
452
+ }
453
+ },
454
+ [state]
455
+ );
456
+ const connectRef = useRef(connect);
457
+ const failConnectionRef = useRef(failConnection);
458
+ useEffect(() => {
459
+ connectRef.current = connect;
460
+ failConnectionRef.current = failConnection;
461
+ });
462
+ useEffect(() => {
463
+ const messageHandler = /* @__PURE__ */ __name((event) => {
464
+ if (event.origin !== window.location.origin) return;
465
+ if (event.data?.type === "mcp_auth_callback") {
466
+ addLog("info", "Received auth callback message.", event.data);
467
+ if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
468
+ authTimeoutRef.current = null;
469
+ if (event.data.success) {
470
+ addLog(
471
+ "info",
472
+ "Authentication successful via popup. Reconnecting client..."
473
+ );
474
+ if (connectingRef.current) {
475
+ addLog(
476
+ "debug",
477
+ "Connection attempt already in progress, resetting flag to allow reconnection."
478
+ );
479
+ }
480
+ connectingRef.current = false;
481
+ setTimeout(() => {
482
+ if (isMountedRef.current) {
483
+ addLog(
484
+ "debug",
485
+ "Initiating reconnection after successful auth callback."
486
+ );
487
+ connectRef.current();
488
+ }
489
+ }, 100);
490
+ } else {
491
+ failConnectionRef.current(
492
+ `Authentication failed in callback: ${event.data.error || "Unknown reason."}`
493
+ );
494
+ }
495
+ }
496
+ }, "messageHandler");
497
+ window.addEventListener("message", messageHandler);
498
+ addLog("debug", "Auth callback message listener added.");
499
+ return () => {
500
+ window.removeEventListener("message", messageHandler);
501
+ addLog("debug", "Auth callback message listener removed.");
502
+ if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
503
+ };
504
+ }, [addLog]);
505
+ useEffect(() => {
506
+ isMountedRef.current = true;
507
+ if (!enabled || !url) {
508
+ addLog(
509
+ "debug",
510
+ enabled ? "No server URL provided, skipping connection." : "Connection disabled via enabled flag."
511
+ );
512
+ setState("discovering");
513
+ return () => {
514
+ isMountedRef.current = false;
515
+ };
516
+ }
517
+ addLog("debug", "useMcp mounted, initiating connection.");
518
+ connectAttemptRef.current = 0;
519
+ if (!authProviderRef.current || authProviderRef.current.serverUrl !== url) {
520
+ authProviderRef.current = new BrowserOAuthClientProvider(url, {
521
+ storageKeyPrefix,
522
+ clientName,
523
+ clientUri,
524
+ callbackUrl,
525
+ preventAutoAuth,
526
+ onPopupWindow
527
+ });
528
+ addLog(
529
+ "debug",
530
+ "BrowserOAuthClientProvider initialized/updated on mount/option change."
531
+ );
532
+ }
533
+ connect();
534
+ return () => {
535
+ isMountedRef.current = false;
536
+ addLog("debug", "useMcp unmounting, disconnecting.");
537
+ disconnect(true);
538
+ };
539
+ }, [
540
+ url,
541
+ enabled,
542
+ storageKeyPrefix,
543
+ callbackUrl,
544
+ clientName,
545
+ clientUri,
546
+ clientConfig.name,
547
+ clientConfig.version
548
+ ]);
549
+ useEffect(() => {
550
+ let retryTimeoutId = null;
551
+ if (state === "failed" && autoRetry && connectAttemptRef.current > 0) {
552
+ const delay = typeof autoRetry === "number" ? autoRetry : DEFAULT_RETRY_DELAY;
553
+ addLog("info", `Connection failed, auto-retrying in ${delay}ms...`);
554
+ retryTimeoutId = setTimeout(() => {
555
+ if (isMountedRef.current && stateRef.current === "failed") {
556
+ retry();
557
+ }
558
+ }, delay);
559
+ }
560
+ return () => {
561
+ if (retryTimeoutId) clearTimeout(retryTimeoutId);
562
+ };
563
+ }, [state, autoRetry, retry, addLog]);
564
+ return {
565
+ state,
566
+ tools,
567
+ resources,
568
+ resourceTemplates,
569
+ prompts,
570
+ error,
571
+ log,
572
+ authUrl,
573
+ client: clientRef.current,
574
+ callTool,
575
+ readResource,
576
+ listResources,
577
+ listPrompts,
578
+ getPrompt,
579
+ retry,
580
+ disconnect,
581
+ authenticate,
582
+ clearStorage
583
+ };
584
+ }
585
+ __name(useMcp, "useMcp");
586
+
587
+ // src/react/useWidget.ts
588
+ import {
589
+ useCallback as useCallback2,
590
+ useEffect as useEffect2,
591
+ useMemo,
592
+ useState as useState2,
593
+ useSyncExternalStore
594
+ } from "react";
595
+
596
+ // src/react/widget-types.ts
597
+ var SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
598
+
599
+ // src/react/useWidget.ts
600
+ function useOpenAiGlobal(key) {
601
+ return useSyncExternalStore(
602
+ (onChange) => {
603
+ const handleSetGlobal = /* @__PURE__ */ __name((event) => {
604
+ const customEvent = event;
605
+ const value = customEvent.detail.globals[key];
606
+ if (value === void 0) {
607
+ return;
608
+ }
609
+ onChange();
610
+ }, "handleSetGlobal");
611
+ if (typeof window !== "undefined") {
612
+ window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);
613
+ }
614
+ return () => {
615
+ if (typeof window !== "undefined") {
616
+ window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);
617
+ }
618
+ };
619
+ },
620
+ () => typeof window !== "undefined" && window.openai ? window.openai[key] : void 0
621
+ );
622
+ }
623
+ __name(useOpenAiGlobal, "useOpenAiGlobal");
624
+ function useWidget(defaultProps) {
625
+ console.log(window?.location?.search, window.openai);
626
+ const isOpenAiAvailable = useMemo(
627
+ () => typeof window !== "undefined" && !!window.openai,
628
+ []
629
+ );
630
+ const provider = useMemo(() => {
631
+ return isOpenAiAvailable ? "openai" : "mcp-ui";
632
+ }, [isOpenAiAvailable]);
633
+ const urlParams = useMemo(() => {
634
+ const urlParams2 = new URLSearchParams(window?.location?.search);
635
+ if (urlParams2.has("mcpUseParams")) {
636
+ return JSON.parse(urlParams2.get("mcpUseParams"));
637
+ }
638
+ return {
639
+ toolInput: {},
640
+ toolOutput: {},
641
+ toolId: ""
642
+ };
643
+ }, [window?.location?.search]);
644
+ console.log(urlParams);
645
+ const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
646
+ const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
647
+ const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
648
+ const widgetState = useOpenAiGlobal("widgetState");
649
+ const theme = useOpenAiGlobal("theme");
650
+ const displayMode = useOpenAiGlobal("displayMode");
651
+ const safeArea = useOpenAiGlobal("safeArea");
652
+ const maxHeight = useOpenAiGlobal("maxHeight");
653
+ const userAgent = useOpenAiGlobal("userAgent");
654
+ const locale = useOpenAiGlobal("locale");
655
+ const [localWidgetState, setLocalWidgetState] = useState2(null);
656
+ useEffect2(() => {
657
+ if (widgetState !== void 0) {
658
+ setLocalWidgetState(widgetState);
659
+ }
660
+ }, [widgetState]);
661
+ const callTool = useCallback2(
662
+ async (name, args) => {
663
+ if (!window.openai?.callTool) {
664
+ throw new Error("window.openai.callTool is not available");
665
+ }
666
+ return window.openai.callTool(name, args);
667
+ },
668
+ []
669
+ );
670
+ const sendFollowUpMessage = useCallback2(
671
+ async (prompt) => {
672
+ if (!window.openai?.sendFollowUpMessage) {
673
+ throw new Error("window.openai.sendFollowUpMessage is not available");
674
+ }
675
+ return window.openai.sendFollowUpMessage({ prompt });
676
+ },
677
+ []
678
+ );
679
+ const openExternal = useCallback2((href) => {
680
+ if (!window.openai?.openExternal) {
681
+ throw new Error("window.openai.openExternal is not available");
682
+ }
683
+ window.openai.openExternal({ href });
684
+ }, []);
685
+ const requestDisplayMode = useCallback2(
686
+ async (mode) => {
687
+ if (!window.openai?.requestDisplayMode) {
688
+ throw new Error("window.openai.requestDisplayMode is not available");
689
+ }
690
+ return window.openai.requestDisplayMode({ mode });
691
+ },
692
+ []
693
+ );
694
+ const setState = useCallback2(
695
+ async (state) => {
696
+ const newState = typeof state === "function" ? state(localWidgetState) : state;
697
+ if (!window.openai?.setWidgetState) {
698
+ throw new Error("window.openai.setWidgetState is not available");
699
+ }
700
+ setLocalWidgetState(newState);
701
+ return window.openai.setWidgetState(newState);
702
+ },
703
+ [localWidgetState]
704
+ );
705
+ return {
706
+ // Props and state (with defaults)
707
+ props: toolInput || defaultProps || {},
708
+ output: toolOutput ?? null,
709
+ metadata: toolResponseMetadata ?? null,
710
+ state: localWidgetState,
711
+ setState,
712
+ // Layout and theme (with safe defaults)
713
+ theme: theme || "light",
714
+ displayMode: displayMode || "inline",
715
+ safeArea: safeArea || { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
716
+ maxHeight: maxHeight || 600,
717
+ userAgent: userAgent || {
718
+ device: { type: "desktop" },
719
+ capabilities: { hover: true, touch: false }
720
+ },
721
+ locale: locale || "en",
722
+ // Actions
723
+ callTool,
724
+ sendFollowUpMessage,
725
+ openExternal,
726
+ requestDisplayMode,
727
+ // Availability
728
+ isAvailable: isOpenAiAvailable
729
+ };
730
+ }
731
+ __name(useWidget, "useWidget");
732
+ function useWidgetProps(defaultProps) {
733
+ const { props } = useWidget(defaultProps);
734
+ return props;
735
+ }
736
+ __name(useWidgetProps, "useWidgetProps");
737
+ function useWidgetTheme() {
738
+ const { theme } = useWidget();
739
+ return theme;
740
+ }
741
+ __name(useWidgetTheme, "useWidgetTheme");
742
+ function useWidgetState(defaultState) {
743
+ const { state, setState } = useWidget();
744
+ useEffect2(() => {
745
+ if (state === null && defaultState !== void 0 && window.openai?.setWidgetState) {
746
+ setState(defaultState);
747
+ }
748
+ }, []);
749
+ return [state, setState];
750
+ }
751
+ __name(useWidgetState, "useWidgetState");
752
+
753
+ export {
754
+ useMcp,
755
+ useWidget,
756
+ useWidgetProps,
757
+ useWidgetTheme,
758
+ useWidgetState
759
+ };