@mastra/mcp 1.4.1 → 1.4.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -381,6 +381,15 @@ var ResourceClientActions = class {
381
381
  }
382
382
  };
383
383
 
384
+ // src/client/error-utils.ts
385
+ function isReconnectableMCPError(error) {
386
+ if (!(error instanceof Error)) {
387
+ return false;
388
+ }
389
+ const errorMessage = error.message.toLowerCase();
390
+ return errorMessage.includes("no valid session") || errorMessage.includes("session") || errorMessage.includes("server not initialized") || errorMessage.includes("not connected") || errorMessage.includes("http 400") || errorMessage.includes("http 401") || errorMessage.includes("http 403") || errorMessage.includes("econnrefused") || errorMessage.includes("fetch failed") || errorMessage.includes("connection refused") || errorMessage.includes("connection closed") || errorMessage.includes("sse stream disconnected") || errorMessage.includes("typeerror: terminated");
391
+ }
392
+
384
393
  // src/client/client.ts
385
394
  var DEFAULT_SERVER_CONNECT_TIMEOUT_MSEC = 3e3;
386
395
  var SSE_FALLBACK_STATUS_CODES = [400, 404, 405];
@@ -739,27 +748,6 @@ var InternalMastraMCPClient = class extends MastraBase {
739
748
  }
740
749
  }
741
750
  }
742
- /**
743
- * Checks if an error indicates a session invalidation that requires reconnection.
744
- *
745
- * Common session-related errors include:
746
- * - "No valid session ID provided" (HTTP 400)
747
- * - "Server not initialized" (HTTP 400)
748
- * - "Not connected" (protocol state error)
749
- * - Connection refused errors
750
- *
751
- * @param error - The error to check
752
- * @returns true if the error indicates a session problem requiring reconnection
753
- *
754
- * @internal
755
- */
756
- isSessionError(error) {
757
- if (!(error instanceof Error)) {
758
- return false;
759
- }
760
- const errorMessage = error.message.toLowerCase();
761
- return errorMessage.includes("no valid session") || errorMessage.includes("session") || errorMessage.includes("server not initialized") || errorMessage.includes("not connected") || errorMessage.includes("http 400") || errorMessage.includes("http 401") || errorMessage.includes("http 403") || errorMessage.includes("econnrefused") || errorMessage.includes("fetch failed") || errorMessage.includes("connection refused") || errorMessage.includes("sse stream disconnected") || errorMessage.includes("typeerror: terminated");
762
- }
763
751
  /**
764
752
  * Forces a reconnection to the MCP server by disconnecting and reconnecting.
765
753
  *
@@ -949,7 +937,7 @@ var InternalMastraMCPClient = class extends MastraBase {
949
937
  try {
950
938
  return await executeToolCall();
951
939
  } catch (e) {
952
- if (this.isSessionError(e)) {
940
+ if (isReconnectableMCPError(e)) {
953
941
  this.log("debug", `Session error detected for tool ${tool.name}, attempting reconnection...`, {
954
942
  error: e instanceof Error ? e.message : String(e)
955
943
  });
@@ -989,6 +977,7 @@ var InternalMastraMCPClient = class extends MastraBase {
989
977
  }
990
978
  };
991
979
  var mcpClientInstances = /* @__PURE__ */ new Map();
980
+ var TOOL_DISCOVERY_MAX_ATTEMPTS = 2;
992
981
  var MCPClient = class extends MastraBase {
993
982
  serverConfigs = {};
994
983
  id;
@@ -1642,6 +1631,7 @@ To fix this you have three different options:
1642
1631
  *
1643
1632
  * @returns Object mapping namespaced tool names to tool implementations.
1644
1633
  * Errors for individual servers are logged but don't throw - failed servers are skipped.
1634
+ * Transient connection failures are retried once after reconnecting the affected server.
1645
1635
  *
1646
1636
  * @example
1647
1637
  * ```typescript
@@ -1659,8 +1649,7 @@ To fix this you have three different options:
1659
1649
  const connectedTools = {};
1660
1650
  for (const serverName of Object.keys(this.serverConfigs)) {
1661
1651
  try {
1662
- const client = await this.getConnectedClientForServer(serverName);
1663
- const tools = await client.tools();
1652
+ const tools = await this.getToolsForServer(serverName);
1664
1653
  for (const [toolName, toolConfig] of Object.entries(tools)) {
1665
1654
  connectedTools[`${serverName}_${toolName}`] = toolConfig;
1666
1655
  }
@@ -1716,6 +1705,7 @@ To fix this you have three different options:
1716
1705
  * or list tools. This allows callers to report specific failure reasons per server.
1717
1706
  *
1718
1707
  * @returns Object with `toolsets` (successful servers) and `errors` (failed servers with error messages).
1708
+ * Transient connection failures are retried once after reconnecting the affected server.
1719
1709
  *
1720
1710
  * @example
1721
1711
  * ```typescript
@@ -1731,8 +1721,7 @@ To fix this you have three different options:
1731
1721
  const errors = {};
1732
1722
  for (const serverName of Object.keys(this.serverConfigs)) {
1733
1723
  try {
1734
- const client = await this.getConnectedClientForServer(serverName);
1735
- const tools = await client.tools();
1724
+ const tools = await this.getToolsForServer(serverName);
1736
1725
  if (tools) {
1737
1726
  connectedToolsets[serverName] = tools;
1738
1727
  }
@@ -1845,6 +1834,26 @@ To fix this you have three different options:
1845
1834
  }
1846
1835
  return this.getConnectedClient(serverName, serverConfig);
1847
1836
  }
1837
+ async getToolsForServer(serverName) {
1838
+ for (let attempt = 1; attempt <= TOOL_DISCOVERY_MAX_ATTEMPTS; attempt++) {
1839
+ try {
1840
+ const client = await this.getConnectedClientForServer(serverName);
1841
+ return await client.tools();
1842
+ } catch (error) {
1843
+ if (attempt === TOOL_DISCOVERY_MAX_ATTEMPTS || !isReconnectableMCPError(error)) {
1844
+ throw error;
1845
+ }
1846
+ this.logger.debug("Retrying MCP tool discovery after reconnect", {
1847
+ serverName,
1848
+ attempt,
1849
+ maxAttempts: TOOL_DISCOVERY_MAX_ATTEMPTS,
1850
+ error: error instanceof Error ? error.message : String(error)
1851
+ });
1852
+ await this.reconnectServer(serverName);
1853
+ }
1854
+ }
1855
+ return {};
1856
+ }
1848
1857
  };
1849
1858
 
1850
1859
  // src/client/oauth-provider.ts