mcp-use 1.2.1-canary.0 → 1.2.2-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/chunk-C3SRZK7H.js +1339 -0
- package/dist/{chunk-JV7HAYUT.js → chunk-CPV4QNHD.js} +126 -293
- package/dist/{chunk-ZUEQQ6YK.js → chunk-EYAIJPBH.js} +3 -235
- package/dist/{chunk-MGUO7HXB.js → chunk-UVUM35MV.js} +3 -957
- package/dist/chunk-VPPILX7B.js +239 -0
- package/dist/index.cjs +223 -303
- package/dist/index.js +11 -10
- package/dist/{langfuse-6AJGHMAV.js → langfuse-MO3AMDBE.js} +2 -1
- package/dist/src/agents/prompts/system_prompt_builder.d.ts.map +1 -1
- package/dist/src/browser.cjs +67 -20
- package/dist/src/browser.js +10 -45
- package/dist/src/client/browser.d.ts.map +1 -1
- package/dist/src/connectors/base.d.ts +46 -4
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/connectors/websocket.d.ts +2 -5
- package/dist/src/connectors/websocket.d.ts.map +1 -1
- package/dist/src/react/index.cjs +1394 -285
- package/dist/src/react/index.js +3 -2
- package/dist/src/react/types.d.ts +22 -0
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts +31 -0
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-62GFHYCL.js +0 -300
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BrowserMCPClient,
|
|
2
3
|
BrowserOAuthClientProvider
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-C3SRZK7H.js";
|
|
4
5
|
import {
|
|
5
6
|
__name
|
|
6
7
|
} from "./chunk-SHUYVCID.js";
|
|
7
8
|
|
|
8
9
|
// src/react/useMcp.ts
|
|
9
|
-
import {
|
|
10
|
-
CallToolResultSchema,
|
|
11
|
-
GetPromptResultSchema,
|
|
12
|
-
ListPromptsResultSchema,
|
|
13
|
-
ListResourcesResultSchema,
|
|
14
|
-
ListToolsResultSchema,
|
|
15
|
-
ReadResourceResultSchema
|
|
16
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
17
10
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
18
|
-
import { auth, UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
19
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
20
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
21
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
22
11
|
import { sanitizeUrl } from "strict-url-sanitise";
|
|
23
12
|
|
|
24
13
|
// src/utils/assert.ts
|
|
@@ -63,7 +52,6 @@ function useMcp(options) {
|
|
|
63
52
|
const [log, setLog] = useState([]);
|
|
64
53
|
const [authUrl, setAuthUrl] = useState(void 0);
|
|
65
54
|
const clientRef = useRef(null);
|
|
66
|
-
const transportRef = useRef(null);
|
|
67
55
|
const authProviderRef = useRef(null);
|
|
68
56
|
const connectingRef = useRef(false);
|
|
69
57
|
const isMountedRef = useRef(true);
|
|
@@ -92,9 +80,15 @@ function useMcp(options) {
|
|
|
92
80
|
connectingRef.current = false;
|
|
93
81
|
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
94
82
|
authTimeoutRef.current = null;
|
|
95
|
-
|
|
83
|
+
if (clientRef.current) {
|
|
84
|
+
try {
|
|
85
|
+
const serverName = "inspector-server";
|
|
86
|
+
await clientRef.current.closeSession(serverName);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
if (!quiet) addLog("warn", "Error closing session:", err);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
96
91
|
clientRef.current = null;
|
|
97
|
-
transportRef.current = null;
|
|
98
92
|
if (isMountedRef.current && !quiet) {
|
|
99
93
|
setState("discovering");
|
|
100
94
|
setTools([]);
|
|
@@ -104,14 +98,6 @@ function useMcp(options) {
|
|
|
104
98
|
setError(void 0);
|
|
105
99
|
setAuthUrl(void 0);
|
|
106
100
|
}
|
|
107
|
-
if (transport) {
|
|
108
|
-
try {
|
|
109
|
-
await transport.close();
|
|
110
|
-
if (!quiet) addLog("debug", "Transport closed");
|
|
111
|
-
} catch (err) {
|
|
112
|
-
if (!quiet) addLog("warn", "Error closing transport:", err);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
101
|
},
|
|
116
102
|
[addLog]
|
|
117
103
|
);
|
|
@@ -163,187 +149,60 @@ function useMcp(options) {
|
|
|
163
149
|
addLog("debug", "BrowserOAuthClientProvider initialized in connect.");
|
|
164
150
|
}
|
|
165
151
|
if (!clientRef.current) {
|
|
166
|
-
clientRef.current = new
|
|
167
|
-
|
|
168
|
-
{ capabilities: {} }
|
|
169
|
-
);
|
|
170
|
-
addLog("debug", "MCP Client initialized in connect.");
|
|
152
|
+
clientRef.current = new BrowserMCPClient();
|
|
153
|
+
addLog("debug", "BrowserMCPClient initialized in connect.");
|
|
171
154
|
}
|
|
172
155
|
const tryConnectWithTransport = /* @__PURE__ */ __name(async (transportTypeParam, isAuthRetry = false) => {
|
|
173
|
-
addLog("info", `Attempting connection with ${transportTypeParam
|
|
174
|
-
if (stateRef.current !== "authenticating") {
|
|
175
|
-
setState("connecting");
|
|
176
|
-
}
|
|
177
|
-
let transportInstance;
|
|
156
|
+
addLog("info", `Attempting connection with transport: ${transportTypeParam}`);
|
|
178
157
|
try {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
transportRef.current = null;
|
|
184
|
-
}
|
|
185
|
-
const commonOptions = {
|
|
186
|
-
authProvider: authProviderRef.current,
|
|
187
|
-
requestInit: {
|
|
188
|
-
headers: {
|
|
189
|
-
Accept: "application/json, text/event-stream",
|
|
190
|
-
...customHeaders
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
// Note: The MCP SDK's SSEClientTransport doesn't expose timeout configuration directly
|
|
194
|
-
// Timeout handling is managed by the underlying EventSource and browser/Node.js fetch implementations
|
|
195
|
-
// The timeout and sseReadTimeout options are preserved for future use or custom implementations
|
|
158
|
+
const serverName = "inspector-server";
|
|
159
|
+
const serverConfig = {
|
|
160
|
+
url,
|
|
161
|
+
transport: transportTypeParam === "sse" ? "http" : transportTypeParam
|
|
196
162
|
};
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
addLog("debug", `Creating ${transportTypeParam.toUpperCase()} transport for URL: ${targetUrl.toString()}`);
|
|
200
|
-
if (transportTypeParam === "http") {
|
|
201
|
-
addLog("debug", "Creating StreamableHTTPClientTransport...");
|
|
202
|
-
transportInstance = new StreamableHTTPClientTransport(targetUrl, commonOptions);
|
|
203
|
-
addLog("debug", "StreamableHTTPClientTransport created successfully");
|
|
204
|
-
} else {
|
|
205
|
-
addLog("debug", "Creating SSEClientTransport...");
|
|
206
|
-
transportInstance = new SSEClientTransport(targetUrl, commonOptions);
|
|
207
|
-
addLog("debug", "SSEClientTransport created successfully");
|
|
163
|
+
if (customHeaders && Object.keys(customHeaders).length > 0) {
|
|
164
|
+
serverConfig.headers = customHeaders;
|
|
208
165
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return "failed";
|
|
217
|
-
}
|
|
218
|
-
transportInstance.onmessage = (message) => {
|
|
219
|
-
addLog("debug", `[Transport] Received: ${JSON.stringify(message)}`);
|
|
220
|
-
clientRef.current?.handleMessage?.(message);
|
|
221
|
-
};
|
|
222
|
-
transportInstance.onerror = (err) => {
|
|
223
|
-
addLog("warn", `Transport error event (${transportTypeParam.toUpperCase()}):`, err);
|
|
224
|
-
failConnection(`Transport error (${transportTypeParam.toUpperCase()}): ${err.message}`, err);
|
|
225
|
-
};
|
|
226
|
-
transportInstance.onclose = () => {
|
|
227
|
-
if (!isMountedRef.current || connectingRef.current) return;
|
|
228
|
-
addLog("info", `Transport connection closed (${successfulTransportRef.current || "unknown"} type).`);
|
|
229
|
-
const currentState = stateRef.current;
|
|
230
|
-
const currentAutoReconnect = autoReconnectRef.current;
|
|
231
|
-
if (currentState === "ready" && currentAutoReconnect) {
|
|
232
|
-
const delay = typeof currentAutoReconnect === "number" ? currentAutoReconnect : DEFAULT_RECONNECT_DELAY;
|
|
233
|
-
addLog("info", `Attempting to reconnect in ${delay}ms...`);
|
|
234
|
-
setState("connecting");
|
|
235
|
-
setTimeout(() => {
|
|
236
|
-
if (isMountedRef.current) {
|
|
237
|
-
connect();
|
|
238
|
-
}
|
|
239
|
-
}, delay);
|
|
240
|
-
} else if (currentState !== "failed" && currentState !== "authenticating") {
|
|
241
|
-
failConnection("Cannot connect to server");
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
try {
|
|
245
|
-
addLog("info", `Connecting client via ${transportTypeParam.toUpperCase()}...`);
|
|
246
|
-
await clientRef.current.connect(transportInstance);
|
|
247
|
-
addLog("info", `Client connected via ${transportTypeParam.toUpperCase()}. Loading tools, resources, and prompts...`);
|
|
248
|
-
successfulTransportRef.current = transportTypeParam;
|
|
249
|
-
setState("loading");
|
|
250
|
-
const toolsResponse = await clientRef.current.request({ method: "tools/list" }, ListToolsResultSchema);
|
|
251
|
-
let resourcesResponse = { resources: [], resourceTemplates: [] };
|
|
252
|
-
try {
|
|
253
|
-
resourcesResponse = await clientRef.current.request({ method: "resources/list" }, ListResourcesResultSchema);
|
|
254
|
-
} catch (err) {
|
|
255
|
-
addLog("debug", "Server does not support resources/list method", err);
|
|
256
|
-
}
|
|
257
|
-
let promptsResponse = { prompts: [] };
|
|
258
|
-
try {
|
|
259
|
-
promptsResponse = await clientRef.current.request({ method: "prompts/list" }, ListPromptsResultSchema);
|
|
260
|
-
} catch (err) {
|
|
261
|
-
addLog("debug", "Server does not support prompts/list method", err);
|
|
262
|
-
}
|
|
263
|
-
if (isMountedRef.current) {
|
|
264
|
-
setTools(toolsResponse.tools);
|
|
265
|
-
setResources(resourcesResponse.resources);
|
|
266
|
-
setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
|
|
267
|
-
setPrompts(promptsResponse.prompts);
|
|
268
|
-
const summary = [`Loaded ${toolsResponse.tools.length} tools`];
|
|
269
|
-
if (resourcesResponse.resources.length > 0 || resourcesResponse.resourceTemplates && resourcesResponse.resourceTemplates.length > 0) {
|
|
270
|
-
summary.push(`${resourcesResponse.resources.length} resources`);
|
|
271
|
-
if (Array.isArray(resourcesResponse.resourceTemplates) && resourcesResponse.resourceTemplates.length > 0) {
|
|
272
|
-
summary.push(`${resourcesResponse.resourceTemplates.length} resource templates`);
|
|
273
|
-
}
|
|
166
|
+
if (authProviderRef.current) {
|
|
167
|
+
const tokens = await authProviderRef.current.tokens();
|
|
168
|
+
if (tokens?.access_token) {
|
|
169
|
+
serverConfig.headers = {
|
|
170
|
+
...serverConfig.headers,
|
|
171
|
+
Authorization: `Bearer ${tokens.access_token}`
|
|
172
|
+
};
|
|
274
173
|
}
|
|
275
|
-
if (promptsResponse.prompts.length > 0) {
|
|
276
|
-
summary.push(`${promptsResponse.prompts.length} prompts`);
|
|
277
|
-
}
|
|
278
|
-
addLog("info", summary.join(", ") + ".");
|
|
279
|
-
setState("ready");
|
|
280
|
-
connectAttemptRef.current = 0;
|
|
281
|
-
return "success";
|
|
282
|
-
} else {
|
|
283
|
-
return "failed";
|
|
284
174
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (preventAutoAuth && !existingTokens) {
|
|
306
|
-
addLog("info", "Authentication required but auto-auth prevented. User action needed.");
|
|
307
|
-
setState("pending_auth");
|
|
308
|
-
return "auth_redirect";
|
|
309
|
-
}
|
|
310
|
-
if (stateRef.current !== "authenticating" && stateRef.current !== "pending_auth") {
|
|
311
|
-
setState("authenticating");
|
|
312
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
313
|
-
authTimeoutRef.current = setTimeout(() => {
|
|
314
|
-
if (isMountedRef.current) {
|
|
315
|
-
const currentState = stateRef.current;
|
|
316
|
-
if (currentState === "authenticating") {
|
|
317
|
-
failConnection("Authentication timed out. Please try again.");
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}, AUTH_TIMEOUT);
|
|
321
|
-
}
|
|
322
|
-
try {
|
|
323
|
-
assert(url, "Server URL is required for authentication");
|
|
324
|
-
const baseUrl = new URL(url).origin;
|
|
325
|
-
const authResult = await auth(authProviderRef.current, { serverUrl: baseUrl });
|
|
326
|
-
if (!isMountedRef.current) return "failed";
|
|
327
|
-
if (authResult === "AUTHORIZED") {
|
|
328
|
-
addLog("info", "Authentication successful via existing token or refresh. Retrying transport connection...");
|
|
329
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
330
|
-
authTimeoutRef.current = null;
|
|
331
|
-
return await tryConnectWithTransport(transportTypeParam, true);
|
|
332
|
-
} else if (authResult === "REDIRECT") {
|
|
333
|
-
addLog("info", "Redirecting for authentication. Waiting for callback...");
|
|
334
|
-
return "auth_redirect";
|
|
335
|
-
}
|
|
336
|
-
} catch (sdkAuthError) {
|
|
337
|
-
if (!isMountedRef.current) return "failed";
|
|
338
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
175
|
+
clientRef.current.addServer(serverName, {
|
|
176
|
+
...serverConfig,
|
|
177
|
+
authProvider: authProviderRef.current
|
|
178
|
+
// ← SDK handles OAuth automatically!
|
|
179
|
+
});
|
|
180
|
+
const session = await clientRef.current.createSession(serverName);
|
|
181
|
+
await session.initialize();
|
|
182
|
+
addLog("info", "\u2705 Successfully connected to MCP server");
|
|
183
|
+
setState("ready");
|
|
184
|
+
successfulTransportRef.current = transportTypeParam;
|
|
185
|
+
setTools(session.connector.tools || []);
|
|
186
|
+
const resourcesResult = await session.connector.listAllResources();
|
|
187
|
+
setResources(resourcesResult.resources || []);
|
|
188
|
+
const promptsResult = await session.connector.listPrompts();
|
|
189
|
+
setPrompts(promptsResult.prompts || []);
|
|
190
|
+
return "success";
|
|
191
|
+
} catch (err) {
|
|
192
|
+
const errorMessage = err?.message || String(err);
|
|
193
|
+
if (err.code === 401 || errorMessage.includes("401") || errorMessage.includes("Unauthorized")) {
|
|
194
|
+
if (customHeaders && Object.keys(customHeaders).length > 0) {
|
|
339
195
|
failConnection(
|
|
340
|
-
|
|
341
|
-
sdkAuthError instanceof Error ? sdkAuthError : void 0
|
|
196
|
+
"Authentication failed: Server returned 401 Unauthorized. Check your Authorization header value is correct."
|
|
342
197
|
);
|
|
343
198
|
return "failed";
|
|
344
199
|
}
|
|
200
|
+
failConnection(
|
|
201
|
+
"Authentication required: Server returned 401 Unauthorized. Add an Authorization header in the Custom Headers section (e.g., Authorization: Bearer YOUR_API_KEY)."
|
|
202
|
+
);
|
|
203
|
+
return "failed";
|
|
345
204
|
}
|
|
346
|
-
failConnection(
|
|
205
|
+
failConnection(errorMessage, err);
|
|
347
206
|
return "failed";
|
|
348
207
|
}
|
|
349
208
|
}, "tryConnectWithTransport");
|
|
@@ -395,55 +254,20 @@ function useMcp(options) {
|
|
|
395
254
|
}
|
|
396
255
|
addLog("info", `Calling tool: ${name}`, args);
|
|
397
256
|
try {
|
|
398
|
-
const
|
|
257
|
+
const serverName = "inspector-server";
|
|
258
|
+
const session = clientRef.current.getSession(serverName);
|
|
259
|
+
if (!session) {
|
|
260
|
+
throw new Error("No active session found");
|
|
261
|
+
}
|
|
262
|
+
const result = await session.connector.callTool(name, args || {});
|
|
399
263
|
addLog("info", `Tool "${name}" call successful:`, result);
|
|
400
264
|
return result;
|
|
401
265
|
} catch (err) {
|
|
402
|
-
addLog("error", `
|
|
403
|
-
|
|
404
|
-
if (errorInstance instanceof UnauthorizedError || errorInstance.message.includes("Unauthorized") || errorInstance.message.includes("401")) {
|
|
405
|
-
addLog("warn", "Tool call unauthorized, attempting re-authentication...");
|
|
406
|
-
setState("authenticating");
|
|
407
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
408
|
-
authTimeoutRef.current = setTimeout(() => {
|
|
409
|
-
if (isMountedRef.current) {
|
|
410
|
-
const currentState2 = stateRef.current;
|
|
411
|
-
if (currentState2 === "authenticating") {
|
|
412
|
-
failConnection("Authentication timed out. Please try again.");
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}, AUTH_TIMEOUT);
|
|
416
|
-
try {
|
|
417
|
-
assert(authProviderRef.current, "Auth Provider not available for tool re-auth");
|
|
418
|
-
assert(url, "Server URL is required for authentication");
|
|
419
|
-
const baseUrl = new URL(url).origin;
|
|
420
|
-
const authResult = await auth(authProviderRef.current, { serverUrl: baseUrl });
|
|
421
|
-
if (!isMountedRef.current) return;
|
|
422
|
-
if (authResult === "AUTHORIZED") {
|
|
423
|
-
addLog("info", "Re-authentication successful. Retrying tool call is recommended, or reconnecting.");
|
|
424
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
425
|
-
connectingRef.current = false;
|
|
426
|
-
connect();
|
|
427
|
-
} else if (authResult === "REDIRECT") {
|
|
428
|
-
addLog("info", "Redirecting for re-authentication for tool call.");
|
|
429
|
-
}
|
|
430
|
-
} catch (sdkAuthError) {
|
|
431
|
-
if (!isMountedRef.current) return;
|
|
432
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
433
|
-
failConnection(
|
|
434
|
-
`Re-authentication failed: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
|
|
435
|
-
sdkAuthError instanceof Error ? sdkAuthError : void 0
|
|
436
|
-
);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
const currentState = stateRef.current;
|
|
440
|
-
if (currentState !== "authenticating") {
|
|
441
|
-
throw err;
|
|
442
|
-
}
|
|
443
|
-
return void 0;
|
|
266
|
+
addLog("error", `Tool "${name}" call failed:`, err);
|
|
267
|
+
throw err;
|
|
444
268
|
}
|
|
445
269
|
},
|
|
446
|
-
[state
|
|
270
|
+
[state]
|
|
447
271
|
);
|
|
448
272
|
const retry = useCallback(() => {
|
|
449
273
|
if (stateRef.current === "failed") {
|
|
@@ -474,17 +298,7 @@ function useMcp(options) {
|
|
|
474
298
|
try {
|
|
475
299
|
assert(authProviderRef.current, "Auth Provider not available for manual auth");
|
|
476
300
|
assert(url, "Server URL is required for authentication");
|
|
477
|
-
|
|
478
|
-
const authResult = await auth(authProviderRef.current, { serverUrl: baseUrl });
|
|
479
|
-
if (!isMountedRef.current) return;
|
|
480
|
-
if (authResult === "AUTHORIZED") {
|
|
481
|
-
addLog("info", "Manual authentication successful. Re-attempting connection...");
|
|
482
|
-
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
483
|
-
connectingRef.current = false;
|
|
484
|
-
connect();
|
|
485
|
-
} else if (authResult === "REDIRECT") {
|
|
486
|
-
addLog("info", "Redirecting for manual authentication. Waiting for callback...");
|
|
487
|
-
}
|
|
301
|
+
addLog("info", "Redirecting for manual authentication. Waiting for callback...");
|
|
488
302
|
} catch (authError) {
|
|
489
303
|
if (!isMountedRef.current) return;
|
|
490
304
|
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);
|
|
@@ -517,75 +331,93 @@ function useMcp(options) {
|
|
|
517
331
|
addLog("warn", "Auth provider not initialized, cannot clear storage.");
|
|
518
332
|
}
|
|
519
333
|
}, [url, addLog, disconnect]);
|
|
520
|
-
const listResources = useCallback(
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
addLog("info", "Listing resources...");
|
|
525
|
-
try {
|
|
526
|
-
const resourcesResponse = await clientRef.current.request({ method: "resources/list" }, ListResourcesResultSchema);
|
|
527
|
-
if (isMountedRef.current) {
|
|
528
|
-
setResources(resourcesResponse.resources);
|
|
529
|
-
setResourceTemplates(Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates : []);
|
|
530
|
-
addLog(
|
|
531
|
-
"info",
|
|
532
|
-
`Listed ${resourcesResponse.resources.length} resources, ${Array.isArray(resourcesResponse.resourceTemplates) ? resourcesResponse.resourceTemplates.length : 0} resource templates.`
|
|
533
|
-
);
|
|
334
|
+
const listResources = useCallback(
|
|
335
|
+
async () => {
|
|
336
|
+
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
337
|
+
throw new Error(`MCP client is not ready (current state: ${state}). Cannot list resources.`);
|
|
534
338
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
339
|
+
addLog("info", "Listing resources");
|
|
340
|
+
try {
|
|
341
|
+
const serverName = "inspector-server";
|
|
342
|
+
const session = clientRef.current.getSession(serverName);
|
|
343
|
+
if (!session) {
|
|
344
|
+
throw new Error("No active session found");
|
|
345
|
+
}
|
|
346
|
+
const resourcesResult = await session.connector.listAllResources();
|
|
347
|
+
setResources(resourcesResult.resources || []);
|
|
348
|
+
addLog("info", "Resources listed successfully");
|
|
349
|
+
} catch (err) {
|
|
350
|
+
addLog("error", "List resources failed:", err);
|
|
351
|
+
throw err;
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
[state]
|
|
355
|
+
);
|
|
540
356
|
const readResource = useCallback(
|
|
541
357
|
async (uri) => {
|
|
542
358
|
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
543
|
-
throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource
|
|
359
|
+
throw new Error(`MCP client is not ready (current state: ${state}). Cannot read resource.`);
|
|
544
360
|
}
|
|
545
361
|
addLog("info", `Reading resource: ${uri}`);
|
|
546
362
|
try {
|
|
547
|
-
const
|
|
548
|
-
|
|
363
|
+
const serverName = "inspector-server";
|
|
364
|
+
const session = clientRef.current.getSession(serverName);
|
|
365
|
+
if (!session) {
|
|
366
|
+
throw new Error("No active session found");
|
|
367
|
+
}
|
|
368
|
+
const result = await session.connector.readResource(uri);
|
|
369
|
+
addLog("info", "Resource read successful:", result);
|
|
549
370
|
return result;
|
|
550
371
|
} catch (err) {
|
|
551
|
-
addLog("error",
|
|
372
|
+
addLog("error", "Resource read failed:", err);
|
|
552
373
|
throw err;
|
|
553
374
|
}
|
|
554
375
|
},
|
|
555
|
-
[state
|
|
376
|
+
[state]
|
|
556
377
|
);
|
|
557
|
-
const listPrompts = useCallback(
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
addLog("info", "Listing prompts...");
|
|
562
|
-
try {
|
|
563
|
-
const promptsResponse = await clientRef.current.request({ method: "prompts/list" }, ListPromptsResultSchema);
|
|
564
|
-
if (isMountedRef.current) {
|
|
565
|
-
setPrompts(promptsResponse.prompts);
|
|
566
|
-
addLog("info", `Listed ${promptsResponse.prompts.length} prompts.`);
|
|
378
|
+
const listPrompts = useCallback(
|
|
379
|
+
async () => {
|
|
380
|
+
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
381
|
+
throw new Error(`MCP client is not ready (current state: ${state}). Cannot list prompts.`);
|
|
567
382
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
383
|
+
addLog("info", "Listing prompts");
|
|
384
|
+
try {
|
|
385
|
+
const serverName = "inspector-server";
|
|
386
|
+
const session = clientRef.current.getSession(serverName);
|
|
387
|
+
if (!session) {
|
|
388
|
+
throw new Error("No active session found");
|
|
389
|
+
}
|
|
390
|
+
const promptsResult = await session.connector.listPrompts();
|
|
391
|
+
setPrompts(promptsResult.prompts || []);
|
|
392
|
+
addLog("info", "Prompts listed successfully");
|
|
393
|
+
} catch (err) {
|
|
394
|
+
addLog("error", "List prompts failed:", err);
|
|
395
|
+
throw err;
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
[state]
|
|
399
|
+
);
|
|
573
400
|
const getPrompt = useCallback(
|
|
574
401
|
async (name, args) => {
|
|
575
402
|
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
576
|
-
throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt
|
|
403
|
+
throw new Error(`MCP client is not ready (current state: ${state}). Cannot get prompt.`);
|
|
577
404
|
}
|
|
578
405
|
addLog("info", `Getting prompt: ${name}`, args);
|
|
579
406
|
try {
|
|
580
|
-
const
|
|
581
|
-
|
|
407
|
+
const serverName = "inspector-server";
|
|
408
|
+
const session = clientRef.current.getSession(serverName);
|
|
409
|
+
if (!session) {
|
|
410
|
+
throw new Error("No active session found");
|
|
411
|
+
}
|
|
412
|
+
const result = await session.connector.getPrompt(name, args || {});
|
|
413
|
+
addLog("info", `Prompt "${name}" retrieved successfully:`, result);
|
|
582
414
|
return result;
|
|
583
415
|
} catch (err) {
|
|
584
|
-
addLog("error", `
|
|
416
|
+
addLog("error", `Prompt "${name}" retrieval failed:`, err);
|
|
585
417
|
throw err;
|
|
586
418
|
}
|
|
587
419
|
},
|
|
588
|
-
[state
|
|
420
|
+
[state]
|
|
589
421
|
);
|
|
590
422
|
const connectRef = useRef(connect);
|
|
591
423
|
const failConnectionRef = useRef(failConnection);
|
|
@@ -678,9 +510,10 @@ function useMcp(options) {
|
|
|
678
510
|
error,
|
|
679
511
|
log,
|
|
680
512
|
authUrl,
|
|
513
|
+
client: clientRef.current,
|
|
681
514
|
callTool,
|
|
682
|
-
listResources,
|
|
683
515
|
readResource,
|
|
516
|
+
listResources,
|
|
684
517
|
listPrompts,
|
|
685
518
|
getPrompt,
|
|
686
519
|
retry,
|