@mastra/mcp 0.11.3-alpha.2 → 0.11.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
@@ -1,14 +1,14 @@
1
1
  import $RefParser from '@apidevtools/json-schema-ref-parser';
2
2
  import { MastraBase } from '@mastra/core/base';
3
3
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
4
- import { createTool } from '@mastra/core/tools';
4
+ import { createTool, validateToolInput } from '@mastra/core/tools';
5
5
  import { makeCoreTool, isZodType } from '@mastra/core/utils';
6
6
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
7
7
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
8
8
  import { StdioClientTransport, getDefaultEnvironment } from '@modelcontextprotocol/sdk/client/stdio.js';
9
9
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
10
10
  import { DEFAULT_REQUEST_TIMEOUT_MSEC } from '@modelcontextprotocol/sdk/shared/protocol.js';
11
- import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, ListPromptsRequestSchema, PromptSchema, GetPromptRequestSchema, ListResourcesResultSchema, ReadResourceResultSchema, ListResourceTemplatesResultSchema, ListPromptsResultSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ResourceUpdatedNotificationSchema, ResourceListChangedNotificationSchema, ElicitRequestSchema, CallToolResultSchema, JSONRPCMessageSchema, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
11
+ import { ListToolsRequestSchema, CallToolRequestSchema, SetLevelRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, ListPromptsRequestSchema, PromptSchema, GetPromptRequestSchema, ListResourcesResultSchema, ReadResourceResultSchema, ListResourceTemplatesResultSchema, ListPromptsResultSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ResourceUpdatedNotificationSchema, ResourceListChangedNotificationSchema, ElicitRequestSchema, CallToolResultSchema, JSONRPCMessageSchema, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
12
12
  import { asyncExitHook, gracefulExit } from 'exit-hook';
13
13
  import { z } from 'zod';
14
14
  import { convertJsonSchemaToZod } from 'zod-from-json-schema';
@@ -82,7 +82,11 @@ var PromptClientActions = class {
82
82
  * @param version Optional version of the prompt to get.
83
83
  * @returns The prompt content.
84
84
  */
85
- async get({ name, args, version }) {
85
+ async get({
86
+ name,
87
+ args,
88
+ version
89
+ }) {
86
90
  return this.client.getPrompt({ name, args, version });
87
91
  }
88
92
  /**
@@ -684,14 +688,17 @@ To fix this you have three different options:
684
688
  const internalClient = await this.getConnectedClientForServer(serverName);
685
689
  return internalClient.elicitation.onRequest(handler);
686
690
  } catch (err) {
687
- throw new MastraError({
688
- id: "MCP_CLIENT_ON_REQUEST_ELICITATION_FAILED",
689
- domain: ErrorDomain.MCP,
690
- category: ErrorCategory.THIRD_PARTY,
691
- details: {
692
- serverName
693
- }
694
- }, err);
691
+ throw new MastraError(
692
+ {
693
+ id: "MCP_CLIENT_ON_REQUEST_ELICITATION_FAILED",
694
+ domain: ErrorDomain.MCP,
695
+ category: ErrorCategory.THIRD_PARTY,
696
+ details: {
697
+ serverName
698
+ }
699
+ },
700
+ err
701
+ );
695
702
  }
696
703
  }
697
704
  };
@@ -706,14 +713,17 @@ To fix this you have three different options:
706
713
  const internalClient = await this.getConnectedClientForServer(serverName);
707
714
  allResources[serverName] = await internalClient.resources.list();
708
715
  } catch (error) {
709
- const mastraError = new MastraError({
710
- id: "MCP_CLIENT_LIST_RESOURCES_FAILED",
711
- domain: ErrorDomain.MCP,
712
- category: ErrorCategory.THIRD_PARTY,
713
- details: {
714
- serverName
715
- }
716
- }, error);
716
+ const mastraError = new MastraError(
717
+ {
718
+ id: "MCP_CLIENT_LIST_RESOURCES_FAILED",
719
+ domain: ErrorDomain.MCP,
720
+ category: ErrorCategory.THIRD_PARTY,
721
+ details: {
722
+ serverName
723
+ }
724
+ },
725
+ error
726
+ );
717
727
  this.logger.trackException(mastraError);
718
728
  this.logger.error("Failed to list resources from server:", { error: mastraError.toString() });
719
729
  }
@@ -727,14 +737,17 @@ To fix this you have three different options:
727
737
  const internalClient = await this.getConnectedClientForServer(serverName);
728
738
  allTemplates[serverName] = await internalClient.resources.templates();
729
739
  } catch (error) {
730
- const mastraError = new MastraError({
731
- id: "MCP_CLIENT_LIST_RESOURCE_TEMPLATES_FAILED",
732
- domain: ErrorDomain.MCP,
733
- category: ErrorCategory.THIRD_PARTY,
734
- details: {
735
- serverName
736
- }
737
- }, error);
740
+ const mastraError = new MastraError(
741
+ {
742
+ id: "MCP_CLIENT_LIST_RESOURCE_TEMPLATES_FAILED",
743
+ domain: ErrorDomain.MCP,
744
+ category: ErrorCategory.THIRD_PARTY,
745
+ details: {
746
+ serverName
747
+ }
748
+ },
749
+ error
750
+ );
738
751
  this.logger.trackException(mastraError);
739
752
  this.logger.error("Failed to list resource templates from server:", { error: mastraError.toString() });
740
753
  }
@@ -746,15 +759,18 @@ To fix this you have three different options:
746
759
  const internalClient = await this.getConnectedClientForServer(serverName);
747
760
  return internalClient.resources.read(uri);
748
761
  } catch (error) {
749
- throw new MastraError({
750
- id: "MCP_CLIENT_READ_RESOURCE_FAILED",
751
- domain: ErrorDomain.MCP,
752
- category: ErrorCategory.THIRD_PARTY,
753
- details: {
754
- serverName,
755
- uri
756
- }
757
- }, error);
762
+ throw new MastraError(
763
+ {
764
+ id: "MCP_CLIENT_READ_RESOURCE_FAILED",
765
+ domain: ErrorDomain.MCP,
766
+ category: ErrorCategory.THIRD_PARTY,
767
+ details: {
768
+ serverName,
769
+ uri
770
+ }
771
+ },
772
+ error
773
+ );
758
774
  }
759
775
  },
760
776
  subscribe: async (serverName, uri) => {
@@ -762,15 +778,18 @@ To fix this you have three different options:
762
778
  const internalClient = await this.getConnectedClientForServer(serverName);
763
779
  return internalClient.resources.subscribe(uri);
764
780
  } catch (error) {
765
- throw new MastraError({
766
- id: "MCP_CLIENT_SUBSCRIBE_RESOURCE_FAILED",
767
- domain: ErrorDomain.MCP,
768
- category: ErrorCategory.THIRD_PARTY,
769
- details: {
770
- serverName,
771
- uri
772
- }
773
- }, error);
781
+ throw new MastraError(
782
+ {
783
+ id: "MCP_CLIENT_SUBSCRIBE_RESOURCE_FAILED",
784
+ domain: ErrorDomain.MCP,
785
+ category: ErrorCategory.THIRD_PARTY,
786
+ details: {
787
+ serverName,
788
+ uri
789
+ }
790
+ },
791
+ error
792
+ );
774
793
  }
775
794
  },
776
795
  unsubscribe: async (serverName, uri) => {
@@ -778,15 +797,18 @@ To fix this you have three different options:
778
797
  const internalClient = await this.getConnectedClientForServer(serverName);
779
798
  return internalClient.resources.unsubscribe(uri);
780
799
  } catch (err) {
781
- throw new MastraError({
782
- id: "MCP_CLIENT_UNSUBSCRIBE_RESOURCE_FAILED",
783
- domain: ErrorDomain.MCP,
784
- category: ErrorCategory.THIRD_PARTY,
785
- details: {
786
- serverName,
787
- uri
788
- }
789
- }, err);
800
+ throw new MastraError(
801
+ {
802
+ id: "MCP_CLIENT_UNSUBSCRIBE_RESOURCE_FAILED",
803
+ domain: ErrorDomain.MCP,
804
+ category: ErrorCategory.THIRD_PARTY,
805
+ details: {
806
+ serverName,
807
+ uri
808
+ }
809
+ },
810
+ err
811
+ );
790
812
  }
791
813
  },
792
814
  onUpdated: async (serverName, handler) => {
@@ -794,14 +816,17 @@ To fix this you have three different options:
794
816
  const internalClient = await this.getConnectedClientForServer(serverName);
795
817
  return internalClient.resources.onUpdated(handler);
796
818
  } catch (err) {
797
- throw new MastraError({
798
- id: "MCP_CLIENT_ON_UPDATED_RESOURCE_FAILED",
799
- domain: ErrorDomain.MCP,
800
- category: ErrorCategory.THIRD_PARTY,
801
- details: {
802
- serverName
803
- }
804
- }, err);
819
+ throw new MastraError(
820
+ {
821
+ id: "MCP_CLIENT_ON_UPDATED_RESOURCE_FAILED",
822
+ domain: ErrorDomain.MCP,
823
+ category: ErrorCategory.THIRD_PARTY,
824
+ details: {
825
+ serverName
826
+ }
827
+ },
828
+ err
829
+ );
805
830
  }
806
831
  },
807
832
  onListChanged: async (serverName, handler) => {
@@ -809,14 +834,17 @@ To fix this you have three different options:
809
834
  const internalClient = await this.getConnectedClientForServer(serverName);
810
835
  return internalClient.resources.onListChanged(handler);
811
836
  } catch (err) {
812
- throw new MastraError({
813
- id: "MCP_CLIENT_ON_LIST_CHANGED_RESOURCE_FAILED",
814
- domain: ErrorDomain.MCP,
815
- category: ErrorCategory.THIRD_PARTY,
816
- details: {
817
- serverName
818
- }
819
- }, err);
837
+ throw new MastraError(
838
+ {
839
+ id: "MCP_CLIENT_ON_LIST_CHANGED_RESOURCE_FAILED",
840
+ domain: ErrorDomain.MCP,
841
+ category: ErrorCategory.THIRD_PARTY,
842
+ details: {
843
+ serverName
844
+ }
845
+ },
846
+ err
847
+ );
820
848
  }
821
849
  }
822
850
  };
@@ -831,34 +859,45 @@ To fix this you have three different options:
831
859
  const internalClient = await this.getConnectedClientForServer(serverName);
832
860
  allPrompts[serverName] = await internalClient.prompts.list();
833
861
  } catch (error) {
834
- const mastraError = new MastraError({
835
- id: "MCP_CLIENT_LIST_PROMPTS_FAILED",
836
- domain: ErrorDomain.MCP,
837
- category: ErrorCategory.THIRD_PARTY,
838
- details: {
839
- serverName
840
- }
841
- }, error);
862
+ const mastraError = new MastraError(
863
+ {
864
+ id: "MCP_CLIENT_LIST_PROMPTS_FAILED",
865
+ domain: ErrorDomain.MCP,
866
+ category: ErrorCategory.THIRD_PARTY,
867
+ details: {
868
+ serverName
869
+ }
870
+ },
871
+ error
872
+ );
842
873
  this.logger.trackException(mastraError);
843
874
  this.logger.error("Failed to list prompts from server:", { error: mastraError.toString() });
844
875
  }
845
876
  }
846
877
  return allPrompts;
847
878
  },
848
- get: async ({ serverName, name, args, version }) => {
879
+ get: async ({
880
+ serverName,
881
+ name,
882
+ args,
883
+ version
884
+ }) => {
849
885
  try {
850
886
  const internalClient = await this.getConnectedClientForServer(serverName);
851
887
  return internalClient.prompts.get({ name, args, version });
852
888
  } catch (error) {
853
- throw new MastraError({
854
- id: "MCP_CLIENT_GET_PROMPT_FAILED",
855
- domain: ErrorDomain.MCP,
856
- category: ErrorCategory.THIRD_PARTY,
857
- details: {
858
- serverName,
859
- name
860
- }
861
- }, error);
889
+ throw new MastraError(
890
+ {
891
+ id: "MCP_CLIENT_GET_PROMPT_FAILED",
892
+ domain: ErrorDomain.MCP,
893
+ category: ErrorCategory.THIRD_PARTY,
894
+ details: {
895
+ serverName,
896
+ name
897
+ }
898
+ },
899
+ error
900
+ );
862
901
  }
863
902
  },
864
903
  onListChanged: async (serverName, handler) => {
@@ -866,14 +905,17 @@ To fix this you have three different options:
866
905
  const internalClient = await this.getConnectedClientForServer(serverName);
867
906
  return internalClient.prompts.onListChanged(handler);
868
907
  } catch (error) {
869
- throw new MastraError({
870
- id: "MCP_CLIENT_ON_LIST_CHANGED_PROMPT_FAILED",
871
- domain: ErrorDomain.MCP,
872
- category: ErrorCategory.THIRD_PARTY,
873
- details: {
874
- serverName
875
- }
876
- }, error);
908
+ throw new MastraError(
909
+ {
910
+ id: "MCP_CLIENT_ON_LIST_CHANGED_PROMPT_FAILED",
911
+ domain: ErrorDomain.MCP,
912
+ category: ErrorCategory.THIRD_PARTY,
913
+ details: {
914
+ serverName
915
+ }
916
+ },
917
+ error
918
+ );
877
919
  }
878
920
  }
879
921
  };
@@ -913,11 +955,14 @@ To fix this you have three different options:
913
955
  }
914
956
  });
915
957
  } catch (error) {
916
- throw new MastraError({
917
- id: "MCP_CLIENT_GET_TOOLS_FAILED",
918
- domain: ErrorDomain.MCP,
919
- category: ErrorCategory.THIRD_PARTY
920
- }, error);
958
+ throw new MastraError(
959
+ {
960
+ id: "MCP_CLIENT_GET_TOOLS_FAILED",
961
+ domain: ErrorDomain.MCP,
962
+ category: ErrorCategory.THIRD_PARTY
963
+ },
964
+ error
965
+ );
921
966
  }
922
967
  return connectedTools;
923
968
  }
@@ -931,11 +976,14 @@ To fix this you have three different options:
931
976
  }
932
977
  });
933
978
  } catch (error) {
934
- throw new MastraError({
935
- id: "MCP_CLIENT_GET_TOOLSETS_FAILED",
936
- domain: ErrorDomain.MCP,
937
- category: ErrorCategory.THIRD_PARTY
938
- }, error);
979
+ throw new MastraError(
980
+ {
981
+ id: "MCP_CLIENT_GET_TOOLSETS_FAILED",
982
+ domain: ErrorDomain.MCP,
983
+ category: ErrorCategory.THIRD_PARTY
984
+ },
985
+ error
986
+ );
939
987
  }
940
988
  return connectedToolsets;
941
989
  }
@@ -983,15 +1031,18 @@ To fix this you have three different options:
983
1031
  try {
984
1032
  await mcpClient.connect();
985
1033
  } catch (e) {
986
- const mastraError = new MastraError({
987
- id: "MCP_CLIENT_CONNECT_FAILED",
988
- domain: ErrorDomain.MCP,
989
- category: ErrorCategory.THIRD_PARTY,
990
- text: `Failed to connect to MCP server ${name}: ${e instanceof Error ? e.stack || e.message : String(e)}`,
991
- details: {
992
- name
993
- }
994
- }, e);
1034
+ const mastraError = new MastraError(
1035
+ {
1036
+ id: "MCP_CLIENT_CONNECT_FAILED",
1037
+ domain: ErrorDomain.MCP,
1038
+ category: ErrorCategory.THIRD_PARTY,
1039
+ text: `Failed to connect to MCP server ${name}: ${e instanceof Error ? e.stack || e.message : String(e)}`,
1040
+ details: {
1041
+ name
1042
+ }
1043
+ },
1044
+ e
1045
+ );
995
1046
  this.logger.trackException(mastraError);
996
1047
  this.logger.error("MCPClient errored connecting to MCP server:", { error: mastraError.toString() });
997
1048
  this.mcpClientsById.delete(name);
@@ -1399,6 +1450,7 @@ var MCPServer = class extends MCPServerBase {
1399
1450
  definedPrompts;
1400
1451
  promptOptions;
1401
1452
  subscriptions = /* @__PURE__ */ new Set();
1453
+ currentLoggingLevel;
1402
1454
  resources;
1403
1455
  prompts;
1404
1456
  elicitation;
@@ -1643,6 +1695,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
1643
1695
  };
1644
1696
  }
1645
1697
  });
1698
+ serverInstance.setRequestHandler(SetLevelRequestSchema, async (request) => {
1699
+ this.currentLoggingLevel = request.params.level;
1700
+ this.logger.debug(`Logging level set to: ${request.params.level}`);
1701
+ return {};
1702
+ });
1646
1703
  if (this.resourceOptions) {
1647
1704
  this.registerResourceHandlersOnServer(serverInstance);
1648
1705
  }
@@ -1960,7 +2017,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
1960
2017
  /**
1961
2018
  * Convert and validate all provided tools, logging registration status.
1962
2019
  * Also converts agents and workflows into tools.
1963
- * @param tools Tool definitions
2020
+ * @param tools Tool definitions (supports ToolsInput, MCPToolsInput)
1964
2021
  * @param agentsConfig Agent definitions to be converted to tools, expected from MCPServerConfig
1965
2022
  * @param workflowsConfig Workflow definitions to be converted to tools, expected from MCPServerConfig
1966
2023
  * @returns Converted tools registry
@@ -1993,7 +2050,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
1993
2050
  outputSchema: coreTool.outputSchema,
1994
2051
  execute: coreTool.execute
1995
2052
  };
1996
- this.logger.info(`Registered explicit tool: '${toolName}'`);
2053
+ this.logger.info(`Registered tool: '${toolName}'`);
1997
2054
  }
1998
2055
  this.logger.info(`Total defined tools registered: ${Object.keys(definedConvertedTools).length}`);
1999
2056
  let agentDerivedTools = {};
@@ -2586,7 +2643,57 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
2586
2643
  }
2587
2644
  }
2588
2645
  };
2646
+ function createMCPTool(opts) {
2647
+ let parameters;
2648
+ let outputSchema;
2649
+ if (opts.inputSchema) {
2650
+ parameters = {
2651
+ jsonSchema: opts.inputSchema,
2652
+ validate: (value) => {
2653
+ try {
2654
+ const result = opts.inputSchema.safeParse(value);
2655
+ return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
2656
+ } catch (e) {
2657
+ return { success: false, error: e };
2658
+ }
2659
+ }
2660
+ };
2661
+ } else {
2662
+ parameters = void 0;
2663
+ }
2664
+ if (opts.outputSchema) {
2665
+ outputSchema = {
2666
+ jsonSchema: opts.outputSchema,
2667
+ validate: (value) => {
2668
+ try {
2669
+ const result = opts.outputSchema.safeParse(value);
2670
+ return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
2671
+ } catch (e) {
2672
+ return { success: false, error: e };
2673
+ }
2674
+ }
2675
+ };
2676
+ }
2677
+ return {
2678
+ id: opts.id,
2679
+ description: opts.description,
2680
+ parameters,
2681
+ outputSchema,
2682
+ execute: async (params, options) => {
2683
+ const mcpOptions = {
2684
+ context: params,
2685
+ elicitation: options.elicitation,
2686
+ extra: options.extra
2687
+ };
2688
+ const { data, error } = validateToolInput(opts.inputSchema, params, opts.id);
2689
+ if (error) {
2690
+ return error;
2691
+ }
2692
+ return opts.execute(data, mcpOptions);
2693
+ }
2694
+ };
2695
+ }
2589
2696
 
2590
- export { MCPClient, MCPConfiguration, MCPServer, MastraMCPClient };
2697
+ export { MCPClient, MCPConfiguration, MCPServer, MastraMCPClient, createMCPTool };
2591
2698
  //# sourceMappingURL=index.js.map
2592
2699
  //# sourceMappingURL=index.js.map