mcp-use 1.11.0-canary.7 → 1.11.0-canary.9
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-REYY7LSD.js → chunk-5QFJZ7H3.js} +2 -2
- package/dist/chunk-D3CNYAYE.js +1055 -0
- package/dist/{chunk-OD6B7KGQ.js → chunk-ESMOFYJ6.js} +27 -2100
- package/dist/{chunk-WTGUJLTR.js → chunk-F3BZFJCD.js} +167 -7
- package/dist/chunk-GXNAXUDI.js +0 -0
- package/dist/{chunk-QP7MQ2UJ.js → chunk-HU2DGJ5J.js} +175 -133
- package/dist/{chunk-REX2YTWF.js → chunk-M7WATKYM.js} +1 -1
- package/dist/chunk-MFSO5PUW.js +1049 -0
- package/dist/{chunk-5LBXMCKC.js → chunk-N3DO4P2L.js} +27 -2100
- package/dist/{chunk-M7CHBY4S.js → chunk-OWPXM4QQ.js} +1 -1
- package/dist/{chunk-3QVRNWW7.js → chunk-Q5LZL6BH.js} +1 -1
- package/dist/{chunk-ZN3MKSKM.js → chunk-UCPSHMNO.js} +1 -1
- package/dist/chunk-UWWLWLS2.js +62 -0
- package/dist/chunk-WW3A2EKQ.js +1055 -0
- package/dist/{chunk-CHHWJQVC.js → chunk-XEFWIBQF.js} +1 -1
- package/dist/index.cjs +211 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -28
- package/dist/notifications-FLGIFS56.js +9 -0
- package/dist/src/adapters/index.cjs +1346 -0
- package/dist/src/adapters/index.js +11 -0
- package/dist/src/agents/index.cjs +46 -4
- package/dist/src/agents/index.js +8 -6
- package/dist/src/browser.cjs +46 -5
- package/dist/src/browser.d.ts +1 -1
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +15 -13
- package/dist/src/client/prompts.js +4 -4
- package/dist/src/client.cjs +3787 -0
- package/dist/src/client.js +20 -0
- package/dist/src/react/index.cjs +211 -9
- package/dist/src/react/index.js +5 -5
- package/dist/src/react/types.d.ts +41 -1
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/react/useWidget.d.ts +11 -7
- package/dist/src/react/useWidget.d.ts.map +1 -1
- package/dist/src/react/widget-types.d.ts +6 -2
- package/dist/src/react/widget-types.d.ts.map +1 -1
- package/dist/src/server/endpoints/mount-mcp.d.ts.map +1 -1
- package/dist/src/server/index.cjs +1269 -144
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +1158 -100
- package/dist/src/server/mcp-server.d.ts +5 -1
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/notifications/index.d.ts +1 -1
- package/dist/src/server/notifications/index.d.ts.map +1 -1
- package/dist/src/server/notifications/notification-registration.d.ts +51 -0
- package/dist/src/server/notifications/notification-registration.d.ts.map +1 -1
- package/dist/src/server/sessions/index.d.ts +3 -1
- package/dist/src/server/sessions/index.d.ts.map +1 -1
- package/dist/src/server/sessions/session-manager.d.ts +30 -16
- package/dist/src/server/sessions/session-manager.d.ts.map +1 -1
- package/dist/src/server/sessions/stores/filesystem.d.ts +121 -0
- package/dist/src/server/sessions/stores/filesystem.d.ts.map +1 -0
- package/dist/src/server/sessions/stores/index.d.ts +94 -0
- package/dist/src/server/sessions/stores/index.d.ts.map +1 -0
- package/dist/src/server/sessions/stores/memory.d.ts +82 -0
- package/dist/src/server/sessions/stores/memory.d.ts.map +1 -0
- package/dist/src/server/sessions/stores/redis.d.ts +164 -0
- package/dist/src/server/sessions/stores/redis.d.ts.map +1 -0
- package/dist/src/server/sessions/streams/index.d.ts +77 -0
- package/dist/src/server/sessions/streams/index.d.ts.map +1 -0
- package/dist/src/server/sessions/streams/memory.d.ts +76 -0
- package/dist/src/server/sessions/streams/memory.d.ts.map +1 -0
- package/dist/src/server/sessions/streams/redis.d.ts +146 -0
- package/dist/src/server/sessions/streams/redis.d.ts.map +1 -0
- package/dist/src/server/types/common.d.ts +105 -28
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/server/types/resource.d.ts +16 -0
- package/dist/src/server/types/resource.d.ts.map +1 -1
- package/dist/src/server/types/widget.d.ts +21 -2
- package/dist/src/server/types/widget.d.ts.map +1 -1
- package/dist/src/server/utils/response-helpers.d.ts +12 -6
- package/dist/src/server/utils/response-helpers.d.ts.map +1 -1
- package/dist/src/server/widgets/index.d.ts +1 -1
- package/dist/src/server/widgets/index.d.ts.map +1 -1
- package/dist/src/server/widgets/mount-widgets-dev.d.ts.map +1 -1
- package/dist/src/server/widgets/setup-widget-routes.d.ts.map +1 -1
- package/dist/src/server/widgets/ui-resource-registration.d.ts.map +1 -1
- package/dist/src/server/widgets/widget-helpers.d.ts +22 -0
- package/dist/src/server/widgets/widget-helpers.d.ts.map +1 -1
- package/dist/src/server/widgets/widget-types.d.ts +2 -0
- package/dist/src/server/widgets/widget-types.d.ts.map +1 -1
- package/dist/src/task_managers/index.d.ts +10 -0
- package/dist/src/task_managers/index.d.ts.map +1 -1
- package/dist/src/task_managers/sse.d.ts +34 -1
- package/dist/src/task_managers/sse.d.ts.map +1 -1
- package/dist/src/task_managers/streamable_http.d.ts +8 -2
- package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/{tool-execution-helpers-PAFGGAGL.js → tool-execution-helpers-MXVN6YNU.js} +2 -2
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +29 -5
- /package/dist/{chunk-H4BZVTGK.js → chunk-LGDFGYRL.js} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BrowserMCPClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5QFJZ7H3.js";
|
|
4
4
|
import {
|
|
5
5
|
BrowserOAuthClientProvider,
|
|
6
6
|
sanitizeUrl
|
|
7
7
|
} from "./chunk-J75I2C26.js";
|
|
8
8
|
import {
|
|
9
9
|
Tel
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Q5LZL6BH.js";
|
|
11
11
|
import {
|
|
12
12
|
__name
|
|
13
13
|
} from "./chunk-3GQAWCBQ.js";
|
|
@@ -101,6 +101,11 @@ function useMcp(options) {
|
|
|
101
101
|
if (clientRef.current) {
|
|
102
102
|
try {
|
|
103
103
|
const serverName = "inspector-server";
|
|
104
|
+
const session = clientRef.current.getSession(serverName);
|
|
105
|
+
if (session && session._healthCheckCleanup) {
|
|
106
|
+
session._healthCheckCleanup();
|
|
107
|
+
session._healthCheckCleanup = null;
|
|
108
|
+
}
|
|
104
109
|
await clientRef.current.closeSession(serverName);
|
|
105
110
|
} catch (err) {
|
|
106
111
|
if (!quiet) addLog("warn", "Error closing session:", err);
|
|
@@ -240,9 +245,25 @@ function useMcp(options) {
|
|
|
240
245
|
serverName,
|
|
241
246
|
false
|
|
242
247
|
);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
session.on("notification", (notification) => {
|
|
249
|
+
onNotification?.(notification);
|
|
250
|
+
if (notification.method === "notifications/tools/list_changed") {
|
|
251
|
+
addLog("info", "Tools list changed, auto-refreshing...");
|
|
252
|
+
refreshTools().catch(
|
|
253
|
+
(err) => addLog("warn", "Auto-refresh tools failed:", err)
|
|
254
|
+
);
|
|
255
|
+
} else if (notification.method === "notifications/resources/list_changed") {
|
|
256
|
+
addLog("info", "Resources list changed, auto-refreshing...");
|
|
257
|
+
refreshResources().catch(
|
|
258
|
+
(err) => addLog("warn", "Auto-refresh resources failed:", err)
|
|
259
|
+
);
|
|
260
|
+
} else if (notification.method === "notifications/prompts/list_changed") {
|
|
261
|
+
addLog("info", "Prompts list changed, auto-refreshing...");
|
|
262
|
+
refreshPrompts().catch(
|
|
263
|
+
(err) => addLog("warn", "Auto-refresh prompts failed:", err)
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
246
267
|
await session.initialize();
|
|
247
268
|
addLog("info", "\u2705 Successfully connected to MCP server");
|
|
248
269
|
addLog("info", "Server info:", session.connector.serverInfo);
|
|
@@ -258,6 +279,63 @@ function useMcp(options) {
|
|
|
258
279
|
);
|
|
259
280
|
setState("ready");
|
|
260
281
|
successfulTransportRef.current = transportTypeParam;
|
|
282
|
+
const setupConnectionMonitoring = /* @__PURE__ */ __name(() => {
|
|
283
|
+
let healthCheckInterval = null;
|
|
284
|
+
let lastSuccessfulCheck = Date.now();
|
|
285
|
+
const HEALTH_CHECK_INTERVAL = 1e4;
|
|
286
|
+
const HEALTH_CHECK_TIMEOUT = 3e4;
|
|
287
|
+
const checkConnectionHealth = /* @__PURE__ */ __name(async () => {
|
|
288
|
+
if (!isMountedRef.current || stateRef.current !== "ready") {
|
|
289
|
+
if (healthCheckInterval) {
|
|
290
|
+
clearInterval(healthCheckInterval);
|
|
291
|
+
healthCheckInterval = null;
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
await session.connector.listTools();
|
|
297
|
+
lastSuccessfulCheck = Date.now();
|
|
298
|
+
} catch (err) {
|
|
299
|
+
const timeSinceLastSuccess = Date.now() - lastSuccessfulCheck;
|
|
300
|
+
if (timeSinceLastSuccess > HEALTH_CHECK_TIMEOUT) {
|
|
301
|
+
addLog(
|
|
302
|
+
"warn",
|
|
303
|
+
`Connection appears to be broken (no response for ${Math.round(timeSinceLastSuccess / 1e3)}s), attempting to reconnect...`
|
|
304
|
+
);
|
|
305
|
+
if (healthCheckInterval) {
|
|
306
|
+
clearInterval(healthCheckInterval);
|
|
307
|
+
healthCheckInterval = null;
|
|
308
|
+
}
|
|
309
|
+
if (autoReconnectRef.current && isMountedRef.current) {
|
|
310
|
+
setState("discovering");
|
|
311
|
+
addLog("info", "Auto-reconnecting to MCP server...");
|
|
312
|
+
setTimeout(
|
|
313
|
+
() => {
|
|
314
|
+
if (isMountedRef.current && stateRef.current === "discovering") {
|
|
315
|
+
connect();
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
typeof autoReconnectRef.current === "number" ? autoReconnectRef.current : DEFAULT_RECONNECT_DELAY
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}, "checkConnectionHealth");
|
|
324
|
+
healthCheckInterval = setInterval(
|
|
325
|
+
checkConnectionHealth,
|
|
326
|
+
HEALTH_CHECK_INTERVAL
|
|
327
|
+
);
|
|
328
|
+
return () => {
|
|
329
|
+
if (healthCheckInterval) {
|
|
330
|
+
clearInterval(healthCheckInterval);
|
|
331
|
+
healthCheckInterval = null;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}, "setupConnectionMonitoring");
|
|
335
|
+
if (autoReconnect) {
|
|
336
|
+
const cleanup = setupConnectionMonitoring();
|
|
337
|
+
session._healthCheckCleanup = cleanup;
|
|
338
|
+
}
|
|
261
339
|
Tel.getInstance().trackUseMcpConnection({
|
|
262
340
|
url,
|
|
263
341
|
transportType: transportTypeParam,
|
|
@@ -609,6 +687,70 @@ function useMcp(options) {
|
|
|
609
687
|
throw err;
|
|
610
688
|
}
|
|
611
689
|
}, [state]);
|
|
690
|
+
const refreshTools = useCallback(async () => {
|
|
691
|
+
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
692
|
+
addLog("debug", "Cannot refresh tools - client not ready");
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
addLog("debug", "Refreshing tools list");
|
|
696
|
+
try {
|
|
697
|
+
const serverName = "inspector-server";
|
|
698
|
+
const session = clientRef.current.getSession(serverName);
|
|
699
|
+
if (!session) {
|
|
700
|
+
addLog("warn", "No active session found for tools refresh");
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
const toolsResult = await session.connector.listTools();
|
|
704
|
+
setTools(toolsResult || []);
|
|
705
|
+
addLog("info", "Tools list refreshed successfully");
|
|
706
|
+
} catch (err) {
|
|
707
|
+
addLog("warn", "Failed to refresh tools:", err);
|
|
708
|
+
}
|
|
709
|
+
}, [addLog]);
|
|
710
|
+
const refreshResources = useCallback(async () => {
|
|
711
|
+
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
712
|
+
addLog("debug", "Cannot refresh resources - client not ready");
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
addLog("debug", "Refreshing resources list");
|
|
716
|
+
try {
|
|
717
|
+
const serverName = "inspector-server";
|
|
718
|
+
const session = clientRef.current.getSession(serverName);
|
|
719
|
+
if (!session) {
|
|
720
|
+
addLog("warn", "No active session found for resources refresh");
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
const resourcesResult = await session.connector.listAllResources();
|
|
724
|
+
setResources(resourcesResult.resources || []);
|
|
725
|
+
addLog("info", "Resources list refreshed successfully");
|
|
726
|
+
} catch (err) {
|
|
727
|
+
addLog("warn", "Failed to refresh resources:", err);
|
|
728
|
+
}
|
|
729
|
+
}, [addLog]);
|
|
730
|
+
const refreshPrompts = useCallback(async () => {
|
|
731
|
+
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
732
|
+
addLog("debug", "Cannot refresh prompts - client not ready");
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
addLog("debug", "Refreshing prompts list");
|
|
736
|
+
try {
|
|
737
|
+
const serverName = "inspector-server";
|
|
738
|
+
const session = clientRef.current.getSession(serverName);
|
|
739
|
+
if (!session) {
|
|
740
|
+
addLog("warn", "No active session found for prompts refresh");
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
const promptsResult = await session.connector.listPrompts();
|
|
744
|
+
setPrompts(promptsResult.prompts || []);
|
|
745
|
+
addLog("info", "Prompts list refreshed successfully");
|
|
746
|
+
} catch (err) {
|
|
747
|
+
addLog("warn", "Failed to refresh prompts:", err);
|
|
748
|
+
}
|
|
749
|
+
}, [addLog]);
|
|
750
|
+
const refreshAll = useCallback(async () => {
|
|
751
|
+
addLog("info", "Refreshing all lists (tools, resources, prompts)");
|
|
752
|
+
await Promise.all([refreshTools(), refreshResources(), refreshPrompts()]);
|
|
753
|
+
}, [refreshTools, refreshResources, refreshPrompts, addLog]);
|
|
612
754
|
const getPrompt = useCallback(
|
|
613
755
|
async (name, args) => {
|
|
614
756
|
if (stateRef.current !== "ready" || !clientRef.current) {
|
|
@@ -760,6 +902,10 @@ function useMcp(options) {
|
|
|
760
902
|
listResources,
|
|
761
903
|
listPrompts,
|
|
762
904
|
getPrompt,
|
|
905
|
+
refreshTools,
|
|
906
|
+
refreshResources,
|
|
907
|
+
refreshPrompts,
|
|
908
|
+
refreshAll,
|
|
763
909
|
retry,
|
|
764
910
|
disconnect,
|
|
765
911
|
authenticate,
|
|
@@ -907,6 +1053,15 @@ function useWidget(defaultProps) {
|
|
|
907
1053
|
const toolInput = provider === "openai" ? useOpenAiGlobal("toolInput") : urlParams.toolInput;
|
|
908
1054
|
const toolOutput = provider === "openai" ? useOpenAiGlobal("toolOutput") : urlParams.toolOutput;
|
|
909
1055
|
const toolResponseMetadata = useOpenAiGlobal("toolResponseMetadata");
|
|
1056
|
+
const widgetProps = useMemo(() => {
|
|
1057
|
+
if (toolResponseMetadata && typeof toolResponseMetadata === "object") {
|
|
1058
|
+
const metaProps = toolResponseMetadata["mcp-use/props"];
|
|
1059
|
+
if (metaProps) {
|
|
1060
|
+
return metaProps;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return defaultProps || {};
|
|
1064
|
+
}, [toolResponseMetadata, defaultProps]);
|
|
910
1065
|
const widgetState = useOpenAiGlobal("widgetState");
|
|
911
1066
|
const theme = useOpenAiGlobal("theme");
|
|
912
1067
|
const displayMode = useOpenAiGlobal("displayMode");
|
|
@@ -971,9 +1126,13 @@ function useWidget(defaultProps) {
|
|
|
971
1126
|
},
|
|
972
1127
|
[widgetState, localWidgetState]
|
|
973
1128
|
);
|
|
1129
|
+
const isPending = useMemo(() => {
|
|
1130
|
+
return provider === "openai" && toolResponseMetadata === null;
|
|
1131
|
+
}, [provider, toolResponseMetadata]);
|
|
974
1132
|
return {
|
|
975
1133
|
// Props and state (with defaults)
|
|
976
|
-
props:
|
|
1134
|
+
props: widgetProps,
|
|
1135
|
+
toolInput: toolInput || {},
|
|
977
1136
|
output: toolOutput ?? null,
|
|
978
1137
|
metadata: toolResponseMetadata ?? null,
|
|
979
1138
|
state: localWidgetState,
|
|
@@ -995,7 +1154,8 @@ function useWidget(defaultProps) {
|
|
|
995
1154
|
openExternal,
|
|
996
1155
|
requestDisplayMode,
|
|
997
1156
|
// Availability
|
|
998
|
-
isAvailable: isOpenAiAvailable
|
|
1157
|
+
isAvailable: isOpenAiAvailable,
|
|
1158
|
+
isPending
|
|
999
1159
|
};
|
|
1000
1160
|
}
|
|
1001
1161
|
__name(useWidget, "useWidget");
|
|
File without changes
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BaseConnector
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XEFWIBQF.js";
|
|
4
4
|
import {
|
|
5
5
|
Tel
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Q5LZL6BH.js";
|
|
7
7
|
import {
|
|
8
8
|
logger
|
|
9
9
|
} from "./chunk-FRUZDWXH.js";
|
|
@@ -284,6 +284,134 @@ var MCPSession = class {
|
|
|
284
284
|
}
|
|
285
285
|
};
|
|
286
286
|
|
|
287
|
+
// src/client/base.ts
|
|
288
|
+
var BaseMCPClient = class {
|
|
289
|
+
static {
|
|
290
|
+
__name(this, "BaseMCPClient");
|
|
291
|
+
}
|
|
292
|
+
config = {};
|
|
293
|
+
sessions = {};
|
|
294
|
+
activeSessions = [];
|
|
295
|
+
constructor(config) {
|
|
296
|
+
if (config) {
|
|
297
|
+
this.config = config;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
static fromDict(_cfg) {
|
|
301
|
+
throw new Error("fromDict must be implemented by concrete class");
|
|
302
|
+
}
|
|
303
|
+
addServer(name, serverConfig) {
|
|
304
|
+
this.config.mcpServers = this.config.mcpServers || {};
|
|
305
|
+
this.config.mcpServers[name] = serverConfig;
|
|
306
|
+
Tel.getInstance().trackClientAddServer(name, serverConfig);
|
|
307
|
+
}
|
|
308
|
+
removeServer(name) {
|
|
309
|
+
if (this.config.mcpServers?.[name]) {
|
|
310
|
+
delete this.config.mcpServers[name];
|
|
311
|
+
this.activeSessions = this.activeSessions.filter((n) => n !== name);
|
|
312
|
+
Tel.getInstance().trackClientRemoveServer(name);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
getServerNames() {
|
|
316
|
+
return Object.keys(this.config.mcpServers ?? {});
|
|
317
|
+
}
|
|
318
|
+
getServerConfig(name) {
|
|
319
|
+
return this.config.mcpServers?.[name];
|
|
320
|
+
}
|
|
321
|
+
getConfig() {
|
|
322
|
+
return this.config ?? {};
|
|
323
|
+
}
|
|
324
|
+
async createSession(serverName, autoInitialize = true) {
|
|
325
|
+
const servers = this.config.mcpServers ?? {};
|
|
326
|
+
if (Object.keys(servers).length === 0) {
|
|
327
|
+
logger.warn("No MCP servers defined in config");
|
|
328
|
+
}
|
|
329
|
+
if (!servers[serverName]) {
|
|
330
|
+
throw new Error(`Server '${serverName}' not found in config`);
|
|
331
|
+
}
|
|
332
|
+
const connector = this.createConnectorFromConfig(servers[serverName]);
|
|
333
|
+
const session = new MCPSession(connector);
|
|
334
|
+
if (autoInitialize) {
|
|
335
|
+
await session.initialize();
|
|
336
|
+
}
|
|
337
|
+
this.sessions[serverName] = session;
|
|
338
|
+
if (!this.activeSessions.includes(serverName)) {
|
|
339
|
+
this.activeSessions.push(serverName);
|
|
340
|
+
}
|
|
341
|
+
return session;
|
|
342
|
+
}
|
|
343
|
+
async createAllSessions(autoInitialize = true) {
|
|
344
|
+
const servers = this.config.mcpServers ?? {};
|
|
345
|
+
if (Object.keys(servers).length === 0) {
|
|
346
|
+
logger.warn("No MCP servers defined in config");
|
|
347
|
+
}
|
|
348
|
+
for (const name of Object.keys(servers)) {
|
|
349
|
+
await this.createSession(name, autoInitialize);
|
|
350
|
+
}
|
|
351
|
+
return this.sessions;
|
|
352
|
+
}
|
|
353
|
+
getSession(serverName) {
|
|
354
|
+
const session = this.sessions[serverName];
|
|
355
|
+
if (!session) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
return session;
|
|
359
|
+
}
|
|
360
|
+
requireSession(serverName) {
|
|
361
|
+
const session = this.sessions[serverName];
|
|
362
|
+
if (!session) {
|
|
363
|
+
throw new Error(
|
|
364
|
+
`Session '${serverName}' not found. Available sessions: ${this.activeSessions.join(", ") || "none"}`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
return session;
|
|
368
|
+
}
|
|
369
|
+
getAllActiveSessions() {
|
|
370
|
+
return Object.fromEntries(
|
|
371
|
+
this.activeSessions.map((n) => [n, this.sessions[n]])
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
async closeSession(serverName) {
|
|
375
|
+
const session = this.sessions[serverName];
|
|
376
|
+
if (!session) {
|
|
377
|
+
logger.warn(
|
|
378
|
+
`No session exists for server ${serverName}, nothing to close`
|
|
379
|
+
);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
try {
|
|
383
|
+
logger.debug(`Closing session for server ${serverName}`);
|
|
384
|
+
await session.disconnect();
|
|
385
|
+
} catch (e) {
|
|
386
|
+
logger.error(`Error closing session for server '${serverName}': ${e}`);
|
|
387
|
+
} finally {
|
|
388
|
+
delete this.sessions[serverName];
|
|
389
|
+
this.activeSessions = this.activeSessions.filter((n) => n !== serverName);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
async closeAllSessions() {
|
|
393
|
+
const serverNames = Object.keys(this.sessions);
|
|
394
|
+
const errors = [];
|
|
395
|
+
for (const serverName of serverNames) {
|
|
396
|
+
try {
|
|
397
|
+
logger.debug(`Closing session for server ${serverName}`);
|
|
398
|
+
await this.closeSession(serverName);
|
|
399
|
+
} catch (e) {
|
|
400
|
+
const errorMsg = `Failed to close session for server '${serverName}': ${e}`;
|
|
401
|
+
logger.error(errorMsg);
|
|
402
|
+
errors.push(errorMsg);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (errors.length) {
|
|
406
|
+
logger.error(
|
|
407
|
+
`Encountered ${errors.length} errors while closing sessions`
|
|
408
|
+
);
|
|
409
|
+
} else {
|
|
410
|
+
logger.debug("All sessions closed successfully");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
|
|
287
415
|
// src/connectors/http.ts
|
|
288
416
|
import { Client } from "@mcp-use/modelcontextprotocol-sdk/client/index.js";
|
|
289
417
|
import {
|
|
@@ -419,6 +547,7 @@ var SseConnectionManager = class extends ConnectionManager {
|
|
|
419
547
|
url;
|
|
420
548
|
opts;
|
|
421
549
|
_transport = null;
|
|
550
|
+
reinitializing = false;
|
|
422
551
|
/**
|
|
423
552
|
* Create an SSE connection manager.
|
|
424
553
|
*
|
|
@@ -431,12 +560,53 @@ var SseConnectionManager = class extends ConnectionManager {
|
|
|
431
560
|
this.opts = opts;
|
|
432
561
|
}
|
|
433
562
|
/**
|
|
434
|
-
* Spawn a new `SSEClientTransport` and
|
|
563
|
+
* Spawn a new `SSEClientTransport` and wrap it with 404 handling.
|
|
564
|
+
* Per MCP spec, clients MUST re-initialize when receiving 404 for stale sessions.
|
|
435
565
|
*/
|
|
436
566
|
async establishConnection() {
|
|
437
|
-
|
|
567
|
+
const transport = new SSEClientTransport(this.url, this.opts);
|
|
568
|
+
const originalSend = transport.send.bind(transport);
|
|
569
|
+
transport.send = async (message) => {
|
|
570
|
+
const sendMessage = /* @__PURE__ */ __name(async (msg) => {
|
|
571
|
+
if (Array.isArray(msg)) {
|
|
572
|
+
for (const singleMsg of msg) {
|
|
573
|
+
await originalSend(singleMsg);
|
|
574
|
+
}
|
|
575
|
+
} else {
|
|
576
|
+
await originalSend(msg);
|
|
577
|
+
}
|
|
578
|
+
}, "sendMessage");
|
|
579
|
+
try {
|
|
580
|
+
await sendMessage(message);
|
|
581
|
+
} catch (error) {
|
|
582
|
+
if (error?.code === 404 && transport.sessionId && !this.reinitializing) {
|
|
583
|
+
logger.warn(
|
|
584
|
+
`[SSE] Session not found (404), re-initializing per MCP spec...`
|
|
585
|
+
);
|
|
586
|
+
this.reinitializing = true;
|
|
587
|
+
try {
|
|
588
|
+
transport.sessionId = void 0;
|
|
589
|
+
await this.reinitialize(transport);
|
|
590
|
+
logger.info(`[SSE] Re-initialization successful, retrying request`);
|
|
591
|
+
await sendMessage(message);
|
|
592
|
+
} finally {
|
|
593
|
+
this.reinitializing = false;
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
throw error;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
this._transport = transport;
|
|
438
601
|
logger.debug(`${this.constructor.name} connected successfully`);
|
|
439
|
-
return
|
|
602
|
+
return transport;
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Re-initialize the transport with a new session
|
|
606
|
+
* This is called when the server returns 404 for a stale session
|
|
607
|
+
*/
|
|
608
|
+
async reinitialize(transport) {
|
|
609
|
+
logger.debug(`[SSE] Re-initialization triggered`);
|
|
440
610
|
}
|
|
441
611
|
/**
|
|
442
612
|
* Close the underlying transport and clean up resources.
|
|
@@ -727,134 +897,6 @@ var HttpConnector = class extends BaseConnector {
|
|
|
727
897
|
}
|
|
728
898
|
};
|
|
729
899
|
|
|
730
|
-
// src/client/base.ts
|
|
731
|
-
var BaseMCPClient = class {
|
|
732
|
-
static {
|
|
733
|
-
__name(this, "BaseMCPClient");
|
|
734
|
-
}
|
|
735
|
-
config = {};
|
|
736
|
-
sessions = {};
|
|
737
|
-
activeSessions = [];
|
|
738
|
-
constructor(config) {
|
|
739
|
-
if (config) {
|
|
740
|
-
this.config = config;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
static fromDict(_cfg) {
|
|
744
|
-
throw new Error("fromDict must be implemented by concrete class");
|
|
745
|
-
}
|
|
746
|
-
addServer(name, serverConfig) {
|
|
747
|
-
this.config.mcpServers = this.config.mcpServers || {};
|
|
748
|
-
this.config.mcpServers[name] = serverConfig;
|
|
749
|
-
Tel.getInstance().trackClientAddServer(name, serverConfig);
|
|
750
|
-
}
|
|
751
|
-
removeServer(name) {
|
|
752
|
-
if (this.config.mcpServers?.[name]) {
|
|
753
|
-
delete this.config.mcpServers[name];
|
|
754
|
-
this.activeSessions = this.activeSessions.filter((n) => n !== name);
|
|
755
|
-
Tel.getInstance().trackClientRemoveServer(name);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
getServerNames() {
|
|
759
|
-
return Object.keys(this.config.mcpServers ?? {});
|
|
760
|
-
}
|
|
761
|
-
getServerConfig(name) {
|
|
762
|
-
return this.config.mcpServers?.[name];
|
|
763
|
-
}
|
|
764
|
-
getConfig() {
|
|
765
|
-
return this.config ?? {};
|
|
766
|
-
}
|
|
767
|
-
async createSession(serverName, autoInitialize = true) {
|
|
768
|
-
const servers = this.config.mcpServers ?? {};
|
|
769
|
-
if (Object.keys(servers).length === 0) {
|
|
770
|
-
logger.warn("No MCP servers defined in config");
|
|
771
|
-
}
|
|
772
|
-
if (!servers[serverName]) {
|
|
773
|
-
throw new Error(`Server '${serverName}' not found in config`);
|
|
774
|
-
}
|
|
775
|
-
const connector = this.createConnectorFromConfig(servers[serverName]);
|
|
776
|
-
const session = new MCPSession(connector);
|
|
777
|
-
if (autoInitialize) {
|
|
778
|
-
await session.initialize();
|
|
779
|
-
}
|
|
780
|
-
this.sessions[serverName] = session;
|
|
781
|
-
if (!this.activeSessions.includes(serverName)) {
|
|
782
|
-
this.activeSessions.push(serverName);
|
|
783
|
-
}
|
|
784
|
-
return session;
|
|
785
|
-
}
|
|
786
|
-
async createAllSessions(autoInitialize = true) {
|
|
787
|
-
const servers = this.config.mcpServers ?? {};
|
|
788
|
-
if (Object.keys(servers).length === 0) {
|
|
789
|
-
logger.warn("No MCP servers defined in config");
|
|
790
|
-
}
|
|
791
|
-
for (const name of Object.keys(servers)) {
|
|
792
|
-
await this.createSession(name, autoInitialize);
|
|
793
|
-
}
|
|
794
|
-
return this.sessions;
|
|
795
|
-
}
|
|
796
|
-
getSession(serverName) {
|
|
797
|
-
const session = this.sessions[serverName];
|
|
798
|
-
if (!session) {
|
|
799
|
-
return null;
|
|
800
|
-
}
|
|
801
|
-
return session;
|
|
802
|
-
}
|
|
803
|
-
requireSession(serverName) {
|
|
804
|
-
const session = this.sessions[serverName];
|
|
805
|
-
if (!session) {
|
|
806
|
-
throw new Error(
|
|
807
|
-
`Session '${serverName}' not found. Available sessions: ${this.activeSessions.join(", ") || "none"}`
|
|
808
|
-
);
|
|
809
|
-
}
|
|
810
|
-
return session;
|
|
811
|
-
}
|
|
812
|
-
getAllActiveSessions() {
|
|
813
|
-
return Object.fromEntries(
|
|
814
|
-
this.activeSessions.map((n) => [n, this.sessions[n]])
|
|
815
|
-
);
|
|
816
|
-
}
|
|
817
|
-
async closeSession(serverName) {
|
|
818
|
-
const session = this.sessions[serverName];
|
|
819
|
-
if (!session) {
|
|
820
|
-
logger.warn(
|
|
821
|
-
`No session exists for server ${serverName}, nothing to close`
|
|
822
|
-
);
|
|
823
|
-
return;
|
|
824
|
-
}
|
|
825
|
-
try {
|
|
826
|
-
logger.debug(`Closing session for server ${serverName}`);
|
|
827
|
-
await session.disconnect();
|
|
828
|
-
} catch (e) {
|
|
829
|
-
logger.error(`Error closing session for server '${serverName}': ${e}`);
|
|
830
|
-
} finally {
|
|
831
|
-
delete this.sessions[serverName];
|
|
832
|
-
this.activeSessions = this.activeSessions.filter((n) => n !== serverName);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
async closeAllSessions() {
|
|
836
|
-
const serverNames = Object.keys(this.sessions);
|
|
837
|
-
const errors = [];
|
|
838
|
-
for (const serverName of serverNames) {
|
|
839
|
-
try {
|
|
840
|
-
logger.debug(`Closing session for server ${serverName}`);
|
|
841
|
-
await this.closeSession(serverName);
|
|
842
|
-
} catch (e) {
|
|
843
|
-
const errorMsg = `Failed to close session for server '${serverName}': ${e}`;
|
|
844
|
-
logger.error(errorMsg);
|
|
845
|
-
errors.push(errorMsg);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
if (errors.length) {
|
|
849
|
-
logger.error(
|
|
850
|
-
`Encountered ${errors.length} errors while closing sessions`
|
|
851
|
-
);
|
|
852
|
-
} else {
|
|
853
|
-
logger.debug("All sessions closed successfully");
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
};
|
|
857
|
-
|
|
858
900
|
export {
|
|
859
901
|
MCPSession,
|
|
860
902
|
BaseMCPClient,
|