@mastra/mcp 1.0.2 → 1.0.3

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
@@ -743,7 +743,7 @@ var InternalMastraMCPClient = class extends MastraBase {
743
743
  return false;
744
744
  }
745
745
  const errorMessage = error.message.toLowerCase();
746
- 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");
746
+ 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");
747
747
  }
748
748
  /**
749
749
  * Forces a reconnection to the MCP server by disconnecting and reconnecting.
@@ -899,6 +899,31 @@ var InternalMastraMCPClient = class extends MastraBase {
899
899
  });
900
900
  }
901
901
  }
902
+ /**
903
+ * Recursively applies `.passthrough()` to all ZodObject schemas so that
904
+ * unknown keys returned by an MCP server are preserved instead of being
905
+ * silently stripped by Zod's default "strip" mode.
906
+ */
907
+ applyPassthrough(schema) {
908
+ if (schema instanceof z.ZodObject) {
909
+ const shape = schema.shape;
910
+ const newShape = {};
911
+ for (const key of Object.keys(shape)) {
912
+ newShape[key] = this.applyPassthrough(shape[key]);
913
+ }
914
+ return z.object(newShape).passthrough();
915
+ }
916
+ if (schema instanceof z.ZodArray) {
917
+ return z.array(this.applyPassthrough(schema.element));
918
+ }
919
+ if (schema instanceof z.ZodOptional) {
920
+ return this.applyPassthrough(schema.unwrap()).optional();
921
+ }
922
+ if (schema instanceof z.ZodNullable) {
923
+ return this.applyPassthrough(schema.unwrap()).nullable();
924
+ }
925
+ return schema;
926
+ }
902
927
  async convertOutputSchema(outputSchema) {
903
928
  if (!outputSchema) return;
904
929
  if (isZodType(outputSchema)) {
@@ -907,11 +932,13 @@ var InternalMastraMCPClient = class extends MastraBase {
907
932
  try {
908
933
  await $RefParser.dereference(outputSchema);
909
934
  const jsonSchemaToConvert = "jsonSchema" in outputSchema ? outputSchema.jsonSchema : outputSchema;
935
+ let zodSchema;
910
936
  if ("toJSONSchema" in z) {
911
- return convertJsonSchemaToZod(jsonSchemaToConvert);
937
+ zodSchema = convertJsonSchemaToZod(jsonSchemaToConvert);
912
938
  } else {
913
- return convertJsonSchemaToZod$1(jsonSchemaToConvert);
939
+ zodSchema = convertJsonSchemaToZod$1(jsonSchemaToConvert);
914
940
  }
941
+ return this.applyPassthrough(zodSchema);
915
942
  } catch (error) {
916
943
  let errorDetails;
917
944
  if (error instanceof Error) {
@@ -1107,7 +1134,7 @@ To fix this you have three different options:
1107
1134
  * await mcp.progress.onUpdate('serverName', (params) => {
1108
1135
  * console.log(`Progress: ${params.progress}%`);
1109
1136
  * console.log(`Status: ${params.message}`);
1110
- *
1137
+ *
1111
1138
  * if (params.total) {
1112
1139
  * console.log(`Completed ${params.progress} of ${params.total} items`);
1113
1140
  * }
@@ -1645,7 +1672,7 @@ To fix this you have three different options:
1645
1672
  this.disconnectPromise = (async () => {
1646
1673
  try {
1647
1674
  mcpClientInstances.delete(this.id);
1648
- await Promise.all(Array.from(this.mcpClientsById.values()).map((client) => client.disconnect()));
1675
+ await Promise.allSettled(Array.from(this.mcpClientsById.values()).map((client) => client.disconnect()));
1649
1676
  this.mcpClientsById.clear();
1650
1677
  } finally {
1651
1678
  this.disconnectPromise = null;
@@ -1659,8 +1686,8 @@ To fix this you have three different options:
1659
1686
  * Tool names are namespaced as `serverName_toolName` to prevent conflicts between servers.
1660
1687
  * This method is intended to be passed directly to an Agent definition.
1661
1688
  *
1662
- * @returns Object mapping namespaced tool names to tool implementations
1663
- * @throws {MastraError} If retrieving tools fails
1689
+ * @returns Object mapping namespaced tool names to tool implementations.
1690
+ * Errors for individual servers are logged but don't throw - failed servers are skipped.
1664
1691
  *
1665
1692
  * @example
1666
1693
  * ```typescript
@@ -1676,21 +1703,28 @@ To fix this you have three different options:
1676
1703
  async listTools() {
1677
1704
  this.addToInstanceCache();
1678
1705
  const connectedTools = {};
1679
- try {
1680
- await this.eachClientTools(async ({ serverName, tools }) => {
1706
+ for (const serverName of Object.keys(this.serverConfigs)) {
1707
+ try {
1708
+ const client = await this.getConnectedClientForServer(serverName);
1709
+ const tools = await client.tools();
1681
1710
  for (const [toolName, toolConfig] of Object.entries(tools)) {
1682
1711
  connectedTools[`${serverName}_${toolName}`] = toolConfig;
1683
1712
  }
1684
- });
1685
- } catch (error) {
1686
- throw new MastraError(
1687
- {
1688
- id: "MCP_CLIENT_GET_TOOLS_FAILED",
1689
- domain: ErrorDomain.MCP,
1690
- category: ErrorCategory.THIRD_PARTY
1691
- },
1692
- error
1693
- );
1713
+ } catch (error) {
1714
+ const mastraError = new MastraError(
1715
+ {
1716
+ id: "MCP_CLIENT_GET_TOOLS_FAILED",
1717
+ domain: ErrorDomain.MCP,
1718
+ category: ErrorCategory.THIRD_PARTY,
1719
+ details: {
1720
+ serverName
1721
+ }
1722
+ },
1723
+ error
1724
+ );
1725
+ this.logger.trackException(mastraError);
1726
+ this.logger.error("Failed to list tools from server:", { error: mastraError.toString() });
1727
+ }
1694
1728
  }
1695
1729
  return connectedTools;
1696
1730
  }
@@ -1700,8 +1734,8 @@ To fix this you have three different options:
1700
1734
  * Unlike listTools(), this returns tools grouped by server without namespacing.
1701
1735
  * This is intended to be passed dynamically to the generate() or stream() method.
1702
1736
  *
1703
- * @returns Object mapping server names to their tool collections
1704
- * @throws {MastraError} If retrieving toolsets fails
1737
+ * @returns Object mapping server names to their tool collections.
1738
+ * Errors for individual servers are logged but don't throw - failed servers are skipped.
1705
1739
  *
1706
1740
  * @example
1707
1741
  * ```typescript
@@ -1720,21 +1754,28 @@ To fix this you have three different options:
1720
1754
  async listToolsets() {
1721
1755
  this.addToInstanceCache();
1722
1756
  const connectedToolsets = {};
1723
- try {
1724
- await this.eachClientTools(async ({ serverName, tools }) => {
1757
+ for (const serverName of Object.keys(this.serverConfigs)) {
1758
+ try {
1759
+ const client = await this.getConnectedClientForServer(serverName);
1760
+ const tools = await client.tools();
1725
1761
  if (tools) {
1726
1762
  connectedToolsets[serverName] = tools;
1727
1763
  }
1728
- });
1729
- } catch (error) {
1730
- throw new MastraError(
1731
- {
1732
- id: "MCP_CLIENT_GET_TOOLSETS_FAILED",
1733
- domain: ErrorDomain.MCP,
1734
- category: ErrorCategory.THIRD_PARTY
1735
- },
1736
- error
1737
- );
1764
+ } catch (error) {
1765
+ const mastraError = new MastraError(
1766
+ {
1767
+ id: "MCP_CLIENT_GET_TOOLSETS_FAILED",
1768
+ domain: ErrorDomain.MCP,
1769
+ category: ErrorCategory.THIRD_PARTY,
1770
+ details: {
1771
+ serverName
1772
+ }
1773
+ },
1774
+ error
1775
+ );
1776
+ this.logger.trackException(mastraError);
1777
+ this.logger.error("Failed to list toolsets from server:", { error: mastraError.toString() });
1778
+ }
1738
1779
  }
1739
1780
  return connectedToolsets;
1740
1781
  }
@@ -1814,15 +1855,6 @@ To fix this you have three different options:
1814
1855
  }
1815
1856
  return this.getConnectedClient(serverName, serverConfig);
1816
1857
  }
1817
- async eachClientTools(cb) {
1818
- await Promise.all(
1819
- Object.entries(this.serverConfigs).map(async ([serverName, serverConfig]) => {
1820
- const client = await this.getConnectedClient(serverName, serverConfig);
1821
- const tools = await client.tools();
1822
- await cb({ serverName, tools, client });
1823
- })
1824
- );
1825
- }
1826
1858
  };
1827
1859
 
1828
1860
  // src/client/oauth-provider.ts