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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/chunk-3RJENWH4.js +248 -0
- package/dist/{chunk-MGUO7HXB.js → chunk-7UX634PO.js} +307 -1066
- package/dist/chunk-KLIBVJ3Z.js +759 -0
- package/dist/chunk-MZLETWQQ.js +250 -0
- package/dist/chunk-RSGKBEHH.js +1411 -0
- package/dist/index.cjs +880 -541
- package/dist/index.d.ts +24 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -33
- package/dist/{langfuse-6AJGHMAV.js → langfuse-LCJ6VJEP.js} +2 -1
- package/dist/src/adapters/base.d.ts +2 -2
- package/dist/src/adapters/base.d.ts.map +1 -1
- package/dist/src/adapters/index.d.ts +2 -2
- package/dist/src/adapters/index.d.ts.map +1 -1
- package/dist/src/adapters/langchain_adapter.d.ts +4 -4
- package/dist/src/adapters/langchain_adapter.d.ts.map +1 -1
- package/dist/src/agents/base.d.ts +1 -1
- package/dist/src/agents/base.d.ts.map +1 -1
- package/dist/src/agents/index.d.ts +3 -3
- package/dist/src/agents/index.d.ts.map +1 -1
- package/dist/src/agents/mcp_agent.d.ts +12 -12
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/prompts/system_prompt_builder.d.ts +2 -2
- package/dist/src/agents/prompts/system_prompt_builder.d.ts.map +1 -1
- package/dist/src/agents/prompts/templates.d.ts.map +1 -1
- package/dist/src/agents/remote.d.ts +2 -2
- package/dist/src/agents/remote.d.ts.map +1 -1
- package/dist/src/agents/types.d.ts +1 -1
- package/dist/src/agents/types.d.ts.map +1 -1
- package/dist/src/agents/utils/ai_sdk.d.ts +1 -1
- package/dist/src/agents/utils/ai_sdk.d.ts.map +1 -1
- package/dist/src/agents/utils/index.d.ts +1 -1
- package/dist/src/agents/utils/index.d.ts.map +1 -1
- package/dist/src/auth/browser-provider.d.ts +2 -2
- package/dist/src/auth/browser-provider.d.ts.map +1 -1
- package/dist/src/auth/callback.d.ts.map +1 -1
- package/dist/src/auth/index.d.ts +3 -3
- package/dist/src/auth/index.d.ts.map +1 -1
- package/dist/src/auth/types.d.ts +1 -1
- package/dist/src/auth/types.d.ts.map +1 -1
- package/dist/src/browser.cjs +573 -219
- package/dist/src/browser.d.ts +17 -17
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +17 -46
- package/dist/src/client/base.d.ts +2 -2
- package/dist/src/client/base.d.ts.map +1 -1
- package/dist/src/client/browser.d.ts +2 -2
- package/dist/src/client/browser.d.ts.map +1 -1
- package/dist/src/client.d.ts +2 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/connectors/base.d.ts +51 -9
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts +3 -3
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/connectors/index.d.ts +4 -4
- package/dist/src/connectors/index.d.ts.map +1 -1
- package/dist/src/connectors/stdio.d.ts +3 -3
- package/dist/src/connectors/stdio.d.ts.map +1 -1
- package/dist/src/connectors/websocket.d.ts +4 -7
- package/dist/src/connectors/websocket.d.ts.map +1 -1
- package/dist/src/logging.d.ts +4 -4
- package/dist/src/logging.d.ts.map +1 -1
- package/dist/src/managers/index.d.ts +2 -2
- package/dist/src/managers/index.d.ts.map +1 -1
- package/dist/src/managers/server_manager.d.ts +4 -4
- package/dist/src/managers/server_manager.d.ts.map +1 -1
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts +3 -3
- package/dist/src/managers/tools/acquire_active_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/add_server_from_config.d.ts +3 -3
- package/dist/src/managers/tools/add_server_from_config.d.ts.map +1 -1
- package/dist/src/managers/tools/base.d.ts +6 -6
- package/dist/src/managers/tools/base.d.ts.map +1 -1
- package/dist/src/managers/tools/connect_mcp_server.d.ts +4 -4
- package/dist/src/managers/tools/connect_mcp_server.d.ts.map +1 -1
- package/dist/src/managers/tools/index.d.ts +5 -5
- package/dist/src/managers/tools/index.d.ts.map +1 -1
- package/dist/src/managers/tools/list_mcp_servers.d.ts +3 -3
- package/dist/src/managers/tools/list_mcp_servers.d.ts.map +1 -1
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts +3 -3
- package/dist/src/managers/tools/release_mcp_server_connection.d.ts.map +1 -1
- package/dist/src/managers/types.d.ts +3 -3
- package/dist/src/managers/types.d.ts.map +1 -1
- package/dist/src/oauth-helper.d.ts.map +1 -1
- package/dist/src/observability/index.d.ts +3 -3
- package/dist/src/observability/index.d.ts.map +1 -1
- package/dist/src/observability/langfuse.d.ts +1 -1
- package/dist/src/observability/langfuse.d.ts.map +1 -1
- package/dist/src/observability/manager.d.ts +1 -1
- package/dist/src/observability/manager.d.ts.map +1 -1
- package/dist/src/observability/types.d.ts +1 -1
- package/dist/src/observability/types.d.ts.map +1 -1
- package/dist/src/react/index.cjs +1571 -321
- package/dist/src/react/index.d.ts +6 -6
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/react/index.js +3 -2
- package/dist/src/react/types.d.ts +27 -5
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts +32 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/react/useWidget.d.ts +5 -2
- package/dist/src/react/useWidget.d.ts.map +1 -1
- package/dist/src/react/widget-types.d.ts +3 -3
- package/dist/src/react/widget-types.d.ts.map +1 -1
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts +3 -3
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -1
- package/dist/src/server/index.cjs +170 -50
- package/dist/src/server/index.d.ts +4 -4
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +174 -51
- package/dist/src/server/logging.d.ts +1 -1
- package/dist/src/server/logging.d.ts.map +1 -1
- package/dist/src/server/mcp-server.d.ts +29 -29
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/types/common.d.ts +2 -2
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/server/types/index.d.ts +4 -4
- package/dist/src/server/types/index.d.ts.map +1 -1
- package/dist/src/server/types/prompt.d.ts +2 -2
- package/dist/src/server/types/prompt.d.ts.map +1 -1
- package/dist/src/server/types/resource.d.ts +24 -24
- package/dist/src/server/types/resource.d.ts.map +1 -1
- package/dist/src/server/types/tool.d.ts +3 -3
- package/dist/src/server/types/tool.d.ts.map +1 -1
- package/dist/src/server/types/widget.d.ts +1 -1
- package/dist/src/server/types.d.ts +1 -1
- package/dist/src/server/types.d.ts.map +1 -1
- package/dist/src/session.d.ts +1 -1
- package/dist/src/session.d.ts.map +1 -1
- package/dist/src/task_managers/base.d.ts.map +1 -1
- package/dist/src/task_managers/index.d.ts +5 -5
- package/dist/src/task_managers/index.d.ts.map +1 -1
- package/dist/src/task_managers/sse.d.ts +3 -3
- package/dist/src/task_managers/sse.d.ts.map +1 -1
- package/dist/src/task_managers/stdio.d.ts +4 -4
- package/dist/src/task_managers/stdio.d.ts.map +1 -1
- package/dist/src/task_managers/streamable_http.d.ts +3 -3
- package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
- package/dist/src/task_managers/websocket.d.ts +2 -2
- package/dist/src/task_managers/websocket.d.ts.map +1 -1
- package/dist/src/telemetry/events.d.ts.map +1 -1
- package/dist/src/telemetry/index.d.ts +4 -4
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/telemetry.d.ts +1 -1
- package/dist/src/telemetry/telemetry.d.ts.map +1 -1
- package/dist/src/telemetry/utils.d.ts +1 -1
- package/dist/src/telemetry/utils.d.ts.map +1 -1
- package/dist/tsup.config.d.ts.map +1 -1
- package/dist/vitest.config.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-62GFHYCL.js +0 -300
- package/dist/chunk-JV7HAYUT.js +0 -860
- package/dist/chunk-ZUEQQ6YK.js +0 -444
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3RJENWH4.js";
|
|
4
4
|
import {
|
|
5
5
|
__name
|
|
6
6
|
} from "./chunk-SHUYVCID.js";
|
|
@@ -152,9 +152,14 @@ var LangChainAdapter = class extends BaseAdapter {
|
|
|
152
152
|
// Blank is acceptable but discouraged.
|
|
153
153
|
schema: argsSchema,
|
|
154
154
|
func: /* @__PURE__ */ __name(async (input) => {
|
|
155
|
-
logger.debug(
|
|
155
|
+
logger.debug(
|
|
156
|
+
`MCP tool "${mcpTool.name}" received input: ${JSON.stringify(input)}`
|
|
157
|
+
);
|
|
156
158
|
try {
|
|
157
|
-
const result = await connector.callTool(
|
|
159
|
+
const result = await connector.callTool(
|
|
160
|
+
mcpTool.name,
|
|
161
|
+
input
|
|
162
|
+
);
|
|
158
163
|
return JSON.stringify(result);
|
|
159
164
|
} catch (err) {
|
|
160
165
|
logger.error(`Error executing MCP tool: ${err.message}`);
|
|
@@ -305,7 +310,9 @@ var ConnectMCPServerTool = class extends MCPServerTool {
|
|
|
305
310
|
const numTools = serverTools.length;
|
|
306
311
|
return `Connected to MCP server '${serverName}'. ${numTools} tools are now available.`;
|
|
307
312
|
} catch (error) {
|
|
308
|
-
logger.error(
|
|
313
|
+
logger.error(
|
|
314
|
+
`Error connecting to server '${serverName}': ${String(error)}`
|
|
315
|
+
);
|
|
309
316
|
return `Failed to connect to server '${serverName}': ${String(error)}`;
|
|
310
317
|
}
|
|
311
318
|
}
|
|
@@ -340,7 +347,9 @@ var ListMCPServersTool = class extends MCPServerTool {
|
|
|
340
347
|
outputLines.push(`${numberOfTools} tools available for this server
|
|
341
348
|
`);
|
|
342
349
|
} catch (error) {
|
|
343
|
-
logger.error(
|
|
350
|
+
logger.error(
|
|
351
|
+
`Unexpected error listing tools for server '${serverName}': ${String(error)}`
|
|
352
|
+
);
|
|
344
353
|
}
|
|
345
354
|
}
|
|
346
355
|
return outputLines.join("\n");
|
|
@@ -402,10 +411,10 @@ var ServerManager = class {
|
|
|
402
411
|
}
|
|
403
412
|
const tableData = allServerNames.map((name) => ({
|
|
404
413
|
"Server Name": name,
|
|
405
|
-
|
|
406
|
-
|
|
414
|
+
Connected: activeSessionNames.includes(name) ? "\u2705" : "\u274C",
|
|
415
|
+
Initialized: this.initializedServers[name] ? "\u2705" : "\u274C",
|
|
407
416
|
"Tool Count": this.serverTools[name]?.length ?? 0,
|
|
408
|
-
|
|
417
|
+
Active: this.activeServer === name ? "\u2705" : "\u274C"
|
|
409
418
|
}));
|
|
410
419
|
logger.info(`Server Manager State: [${context}]`);
|
|
411
420
|
console.table(tableData);
|
|
@@ -422,13 +431,19 @@ var ServerManager = class {
|
|
|
422
431
|
try {
|
|
423
432
|
let session = null;
|
|
424
433
|
session = this.client.getSession(serverName);
|
|
425
|
-
logger.debug(
|
|
434
|
+
logger.debug(
|
|
435
|
+
`Using existing session for server '${serverName}' to prefetch tools.`
|
|
436
|
+
);
|
|
426
437
|
if (!session) {
|
|
427
438
|
session = await this.client.createSession(serverName).catch((createSessionError) => {
|
|
428
|
-
logger.warn(
|
|
439
|
+
logger.warn(
|
|
440
|
+
`Could not create session for '${serverName}' during prefetch: ${createSessionError}`
|
|
441
|
+
);
|
|
429
442
|
return null;
|
|
430
443
|
});
|
|
431
|
-
logger.debug(
|
|
444
|
+
logger.debug(
|
|
445
|
+
`Temporarily created session for '${serverName}' to prefetch tools.`
|
|
446
|
+
);
|
|
432
447
|
}
|
|
433
448
|
if (session) {
|
|
434
449
|
const connector = session.connector;
|
|
@@ -436,7 +451,9 @@ var ServerManager = class {
|
|
|
436
451
|
try {
|
|
437
452
|
tools = await this.adapter.createToolsFromConnectors([connector]);
|
|
438
453
|
} catch (toolFetchError) {
|
|
439
|
-
logger.error(
|
|
454
|
+
logger.error(
|
|
455
|
+
`Failed to create tools from connector for server '${serverName}': ${toolFetchError}`
|
|
456
|
+
);
|
|
440
457
|
continue;
|
|
441
458
|
}
|
|
442
459
|
const cachedTools = this.serverTools[serverName];
|
|
@@ -444,7 +461,9 @@ var ServerManager = class {
|
|
|
444
461
|
if (toolsChanged) {
|
|
445
462
|
this.serverTools[serverName] = tools;
|
|
446
463
|
this.initializedServers[serverName] = true;
|
|
447
|
-
logger.debug(
|
|
464
|
+
logger.debug(
|
|
465
|
+
`Prefetched ${tools.length} tools for server '${serverName}'.`
|
|
466
|
+
);
|
|
448
467
|
} else {
|
|
449
468
|
logger.debug(
|
|
450
469
|
`Tools for server '${serverName}' unchanged, using cached version.`
|
|
@@ -452,7 +471,9 @@ var ServerManager = class {
|
|
|
452
471
|
}
|
|
453
472
|
}
|
|
454
473
|
} catch (outerError) {
|
|
455
|
-
logger.error(
|
|
474
|
+
logger.error(
|
|
475
|
+
`Error prefetching tools for server '${serverName}': ${outerError}`
|
|
476
|
+
);
|
|
456
477
|
}
|
|
457
478
|
}
|
|
458
479
|
}
|
|
@@ -510,11 +531,18 @@ var ObservabilityManager = class {
|
|
|
510
531
|
return;
|
|
511
532
|
}
|
|
512
533
|
try {
|
|
513
|
-
const { langfuseHandler: langfuseHandler2, langfuseInitPromise: langfuseInitPromise2 } = await import("./langfuse-
|
|
534
|
+
const { langfuseHandler: langfuseHandler2, langfuseInitPromise: langfuseInitPromise2 } = await import("./langfuse-LCJ6VJEP.js");
|
|
514
535
|
if (this.agentId || this.metadata || this.metadataProvider || this.tagsProvider) {
|
|
515
|
-
const { initializeLangfuse } = await import("./langfuse-
|
|
516
|
-
await initializeLangfuse(
|
|
517
|
-
|
|
536
|
+
const { initializeLangfuse } = await import("./langfuse-LCJ6VJEP.js");
|
|
537
|
+
await initializeLangfuse(
|
|
538
|
+
this.agentId,
|
|
539
|
+
this.metadata,
|
|
540
|
+
this.metadataProvider,
|
|
541
|
+
this.tagsProvider
|
|
542
|
+
);
|
|
543
|
+
logger.debug(
|
|
544
|
+
`ObservabilityManager: Reinitialized Langfuse with agent ID: ${this.agentId}, metadata: ${JSON.stringify(this.metadata)}`
|
|
545
|
+
);
|
|
518
546
|
} else {
|
|
519
547
|
const initPromise = langfuseInitPromise2();
|
|
520
548
|
if (initPromise) {
|
|
@@ -538,16 +566,22 @@ var ObservabilityManager = class {
|
|
|
538
566
|
*/
|
|
539
567
|
async getCallbacks() {
|
|
540
568
|
if (!this.observe) {
|
|
541
|
-
logger.debug(
|
|
569
|
+
logger.debug(
|
|
570
|
+
"ObservabilityManager: Observability disabled via observe=false"
|
|
571
|
+
);
|
|
542
572
|
return [];
|
|
543
573
|
}
|
|
544
574
|
if (this.customCallbacks) {
|
|
545
|
-
logger.debug(
|
|
575
|
+
logger.debug(
|
|
576
|
+
`ObservabilityManager: Using ${this.customCallbacks.length} custom callbacks`
|
|
577
|
+
);
|
|
546
578
|
return this.customCallbacks;
|
|
547
579
|
}
|
|
548
580
|
await this.collectAvailableHandlers();
|
|
549
581
|
if (this.availableHandlers.length > 0) {
|
|
550
|
-
logger.debug(
|
|
582
|
+
logger.debug(
|
|
583
|
+
`ObservabilityManager: Using ${this.availableHandlers.length} handlers`
|
|
584
|
+
);
|
|
551
585
|
} else {
|
|
552
586
|
logger.debug("ObservabilityManager: No callbacks configured");
|
|
553
587
|
}
|
|
@@ -604,7 +638,9 @@ var ObservabilityManager = class {
|
|
|
604
638
|
this.customCallbacks = [];
|
|
605
639
|
}
|
|
606
640
|
this.customCallbacks.push(callback);
|
|
607
|
-
logger.debug(
|
|
641
|
+
logger.debug(
|
|
642
|
+
`ObservabilityManager: Added custom callback: ${callback.constructor.name}`
|
|
643
|
+
);
|
|
608
644
|
}
|
|
609
645
|
/**
|
|
610
646
|
* Clear all custom callbacks.
|
|
@@ -735,7 +771,15 @@ function getModelName(llm) {
|
|
|
735
771
|
if ("_identifyingParams" in llm) {
|
|
736
772
|
const identifyingParams = llm._identifyingParams;
|
|
737
773
|
if (typeof identifyingParams === "object" && identifyingParams !== null) {
|
|
738
|
-
for (const key of [
|
|
774
|
+
for (const key of [
|
|
775
|
+
"model",
|
|
776
|
+
"modelName",
|
|
777
|
+
"model_name",
|
|
778
|
+
"modelId",
|
|
779
|
+
"model_id",
|
|
780
|
+
"deploymentName",
|
|
781
|
+
"deployment_name"
|
|
782
|
+
]) {
|
|
739
783
|
if (key in identifyingParams) {
|
|
740
784
|
return String(identifyingParams[key]);
|
|
741
785
|
}
|
|
@@ -826,8 +870,16 @@ var Telemetry = class _Telemetry {
|
|
|
826
870
|
__name(this, "Telemetry");
|
|
827
871
|
}
|
|
828
872
|
static instance = null;
|
|
829
|
-
USER_ID_PATH = path2.join(
|
|
830
|
-
|
|
873
|
+
USER_ID_PATH = path2.join(
|
|
874
|
+
getCacheHome(),
|
|
875
|
+
"mcp_use_3",
|
|
876
|
+
"telemetry_user_id"
|
|
877
|
+
);
|
|
878
|
+
VERSION_DOWNLOAD_PATH = path2.join(
|
|
879
|
+
getCacheHome(),
|
|
880
|
+
"mcp_use",
|
|
881
|
+
"download_version"
|
|
882
|
+
);
|
|
831
883
|
PROJECT_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
832
884
|
HOST = "https://eu.i.posthog.com";
|
|
833
885
|
SCARF_GATEWAY_URL = "https://mcpuse.gateway.scarf.sh/events-ts";
|
|
@@ -847,17 +899,18 @@ var Telemetry = class _Telemetry {
|
|
|
847
899
|
} else if (!isNodeJS) {
|
|
848
900
|
this._posthogClient = null;
|
|
849
901
|
this._scarfClient = null;
|
|
850
|
-
logger.debug(
|
|
902
|
+
logger.debug(
|
|
903
|
+
"Telemetry disabled - non-Node.js environment detected (e.g., Cloudflare Workers)"
|
|
904
|
+
);
|
|
851
905
|
} else {
|
|
852
|
-
logger.info(
|
|
906
|
+
logger.info(
|
|
907
|
+
"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable."
|
|
908
|
+
);
|
|
853
909
|
try {
|
|
854
|
-
this._posthogClient = new PostHog(
|
|
855
|
-
this.
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
disableGeoip: false
|
|
859
|
-
}
|
|
860
|
-
);
|
|
910
|
+
this._posthogClient = new PostHog(this.PROJECT_API_KEY, {
|
|
911
|
+
host: this.HOST,
|
|
912
|
+
disableGeoip: false
|
|
913
|
+
});
|
|
861
914
|
} catch (e) {
|
|
862
915
|
logger.warn(`Failed to initialize PostHog telemetry: ${e}`);
|
|
863
916
|
this._posthogClient = null;
|
|
@@ -967,7 +1020,9 @@ var Telemetry = class _Telemetry {
|
|
|
967
1020
|
if (!fs2.existsSync(this.VERSION_DOWNLOAD_PATH)) {
|
|
968
1021
|
shouldTrack = true;
|
|
969
1022
|
firstDownload = true;
|
|
970
|
-
fs2.mkdirSync(path2.dirname(this.VERSION_DOWNLOAD_PATH), {
|
|
1023
|
+
fs2.mkdirSync(path2.dirname(this.VERSION_DOWNLOAD_PATH), {
|
|
1024
|
+
recursive: true
|
|
1025
|
+
});
|
|
971
1026
|
fs2.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
972
1027
|
} else {
|
|
973
1028
|
const savedVersion = fs2.readFileSync(this.VERSION_DOWNLOAD_PATH, "utf-8").trim();
|
|
@@ -978,7 +1033,9 @@ var Telemetry = class _Telemetry {
|
|
|
978
1033
|
}
|
|
979
1034
|
}
|
|
980
1035
|
if (shouldTrack) {
|
|
981
|
-
logger.debug(
|
|
1036
|
+
logger.debug(
|
|
1037
|
+
`Tracking package download event with properties: ${JSON.stringify(properties)}`
|
|
1038
|
+
);
|
|
982
1039
|
const eventProperties = { ...properties || {} };
|
|
983
1040
|
eventProperties.mcp_use_version = currentVersion;
|
|
984
1041
|
eventProperties.user_id = this.userId;
|
|
@@ -1115,7 +1172,9 @@ var RemoteAgent = class {
|
|
|
1115
1172
|
`Agent not found: Agent '${this.agentId}' does not exist or you don't have access to it. Please verify the agent ID and ensure it exists in your account.`
|
|
1116
1173
|
);
|
|
1117
1174
|
}
|
|
1118
|
-
throw new Error(
|
|
1175
|
+
throw new Error(
|
|
1176
|
+
`Failed to create chat session: ${statusCode} - ${responseText}`
|
|
1177
|
+
);
|
|
1119
1178
|
}
|
|
1120
1179
|
const chatData = await response.json();
|
|
1121
1180
|
const chatId = chatData.id;
|
|
@@ -1188,8 +1247,12 @@ var RemoteAgent = class {
|
|
|
1188
1247
|
"Internal server error occurred during agent execution. Please try again later or contact support if the issue persists."
|
|
1189
1248
|
);
|
|
1190
1249
|
} else {
|
|
1191
|
-
logger.error(
|
|
1192
|
-
|
|
1250
|
+
logger.error(
|
|
1251
|
+
`\u274C Remote execution failed with status ${statusCode}: ${responseText}`
|
|
1252
|
+
);
|
|
1253
|
+
throw new Error(
|
|
1254
|
+
`Remote agent execution failed: ${statusCode} - ${responseText}`
|
|
1255
|
+
);
|
|
1193
1256
|
}
|
|
1194
1257
|
}
|
|
1195
1258
|
const result = await response.json();
|
|
@@ -1240,7 +1303,13 @@ Raw error: ${result}`
|
|
|
1240
1303
|
}
|
|
1241
1304
|
// eslint-disable-next-line require-yield
|
|
1242
1305
|
async *stream(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
|
1243
|
-
const result = await this.run(
|
|
1306
|
+
const result = await this.run(
|
|
1307
|
+
query,
|
|
1308
|
+
maxSteps,
|
|
1309
|
+
manageConnector,
|
|
1310
|
+
externalHistory,
|
|
1311
|
+
outputSchema
|
|
1312
|
+
);
|
|
1244
1313
|
return result;
|
|
1245
1314
|
}
|
|
1246
1315
|
async close() {
|
|
@@ -1249,7 +1318,14 @@ Raw error: ${result}`
|
|
|
1249
1318
|
};
|
|
1250
1319
|
|
|
1251
1320
|
// src/agents/mcp_agent.ts
|
|
1252
|
-
import {
|
|
1321
|
+
import {
|
|
1322
|
+
createAgent,
|
|
1323
|
+
modelCallLimitMiddleware,
|
|
1324
|
+
SystemMessage as SystemMessage2,
|
|
1325
|
+
AIMessage,
|
|
1326
|
+
HumanMessage,
|
|
1327
|
+
ToolMessage
|
|
1328
|
+
} from "langchain";
|
|
1253
1329
|
import { zodToJsonSchema as zodToJsonSchema2 } from "zod-to-json-schema";
|
|
1254
1330
|
|
|
1255
1331
|
// src/agents/prompts/system_prompt_builder.ts
|
|
@@ -1258,8 +1334,7 @@ function generateToolDescriptions(tools, disallowedTools) {
|
|
|
1258
1334
|
const disallowedSet = new Set(disallowedTools ?? []);
|
|
1259
1335
|
const descriptions = [];
|
|
1260
1336
|
for (const tool of tools) {
|
|
1261
|
-
if (disallowedSet.has(tool.name))
|
|
1262
|
-
continue;
|
|
1337
|
+
if (disallowedSet.has(tool.name)) continue;
|
|
1263
1338
|
const escaped = tool.description.replace(/\{/g, "{{").replace(/\}/g, "}}");
|
|
1264
1339
|
descriptions.push(`- ${tool.name}: ${escaped}`);
|
|
1265
1340
|
}
|
|
@@ -1272,7 +1347,9 @@ function buildSystemPromptContent(template, toolDescriptionLines, additionalInst
|
|
|
1272
1347
|
if (template.includes("{tool_descriptions}")) {
|
|
1273
1348
|
content = template.replace("{tool_descriptions}", block);
|
|
1274
1349
|
} else {
|
|
1275
|
-
console.warn(
|
|
1350
|
+
console.warn(
|
|
1351
|
+
"`{tool_descriptions}` placeholder not found; appending at end."
|
|
1352
|
+
);
|
|
1276
1353
|
content = `${template}
|
|
1277
1354
|
|
|
1278
1355
|
Available tools:
|
|
@@ -1410,7 +1487,9 @@ var MCPAgent = class {
|
|
|
1410
1487
|
return;
|
|
1411
1488
|
}
|
|
1412
1489
|
if (!options.llm) {
|
|
1413
|
-
throw new Error(
|
|
1490
|
+
throw new Error(
|
|
1491
|
+
"llm is required for local execution. For remote execution, provide agentId instead."
|
|
1492
|
+
);
|
|
1414
1493
|
}
|
|
1415
1494
|
this.llm = options.llm;
|
|
1416
1495
|
this.client = options.client;
|
|
@@ -1428,11 +1507,15 @@ var MCPAgent = class {
|
|
|
1428
1507
|
this.verbose = options.verbose ?? false;
|
|
1429
1508
|
this.observe = options.observe ?? true;
|
|
1430
1509
|
if (!this.client && this.connectors.length === 0) {
|
|
1431
|
-
throw new Error(
|
|
1510
|
+
throw new Error(
|
|
1511
|
+
"Either 'client' or at least one 'connector' must be provided."
|
|
1512
|
+
);
|
|
1432
1513
|
}
|
|
1433
1514
|
if (this.useServerManager) {
|
|
1434
1515
|
if (!this.client) {
|
|
1435
|
-
throw new Error(
|
|
1516
|
+
throw new Error(
|
|
1517
|
+
"'client' must be provided when 'useServerManager' is true."
|
|
1518
|
+
);
|
|
1436
1519
|
}
|
|
1437
1520
|
this.adapter = options.adapter ?? new LangChainAdapter(this.disallowedTools);
|
|
1438
1521
|
this.serverManager = options.serverManagerFactory?.(this.client) ?? new ServerManager(this.client, this.adapter);
|
|
@@ -1492,25 +1575,37 @@ var MCPAgent = class {
|
|
|
1492
1575
|
} else {
|
|
1493
1576
|
if (this.client) {
|
|
1494
1577
|
this.sessions = this.client.getAllActiveSessions();
|
|
1495
|
-
logger.info(
|
|
1578
|
+
logger.info(
|
|
1579
|
+
`\u{1F50C} Found ${Object.keys(this.sessions).length} existing sessions`
|
|
1580
|
+
);
|
|
1496
1581
|
if (Object.keys(this.sessions).length === 0) {
|
|
1497
1582
|
logger.info("\u{1F504} No active sessions found, creating new ones...");
|
|
1498
1583
|
this.sessions = await this.client.createAllSessions();
|
|
1499
|
-
logger.info(
|
|
1584
|
+
logger.info(
|
|
1585
|
+
`\u2705 Created ${Object.keys(this.sessions).length} new sessions`
|
|
1586
|
+
);
|
|
1500
1587
|
}
|
|
1501
1588
|
this._tools = await LangChainAdapter.createTools(this.client);
|
|
1502
1589
|
this._tools.push(...this.additionalTools);
|
|
1503
|
-
logger.info(
|
|
1590
|
+
logger.info(
|
|
1591
|
+
`\u{1F6E0}\uFE0F Created ${this._tools.length} LangChain tools from client`
|
|
1592
|
+
);
|
|
1504
1593
|
} else {
|
|
1505
|
-
logger.info(
|
|
1594
|
+
logger.info(
|
|
1595
|
+
`\u{1F517} Connecting to ${this.connectors.length} direct connectors...`
|
|
1596
|
+
);
|
|
1506
1597
|
for (const connector of this.connectors) {
|
|
1507
1598
|
if (!connector.isClientConnected) {
|
|
1508
1599
|
await connector.connect();
|
|
1509
1600
|
}
|
|
1510
1601
|
}
|
|
1511
|
-
this._tools = await this.adapter.createToolsFromConnectors(
|
|
1602
|
+
this._tools = await this.adapter.createToolsFromConnectors(
|
|
1603
|
+
this.connectors
|
|
1604
|
+
);
|
|
1512
1605
|
this._tools.push(...this.additionalTools);
|
|
1513
|
-
logger.info(
|
|
1606
|
+
logger.info(
|
|
1607
|
+
`\u{1F6E0}\uFE0F Created ${this._tools.length} LangChain tools from connectors`
|
|
1608
|
+
);
|
|
1514
1609
|
}
|
|
1515
1610
|
logger.info(`\u{1F9F0} Found ${this._tools.length} tools across all connectors`);
|
|
1516
1611
|
await this.createSystemMessageFromTools(this._tools);
|
|
@@ -1520,7 +1615,9 @@ var MCPAgent = class {
|
|
|
1520
1615
|
const mcpServerInfo = this.getMCPServerInfo();
|
|
1521
1616
|
if (Object.keys(mcpServerInfo).length > 0) {
|
|
1522
1617
|
this.setMetadata(mcpServerInfo);
|
|
1523
|
-
logger.debug(
|
|
1618
|
+
logger.debug(
|
|
1619
|
+
`MCP server info added to metadata: ${JSON.stringify(mcpServerInfo)}`
|
|
1620
|
+
);
|
|
1524
1621
|
}
|
|
1525
1622
|
logger.info("\u2728 Agent initialization complete");
|
|
1526
1623
|
}
|
|
@@ -1538,7 +1635,9 @@ var MCPAgent = class {
|
|
|
1538
1635
|
if (this.memoryEnabled) {
|
|
1539
1636
|
this.conversationHistory = [
|
|
1540
1637
|
this.systemMessage,
|
|
1541
|
-
...this.conversationHistory.filter(
|
|
1638
|
+
...this.conversationHistory.filter(
|
|
1639
|
+
(m) => !(m instanceof SystemMessage2)
|
|
1640
|
+
)
|
|
1542
1641
|
];
|
|
1543
1642
|
}
|
|
1544
1643
|
}
|
|
@@ -1556,7 +1655,9 @@ var MCPAgent = class {
|
|
|
1556
1655
|
systemPrompt: systemContent,
|
|
1557
1656
|
middleware
|
|
1558
1657
|
});
|
|
1559
|
-
logger.debug(
|
|
1658
|
+
logger.debug(
|
|
1659
|
+
`Created agent with max_steps=${this.maxSteps} (via ModelCallLimitMiddleware) and ${this.callbacks.length} callbacks`
|
|
1660
|
+
);
|
|
1560
1661
|
return agent;
|
|
1561
1662
|
}
|
|
1562
1663
|
getConversationHistory() {
|
|
@@ -1566,8 +1667,7 @@ var MCPAgent = class {
|
|
|
1566
1667
|
this.conversationHistory = this.memoryEnabled && this.systemMessage ? [this.systemMessage] : [];
|
|
1567
1668
|
}
|
|
1568
1669
|
addToHistory(message) {
|
|
1569
|
-
if (this.memoryEnabled)
|
|
1570
|
-
this.conversationHistory.push(message);
|
|
1670
|
+
if (this.memoryEnabled) this.conversationHistory.push(message);
|
|
1571
1671
|
}
|
|
1572
1672
|
getSystemMessage() {
|
|
1573
1673
|
return this.systemMessage;
|
|
@@ -1575,7 +1675,9 @@ var MCPAgent = class {
|
|
|
1575
1675
|
setSystemMessage(message) {
|
|
1576
1676
|
this.systemMessage = new SystemMessage2(message);
|
|
1577
1677
|
if (this.memoryEnabled) {
|
|
1578
|
-
this.conversationHistory = this.conversationHistory.filter(
|
|
1678
|
+
this.conversationHistory = this.conversationHistory.filter(
|
|
1679
|
+
(m) => !(m instanceof SystemMessage2)
|
|
1680
|
+
);
|
|
1579
1681
|
this.conversationHistory.unshift(this.systemMessage);
|
|
1580
1682
|
}
|
|
1581
1683
|
if (this._initialized && this._tools.length) {
|
|
@@ -1587,7 +1689,9 @@ var MCPAgent = class {
|
|
|
1587
1689
|
this.disallowedTools = disallowedTools;
|
|
1588
1690
|
this.adapter = new LangChainAdapter(this.disallowedTools);
|
|
1589
1691
|
if (this._initialized) {
|
|
1590
|
-
logger.debug(
|
|
1692
|
+
logger.debug(
|
|
1693
|
+
"Agent already initialized. Changes will take effect on next initialization."
|
|
1694
|
+
);
|
|
1591
1695
|
}
|
|
1592
1696
|
}
|
|
1593
1697
|
getDisallowedTools() {
|
|
@@ -1653,16 +1757,22 @@ var MCPAgent = class {
|
|
|
1653
1757
|
try {
|
|
1654
1758
|
const serialized = JSON.stringify(value);
|
|
1655
1759
|
if (serialized.length > 1e3) {
|
|
1656
|
-
logger.warn(
|
|
1760
|
+
logger.warn(
|
|
1761
|
+
`Metadata value for key '${sanitizedKey}' is too large. Truncating.`
|
|
1762
|
+
);
|
|
1657
1763
|
sanitized[sanitizedKey] = `${serialized.substring(0, 1e3)}...`;
|
|
1658
1764
|
} else {
|
|
1659
1765
|
sanitized[sanitizedKey] = value;
|
|
1660
1766
|
}
|
|
1661
1767
|
} catch (error) {
|
|
1662
|
-
logger.warn(
|
|
1768
|
+
logger.warn(
|
|
1769
|
+
`Failed to serialize metadata value for key '${sanitizedKey}': ${error}. Skipping.`
|
|
1770
|
+
);
|
|
1663
1771
|
}
|
|
1664
1772
|
} else {
|
|
1665
|
-
logger.warn(
|
|
1773
|
+
logger.warn(
|
|
1774
|
+
`Unsupported metadata value type for key '${sanitizedKey}': ${typeof value}. Skipping.`
|
|
1775
|
+
);
|
|
1666
1776
|
}
|
|
1667
1777
|
}
|
|
1668
1778
|
return sanitized;
|
|
@@ -1709,15 +1819,24 @@ var MCPAgent = class {
|
|
|
1709
1819
|
};
|
|
1710
1820
|
}
|
|
1711
1821
|
} catch (error) {
|
|
1712
|
-
logger.warn(
|
|
1713
|
-
|
|
1822
|
+
logger.warn(
|
|
1823
|
+
`Failed to get config for server '${serverName}': ${error}`
|
|
1824
|
+
);
|
|
1825
|
+
serverConfigs[serverName] = {
|
|
1826
|
+
type: "error",
|
|
1827
|
+
error: "config_unavailable"
|
|
1828
|
+
};
|
|
1714
1829
|
}
|
|
1715
1830
|
}
|
|
1716
1831
|
serverInfo.mcp_server_configs = serverConfigs;
|
|
1717
1832
|
} else if (this.connectors && this.connectors.length > 0) {
|
|
1718
1833
|
serverInfo.mcp_servers_count = this.connectors.length;
|
|
1719
|
-
serverInfo.mcp_server_names = this.connectors.map(
|
|
1720
|
-
|
|
1834
|
+
serverInfo.mcp_server_names = this.connectors.map(
|
|
1835
|
+
(c) => c.publicIdentifier
|
|
1836
|
+
);
|
|
1837
|
+
serverInfo.mcp_server_types = this.connectors.map(
|
|
1838
|
+
(c) => c.constructor.name
|
|
1839
|
+
);
|
|
1721
1840
|
}
|
|
1722
1841
|
} catch (error) {
|
|
1723
1842
|
logger.warn(`Failed to collect MCP server info: ${error}`);
|
|
@@ -1771,7 +1890,13 @@ var MCPAgent = class {
|
|
|
1771
1890
|
}
|
|
1772
1891
|
async run(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
|
1773
1892
|
if (this.isRemote && this.remoteAgent) {
|
|
1774
|
-
return this.remoteAgent.run(
|
|
1893
|
+
return this.remoteAgent.run(
|
|
1894
|
+
query,
|
|
1895
|
+
maxSteps,
|
|
1896
|
+
manageConnector,
|
|
1897
|
+
externalHistory,
|
|
1898
|
+
outputSchema
|
|
1899
|
+
);
|
|
1775
1900
|
}
|
|
1776
1901
|
const generator = this.stream(
|
|
1777
1902
|
query,
|
|
@@ -1784,7 +1909,13 @@ var MCPAgent = class {
|
|
|
1784
1909
|
}
|
|
1785
1910
|
async *stream(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
|
|
1786
1911
|
if (this.isRemote && this.remoteAgent) {
|
|
1787
|
-
const result = await this.remoteAgent.run(
|
|
1912
|
+
const result = await this.remoteAgent.run(
|
|
1913
|
+
query,
|
|
1914
|
+
maxSteps,
|
|
1915
|
+
manageConnector,
|
|
1916
|
+
externalHistory,
|
|
1917
|
+
outputSchema
|
|
1918
|
+
);
|
|
1788
1919
|
return result;
|
|
1789
1920
|
}
|
|
1790
1921
|
let initializedHere = false;
|
|
@@ -1829,27 +1960,31 @@ var MCPAgent = class {
|
|
|
1829
1960
|
logger.info("\u{1F3C1} Starting agent execution");
|
|
1830
1961
|
const maxRestarts = 3;
|
|
1831
1962
|
let restartCount = 0;
|
|
1832
|
-
const accumulatedMessages = [
|
|
1963
|
+
const accumulatedMessages = [
|
|
1964
|
+
...langchainHistory,
|
|
1965
|
+
new HumanMessage(query)
|
|
1966
|
+
];
|
|
1833
1967
|
while (restartCount <= maxRestarts) {
|
|
1834
1968
|
const inputs = { messages: accumulatedMessages };
|
|
1835
1969
|
let shouldRestart = false;
|
|
1836
|
-
const stream = await this._agentExecutor.stream(
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
...this.metadata.session_id && { sessionId: this.metadata.session_id }
|
|
1970
|
+
const stream = await this._agentExecutor.stream(inputs, {
|
|
1971
|
+
streamMode: "updates",
|
|
1972
|
+
// Get updates as they happen
|
|
1973
|
+
callbacks: this.callbacks,
|
|
1974
|
+
metadata: this.getMetadata(),
|
|
1975
|
+
tags: this.getTags(),
|
|
1976
|
+
// Set trace name for LangChain/Langfuse
|
|
1977
|
+
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
1978
|
+
// Pass sessionId for Langfuse if present in metadata
|
|
1979
|
+
...this.metadata.session_id && {
|
|
1980
|
+
sessionId: this.metadata.session_id
|
|
1848
1981
|
}
|
|
1849
|
-
);
|
|
1982
|
+
});
|
|
1850
1983
|
for await (const chunk of stream) {
|
|
1851
1984
|
for (const [nodeName, nodeOutput] of Object.entries(chunk)) {
|
|
1852
|
-
logger.debug(
|
|
1985
|
+
logger.debug(
|
|
1986
|
+
`\u{1F4E6} Node '${nodeName}' output: ${JSON.stringify(nodeOutput)}`
|
|
1987
|
+
);
|
|
1853
1988
|
if (nodeOutput && typeof nodeOutput === "object" && "messages" in nodeOutput) {
|
|
1854
1989
|
let messages = nodeOutput.messages;
|
|
1855
1990
|
if (!Array.isArray(messages)) {
|
|
@@ -1871,7 +2006,9 @@ var MCPAgent = class {
|
|
|
1871
2006
|
if (toolInputStr.length > 100) {
|
|
1872
2007
|
toolInputStr = `${toolInputStr.slice(0, 97)}...`;
|
|
1873
2008
|
}
|
|
1874
|
-
logger.info(
|
|
2009
|
+
logger.info(
|
|
2010
|
+
`\u{1F527} Tool call: ${toolName} with input: ${toolInputStr}`
|
|
2011
|
+
);
|
|
1875
2012
|
yield {
|
|
1876
2013
|
action: {
|
|
1877
2014
|
tool: toolName,
|
|
@@ -1893,9 +2030,15 @@ var MCPAgent = class {
|
|
|
1893
2030
|
logger.info(`\u{1F4C4} Tool result: ${observationStr}`);
|
|
1894
2031
|
if (this.useServerManager && this.serverManager) {
|
|
1895
2032
|
const currentTools = this.serverManager.tools;
|
|
1896
|
-
const currentToolNames = new Set(
|
|
1897
|
-
|
|
1898
|
-
|
|
2033
|
+
const currentToolNames = new Set(
|
|
2034
|
+
currentTools.map((t) => t.name)
|
|
2035
|
+
);
|
|
2036
|
+
const existingToolNames = new Set(
|
|
2037
|
+
this._tools.map((t) => t.name)
|
|
2038
|
+
);
|
|
2039
|
+
if (currentToolNames.size !== existingToolNames.size || [...currentToolNames].some(
|
|
2040
|
+
(n) => !existingToolNames.has(n)
|
|
2041
|
+
)) {
|
|
1899
2042
|
logger.info(
|
|
1900
2043
|
`\u{1F504} Tools changed during execution. New tools: ${[...currentToolNames].join(", ")}`
|
|
1901
2044
|
);
|
|
@@ -1930,7 +2073,9 @@ var MCPAgent = class {
|
|
|
1930
2073
|
break;
|
|
1931
2074
|
}
|
|
1932
2075
|
if (restartCount > maxRestarts) {
|
|
1933
|
-
logger.warn(
|
|
2076
|
+
logger.warn(
|
|
2077
|
+
`\u26A0\uFE0F Max restarts (${maxRestarts}) reached. Continuing with current tools.`
|
|
2078
|
+
);
|
|
1934
2079
|
break;
|
|
1935
2080
|
}
|
|
1936
2081
|
}
|
|
@@ -1949,17 +2094,25 @@ var MCPAgent = class {
|
|
|
1949
2094
|
outputSchema
|
|
1950
2095
|
);
|
|
1951
2096
|
if (this.memoryEnabled) {
|
|
1952
|
-
this.addToHistory(
|
|
2097
|
+
this.addToHistory(
|
|
2098
|
+
new AIMessage(
|
|
2099
|
+
`Structured result: ${JSON.stringify(structuredResult)}`
|
|
2100
|
+
)
|
|
2101
|
+
);
|
|
1953
2102
|
}
|
|
1954
2103
|
logger.info("\u2705 Structured output successful");
|
|
1955
2104
|
success = true;
|
|
1956
2105
|
return structuredResult;
|
|
1957
2106
|
} catch (e) {
|
|
1958
2107
|
logger.error(`\u274C Structured output failed: ${e}`);
|
|
1959
|
-
throw new Error(
|
|
2108
|
+
throw new Error(
|
|
2109
|
+
`Failed to generate structured output: ${e instanceof Error ? e.message : String(e)}`
|
|
2110
|
+
);
|
|
1960
2111
|
}
|
|
1961
2112
|
}
|
|
1962
|
-
logger.info(
|
|
2113
|
+
logger.info(
|
|
2114
|
+
`\u{1F389} Agent execution complete in ${((Date.now() - startTime) / 1e3).toFixed(2)} seconds`
|
|
2115
|
+
);
|
|
1963
2116
|
success = true;
|
|
1964
2117
|
return finalOutput || "No output generated";
|
|
1965
2118
|
} catch (e) {
|
|
@@ -1986,7 +2139,9 @@ var MCPAgent = class {
|
|
|
1986
2139
|
modelProvider: this.modelProvider,
|
|
1987
2140
|
modelName: this.modelName,
|
|
1988
2141
|
serverCount,
|
|
1989
|
-
serverIdentifiers: this.connectors.map(
|
|
2142
|
+
serverIdentifiers: this.connectors.map(
|
|
2143
|
+
(connector) => connector.publicIdentifier
|
|
2144
|
+
),
|
|
1990
2145
|
totalToolsAvailable: toolsAvailable.length,
|
|
1991
2146
|
toolsAvailableNames: toolsAvailable.map((t) => t.name),
|
|
1992
2147
|
maxStepsConfigured: this.maxSteps,
|
|
@@ -2090,7 +2245,10 @@ var MCPAgent = class {
|
|
|
2090
2245
|
logger.info(`\u26A0\uFE0F Skipped message of type: ${msg.constructor.name}`);
|
|
2091
2246
|
}
|
|
2092
2247
|
}
|
|
2093
|
-
const inputs = [
|
|
2248
|
+
const inputs = [
|
|
2249
|
+
...langchainHistory,
|
|
2250
|
+
new HumanMessage(query)
|
|
2251
|
+
];
|
|
2094
2252
|
logger.info("callbacks", this.callbacks);
|
|
2095
2253
|
const eventStream = agentExecutor.streamEvents(
|
|
2096
2254
|
{ messages: inputs },
|
|
@@ -2103,7 +2261,9 @@ var MCPAgent = class {
|
|
|
2103
2261
|
// Set trace name for LangChain/Langfuse
|
|
2104
2262
|
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
2105
2263
|
// Pass sessionId for Langfuse if present in metadata
|
|
2106
|
-
...this.metadata.session_id && {
|
|
2264
|
+
...this.metadata.session_id && {
|
|
2265
|
+
sessionId: this.metadata.session_id
|
|
2266
|
+
}
|
|
2107
2267
|
}
|
|
2108
2268
|
);
|
|
2109
2269
|
for await (const event of eventStream) {
|
|
@@ -2122,7 +2282,9 @@ var MCPAgent = class {
|
|
|
2122
2282
|
}
|
|
2123
2283
|
const normalizedContent = this._normalizeOutput(chunk.content);
|
|
2124
2284
|
finalResponse += normalizedContent;
|
|
2125
|
-
logger.debug(
|
|
2285
|
+
logger.debug(
|
|
2286
|
+
`\u{1F4DD} Accumulated response length: ${finalResponse.length}`
|
|
2287
|
+
);
|
|
2126
2288
|
}
|
|
2127
2289
|
}
|
|
2128
2290
|
yield event;
|
|
@@ -2179,7 +2341,11 @@ var MCPAgent = class {
|
|
|
2179
2341
|
data: { output: conversionResult }
|
|
2180
2342
|
};
|
|
2181
2343
|
if (this.memoryEnabled) {
|
|
2182
|
-
this.addToHistory(
|
|
2344
|
+
this.addToHistory(
|
|
2345
|
+
new AIMessage(
|
|
2346
|
+
`Structured result: ${JSON.stringify(conversionResult)}`
|
|
2347
|
+
)
|
|
2348
|
+
);
|
|
2183
2349
|
}
|
|
2184
2350
|
logger.info("\u2705 Structured output successful");
|
|
2185
2351
|
}
|
|
@@ -2198,7 +2364,9 @@ var MCPAgent = class {
|
|
|
2198
2364
|
} catch (e) {
|
|
2199
2365
|
logger.error(`\u274C Error during streamEvents: ${e}`);
|
|
2200
2366
|
if (initializedHere && manageConnector) {
|
|
2201
|
-
logger.info(
|
|
2367
|
+
logger.info(
|
|
2368
|
+
"\u{1F9F9} Cleaning up resources after initialization error in streamEvents"
|
|
2369
|
+
);
|
|
2202
2370
|
await this.close();
|
|
2203
2371
|
}
|
|
2204
2372
|
throw e;
|
|
@@ -2218,7 +2386,9 @@ var MCPAgent = class {
|
|
|
2218
2386
|
modelProvider: this.modelProvider,
|
|
2219
2387
|
modelName: this.modelName,
|
|
2220
2388
|
serverCount,
|
|
2221
|
-
serverIdentifiers: this.connectors.map(
|
|
2389
|
+
serverIdentifiers: this.connectors.map(
|
|
2390
|
+
(connector) => connector.publicIdentifier
|
|
2391
|
+
),
|
|
2222
2392
|
totalToolsAvailable: this._tools.length,
|
|
2223
2393
|
toolsAvailableNames: this._tools.map((t) => t.name),
|
|
2224
2394
|
maxStepsConfigured: this.maxSteps,
|
|
@@ -2246,11 +2416,15 @@ var MCPAgent = class {
|
|
|
2246
2416
|
* @param outputSchema - The Zod schema to validate against
|
|
2247
2417
|
*/
|
|
2248
2418
|
async _attemptStructuredOutput(rawResult, llm, outputSchema) {
|
|
2249
|
-
logger.info(
|
|
2419
|
+
logger.info(
|
|
2420
|
+
`\u{1F504} Attempting structured output with schema: ${JSON.stringify(outputSchema, null, 2)}`
|
|
2421
|
+
);
|
|
2250
2422
|
logger.info(`\u{1F504} Raw result: ${JSON.stringify(rawResult, null, 2)}`);
|
|
2251
2423
|
let structuredLlm = null;
|
|
2252
2424
|
let schemaDescription = "";
|
|
2253
|
-
logger.debug(
|
|
2425
|
+
logger.debug(
|
|
2426
|
+
`\u{1F504} Structured output requested, schema: ${JSON.stringify(zodToJsonSchema2(outputSchema), null, 2)}`
|
|
2427
|
+
);
|
|
2254
2428
|
if (llm && "withStructuredOutput" in llm && typeof llm.withStructuredOutput === "function") {
|
|
2255
2429
|
structuredLlm = llm.withStructuredOutput(outputSchema);
|
|
2256
2430
|
} else if (llm) {
|
|
@@ -2302,11 +2476,17 @@ var MCPAgent = class {
|
|
|
2302
2476
|
`;
|
|
2303
2477
|
}
|
|
2304
2478
|
try {
|
|
2305
|
-
logger.info(
|
|
2479
|
+
logger.info(
|
|
2480
|
+
`\u{1F504} Structured output attempt ${attempt} - using streaming approach`
|
|
2481
|
+
);
|
|
2306
2482
|
const contentPreview = textContent.length > 300 ? `${textContent.slice(0, 300)}...` : textContent;
|
|
2307
|
-
logger.info(
|
|
2308
|
-
|
|
2309
|
-
|
|
2483
|
+
logger.info(
|
|
2484
|
+
`\u{1F504} Content being formatted (${textContent.length} chars): ${contentPreview}`
|
|
2485
|
+
);
|
|
2486
|
+
logger.info(
|
|
2487
|
+
`\u{1F504} Full format prompt (${formatPrompt.length} chars):
|
|
2488
|
+
${formatPrompt}`
|
|
2489
|
+
);
|
|
2310
2490
|
const stream = await structuredLlm.stream(formatPrompt);
|
|
2311
2491
|
let structuredResult = null;
|
|
2312
2492
|
let chunkCount = 0;
|
|
@@ -2332,19 +2512,30 @@ ${formatPrompt}`);
|
|
|
2332
2512
|
logger.info(`\u{1F504} Structured output streaming: ${chunkCount} chunks`);
|
|
2333
2513
|
}
|
|
2334
2514
|
}
|
|
2335
|
-
logger.info(
|
|
2515
|
+
logger.info(
|
|
2516
|
+
`\u{1F504} Structured result attempt ${attempt}: ${JSON.stringify(structuredResult, null, 2)}`
|
|
2517
|
+
);
|
|
2336
2518
|
if (!structuredResult) {
|
|
2337
2519
|
throw new Error("No structured result received from stream");
|
|
2338
2520
|
}
|
|
2339
|
-
const validatedResult = this._validateStructuredResult(
|
|
2521
|
+
const validatedResult = this._validateStructuredResult(
|
|
2522
|
+
structuredResult,
|
|
2523
|
+
outputSchema
|
|
2524
|
+
);
|
|
2340
2525
|
logger.info(`\u2705 Structured output successful on attempt ${attempt}`);
|
|
2341
2526
|
return validatedResult;
|
|
2342
2527
|
} catch (e) {
|
|
2343
2528
|
lastError = e instanceof Error ? e.message : String(e);
|
|
2344
|
-
logger.warn(
|
|
2529
|
+
logger.warn(
|
|
2530
|
+
`\u26A0\uFE0F Structured output attempt ${attempt} failed: ${lastError}`
|
|
2531
|
+
);
|
|
2345
2532
|
if (attempt === maxRetries) {
|
|
2346
|
-
logger.error(
|
|
2347
|
-
|
|
2533
|
+
logger.error(
|
|
2534
|
+
`\u274C All ${maxRetries} structured output attempts failed`
|
|
2535
|
+
);
|
|
2536
|
+
throw new Error(
|
|
2537
|
+
`Failed to generate valid structured output after ${maxRetries} attempts. Last error: ${lastError}`
|
|
2538
|
+
);
|
|
2348
2539
|
}
|
|
2349
2540
|
continue;
|
|
2350
2541
|
}
|
|
@@ -2359,14 +2550,18 @@ ${formatPrompt}`);
|
|
|
2359
2550
|
const validatedResult = outputSchema.parse(structuredResult);
|
|
2360
2551
|
const schemaType = outputSchema;
|
|
2361
2552
|
if (schemaType._def && schemaType._def.shape) {
|
|
2362
|
-
for (const [fieldName, fieldSchema] of Object.entries(
|
|
2553
|
+
for (const [fieldName, fieldSchema] of Object.entries(
|
|
2554
|
+
schemaType._def.shape
|
|
2555
|
+
)) {
|
|
2363
2556
|
const field = fieldSchema;
|
|
2364
2557
|
const isOptional = field.isOptional?.() ?? field._def?.typeName === "ZodOptional";
|
|
2365
2558
|
const isNullable = field.isNullable?.() ?? field._def?.typeName === "ZodNullable";
|
|
2366
2559
|
if (!isOptional && !isNullable) {
|
|
2367
2560
|
const value = validatedResult[fieldName];
|
|
2368
2561
|
if (value === null || value === void 0 || typeof value === "string" && !value.trim() || Array.isArray(value) && value.length === 0) {
|
|
2369
|
-
throw new Error(
|
|
2562
|
+
throw new Error(
|
|
2563
|
+
`Required field '${fieldName}' is missing or empty`
|
|
2564
|
+
);
|
|
2370
2565
|
}
|
|
2371
2566
|
}
|
|
2372
2567
|
}
|
|
@@ -2403,841 +2598,6 @@ ${formatPrompt}`);
|
|
|
2403
2598
|
}
|
|
2404
2599
|
};
|
|
2405
2600
|
|
|
2406
|
-
// src/session.ts
|
|
2407
|
-
var MCPSession = class {
|
|
2408
|
-
static {
|
|
2409
|
-
__name(this, "MCPSession");
|
|
2410
|
-
}
|
|
2411
|
-
connector;
|
|
2412
|
-
autoConnect;
|
|
2413
|
-
constructor(connector, autoConnect = true) {
|
|
2414
|
-
this.connector = connector;
|
|
2415
|
-
this.autoConnect = autoConnect;
|
|
2416
|
-
}
|
|
2417
|
-
async connect() {
|
|
2418
|
-
await this.connector.connect();
|
|
2419
|
-
}
|
|
2420
|
-
async disconnect() {
|
|
2421
|
-
await this.connector.disconnect();
|
|
2422
|
-
}
|
|
2423
|
-
async initialize() {
|
|
2424
|
-
if (!this.isConnected && this.autoConnect) {
|
|
2425
|
-
await this.connect();
|
|
2426
|
-
}
|
|
2427
|
-
await this.connector.initialize();
|
|
2428
|
-
}
|
|
2429
|
-
get isConnected() {
|
|
2430
|
-
return this.connector && this.connector.isClientConnected;
|
|
2431
|
-
}
|
|
2432
|
-
};
|
|
2433
|
-
|
|
2434
|
-
// src/connectors/base.ts
|
|
2435
|
-
var BaseConnector = class {
|
|
2436
|
-
static {
|
|
2437
|
-
__name(this, "BaseConnector");
|
|
2438
|
-
}
|
|
2439
|
-
client = null;
|
|
2440
|
-
connectionManager = null;
|
|
2441
|
-
toolsCache = null;
|
|
2442
|
-
connected = false;
|
|
2443
|
-
opts;
|
|
2444
|
-
constructor(opts = {}) {
|
|
2445
|
-
this.opts = opts;
|
|
2446
|
-
}
|
|
2447
|
-
/** Disconnect and release resources. */
|
|
2448
|
-
async disconnect() {
|
|
2449
|
-
if (!this.connected) {
|
|
2450
|
-
logger.debug("Not connected to MCP implementation");
|
|
2451
|
-
return;
|
|
2452
|
-
}
|
|
2453
|
-
logger.debug("Disconnecting from MCP implementation");
|
|
2454
|
-
await this.cleanupResources();
|
|
2455
|
-
this.connected = false;
|
|
2456
|
-
logger.debug("Disconnected from MCP implementation");
|
|
2457
|
-
}
|
|
2458
|
-
/** Check if the client is connected */
|
|
2459
|
-
get isClientConnected() {
|
|
2460
|
-
return this.client != null;
|
|
2461
|
-
}
|
|
2462
|
-
/**
|
|
2463
|
-
* Initialise the MCP session **after** `connect()` has succeeded.
|
|
2464
|
-
*
|
|
2465
|
-
* In the SDK, `Client.connect(transport)` automatically performs the
|
|
2466
|
-
* protocol‑level `initialize` handshake, so we only need to cache the list of
|
|
2467
|
-
* tools and expose some server info.
|
|
2468
|
-
*/
|
|
2469
|
-
async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
|
|
2470
|
-
if (!this.client) {
|
|
2471
|
-
throw new Error("MCP client is not connected");
|
|
2472
|
-
}
|
|
2473
|
-
logger.debug("Caching server capabilities & tools");
|
|
2474
|
-
const capabilities = this.client.getServerCapabilities();
|
|
2475
|
-
const listToolsRes = await this.client.listTools(void 0, defaultRequestOptions);
|
|
2476
|
-
this.toolsCache = listToolsRes.tools ?? [];
|
|
2477
|
-
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
2478
|
-
return capabilities;
|
|
2479
|
-
}
|
|
2480
|
-
/** Lazily expose the cached tools list. */
|
|
2481
|
-
get tools() {
|
|
2482
|
-
if (!this.toolsCache) {
|
|
2483
|
-
throw new Error("MCP client is not initialized; call initialize() first");
|
|
2484
|
-
}
|
|
2485
|
-
return this.toolsCache;
|
|
2486
|
-
}
|
|
2487
|
-
/** Call a tool on the server. */
|
|
2488
|
-
async callTool(name, args, options) {
|
|
2489
|
-
if (!this.client) {
|
|
2490
|
-
throw new Error("MCP client is not connected");
|
|
2491
|
-
}
|
|
2492
|
-
logger.debug(`Calling tool '${name}' with args`, args);
|
|
2493
|
-
const res = await this.client.callTool({ name, arguments: args }, void 0, options);
|
|
2494
|
-
logger.debug(`Tool '${name}' returned`, res);
|
|
2495
|
-
return res;
|
|
2496
|
-
}
|
|
2497
|
-
/**
|
|
2498
|
-
* List resources from the server with optional pagination
|
|
2499
|
-
*
|
|
2500
|
-
* @param cursor - Optional cursor for pagination
|
|
2501
|
-
* @param options - Request options
|
|
2502
|
-
* @returns Resource list with optional nextCursor for pagination
|
|
2503
|
-
*/
|
|
2504
|
-
async listResources(cursor, options) {
|
|
2505
|
-
if (!this.client) {
|
|
2506
|
-
throw new Error("MCP client is not connected");
|
|
2507
|
-
}
|
|
2508
|
-
logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
|
|
2509
|
-
return await this.client.listResources({ cursor }, options);
|
|
2510
|
-
}
|
|
2511
|
-
/**
|
|
2512
|
-
* List all resources from the server, automatically handling pagination
|
|
2513
|
-
*
|
|
2514
|
-
* @param options - Request options
|
|
2515
|
-
* @returns Complete list of all resources
|
|
2516
|
-
*/
|
|
2517
|
-
async listAllResources(options) {
|
|
2518
|
-
if (!this.client) {
|
|
2519
|
-
throw new Error("MCP client is not connected");
|
|
2520
|
-
}
|
|
2521
|
-
logger.debug("Listing all resources (with auto-pagination)");
|
|
2522
|
-
const allResources = [];
|
|
2523
|
-
let cursor = void 0;
|
|
2524
|
-
do {
|
|
2525
|
-
const result = await this.client.listResources({ cursor }, options);
|
|
2526
|
-
allResources.push(...result.resources || []);
|
|
2527
|
-
cursor = result.nextCursor;
|
|
2528
|
-
} while (cursor);
|
|
2529
|
-
return { resources: allResources };
|
|
2530
|
-
}
|
|
2531
|
-
/**
|
|
2532
|
-
* List resource templates from the server
|
|
2533
|
-
*
|
|
2534
|
-
* @param options - Request options
|
|
2535
|
-
* @returns List of available resource templates
|
|
2536
|
-
*/
|
|
2537
|
-
async listResourceTemplates(options) {
|
|
2538
|
-
if (!this.client) {
|
|
2539
|
-
throw new Error("MCP client is not connected");
|
|
2540
|
-
}
|
|
2541
|
-
logger.debug("Listing resource templates");
|
|
2542
|
-
return await this.client.listResourceTemplates(void 0, options);
|
|
2543
|
-
}
|
|
2544
|
-
/** Read a resource by URI. */
|
|
2545
|
-
async readResource(uri, options) {
|
|
2546
|
-
if (!this.client) {
|
|
2547
|
-
throw new Error("MCP client is not connected");
|
|
2548
|
-
}
|
|
2549
|
-
logger.debug(`Reading resource ${uri}`);
|
|
2550
|
-
const res = await this.client.readResource({ uri }, options);
|
|
2551
|
-
return { content: res.content, mimeType: res.mimeType };
|
|
2552
|
-
}
|
|
2553
|
-
/**
|
|
2554
|
-
* Subscribe to resource updates
|
|
2555
|
-
*
|
|
2556
|
-
* @param uri - URI of the resource to subscribe to
|
|
2557
|
-
* @param options - Request options
|
|
2558
|
-
*/
|
|
2559
|
-
async subscribeToResource(uri, options) {
|
|
2560
|
-
if (!this.client) {
|
|
2561
|
-
throw new Error("MCP client is not connected");
|
|
2562
|
-
}
|
|
2563
|
-
logger.debug(`Subscribing to resource: ${uri}`);
|
|
2564
|
-
return await this.client.subscribeResource({ uri }, options);
|
|
2565
|
-
}
|
|
2566
|
-
/**
|
|
2567
|
-
* Unsubscribe from resource updates
|
|
2568
|
-
*
|
|
2569
|
-
* @param uri - URI of the resource to unsubscribe from
|
|
2570
|
-
* @param options - Request options
|
|
2571
|
-
*/
|
|
2572
|
-
async unsubscribeFromResource(uri, options) {
|
|
2573
|
-
if (!this.client) {
|
|
2574
|
-
throw new Error("MCP client is not connected");
|
|
2575
|
-
}
|
|
2576
|
-
logger.debug(`Unsubscribing from resource: ${uri}`);
|
|
2577
|
-
return await this.client.unsubscribeResource({ uri }, options);
|
|
2578
|
-
}
|
|
2579
|
-
async listPrompts() {
|
|
2580
|
-
if (!this.client) {
|
|
2581
|
-
throw new Error("MCP client is not connected");
|
|
2582
|
-
}
|
|
2583
|
-
logger.debug("Listing prompt");
|
|
2584
|
-
return await this.client.listPrompts();
|
|
2585
|
-
}
|
|
2586
|
-
async getPrompt(name, args) {
|
|
2587
|
-
if (!this.client) {
|
|
2588
|
-
throw new Error("MCP client is not connected");
|
|
2589
|
-
}
|
|
2590
|
-
logger.debug(`Getting prompt ${name}`);
|
|
2591
|
-
return await this.client.getPrompt({ name, arguments: args });
|
|
2592
|
-
}
|
|
2593
|
-
/** Send a raw request through the client. */
|
|
2594
|
-
async request(method, params = null, options) {
|
|
2595
|
-
if (!this.client) {
|
|
2596
|
-
throw new Error("MCP client is not connected");
|
|
2597
|
-
}
|
|
2598
|
-
logger.debug(`Sending raw request '${method}' with params`, params);
|
|
2599
|
-
return await this.client.request({ method, params: params ?? {} }, void 0, options);
|
|
2600
|
-
}
|
|
2601
|
-
/**
|
|
2602
|
-
* Helper to tear down the client & connection manager safely.
|
|
2603
|
-
*/
|
|
2604
|
-
async cleanupResources() {
|
|
2605
|
-
const issues = [];
|
|
2606
|
-
if (this.client) {
|
|
2607
|
-
try {
|
|
2608
|
-
if (typeof this.client.close === "function") {
|
|
2609
|
-
await this.client.close();
|
|
2610
|
-
}
|
|
2611
|
-
} catch (e) {
|
|
2612
|
-
const msg = `Error closing client: ${e}`;
|
|
2613
|
-
logger.warn(msg);
|
|
2614
|
-
issues.push(msg);
|
|
2615
|
-
} finally {
|
|
2616
|
-
this.client = null;
|
|
2617
|
-
}
|
|
2618
|
-
}
|
|
2619
|
-
if (this.connectionManager) {
|
|
2620
|
-
try {
|
|
2621
|
-
await this.connectionManager.stop();
|
|
2622
|
-
} catch (e) {
|
|
2623
|
-
const msg = `Error stopping connection manager: ${e}`;
|
|
2624
|
-
logger.warn(msg);
|
|
2625
|
-
issues.push(msg);
|
|
2626
|
-
} finally {
|
|
2627
|
-
this.connectionManager = null;
|
|
2628
|
-
}
|
|
2629
|
-
}
|
|
2630
|
-
this.toolsCache = null;
|
|
2631
|
-
if (issues.length) {
|
|
2632
|
-
logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
};
|
|
2636
|
-
|
|
2637
|
-
// src/connectors/http.ts
|
|
2638
|
-
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2639
|
-
import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
2640
|
-
|
|
2641
|
-
// src/task_managers/sse.ts
|
|
2642
|
-
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
2643
|
-
|
|
2644
|
-
// src/task_managers/base.ts
|
|
2645
|
-
var ConnectionManager = class {
|
|
2646
|
-
static {
|
|
2647
|
-
__name(this, "ConnectionManager");
|
|
2648
|
-
}
|
|
2649
|
-
_readyPromise;
|
|
2650
|
-
_readyResolver;
|
|
2651
|
-
_donePromise;
|
|
2652
|
-
_doneResolver;
|
|
2653
|
-
_exception = null;
|
|
2654
|
-
_connection = null;
|
|
2655
|
-
_task = null;
|
|
2656
|
-
_abortController = null;
|
|
2657
|
-
constructor() {
|
|
2658
|
-
this.reset();
|
|
2659
|
-
}
|
|
2660
|
-
/**
|
|
2661
|
-
* Start the connection manager and establish a connection.
|
|
2662
|
-
*
|
|
2663
|
-
* @returns The established connection.
|
|
2664
|
-
* @throws If the connection cannot be established.
|
|
2665
|
-
*/
|
|
2666
|
-
async start() {
|
|
2667
|
-
this.reset();
|
|
2668
|
-
logger.debug(`Starting ${this.constructor.name}`);
|
|
2669
|
-
this._task = this.connectionTask();
|
|
2670
|
-
await this._readyPromise;
|
|
2671
|
-
if (this._exception) {
|
|
2672
|
-
throw this._exception;
|
|
2673
|
-
}
|
|
2674
|
-
if (this._connection === null) {
|
|
2675
|
-
throw new Error("Connection was not established");
|
|
2676
|
-
}
|
|
2677
|
-
return this._connection;
|
|
2678
|
-
}
|
|
2679
|
-
/**
|
|
2680
|
-
* Stop the connection manager and close the connection.
|
|
2681
|
-
*/
|
|
2682
|
-
async stop() {
|
|
2683
|
-
if (this._task && this._abortController) {
|
|
2684
|
-
logger.debug(`Cancelling ${this.constructor.name} task`);
|
|
2685
|
-
this._abortController.abort();
|
|
2686
|
-
try {
|
|
2687
|
-
await this._task;
|
|
2688
|
-
} catch (e) {
|
|
2689
|
-
if (e instanceof Error && e.name === "AbortError") {
|
|
2690
|
-
logger.debug(`${this.constructor.name} task aborted successfully`);
|
|
2691
|
-
} else {
|
|
2692
|
-
logger.warn(`Error stopping ${this.constructor.name} task: ${e}`);
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
}
|
|
2696
|
-
await this._donePromise;
|
|
2697
|
-
logger.debug(`${this.constructor.name} task completed`);
|
|
2698
|
-
}
|
|
2699
|
-
/**
|
|
2700
|
-
* Reset all internal state.
|
|
2701
|
-
*/
|
|
2702
|
-
reset() {
|
|
2703
|
-
this._readyPromise = new Promise((res) => this._readyResolver = res);
|
|
2704
|
-
this._donePromise = new Promise((res) => this._doneResolver = res);
|
|
2705
|
-
this._exception = null;
|
|
2706
|
-
this._connection = null;
|
|
2707
|
-
this._task = null;
|
|
2708
|
-
this._abortController = new AbortController();
|
|
2709
|
-
}
|
|
2710
|
-
/**
|
|
2711
|
-
* The background task responsible for establishing and maintaining the
|
|
2712
|
-
* connection until it is cancelled.
|
|
2713
|
-
*/
|
|
2714
|
-
async connectionTask() {
|
|
2715
|
-
logger.debug(`Running ${this.constructor.name} task`);
|
|
2716
|
-
try {
|
|
2717
|
-
this._connection = await this.establishConnection();
|
|
2718
|
-
logger.debug(`${this.constructor.name} connected successfully`);
|
|
2719
|
-
this._readyResolver();
|
|
2720
|
-
await this.waitForAbort();
|
|
2721
|
-
} catch (err) {
|
|
2722
|
-
this._exception = err;
|
|
2723
|
-
logger.error(`Error in ${this.constructor.name} task: ${err}`);
|
|
2724
|
-
this._readyResolver();
|
|
2725
|
-
} finally {
|
|
2726
|
-
if (this._connection !== null) {
|
|
2727
|
-
try {
|
|
2728
|
-
await this.closeConnection(this._connection);
|
|
2729
|
-
} catch (closeErr) {
|
|
2730
|
-
logger.warn(`Error closing connection in ${this.constructor.name}: ${closeErr}`);
|
|
2731
|
-
}
|
|
2732
|
-
this._connection = null;
|
|
2733
|
-
}
|
|
2734
|
-
this._doneResolver();
|
|
2735
|
-
}
|
|
2736
|
-
}
|
|
2737
|
-
/**
|
|
2738
|
-
* Helper that returns a promise which resolves when the abort signal fires.
|
|
2739
|
-
*/
|
|
2740
|
-
async waitForAbort() {
|
|
2741
|
-
return new Promise((_resolve, _reject) => {
|
|
2742
|
-
if (!this._abortController) {
|
|
2743
|
-
return;
|
|
2744
|
-
}
|
|
2745
|
-
const signal = this._abortController.signal;
|
|
2746
|
-
if (signal.aborted) {
|
|
2747
|
-
_resolve();
|
|
2748
|
-
return;
|
|
2749
|
-
}
|
|
2750
|
-
const onAbort = /* @__PURE__ */ __name(() => {
|
|
2751
|
-
signal.removeEventListener("abort", onAbort);
|
|
2752
|
-
_resolve();
|
|
2753
|
-
}, "onAbort");
|
|
2754
|
-
signal.addEventListener("abort", onAbort);
|
|
2755
|
-
});
|
|
2756
|
-
}
|
|
2757
|
-
};
|
|
2758
|
-
|
|
2759
|
-
// src/task_managers/sse.ts
|
|
2760
|
-
var SseConnectionManager = class extends ConnectionManager {
|
|
2761
|
-
static {
|
|
2762
|
-
__name(this, "SseConnectionManager");
|
|
2763
|
-
}
|
|
2764
|
-
url;
|
|
2765
|
-
opts;
|
|
2766
|
-
_transport = null;
|
|
2767
|
-
/**
|
|
2768
|
-
* Create an SSE connection manager.
|
|
2769
|
-
*
|
|
2770
|
-
* @param url The SSE endpoint URL.
|
|
2771
|
-
* @param opts Optional transport options (auth, headers, etc.).
|
|
2772
|
-
*/
|
|
2773
|
-
constructor(url, opts) {
|
|
2774
|
-
super();
|
|
2775
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
|
2776
|
-
this.opts = opts;
|
|
2777
|
-
}
|
|
2778
|
-
/**
|
|
2779
|
-
* Spawn a new `SSEClientTransport` and start the connection.
|
|
2780
|
-
*/
|
|
2781
|
-
async establishConnection() {
|
|
2782
|
-
this._transport = new SSEClientTransport(this.url, this.opts);
|
|
2783
|
-
logger.debug(`${this.constructor.name} connected successfully`);
|
|
2784
|
-
return this._transport;
|
|
2785
|
-
}
|
|
2786
|
-
/**
|
|
2787
|
-
* Close the underlying transport and clean up resources.
|
|
2788
|
-
*/
|
|
2789
|
-
async closeConnection(_connection) {
|
|
2790
|
-
if (this._transport) {
|
|
2791
|
-
try {
|
|
2792
|
-
await this._transport.close();
|
|
2793
|
-
} catch (e) {
|
|
2794
|
-
logger.warn(`Error closing SSE transport: ${e}`);
|
|
2795
|
-
} finally {
|
|
2796
|
-
this._transport = null;
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
};
|
|
2801
|
-
|
|
2802
|
-
// src/task_managers/streamable_http.ts
|
|
2803
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
2804
|
-
var StreamableHttpConnectionManager = class extends ConnectionManager {
|
|
2805
|
-
static {
|
|
2806
|
-
__name(this, "StreamableHttpConnectionManager");
|
|
2807
|
-
}
|
|
2808
|
-
url;
|
|
2809
|
-
opts;
|
|
2810
|
-
_transport = null;
|
|
2811
|
-
/**
|
|
2812
|
-
* Create a Streamable HTTP connection manager.
|
|
2813
|
-
*
|
|
2814
|
-
* @param url The HTTP endpoint URL.
|
|
2815
|
-
* @param opts Optional transport options (auth, headers, etc.).
|
|
2816
|
-
*/
|
|
2817
|
-
constructor(url, opts) {
|
|
2818
|
-
super();
|
|
2819
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
|
2820
|
-
this.opts = opts;
|
|
2821
|
-
}
|
|
2822
|
-
/**
|
|
2823
|
-
* Spawn a new `StreamableHTTPClientTransport` and return it.
|
|
2824
|
-
* The Client.connect() method will handle starting the transport.
|
|
2825
|
-
*/
|
|
2826
|
-
async establishConnection() {
|
|
2827
|
-
this._transport = new StreamableHTTPClientTransport(this.url, this.opts);
|
|
2828
|
-
logger.debug(`${this.constructor.name} created successfully`);
|
|
2829
|
-
return this._transport;
|
|
2830
|
-
}
|
|
2831
|
-
/**
|
|
2832
|
-
* Close the underlying transport and clean up resources.
|
|
2833
|
-
*/
|
|
2834
|
-
async closeConnection(_connection) {
|
|
2835
|
-
if (this._transport) {
|
|
2836
|
-
try {
|
|
2837
|
-
await this._transport.close();
|
|
2838
|
-
} catch (e) {
|
|
2839
|
-
logger.warn(`Error closing Streamable HTTP transport: ${e}`);
|
|
2840
|
-
} finally {
|
|
2841
|
-
this._transport = null;
|
|
2842
|
-
}
|
|
2843
|
-
}
|
|
2844
|
-
}
|
|
2845
|
-
/**
|
|
2846
|
-
* Get the session ID from the transport if available.
|
|
2847
|
-
*/
|
|
2848
|
-
get sessionId() {
|
|
2849
|
-
return this._transport?.sessionId;
|
|
2850
|
-
}
|
|
2851
|
-
};
|
|
2852
|
-
|
|
2853
|
-
// src/connectors/http.ts
|
|
2854
|
-
var HttpConnector = class extends BaseConnector {
|
|
2855
|
-
static {
|
|
2856
|
-
__name(this, "HttpConnector");
|
|
2857
|
-
}
|
|
2858
|
-
baseUrl;
|
|
2859
|
-
headers;
|
|
2860
|
-
timeout;
|
|
2861
|
-
sseReadTimeout;
|
|
2862
|
-
clientInfo;
|
|
2863
|
-
preferSse;
|
|
2864
|
-
transportType = null;
|
|
2865
|
-
constructor(baseUrl, opts = {}) {
|
|
2866
|
-
super(opts);
|
|
2867
|
-
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
2868
|
-
this.headers = { ...opts.headers ?? {} };
|
|
2869
|
-
if (opts.authToken) {
|
|
2870
|
-
this.headers.Authorization = `Bearer ${opts.authToken}`;
|
|
2871
|
-
}
|
|
2872
|
-
this.timeout = opts.timeout ?? 3e4;
|
|
2873
|
-
this.sseReadTimeout = opts.sseReadTimeout ?? 3e5;
|
|
2874
|
-
this.clientInfo = opts.clientInfo ?? { name: "http-connector", version: "1.0.0" };
|
|
2875
|
-
this.preferSse = opts.preferSse ?? false;
|
|
2876
|
-
}
|
|
2877
|
-
/** Establish connection to the MCP implementation via HTTP (streamable or SSE). */
|
|
2878
|
-
async connect() {
|
|
2879
|
-
if (this.connected) {
|
|
2880
|
-
logger.debug("Already connected to MCP implementation");
|
|
2881
|
-
return;
|
|
2882
|
-
}
|
|
2883
|
-
const baseUrl = this.baseUrl;
|
|
2884
|
-
if (this.preferSse) {
|
|
2885
|
-
logger.debug(`Connecting to MCP implementation via HTTP/SSE: ${baseUrl}`);
|
|
2886
|
-
await this.connectWithSse(baseUrl);
|
|
2887
|
-
return;
|
|
2888
|
-
}
|
|
2889
|
-
logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);
|
|
2890
|
-
try {
|
|
2891
|
-
logger.info("\u{1F504} Attempting streamable HTTP transport...");
|
|
2892
|
-
await this.connectWithStreamableHttp(baseUrl);
|
|
2893
|
-
logger.info("\u2705 Successfully connected via streamable HTTP");
|
|
2894
|
-
} catch (err) {
|
|
2895
|
-
let fallbackReason = "Unknown error";
|
|
2896
|
-
if (err instanceof StreamableHTTPError) {
|
|
2897
|
-
if (err.code === 400 && err.message.includes("Missing session ID")) {
|
|
2898
|
-
fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
|
|
2899
|
-
logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
|
|
2900
|
-
} else if (err.code === 404 || err.code === 405) {
|
|
2901
|
-
fallbackReason = `Server returned ${err.code} - server likely doesn't support streamable HTTP`;
|
|
2902
|
-
logger.debug(fallbackReason);
|
|
2903
|
-
} else {
|
|
2904
|
-
fallbackReason = `Server returned ${err.code}: ${err.message}`;
|
|
2905
|
-
logger.debug(fallbackReason);
|
|
2906
|
-
}
|
|
2907
|
-
} else if (err instanceof Error) {
|
|
2908
|
-
const errorStr = err.toString();
|
|
2909
|
-
const errorMsg = err.message || "";
|
|
2910
|
-
if (errorStr.includes("Missing session ID") || errorStr.includes("Bad Request: Missing session ID") || errorMsg.includes("FastMCP session ID error")) {
|
|
2911
|
-
fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
|
|
2912
|
-
logger.warn(`\u26A0\uFE0F ${fallbackReason}`);
|
|
2913
|
-
} else if (errorStr.includes("405 Method Not Allowed") || errorStr.includes("404 Not Found")) {
|
|
2914
|
-
fallbackReason = "Server doesn't support streamable HTTP (405/404)";
|
|
2915
|
-
logger.debug(fallbackReason);
|
|
2916
|
-
} else {
|
|
2917
|
-
fallbackReason = `Streamable HTTP failed: ${err.message}`;
|
|
2918
|
-
logger.debug(fallbackReason);
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
logger.info("\u{1F504} Falling back to SSE transport...");
|
|
2922
|
-
try {
|
|
2923
|
-
await this.connectWithSse(baseUrl);
|
|
2924
|
-
} catch (sseErr) {
|
|
2925
|
-
logger.error(`Failed to connect with both transports:`);
|
|
2926
|
-
logger.error(` Streamable HTTP: ${fallbackReason}`);
|
|
2927
|
-
logger.error(` SSE: ${sseErr}`);
|
|
2928
|
-
await this.cleanupResources();
|
|
2929
|
-
throw new Error("Could not connect to server with any available transport");
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
}
|
|
2933
|
-
async connectWithStreamableHttp(baseUrl) {
|
|
2934
|
-
try {
|
|
2935
|
-
this.connectionManager = new StreamableHttpConnectionManager(
|
|
2936
|
-
baseUrl,
|
|
2937
|
-
{
|
|
2938
|
-
requestInit: {
|
|
2939
|
-
headers: this.headers
|
|
2940
|
-
},
|
|
2941
|
-
// Pass through timeout and other options
|
|
2942
|
-
reconnectionOptions: {
|
|
2943
|
-
maxReconnectionDelay: 3e4,
|
|
2944
|
-
initialReconnectionDelay: 1e3,
|
|
2945
|
-
reconnectionDelayGrowFactor: 1.5,
|
|
2946
|
-
maxRetries: 2
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
);
|
|
2950
|
-
const transport = await this.connectionManager.start();
|
|
2951
|
-
this.client = new Client(this.clientInfo, this.opts.clientOptions);
|
|
2952
|
-
try {
|
|
2953
|
-
await this.client.connect(transport);
|
|
2954
|
-
} catch (connectErr) {
|
|
2955
|
-
if (connectErr instanceof Error) {
|
|
2956
|
-
const errMsg = connectErr.message || connectErr.toString();
|
|
2957
|
-
if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID")) {
|
|
2958
|
-
const wrappedError = new Error(`FastMCP session ID error: ${errMsg}`);
|
|
2959
|
-
wrappedError.cause = connectErr;
|
|
2960
|
-
throw wrappedError;
|
|
2961
|
-
}
|
|
2962
|
-
}
|
|
2963
|
-
throw connectErr;
|
|
2964
|
-
}
|
|
2965
|
-
this.connected = true;
|
|
2966
|
-
this.transportType = "streamable-http";
|
|
2967
|
-
logger.debug(`Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`);
|
|
2968
|
-
} catch (err) {
|
|
2969
|
-
await this.cleanupResources();
|
|
2970
|
-
throw err;
|
|
2971
|
-
}
|
|
2972
|
-
}
|
|
2973
|
-
async connectWithSse(baseUrl) {
|
|
2974
|
-
try {
|
|
2975
|
-
this.connectionManager = new SseConnectionManager(
|
|
2976
|
-
baseUrl,
|
|
2977
|
-
{
|
|
2978
|
-
requestInit: {
|
|
2979
|
-
headers: this.headers
|
|
2980
|
-
}
|
|
2981
|
-
}
|
|
2982
|
-
);
|
|
2983
|
-
const transport = await this.connectionManager.start();
|
|
2984
|
-
this.client = new Client(this.clientInfo, this.opts.clientOptions);
|
|
2985
|
-
await this.client.connect(transport);
|
|
2986
|
-
this.connected = true;
|
|
2987
|
-
this.transportType = "sse";
|
|
2988
|
-
logger.debug(`Successfully connected to MCP implementation via HTTP/SSE: ${baseUrl}`);
|
|
2989
|
-
} catch (err) {
|
|
2990
|
-
await this.cleanupResources();
|
|
2991
|
-
throw err;
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
get publicIdentifier() {
|
|
2995
|
-
return {
|
|
2996
|
-
type: "http",
|
|
2997
|
-
url: this.baseUrl,
|
|
2998
|
-
transport: this.transportType || "unknown"
|
|
2999
|
-
};
|
|
3000
|
-
}
|
|
3001
|
-
/**
|
|
3002
|
-
* Get the transport type being used (streamable-http or sse)
|
|
3003
|
-
*/
|
|
3004
|
-
getTransportType() {
|
|
3005
|
-
return this.transportType;
|
|
3006
|
-
}
|
|
3007
|
-
};
|
|
3008
|
-
|
|
3009
|
-
// src/connectors/websocket.ts
|
|
3010
|
-
import { v4 as uuidv42 } from "uuid";
|
|
3011
|
-
|
|
3012
|
-
// src/task_managers/websocket.ts
|
|
3013
|
-
import WS from "ws";
|
|
3014
|
-
var WebSocketConnectionManager = class extends ConnectionManager {
|
|
3015
|
-
static {
|
|
3016
|
-
__name(this, "WebSocketConnectionManager");
|
|
3017
|
-
}
|
|
3018
|
-
url;
|
|
3019
|
-
headers;
|
|
3020
|
-
_ws = null;
|
|
3021
|
-
/**
|
|
3022
|
-
* @param url The WebSocket URL to connect to.
|
|
3023
|
-
* @param headers Optional headers to include in the connection handshake.
|
|
3024
|
-
*/
|
|
3025
|
-
constructor(url, headers = {}) {
|
|
3026
|
-
super();
|
|
3027
|
-
this.url = url;
|
|
3028
|
-
this.headers = headers;
|
|
3029
|
-
}
|
|
3030
|
-
/** Establish a WebSocket connection and wait until it is open. */
|
|
3031
|
-
async establishConnection() {
|
|
3032
|
-
logger.debug(`Connecting to WebSocket: ${this.url}`);
|
|
3033
|
-
return new Promise((resolve, reject) => {
|
|
3034
|
-
const ws = new WS(this.url, { headers: this.headers });
|
|
3035
|
-
this._ws = ws;
|
|
3036
|
-
const onOpen = /* @__PURE__ */ __name(() => {
|
|
3037
|
-
cleanup();
|
|
3038
|
-
logger.debug("WebSocket connected successfully");
|
|
3039
|
-
resolve(ws);
|
|
3040
|
-
}, "onOpen");
|
|
3041
|
-
const onError = /* @__PURE__ */ __name((err) => {
|
|
3042
|
-
cleanup();
|
|
3043
|
-
logger.error(`Failed to connect to WebSocket: ${err}`);
|
|
3044
|
-
reject(err);
|
|
3045
|
-
}, "onError");
|
|
3046
|
-
const cleanup = /* @__PURE__ */ __name(() => {
|
|
3047
|
-
ws.off("open", onOpen);
|
|
3048
|
-
ws.off("error", onError);
|
|
3049
|
-
}, "cleanup");
|
|
3050
|
-
ws.on("open", onOpen);
|
|
3051
|
-
ws.on("error", onError);
|
|
3052
|
-
});
|
|
3053
|
-
}
|
|
3054
|
-
/** Cleanly close the WebSocket connection. */
|
|
3055
|
-
async closeConnection(connection) {
|
|
3056
|
-
logger.debug("Closing WebSocket connection");
|
|
3057
|
-
return new Promise((resolve) => {
|
|
3058
|
-
const onClose = /* @__PURE__ */ __name(() => {
|
|
3059
|
-
connection.off("close", onClose);
|
|
3060
|
-
this._ws = null;
|
|
3061
|
-
resolve();
|
|
3062
|
-
}, "onClose");
|
|
3063
|
-
if (connection.readyState === WS.CLOSED) {
|
|
3064
|
-
onClose();
|
|
3065
|
-
return;
|
|
3066
|
-
}
|
|
3067
|
-
connection.on("close", onClose);
|
|
3068
|
-
try {
|
|
3069
|
-
connection.close();
|
|
3070
|
-
} catch (e) {
|
|
3071
|
-
logger.warn(`Error closing WebSocket connection: ${e}`);
|
|
3072
|
-
onClose();
|
|
3073
|
-
}
|
|
3074
|
-
});
|
|
3075
|
-
}
|
|
3076
|
-
};
|
|
3077
|
-
|
|
3078
|
-
// src/connectors/websocket.ts
|
|
3079
|
-
var WebSocketConnector = class extends BaseConnector {
|
|
3080
|
-
static {
|
|
3081
|
-
__name(this, "WebSocketConnector");
|
|
3082
|
-
}
|
|
3083
|
-
url;
|
|
3084
|
-
headers;
|
|
3085
|
-
connectionManager = null;
|
|
3086
|
-
ws = null;
|
|
3087
|
-
receiverTask = null;
|
|
3088
|
-
pending = /* @__PURE__ */ new Map();
|
|
3089
|
-
toolsCache = null;
|
|
3090
|
-
constructor(url, opts = {}) {
|
|
3091
|
-
super();
|
|
3092
|
-
this.url = url;
|
|
3093
|
-
this.headers = { ...opts.headers ?? {} };
|
|
3094
|
-
if (opts.authToken)
|
|
3095
|
-
this.headers.Authorization = `Bearer ${opts.authToken}`;
|
|
3096
|
-
}
|
|
3097
|
-
async connect() {
|
|
3098
|
-
if (this.connected) {
|
|
3099
|
-
logger.debug("Already connected to MCP implementation");
|
|
3100
|
-
return;
|
|
3101
|
-
}
|
|
3102
|
-
logger.debug(`Connecting via WebSocket: ${this.url}`);
|
|
3103
|
-
try {
|
|
3104
|
-
this.connectionManager = new WebSocketConnectionManager(this.url, this.headers);
|
|
3105
|
-
this.ws = await this.connectionManager.start();
|
|
3106
|
-
this.receiverTask = this.receiveLoop();
|
|
3107
|
-
this.connected = true;
|
|
3108
|
-
logger.debug("WebSocket connected successfully");
|
|
3109
|
-
} catch (e) {
|
|
3110
|
-
logger.error(`Failed to connect: ${e}`);
|
|
3111
|
-
await this.cleanupResources();
|
|
3112
|
-
throw e;
|
|
3113
|
-
}
|
|
3114
|
-
}
|
|
3115
|
-
async disconnect() {
|
|
3116
|
-
if (!this.connected) {
|
|
3117
|
-
logger.debug("Not connected to MCP implementation");
|
|
3118
|
-
return;
|
|
3119
|
-
}
|
|
3120
|
-
logger.debug("Disconnecting \u2026");
|
|
3121
|
-
await this.cleanupResources();
|
|
3122
|
-
this.connected = false;
|
|
3123
|
-
}
|
|
3124
|
-
sendRequest(method, params = null) {
|
|
3125
|
-
if (!this.ws)
|
|
3126
|
-
throw new Error("WebSocket is not connected");
|
|
3127
|
-
const id = uuidv42();
|
|
3128
|
-
const payload = JSON.stringify({ id, method, params: params ?? {} });
|
|
3129
|
-
return new Promise((resolve, reject) => {
|
|
3130
|
-
this.pending.set(id, { resolve, reject });
|
|
3131
|
-
this.ws.send(payload, (err) => {
|
|
3132
|
-
if (err) {
|
|
3133
|
-
this.pending.delete(id);
|
|
3134
|
-
reject(err);
|
|
3135
|
-
}
|
|
3136
|
-
});
|
|
3137
|
-
});
|
|
3138
|
-
}
|
|
3139
|
-
async receiveLoop() {
|
|
3140
|
-
if (!this.ws)
|
|
3141
|
-
return;
|
|
3142
|
-
const socket = this.ws;
|
|
3143
|
-
const onMessage = /* @__PURE__ */ __name((msg) => {
|
|
3144
|
-
let data;
|
|
3145
|
-
try {
|
|
3146
|
-
data = JSON.parse(msg.data ?? msg);
|
|
3147
|
-
} catch (e) {
|
|
3148
|
-
logger.warn("Received non\u2011JSON frame", e);
|
|
3149
|
-
return;
|
|
3150
|
-
}
|
|
3151
|
-
const id = data.id;
|
|
3152
|
-
if (id && this.pending.has(id)) {
|
|
3153
|
-
const { resolve, reject } = this.pending.get(id);
|
|
3154
|
-
this.pending.delete(id);
|
|
3155
|
-
if ("result" in data)
|
|
3156
|
-
resolve(data.result);
|
|
3157
|
-
else if ("error" in data)
|
|
3158
|
-
reject(data.error);
|
|
3159
|
-
} else {
|
|
3160
|
-
logger.debug("Received unsolicited message", data);
|
|
3161
|
-
}
|
|
3162
|
-
}, "onMessage");
|
|
3163
|
-
if (socket.addEventListener) {
|
|
3164
|
-
socket.addEventListener("message", onMessage);
|
|
3165
|
-
} else {
|
|
3166
|
-
socket.on("message", onMessage);
|
|
3167
|
-
}
|
|
3168
|
-
return new Promise((resolve) => {
|
|
3169
|
-
const onClose = /* @__PURE__ */ __name(() => {
|
|
3170
|
-
if (socket.removeEventListener) {
|
|
3171
|
-
socket.removeEventListener("message", onMessage);
|
|
3172
|
-
} else {
|
|
3173
|
-
socket.off("message", onMessage);
|
|
3174
|
-
}
|
|
3175
|
-
this.rejectAll(new Error("WebSocket closed"));
|
|
3176
|
-
resolve();
|
|
3177
|
-
}, "onClose");
|
|
3178
|
-
if (socket.addEventListener) {
|
|
3179
|
-
socket.addEventListener("close", onClose);
|
|
3180
|
-
} else {
|
|
3181
|
-
socket.on("close", onClose);
|
|
3182
|
-
}
|
|
3183
|
-
});
|
|
3184
|
-
}
|
|
3185
|
-
rejectAll(err) {
|
|
3186
|
-
for (const { reject } of this.pending.values()) reject(err);
|
|
3187
|
-
this.pending.clear();
|
|
3188
|
-
}
|
|
3189
|
-
async initialize() {
|
|
3190
|
-
logger.debug("Initializing MCP session over WebSocket");
|
|
3191
|
-
const result = await this.sendRequest("initialize");
|
|
3192
|
-
const toolsList = await this.listTools();
|
|
3193
|
-
this.toolsCache = toolsList.map((t) => t);
|
|
3194
|
-
logger.debug(`Initialized with ${this.toolsCache.length} tools`);
|
|
3195
|
-
return result;
|
|
3196
|
-
}
|
|
3197
|
-
async listTools() {
|
|
3198
|
-
const res = await this.sendRequest("tools/list");
|
|
3199
|
-
return res.tools ?? [];
|
|
3200
|
-
}
|
|
3201
|
-
async callTool(name, args) {
|
|
3202
|
-
return await this.sendRequest("tools/call", { name, arguments: args });
|
|
3203
|
-
}
|
|
3204
|
-
async listResources() {
|
|
3205
|
-
const resources = await this.sendRequest("resources/list");
|
|
3206
|
-
return { resources: Array.isArray(resources) ? resources : [] };
|
|
3207
|
-
}
|
|
3208
|
-
async readResource(uri) {
|
|
3209
|
-
const res = await this.sendRequest("resources/read", { uri });
|
|
3210
|
-
return { content: res.content, mimeType: res.mimeType };
|
|
3211
|
-
}
|
|
3212
|
-
async request(method, params = null) {
|
|
3213
|
-
return await this.sendRequest(method, params);
|
|
3214
|
-
}
|
|
3215
|
-
get tools() {
|
|
3216
|
-
if (!this.toolsCache)
|
|
3217
|
-
throw new Error("MCP client is not initialized");
|
|
3218
|
-
return this.toolsCache;
|
|
3219
|
-
}
|
|
3220
|
-
async cleanupResources() {
|
|
3221
|
-
if (this.receiverTask)
|
|
3222
|
-
await this.receiverTask.catch(() => {
|
|
3223
|
-
});
|
|
3224
|
-
this.receiverTask = null;
|
|
3225
|
-
this.rejectAll(new Error("WebSocket disconnected"));
|
|
3226
|
-
if (this.connectionManager) {
|
|
3227
|
-
await this.connectionManager.stop();
|
|
3228
|
-
this.connectionManager = null;
|
|
3229
|
-
this.ws = null;
|
|
3230
|
-
}
|
|
3231
|
-
this.toolsCache = null;
|
|
3232
|
-
}
|
|
3233
|
-
get publicIdentifier() {
|
|
3234
|
-
return {
|
|
3235
|
-
type: "websocket",
|
|
3236
|
-
url: this.url
|
|
3237
|
-
};
|
|
3238
|
-
}
|
|
3239
|
-
};
|
|
3240
|
-
|
|
3241
2601
|
// src/agents/utils/ai_sdk.ts
|
|
3242
2602
|
async function* streamEventsToAISDK(streamEvents) {
|
|
3243
2603
|
for await (const event of streamEvents) {
|
|
@@ -3293,119 +2653,6 @@ async function* streamEventsToAISDKWithTools(streamEvents) {
|
|
|
3293
2653
|
}
|
|
3294
2654
|
__name(streamEventsToAISDKWithTools, "streamEventsToAISDKWithTools");
|
|
3295
2655
|
|
|
3296
|
-
// src/client/base.ts
|
|
3297
|
-
var BaseMCPClient = class {
|
|
3298
|
-
static {
|
|
3299
|
-
__name(this, "BaseMCPClient");
|
|
3300
|
-
}
|
|
3301
|
-
config = {};
|
|
3302
|
-
sessions = {};
|
|
3303
|
-
activeSessions = [];
|
|
3304
|
-
constructor(config) {
|
|
3305
|
-
if (config) {
|
|
3306
|
-
this.config = config;
|
|
3307
|
-
}
|
|
3308
|
-
}
|
|
3309
|
-
static fromDict(_cfg) {
|
|
3310
|
-
throw new Error("fromDict must be implemented by concrete class");
|
|
3311
|
-
}
|
|
3312
|
-
addServer(name, serverConfig) {
|
|
3313
|
-
this.config.mcpServers = this.config.mcpServers || {};
|
|
3314
|
-
this.config.mcpServers[name] = serverConfig;
|
|
3315
|
-
}
|
|
3316
|
-
removeServer(name) {
|
|
3317
|
-
if (this.config.mcpServers?.[name]) {
|
|
3318
|
-
delete this.config.mcpServers[name];
|
|
3319
|
-
this.activeSessions = this.activeSessions.filter((n) => n !== name);
|
|
3320
|
-
}
|
|
3321
|
-
}
|
|
3322
|
-
getServerNames() {
|
|
3323
|
-
return Object.keys(this.config.mcpServers ?? {});
|
|
3324
|
-
}
|
|
3325
|
-
getServerConfig(name) {
|
|
3326
|
-
return this.config.mcpServers?.[name];
|
|
3327
|
-
}
|
|
3328
|
-
getConfig() {
|
|
3329
|
-
return this.config ?? {};
|
|
3330
|
-
}
|
|
3331
|
-
async createSession(serverName, autoInitialize = true) {
|
|
3332
|
-
const servers = this.config.mcpServers ?? {};
|
|
3333
|
-
if (Object.keys(servers).length === 0) {
|
|
3334
|
-
logger.warn("No MCP servers defined in config");
|
|
3335
|
-
}
|
|
3336
|
-
if (!servers[serverName]) {
|
|
3337
|
-
throw new Error(`Server '${serverName}' not found in config`);
|
|
3338
|
-
}
|
|
3339
|
-
const connector = this.createConnectorFromConfig(servers[serverName]);
|
|
3340
|
-
const session = new MCPSession(connector);
|
|
3341
|
-
if (autoInitialize) {
|
|
3342
|
-
await session.initialize();
|
|
3343
|
-
}
|
|
3344
|
-
this.sessions[serverName] = session;
|
|
3345
|
-
if (!this.activeSessions.includes(serverName)) {
|
|
3346
|
-
this.activeSessions.push(serverName);
|
|
3347
|
-
}
|
|
3348
|
-
return session;
|
|
3349
|
-
}
|
|
3350
|
-
async createAllSessions(autoInitialize = true) {
|
|
3351
|
-
const servers = this.config.mcpServers ?? {};
|
|
3352
|
-
if (Object.keys(servers).length === 0) {
|
|
3353
|
-
logger.warn("No MCP servers defined in config");
|
|
3354
|
-
}
|
|
3355
|
-
for (const name of Object.keys(servers)) {
|
|
3356
|
-
await this.createSession(name, autoInitialize);
|
|
3357
|
-
}
|
|
3358
|
-
return this.sessions;
|
|
3359
|
-
}
|
|
3360
|
-
getSession(serverName) {
|
|
3361
|
-
const session = this.sessions[serverName];
|
|
3362
|
-
if (!session) {
|
|
3363
|
-
return null;
|
|
3364
|
-
}
|
|
3365
|
-
return session;
|
|
3366
|
-
}
|
|
3367
|
-
getAllActiveSessions() {
|
|
3368
|
-
return Object.fromEntries(
|
|
3369
|
-
this.activeSessions.map((n) => [n, this.sessions[n]])
|
|
3370
|
-
);
|
|
3371
|
-
}
|
|
3372
|
-
async closeSession(serverName) {
|
|
3373
|
-
const session = this.sessions[serverName];
|
|
3374
|
-
if (!session) {
|
|
3375
|
-
logger.warn(`No session exists for server ${serverName}, nothing to close`);
|
|
3376
|
-
return;
|
|
3377
|
-
}
|
|
3378
|
-
try {
|
|
3379
|
-
logger.debug(`Closing session for server ${serverName}`);
|
|
3380
|
-
await session.disconnect();
|
|
3381
|
-
} catch (e) {
|
|
3382
|
-
logger.error(`Error closing session for server '${serverName}': ${e}`);
|
|
3383
|
-
} finally {
|
|
3384
|
-
delete this.sessions[serverName];
|
|
3385
|
-
this.activeSessions = this.activeSessions.filter((n) => n !== serverName);
|
|
3386
|
-
}
|
|
3387
|
-
}
|
|
3388
|
-
async closeAllSessions() {
|
|
3389
|
-
const serverNames = Object.keys(this.sessions);
|
|
3390
|
-
const errors = [];
|
|
3391
|
-
for (const serverName of serverNames) {
|
|
3392
|
-
try {
|
|
3393
|
-
logger.debug(`Closing session for server ${serverName}`);
|
|
3394
|
-
await this.closeSession(serverName);
|
|
3395
|
-
} catch (e) {
|
|
3396
|
-
const errorMsg = `Failed to close session for server '${serverName}': ${e}`;
|
|
3397
|
-
logger.error(errorMsg);
|
|
3398
|
-
errors.push(errorMsg);
|
|
3399
|
-
}
|
|
3400
|
-
}
|
|
3401
|
-
if (errors.length) {
|
|
3402
|
-
logger.error(`Encountered ${errors.length} errors while closing sessions`);
|
|
3403
|
-
} else {
|
|
3404
|
-
logger.debug("All sessions closed successfully");
|
|
3405
|
-
}
|
|
3406
|
-
}
|
|
3407
|
-
};
|
|
3408
|
-
|
|
3409
2656
|
export {
|
|
3410
2657
|
BaseAdapter,
|
|
3411
2658
|
LangChainAdapter,
|
|
@@ -3420,12 +2667,6 @@ export {
|
|
|
3420
2667
|
setTelemetrySource,
|
|
3421
2668
|
RemoteAgent,
|
|
3422
2669
|
MCPAgent,
|
|
3423
|
-
MCPSession,
|
|
3424
|
-
BaseMCPClient,
|
|
3425
|
-
ConnectionManager,
|
|
3426
|
-
BaseConnector,
|
|
3427
|
-
HttpConnector,
|
|
3428
|
-
WebSocketConnector,
|
|
3429
2670
|
streamEventsToAISDK,
|
|
3430
2671
|
createReadableStreamFromGenerator,
|
|
3431
2672
|
streamEventsToAISDKWithTools
|