@elizaos/plugin-mcp 1.3.5 → 1.7.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.
@@ -711,6 +711,33 @@ async function handleMcpError(state, mcpProvider, error, runtime2, message, type
711
711
  };
712
712
  }
713
713
 
714
+ // src/utils/handler.ts
715
+ async function handleNoToolAvailable(callback, toolSelection) {
716
+ const responseText = "I don't have a specific tool that can help with that request. Let me try to assist you directly instead.";
717
+ const thoughtText = "No appropriate MCP tool available for this request. Falling back to direct assistance.";
718
+ if (callback && toolSelection?.noToolAvailable) {
719
+ await callback({
720
+ text: responseText,
721
+ thought: thoughtText,
722
+ actions: ["REPLY"]
723
+ });
724
+ }
725
+ return {
726
+ text: responseText,
727
+ values: {
728
+ success: true,
729
+ noToolAvailable: true,
730
+ fallbackToDirectAssistance: true
731
+ },
732
+ data: {
733
+ actionName: "CALL_MCP_TOOL",
734
+ noToolAvailable: true,
735
+ reason: toolSelection?.reasoning || "No appropriate tool available"
736
+ },
737
+ success: true
738
+ };
739
+ }
740
+
714
741
  // src/utils/processing.ts
715
742
  var import_core2 = require("@elizaos/core");
716
743
  var import_core3 = require("@elizaos/core");
@@ -775,82 +802,54 @@ Your response (written as if directly to the user):
775
802
  `;
776
803
 
777
804
  // src/utils/mcp.ts
805
+ var NO_DESC = "No description";
778
806
  async function createMcpMemory(runtime2, message, type, serverName, content, metadata) {
779
807
  const memory = await runtime2.addEmbeddingToMemory({
780
808
  entityId: message.entityId,
781
809
  agentId: runtime2.agentId,
782
810
  roomId: message.roomId,
783
811
  content: {
784
- text: `Used the "${type}" from "${serverName}" server.
785
- Content: ${content}`,
786
- metadata: {
787
- ...metadata,
788
- serverName
789
- }
812
+ text: `Used "${type}" from "${serverName}". Content: ${content}`,
813
+ metadata: { ...metadata, serverName }
790
814
  }
791
815
  });
792
816
  await runtime2.createMemory(memory, type === "resource" ? "resources" : "tools", true);
793
817
  }
794
818
  function buildMcpProviderData(servers) {
795
- const mcpData = {};
796
- let textContent = "";
797
819
  if (servers.length === 0) {
798
- return {
799
- values: { mcp: {} },
800
- data: { mcp: {} },
801
- text: "No MCP servers are currently connected."
802
- };
820
+ return { values: { mcp: {} }, data: { mcp: {} }, text: "No MCP servers connected." };
803
821
  }
822
+ const mcpData = {};
823
+ const lines = [`# MCP Configuration
824
+ `];
804
825
  for (const server of servers) {
805
- mcpData[server.name] = {
806
- status: server.status,
807
- tools: {},
808
- resources: {}
809
- };
810
- textContent += `## Server: ${server.name} (${server.status})
811
-
812
- `;
813
- if (server.tools && server.tools.length > 0) {
814
- textContent += `### Tools:
815
-
816
- `;
817
- for (const tool of server.tools) {
818
- mcpData[server.name].tools[tool.name] = {
819
- description: tool.description || "No description available",
820
- inputSchema: tool.inputSchema || {}
821
- };
822
- textContent += `- **${tool.name}**: ${tool.description || "No description available"}
823
- `;
824
- }
825
- textContent += `
826
- `;
827
- }
828
- if (server.resources && server.resources.length > 0) {
829
- textContent += `### Resources:
830
-
831
- `;
832
- for (const resource of server.resources) {
833
- mcpData[server.name].resources[resource.uri] = {
834
- name: resource.name,
835
- description: resource.description || "No description available",
836
- mimeType: resource.mimeType
837
- };
838
- textContent += `- **${resource.name}** (${resource.uri}): ${resource.description || "No description available"}
839
- `;
840
- }
841
- textContent += `
842
- `;
843
- }
844
- }
845
- return {
846
- values: { mcp: mcpData, mcpText: `# MCP Configuration
847
-
848
- ${textContent}` },
849
- data: { mcp: mcpData },
850
- text: `# MCP Configuration
851
-
852
- ${textContent}`
853
- };
826
+ const tools = {};
827
+ const resources = {};
828
+ lines.push(`## ${server.name} (${server.status})
829
+ `);
830
+ if (server.tools?.length) {
831
+ lines.push(`### Tools
832
+ `);
833
+ for (const t of server.tools) {
834
+ tools[t.name] = { description: t.description || NO_DESC, inputSchema: t.inputSchema || {} };
835
+ lines.push(`- **${t.name}**: ${t.description || NO_DESC}`);
836
+ }
837
+ lines.push("");
838
+ }
839
+ if (server.resources?.length) {
840
+ lines.push(`### Resources
841
+ `);
842
+ for (const r of server.resources) {
843
+ resources[r.uri] = { name: r.name, description: r.description || NO_DESC, mimeType: r.mimeType };
844
+ lines.push(`- **${r.name}** (${r.uri}): ${r.description || NO_DESC}`);
845
+ }
846
+ lines.push("");
847
+ }
848
+ mcpData[server.name] = { status: server.status, tools, resources };
849
+ }
850
+ const text = lines.join(`
851
+ `);
852
+ return { values: { mcp: mcpData, mcpText: text }, data: { mcp: mcpData }, text };
854
853
  }
855
854
 
856
855
  // src/utils/processing.ts
@@ -1112,9 +1111,10 @@ ${JSON.stringify(parsedJson, null, 2)}`);
1112
1111
  }
1113
1112
  function getMaxRetries(runtime2) {
1114
1113
  try {
1115
- const settings = runtime2.getSetting("mcp");
1116
- if (settings && "maxRetries" in settings && settings.maxRetries !== undefined) {
1117
- const configValue = Number(settings.maxRetries);
1114
+ const rawSettings = runtime2.getSetting("mcp");
1115
+ const settings = rawSettings;
1116
+ if (settings && typeof settings.maxRetries === "number") {
1117
+ const configValue = settings.maxRetries;
1118
1118
  if (!Number.isNaN(configValue) && configValue >= 0) {
1119
1119
  import_core4.logger.debug(`[WITH-MODEL-RETRY] Using configured selection retries: ${configValue}`);
1120
1120
  return configValue;
@@ -1444,33 +1444,6 @@ function createFeedbackPrompt2(originalResponse, errorMessage, itemType, itemsDe
1444
1444
  User request: ${userMessage}`;
1445
1445
  }
1446
1446
 
1447
- // src/utils/handler.ts
1448
- async function handleNoToolAvailable(callback, toolSelection) {
1449
- const responseText = "I don't have a specific tool that can help with that request. Let me try to assist you directly instead.";
1450
- const thoughtText = "No appropriate MCP tool available for this request. Falling back to direct assistance.";
1451
- if (callback && toolSelection?.noToolAvailable) {
1452
- await callback({
1453
- text: responseText,
1454
- thought: thoughtText,
1455
- actions: ["REPLY"]
1456
- });
1457
- }
1458
- return {
1459
- text: responseText,
1460
- values: {
1461
- success: true,
1462
- noToolAvailable: true,
1463
- fallbackToDirectAssistance: true
1464
- },
1465
- data: {
1466
- actionName: "CALL_MCP_TOOL",
1467
- noToolAvailable: true,
1468
- reason: toolSelection?.reasoning || "No appropriate tool available"
1469
- },
1470
- success: true
1471
- };
1472
- }
1473
-
1474
1447
  // src/actions/callToolAction.ts
1475
1448
  var callToolAction = {
1476
1449
  name: "CALL_MCP_TOOL",
@@ -1532,7 +1505,7 @@ ${JSON.stringify(toolSelectionArgument, null, 2)}`);
1532
1505
  const result = await mcpService.callTool(serverName, toolName, toolSelectionArgument.toolArguments);
1533
1506
  const { toolOutput, hasAttachments, attachments } = processToolResult(result, serverName, toolName, runtime2, message.entityId);
1534
1507
  const replyMemory = await handleToolResponse(runtime2, message, serverName, toolName, toolSelectionArgument.toolArguments, toolOutput, hasAttachments, attachments, composedState, mcpProvider, callback);
1535
- return {
1508
+ const actionResult = {
1536
1509
  text: `Successfully called tool: ${serverName}/${toolName}. Reasoned response: ${replyMemory.content.text}`,
1537
1510
  values: {
1538
1511
  success: true,
@@ -1553,6 +1526,15 @@ ${JSON.stringify(toolSelectionArgument, null, 2)}`);
1553
1526
  },
1554
1527
  success: true
1555
1528
  };
1529
+ import_core6.logger.info({
1530
+ serverName,
1531
+ toolName,
1532
+ hasOutput: !!toolOutput,
1533
+ outputLength: toolOutput?.length || 0,
1534
+ hasAttachments,
1535
+ reasoning: toolSelectionName.reasoning
1536
+ }, `[CALL_MCP_TOOL] Action result`);
1537
+ return actionResult;
1556
1538
  } catch (error) {
1557
1539
  return await handleMcpError(composedState, mcpProvider, error, runtime2, message, "tool", callback);
1558
1540
  }
@@ -1790,19 +1772,20 @@ var readResourceAction = {
1790
1772
  };
1791
1773
 
1792
1774
  // src/provider.ts
1775
+ var createEmptyProvider = () => ({
1776
+ values: { mcp: {} },
1777
+ data: { mcp: {} },
1778
+ text: "No MCP servers available."
1779
+ });
1793
1780
  var provider = {
1794
1781
  name: "MCP",
1795
- description: "Information about connected MCP servers, tools, and resources",
1782
+ description: "Connected MCP servers, tools, and resources",
1796
1783
  get: async (runtime2, _message, _state) => {
1797
- const mcpService = runtime2.getService(MCP_SERVICE_NAME);
1798
- if (!mcpService) {
1799
- return {
1800
- values: { mcp: {} },
1801
- data: { mcp: {} },
1802
- text: "No MCP servers are available."
1803
- };
1804
- }
1805
- return mcpService.getProviderData();
1784
+ const svc = runtime2.getService(MCP_SERVICE_NAME);
1785
+ if (!svc)
1786
+ return createEmptyProvider();
1787
+ await svc.waitForInitialization();
1788
+ return svc.getProviderData();
1806
1789
  }
1807
1790
  };
1808
1791
 
@@ -1811,6 +1794,9 @@ var import_core8 = require("@elizaos/core");
1811
1794
  var import_client = require("@modelcontextprotocol/sdk/client/index.js");
1812
1795
  var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
1813
1796
  var import_stdio = require("@modelcontextprotocol/sdk/client/stdio.js");
1797
+ var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
1798
+ var errMsg = (e) => e instanceof Error ? e.message : String(e);
1799
+
1814
1800
  class McpService extends import_core8.Service {
1815
1801
  static serviceType = MCP_SERVICE_NAME;
1816
1802
  capabilityDescription = "Enables the agent to interact with MCP (Model Context Protocol) servers";
@@ -1827,7 +1813,6 @@ class McpService extends import_core8.Service {
1827
1813
  initializationPromise = null;
1828
1814
  constructor(runtime2) {
1829
1815
  super(runtime2);
1830
- import_core8.logger.info("[McpService] Constructor called, starting initialization...");
1831
1816
  this.initializationPromise = this.initializeMcpServers();
1832
1817
  }
1833
1818
  static async start(runtime2) {
@@ -1843,115 +1828,70 @@ class McpService extends import_core8.Service {
1843
1828
  }
1844
1829
  }
1845
1830
  async stop() {
1846
- for (const [name] of this.connections) {
1831
+ for (const name of this.connections.keys()) {
1847
1832
  await this.deleteConnection(name);
1848
1833
  }
1849
- this.connections.clear();
1850
- for (const state of this.connectionStates.values()) {
1834
+ for (const [name, state] of this.connectionStates.entries()) {
1851
1835
  if (state.pingInterval)
1852
1836
  clearInterval(state.pingInterval);
1853
1837
  if (state.reconnectTimeout)
1854
1838
  clearTimeout(state.reconnectTimeout);
1839
+ this.connectionStates.delete(name);
1855
1840
  }
1856
- this.connectionStates.clear();
1857
1841
  }
1858
1842
  async initializeMcpServers() {
1859
- import_core8.logger.info("[McpService] Starting MCP server initialization...");
1860
1843
  try {
1861
1844
  const mcpSettings = this.getMcpSettings();
1862
- const serverCount = mcpSettings?.servers ? Object.keys(mcpSettings.servers).length : 0;
1863
- const serverNames = mcpSettings?.servers ? Object.keys(mcpSettings.servers) : [];
1864
- import_core8.logger.info(`[McpService] Getting MCP settings... hasSettings=${!!mcpSettings} hasServers=${!!mcpSettings?.servers} serverCount=${serverCount} servers=${JSON.stringify(serverNames)}`);
1865
- if (!mcpSettings || !mcpSettings.servers) {
1866
- import_core8.logger.info("[McpService] No MCP servers configured.");
1867
- this.mcpProvider = buildMcpProviderData([]);
1868
- return;
1869
- }
1870
- if (Object.keys(mcpSettings.servers).length === 0) {
1871
- import_core8.logger.info("[McpService] MCP settings exist but no servers configured.");
1845
+ if (!mcpSettings?.servers || Object.keys(mcpSettings.servers).length === 0) {
1872
1846
  this.mcpProvider = buildMcpProviderData([]);
1873
1847
  return;
1874
1848
  }
1875
- import_core8.logger.info(`[McpService] Connecting to ${Object.keys(mcpSettings.servers).length} MCP servers: ${JSON.stringify(Object.keys(mcpSettings.servers))}`);
1876
1849
  const connectionStartTime = Date.now();
1877
1850
  await this.updateServerConnections(mcpSettings.servers);
1878
1851
  const connectionDuration = Date.now() - connectionStartTime;
1879
1852
  const servers = this.getServers();
1880
- const connectedServers = servers.filter((s) => s.status === "connected");
1881
- const failedServers = servers.filter((s) => s.status !== "connected");
1882
- if (connectedServers.length > 0) {
1883
- const toolCounts = connectedServers.map((s) => `${s.name}:${s.tools?.length || 0}tools`).join(", ");
1884
- import_core8.logger.info(`[McpService] ✓ Successfully connected ${connectedServers.length}/${servers.length} servers in ${connectionDuration}ms: ${toolCounts}`);
1853
+ const connected = servers.filter((s) => s.status === "connected");
1854
+ const failed = servers.filter((s) => s.status !== "connected");
1855
+ if (connected.length > 0) {
1856
+ import_core8.logger.info(`[MCP] Connected ${connected.length}/${servers.length} in ${connectionDuration}ms (${connected.map((s) => `${s.name}:${s.tools?.length || 0}`).join(", ")})`);
1885
1857
  }
1886
- if (failedServers.length > 0) {
1887
- const failedDetails = failedServers.map((s) => `${s.name}(${s.error || "unknown error"})`).join(", ");
1888
- import_core8.logger.warn(`[McpService] ⚠️ Failed to connect to ${failedServers.length}/${servers.length} servers: ${failedDetails}`);
1858
+ if (failed.length > 0) {
1859
+ import_core8.logger.warn(`[MCP] Failed: ${failed.map((s) => s.name).join(", ")}`);
1889
1860
  }
1890
- if (connectedServers.length === 0 && servers.length > 0) {
1891
- import_core8.logger.error(`[McpService] ALL MCP servers failed to connect! MCP tools will NOT be available.`);
1861
+ if (connected.length === 0 && servers.length > 0) {
1862
+ import_core8.logger.error(`[MCP] All servers failed`);
1892
1863
  }
1893
1864
  this.mcpProvider = buildMcpProviderData(servers);
1894
- const mcpDataKeys = Object.keys(this.mcpProvider.data?.mcp || {});
1895
- import_core8.logger.info(`[McpService] MCP provider data built: ${mcpDataKeys.length} server(s) available`);
1896
1865
  } catch (error) {
1897
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error) }, "❌ Failed to initialize MCP servers - MCP tools will NOT be available");
1866
+ import_core8.logger.error({ error: errMsg(error) }, "[MCP] Initialization failed");
1898
1867
  this.mcpProvider = buildMcpProviderData([]);
1899
1868
  }
1900
1869
  }
1901
1870
  getMcpSettings() {
1902
1871
  let settings = this.runtime.getSetting("mcp");
1903
- import_core8.logger.info(`[McpService] getSetting("mcp") result: type=${typeof settings} isNull=${settings === null} hasServers=${!!settings?.servers}`);
1904
1872
  if (!settings || typeof settings === "object" && !settings.servers) {
1905
- const characterSettings = this.runtime.character?.settings;
1906
- if (characterSettings?.mcp) {
1907
- import_core8.logger.info("[McpService] Found MCP settings in character.settings.mcp (fallback)");
1908
- settings = characterSettings.mcp;
1909
- }
1873
+ settings = this.runtime.character?.settings?.mcp;
1910
1874
  }
1911
1875
  if (!settings || typeof settings === "object" && !settings.servers) {
1912
- const runtimeSettings = this.runtime.settings;
1913
- if (runtimeSettings?.mcp) {
1914
- import_core8.logger.info("[McpService] Found MCP settings in runtime.settings.mcp (fallback)");
1915
- settings = runtimeSettings.mcp;
1916
- }
1876
+ settings = this.runtime.settings?.mcp;
1917
1877
  }
1918
- if (settings && typeof settings === "object" && settings.servers) {
1919
- import_core8.logger.info(`[McpService] MCP settings found with ${Object.keys(settings.servers).length} server(s)`);
1920
- return settings;
1921
- }
1922
- import_core8.logger.info("[McpService] No valid MCP settings found");
1923
- return;
1878
+ return settings && typeof settings === "object" && settings.servers ? settings : undefined;
1924
1879
  }
1925
1880
  async updateServerConnections(serverConfigs) {
1926
- const currentNames = new Set(this.connections.keys());
1927
1881
  const newNames = new Set(Object.keys(serverConfigs));
1928
- for (const name of currentNames) {
1929
- if (!newNames.has(name)) {
1882
+ for (const name of this.connections.keys()) {
1883
+ if (!newNames.has(name))
1930
1884
  await this.deleteConnection(name);
1931
- import_core8.logger.info(`Deleted MCP server: ${name}`);
1932
- }
1933
1885
  }
1934
- const connectionPromises = Object.entries(serverConfigs).map(async ([name, config]) => {
1935
- const currentConnection = this.connections.get(name);
1936
- if (!currentConnection) {
1937
- try {
1938
- await this.initializeConnection(name, config);
1939
- import_core8.logger.info(`✓ Connected to MCP server: ${name}`);
1940
- } catch (error) {
1941
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName: name }, `✗ Failed to connect to new MCP server ${name}`);
1942
- }
1943
- } else if (JSON.stringify(config) !== currentConnection.server.config) {
1944
- try {
1945
- await this.deleteConnection(name);
1946
- await this.initializeConnection(name, config);
1947
- import_core8.logger.info(`✓ Reconnected MCP server with updated config: ${name}`);
1948
- } catch (error) {
1949
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName: name }, `✗ Failed to reconnect MCP server ${name}`);
1950
- }
1886
+ await Promise.allSettled(Object.entries(serverConfigs).map(async ([name, config]) => {
1887
+ const current = this.connections.get(name);
1888
+ if (!current) {
1889
+ await this.initializeConnection(name, config).catch((e) => import_core8.logger.error({ error: errMsg(e), serverName: name }, `[MCP] Failed: ${name}`));
1890
+ } else if (JSON.stringify(config) !== current.server.config) {
1891
+ await this.deleteConnection(name);
1892
+ await this.initializeConnection(name, config).catch((e) => import_core8.logger.error({ error: errMsg(e), serverName: name }, `[MCP] Failed: ${name}`));
1951
1893
  }
1952
- });
1953
- await Promise.allSettled(connectionPromises);
1954
- import_core8.logger.info(`[McpService] All server connection attempts completed`);
1894
+ }));
1955
1895
  }
1956
1896
  async initializeConnection(name, config) {
1957
1897
  await this.deleteConnection(name);
@@ -1965,19 +1905,19 @@ class McpService extends import_core8.Service {
1965
1905
  const client = new import_client.Client({ name: "ElizaOS", version: "1.0.0" }, { capabilities: {} });
1966
1906
  const transport = config.type === "stdio" ? await this.buildStdioClientTransport(name, config) : await this.buildHttpClientTransport(name, config);
1967
1907
  const connection = {
1968
- server: {
1969
- name,
1970
- config: JSON.stringify(config),
1971
- status: "connecting"
1972
- },
1908
+ server: { name, config: JSON.stringify(config), status: "connecting" },
1973
1909
  client,
1974
1910
  transport
1975
1911
  };
1976
1912
  this.connections.set(name, connection);
1977
1913
  this.setupTransportHandlers(name, connection, state);
1978
- await client.connect(transport);
1914
+ const connectPromise = client.connect(transport);
1915
+ connectPromise.catch(() => {});
1916
+ await Promise.race([
1917
+ connectPromise,
1918
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout connecting to ${name}`)), 60000))
1919
+ ]);
1979
1920
  const capabilities = client.getServerCapabilities();
1980
- import_core8.logger.debug(`[${name}] Server capabilities:`, JSON.stringify(capabilities || {}));
1981
1921
  const tools = await this.fetchToolsList(name);
1982
1922
  const resources = capabilities?.resources ? await this.fetchResourcesList(name) : [];
1983
1923
  const resourceTemplates = capabilities?.resources ? await this.fetchResourceTemplatesList(name) : [];
@@ -1995,7 +1935,6 @@ class McpService extends import_core8.Service {
1995
1935
  state.reconnectAttempts = 0;
1996
1936
  state.consecutivePingFailures = 0;
1997
1937
  this.startPingMonitoring(name);
1998
- import_core8.logger.info(`Successfully connected to MCP server: ${name}`);
1999
1938
  } catch (error) {
2000
1939
  state.status = "disconnected";
2001
1940
  state.lastError = error instanceof Error ? error : new Error(String(error));
@@ -2005,26 +1944,21 @@ class McpService extends import_core8.Service {
2005
1944
  }
2006
1945
  setupTransportHandlers(name, connection, state) {
2007
1946
  const config = JSON.parse(connection.server.config);
2008
- const isHttpTransport = config.type !== "stdio";
1947
+ const isHttp = config.type !== "stdio";
2009
1948
  connection.transport.onerror = async (error) => {
2010
- const errorMessage = error?.message || String(error);
2011
- const isExpectedTimeout = isHttpTransport && (errorMessage === "undefined" || errorMessage === "" || errorMessage.includes("SSE error") || errorMessage.includes("timeout"));
2012
- if (isExpectedTimeout) {
2013
- import_core8.logger.debug({ serverName: name }, `SSE connection timeout for "${name}" (expected, will reconnect)`);
2014
- } else {
2015
- import_core8.logger.error({ error, serverName: name }, `Transport error for "${name}"`);
1949
+ const msg = error?.message || String(error);
1950
+ const isExpectedTimeout = isHttp && (!msg || msg === "undefined" || msg.includes("SSE") || msg.includes("timeout"));
1951
+ if (!isExpectedTimeout) {
1952
+ import_core8.logger.error({ error, serverName: name }, `Transport error: ${name}`);
2016
1953
  connection.server.status = "disconnected";
2017
- this.appendErrorMessage(connection, error.message);
1954
+ this.appendErrorMessage(connection, msg);
2018
1955
  }
2019
- if (!isHttpTransport) {
1956
+ if (!isHttp)
2020
1957
  this.handleDisconnection(name, error);
2021
- }
2022
1958
  };
2023
1959
  connection.transport.onclose = async () => {
2024
- if (isHttpTransport) {
2025
- import_core8.logger.debug({ serverName: name }, `SSE connection closed for "${name}" (stateless, will reconnect on demand)`);
2026
- } else {
2027
- import_core8.logger.warn({ serverName: name }, `Transport closed for "${name}"`);
1960
+ if (!isHttp) {
1961
+ import_core8.logger.warn({ serverName: name }, `Transport closed: ${name}`);
2028
1962
  connection.server.status = "disconnected";
2029
1963
  this.handleDisconnection(name, new Error("Transport closed"));
2030
1964
  }
@@ -2035,11 +1969,8 @@ class McpService extends import_core8.Service {
2035
1969
  if (!connection)
2036
1970
  return;
2037
1971
  const config = JSON.parse(connection.server.config);
2038
- const isHttpTransport = config.type !== "stdio";
2039
- if (isHttpTransport) {
2040
- import_core8.logger.debug(`[McpService] Skipping ping monitoring for HTTP server: ${name}`);
1972
+ if (config.type !== "stdio")
2041
1973
  return;
2042
- }
2043
1974
  const state = this.connectionStates.get(name);
2044
1975
  if (!state || !this.pingConfig.enabled)
2045
1976
  return;
@@ -2047,7 +1978,7 @@ class McpService extends import_core8.Service {
2047
1978
  clearInterval(state.pingInterval);
2048
1979
  state.pingInterval = setInterval(() => {
2049
1980
  this.sendPing(name).catch((err) => {
2050
- import_core8.logger.warn({ error: err instanceof Error ? err.message : String(err), serverName: name }, `Ping failed for ${name}`);
1981
+ import_core8.logger.warn({ error: errMsg(err), serverName: name }, `Ping failed: ${name}`);
2051
1982
  this.handlePingFailure(name, err);
2052
1983
  });
2053
1984
  }, this.pingConfig.intervalMs);
@@ -2055,7 +1986,7 @@ class McpService extends import_core8.Service {
2055
1986
  async sendPing(name) {
2056
1987
  const connection = this.connections.get(name);
2057
1988
  if (!connection)
2058
- throw new Error(`No connection for ping: ${name}`);
1989
+ throw new Error(`No connection: ${name}`);
2059
1990
  await Promise.race([
2060
1991
  connection.client.listTools(),
2061
1992
  new Promise((_, reject) => setTimeout(() => reject(new Error("Ping timeout")), this.pingConfig.timeoutMs))
@@ -2097,7 +2028,7 @@ class McpService extends import_core8.Service {
2097
2028
  try {
2098
2029
  await this.initializeConnection(name, JSON.parse(config));
2099
2030
  } catch (err) {
2100
- import_core8.logger.error({ error: err instanceof Error ? err.message : String(err), serverName: name }, `Reconnect attempt failed for ${name}`);
2031
+ import_core8.logger.error({ error: errMsg(err), serverName: name }, `Reconnect attempt failed for ${name}`);
2101
2032
  this.handleDisconnection(name, err);
2102
2033
  }
2103
2034
  }
@@ -2110,7 +2041,7 @@ class McpService extends import_core8.Service {
2110
2041
  await connection.transport.close();
2111
2042
  await connection.client.close();
2112
2043
  } catch (error) {
2113
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName: name }, `Failed to close transport for ${name}`);
2044
+ import_core8.logger.error({ error: errMsg(error), serverName: name }, `Failed to close transport for ${name}`);
2114
2045
  }
2115
2046
  this.connections.delete(name);
2116
2047
  }
@@ -2123,9 +2054,6 @@ class McpService extends import_core8.Service {
2123
2054
  this.connectionStates.delete(name);
2124
2055
  }
2125
2056
  }
2126
- getServerConnection(serverName) {
2127
- return this.connections.get(serverName);
2128
- }
2129
2057
  async buildStdioClientTransport(name, config) {
2130
2058
  if (!config.command) {
2131
2059
  throw new Error(`Missing command for stdio MCP server ${name}`);
@@ -2142,74 +2070,61 @@ class McpService extends import_core8.Service {
2142
2070
  });
2143
2071
  }
2144
2072
  async buildHttpClientTransport(name, config) {
2145
- if (!config.url) {
2146
- throw new Error(`Missing URL for HTTP MCP server ${name}`);
2147
- }
2073
+ if (!config.url)
2074
+ throw new Error(`Missing URL for MCP server ${name}`);
2075
+ const url = new URL(config.url);
2076
+ const opts = config.headers ? { requestInit: { headers: config.headers } } : undefined;
2148
2077
  if (config.type === "sse") {
2149
- import_core8.logger.warn(`Server "${name}": "sse" transport type is deprecated. Use "streamable-http" or "http" instead for the modern Streamable HTTP transport.`);
2078
+ import_core8.logger.warn(`[MCP] "${name}": SSE requires Redis. Use "streamable-http" instead.`);
2079
+ return new import_sse.SSEClientTransport(url, opts);
2150
2080
  }
2151
- return new import_sse.SSEClientTransport(new URL(config.url));
2081
+ return new import_streamableHttp.StreamableHTTPClientTransport(url, opts);
2152
2082
  }
2153
2083
  appendErrorMessage(connection, error) {
2154
- const newError = connection.server.error ? `${connection.server.error}
2084
+ connection.server.error = connection.server.error ? `${connection.server.error}
2155
2085
  ${error}` : error;
2156
- connection.server.error = newError;
2157
2086
  }
2158
2087
  async fetchToolsList(serverName) {
2088
+ const connection = this.connections.get(serverName);
2089
+ if (!connection)
2090
+ return [];
2159
2091
  try {
2160
- const connection = this.getServerConnection(serverName);
2161
- if (!connection) {
2162
- return [];
2163
- }
2164
2092
  const response = await connection.client.listTools();
2165
- const tools = (response?.tools || []).map((tool) => {
2166
- let processedTool = { ...tool };
2167
- if (tool.inputSchema) {
2168
- try {
2169
- if (!this.compatibilityInitialized) {
2170
- this.initializeToolCompatibility();
2171
- }
2172
- processedTool.inputSchema = this.applyToolCompatibility(tool.inputSchema);
2173
- import_core8.logger.debug(`Applied tool compatibility for: ${tool.name} on server: ${serverName}`);
2174
- } catch (error) {
2175
- import_core8.logger.warn({ error, toolName: tool.name, serverName }, `Tool compatibility failed for ${tool.name} on ${serverName}`);
2176
- }
2093
+ return (response?.tools || []).map((tool) => {
2094
+ if (!tool.inputSchema)
2095
+ return tool;
2096
+ if (!this.compatibilityInitialized)
2097
+ this.initializeToolCompatibility();
2098
+ try {
2099
+ return { ...tool, inputSchema: this.applyToolCompatibility(tool.inputSchema) };
2100
+ } catch {
2101
+ return tool;
2177
2102
  }
2178
- return processedTool;
2179
2103
  });
2180
- import_core8.logger.info(`Fetched ${tools.length} tools for ${serverName}`);
2181
- for (const tool of tools) {
2182
- import_core8.logger.info(`[${serverName}] ${tool.name}: ${tool.description}`);
2183
- }
2184
- return tools;
2185
2104
  } catch (error) {
2186
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName }, `Failed to fetch tools for ${serverName}`);
2105
+ import_core8.logger.error({ error: errMsg(error), serverName }, `Failed to fetch tools: ${serverName}`);
2187
2106
  return [];
2188
2107
  }
2189
2108
  }
2190
- async fetchResourcesList(serverName) {
2109
+ async fetchResourcesList(name) {
2110
+ const conn = this.connections.get(name);
2111
+ if (!conn)
2112
+ return [];
2191
2113
  try {
2192
- const connection = this.getServerConnection(serverName);
2193
- if (!connection) {
2194
- return [];
2195
- }
2196
- const response = await connection.client.listResources();
2197
- return response?.resources || [];
2114
+ return (await conn.client.listResources())?.resources || [];
2198
2115
  } catch (error) {
2199
- import_core8.logger.warn({ error: error instanceof Error ? error.message : String(error), serverName }, `No resources found for ${serverName}`);
2116
+ import_core8.logger.debug({ error: errMsg(error), serverName: name }, `No resources for ${name}`);
2200
2117
  return [];
2201
2118
  }
2202
2119
  }
2203
- async fetchResourceTemplatesList(serverName) {
2120
+ async fetchResourceTemplatesList(name) {
2121
+ const conn = this.connections.get(name);
2122
+ if (!conn)
2123
+ return [];
2204
2124
  try {
2205
- const connection = this.getServerConnection(serverName);
2206
- if (!connection) {
2207
- return [];
2208
- }
2209
- const response = await connection.client.listResourceTemplates();
2210
- return response?.resourceTemplates || [];
2125
+ return (await conn.client.listResourceTemplates())?.resourceTemplates || [];
2211
2126
  } catch (error) {
2212
- import_core8.logger.warn({ error: error instanceof Error ? error.message : String(error), serverName }, `No resource templates found for ${serverName}`);
2127
+ import_core8.logger.debug({ error: errMsg(error), serverName: name }, `No resource templates for ${name}`);
2213
2128
  return [];
2214
2129
  }
2215
2130
  }
@@ -2219,76 +2134,53 @@ ${error}` : error;
2219
2134
  getProviderData() {
2220
2135
  return this.mcpProvider;
2221
2136
  }
2222
- async callTool(serverName, toolName, toolArguments) {
2223
- const connection = this.connections.get(serverName);
2224
- if (!connection) {
2225
- throw new Error(`No connection found for server: ${serverName}`);
2226
- }
2227
- if (connection.server.disabled) {
2228
- throw new Error(`Server "${serverName}" is disabled`);
2229
- }
2230
- let timeout = DEFAULT_MCP_TIMEOUT_SECONDS;
2231
- try {
2232
- const config = JSON.parse(connection.server.config);
2233
- timeout = config.timeoutInMillis || DEFAULT_MCP_TIMEOUT_SECONDS;
2234
- } catch (error) {
2235
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName }, `Failed to parse timeout configuration for server ${serverName}`);
2236
- }
2237
- const result = await connection.client.callTool({ name: toolName, arguments: toolArguments }, undefined, { timeout });
2238
- if (!result.content) {
2239
- throw new Error("Invalid tool result: missing content array");
2240
- }
2137
+ async callTool(serverName, toolName, args) {
2138
+ const conn = this.connections.get(serverName);
2139
+ if (!conn)
2140
+ throw new Error(`No connection: ${serverName}`);
2141
+ if (conn.server.disabled)
2142
+ throw new Error(`Server disabled: ${serverName}`);
2143
+ const config = JSON.parse(conn.server.config);
2144
+ const timeout = (config.type === "stdio" ? config.timeoutInMillis : config.timeout) ?? DEFAULT_MCP_TIMEOUT_SECONDS;
2145
+ const result = await conn.client.callTool({ name: toolName, arguments: args }, undefined, {
2146
+ timeout
2147
+ });
2148
+ if (!result.content)
2149
+ throw new Error("Invalid tool result: missing content");
2241
2150
  return result;
2242
2151
  }
2243
2152
  async readResource(serverName, uri) {
2244
- const connection = this.connections.get(serverName);
2245
- if (!connection) {
2246
- throw new Error(`No connection found for server: ${serverName}`);
2247
- }
2248
- if (connection.server.disabled) {
2249
- throw new Error(`Server "${serverName}" is disabled`);
2250
- }
2251
- return await connection.client.readResource({ uri });
2153
+ const conn = this.connections.get(serverName);
2154
+ if (!conn)
2155
+ throw new Error(`No connection: ${serverName}`);
2156
+ if (conn.server.disabled)
2157
+ throw new Error(`Server disabled: ${serverName}`);
2158
+ return conn.client.readResource({ uri });
2252
2159
  }
2253
2160
  async restartConnection(serverName) {
2254
- const connection = this.connections.get(serverName);
2255
- const config = connection?.server.config;
2256
- if (config) {
2257
- import_core8.logger.info(`Restarting ${serverName} MCP server...`);
2258
- connection.server.status = "connecting";
2259
- connection.server.error = "";
2260
- try {
2261
- await this.deleteConnection(serverName);
2262
- await this.initializeConnection(serverName, JSON.parse(config));
2263
- import_core8.logger.info(`${serverName} MCP server connected`);
2264
- } catch (error) {
2265
- import_core8.logger.error({ error: error instanceof Error ? error.message : String(error), serverName }, `Failed to restart connection for ${serverName}`);
2266
- throw new Error(`Failed to connect to ${serverName} MCP server`);
2267
- }
2268
- }
2161
+ const conn = this.connections.get(serverName);
2162
+ if (!conn)
2163
+ throw new Error(`No connection: ${serverName}`);
2164
+ const config = conn.server.config;
2165
+ conn.server.status = "connecting";
2166
+ conn.server.error = "";
2167
+ await this.deleteConnection(serverName);
2168
+ await this.initializeConnection(serverName, JSON.parse(config));
2269
2169
  }
2270
2170
  initializeToolCompatibility() {
2271
2171
  if (this.compatibilityInitialized)
2272
2172
  return;
2273
2173
  this.toolCompatibility = createMcpToolCompatibilitySync(this.runtime);
2274
2174
  this.compatibilityInitialized = true;
2275
- if (this.toolCompatibility) {
2276
- import_core8.logger.info(`Tool compatibility enabled`);
2277
- } else {
2278
- import_core8.logger.info(`No tool compatibility needed`);
2279
- }
2280
2175
  }
2281
2176
  applyToolCompatibility(toolSchema) {
2282
- if (!this.compatibilityInitialized) {
2177
+ if (!this.compatibilityInitialized)
2283
2178
  this.initializeToolCompatibility();
2284
- }
2285
- if (!this.toolCompatibility || !toolSchema) {
2179
+ if (!this.toolCompatibility || !toolSchema)
2286
2180
  return toolSchema;
2287
- }
2288
2181
  try {
2289
2182
  return this.toolCompatibility.transformToolSchema(toolSchema);
2290
- } catch (error) {
2291
- import_core8.logger.warn({ error }, `Tool compatibility transformation failed`);
2183
+ } catch {
2292
2184
  return toolSchema;
2293
2185
  }
2294
2186
  }
@@ -2307,4 +2199,4 @@ var mcpPlugin = {
2307
2199
  };
2308
2200
  var src_default = mcpPlugin;
2309
2201
 
2310
- //# debugId=06B19883B039D4B264756E2164756E21
2202
+ //# debugId=4999FDCEADE0A8A564756E2164756E21