@mastra/mcp 1.0.0-beta.3 → 1.0.0-beta.4

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.cjs CHANGED
@@ -1,38 +1,38 @@
1
1
  'use strict';
2
2
 
3
+ var $RefParser = require('@apidevtools/json-schema-ref-parser');
3
4
  var base = require('@mastra/core/base');
4
5
  var error = require('@mastra/core/error');
5
- var protocol_js = require('@modelcontextprotocol/sdk/shared/protocol.js');
6
- var equal = require('fast-deep-equal');
7
- var uuid = require('uuid');
8
- var $RefParser = require('@apidevtools/json-schema-ref-parser');
9
6
  var tools = require('@mastra/core/tools');
10
7
  var utils = require('@mastra/core/utils');
11
- var index_js$1 = require('@modelcontextprotocol/sdk/client/index.js');
12
- var sse_js$1 = require('@modelcontextprotocol/sdk/client/sse.js');
13
- var stdio_js$1 = require('@modelcontextprotocol/sdk/client/stdio.js');
14
- var streamableHttp_js$1 = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
8
+ var index_js = require('@modelcontextprotocol/sdk/client/index.js');
9
+ var sse_js = require('@modelcontextprotocol/sdk/client/sse.js');
10
+ var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
11
+ var streamableHttp_js = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
12
+ var protocol_js = require('@modelcontextprotocol/sdk/shared/protocol.js');
15
13
  var types_js = require('@modelcontextprotocol/sdk/types.js');
16
14
  var exitHook = require('exit-hook');
17
15
  var zod = require('zod');
18
16
  var zodFromJsonSchema = require('zod-from-json-schema');
19
17
  var zodFromJsonSchemaV3 = require('zod-from-json-schema-v3');
18
+ var equal = require('fast-deep-equal');
19
+ var uuid = require('uuid');
20
20
  var crypto$1 = require('crypto');
21
21
  var mcp = require('@mastra/core/mcp');
22
22
  var requestContext = require('@mastra/core/request-context');
23
- var index_js = require('@modelcontextprotocol/sdk/server/index.js');
24
- var sse_js = require('@modelcontextprotocol/sdk/server/sse.js');
25
- var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
26
- var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
23
+ var index_js$1 = require('@modelcontextprotocol/sdk/server/index.js');
24
+ var sse_js$1 = require('@modelcontextprotocol/sdk/server/sse.js');
25
+ var stdio_js$1 = require('@modelcontextprotocol/sdk/server/stdio.js');
26
+ var streamableHttp_js$1 = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
27
27
 
28
28
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
29
29
 
30
- var equal__default = /*#__PURE__*/_interopDefault(equal);
31
30
  var $RefParser__default = /*#__PURE__*/_interopDefault($RefParser);
31
+ var equal__default = /*#__PURE__*/_interopDefault(equal);
32
32
 
33
- // src/client/configuration.ts
33
+ // src/client/client.ts
34
34
 
35
- // src/client/elicitationActions.ts
35
+ // src/client/actions/elicitation.ts
36
36
  var ElicitationClientActions = class {
37
37
  client;
38
38
  logger;
@@ -85,6 +85,23 @@ var ElicitationClientActions = class {
85
85
  this.client.setElicitationRequestHandler(handler);
86
86
  }
87
87
  };
88
+
89
+ // src/client/actions/progress.ts
90
+ var ProgressClientActions = class {
91
+ client;
92
+ logger;
93
+ constructor({ client, logger }) {
94
+ this.client = client;
95
+ this.logger = logger;
96
+ }
97
+ /**
98
+ * Set a notification handler for progress updates.
99
+ * @param handler The callback function to handle progress notifications.
100
+ */
101
+ onUpdate(handler) {
102
+ this.client.setProgressNotificationHandler(handler);
103
+ }
104
+ };
88
105
  var PromptClientActions = class {
89
106
  client;
90
107
  logger;
@@ -398,17 +415,21 @@ var InternalMastraMCPClient = class extends base.MastraBase {
398
415
  timeout;
399
416
  logHandler;
400
417
  enableServerLogs;
418
+ enableProgressTracking;
401
419
  serverConfig;
402
420
  transport;
403
421
  currentOperationContext = null;
404
422
  exitHookUnsubscribe;
405
423
  sigTermHandler;
424
+ _roots;
406
425
  /** Provides access to resource operations (list, read, subscribe, etc.) */
407
426
  resources;
408
427
  /** Provides access to prompt operations (list, get, notifications) */
409
428
  prompts;
410
429
  /** Provides access to elicitation operations (request handling) */
411
430
  elicitation;
431
+ /** Provides access to progress operations (notifications) */
432
+ progress;
412
433
  /**
413
434
  * @internal
414
435
  */
@@ -425,8 +446,16 @@ var InternalMastraMCPClient = class extends base.MastraBase {
425
446
  this.logHandler = server.logger;
426
447
  this.enableServerLogs = server.enableServerLogs ?? true;
427
448
  this.serverConfig = server;
428
- const clientCapabilities = { ...capabilities, elicitation: {} };
429
- this.client = new index_js$1.Client(
449
+ this.enableProgressTracking = !!server.enableProgressTracking;
450
+ this._roots = server.roots ?? [];
451
+ const hasRoots = this._roots.length > 0 || !!capabilities.roots;
452
+ const clientCapabilities = {
453
+ ...capabilities,
454
+ elicitation: {},
455
+ // Auto-enable roots capability if roots are provided
456
+ ...hasRoots ? { roots: { listChanged: true, ...capabilities.roots ?? {} } } : {}
457
+ };
458
+ this.client = new index_js.Client(
430
459
  {
431
460
  name,
432
461
  version
@@ -436,9 +465,13 @@ var InternalMastraMCPClient = class extends base.MastraBase {
436
465
  }
437
466
  );
438
467
  this.setupLogging();
468
+ if (hasRoots) {
469
+ this.setupRootsHandler();
470
+ }
439
471
  this.resources = new ResourceClientActions({ client: this, logger: this.logger });
440
472
  this.prompts = new PromptClientActions({ client: this, logger: this.logger });
441
473
  this.elicitation = new ElicitationClientActions({ client: this, logger: this.logger });
474
+ this.progress = new ProgressClientActions({ client: this, logger: this.logger });
442
475
  }
443
476
  /**
444
477
  * Log a message at the specified level
@@ -477,13 +510,70 @@ var InternalMastraMCPClient = class extends base.MastraBase {
477
510
  );
478
511
  }
479
512
  }
513
+ /**
514
+ * Set up handler for roots/list requests from the server.
515
+ *
516
+ * Per MCP spec (https://modelcontextprotocol.io/specification/2025-11-25/client/roots):
517
+ * When a server sends a roots/list request, the client responds with the configured roots.
518
+ */
519
+ setupRootsHandler() {
520
+ this.log("debug", "Setting up roots/list request handler");
521
+ this.client.setRequestHandler(types_js.ListRootsRequestSchema, async () => {
522
+ this.log("debug", `Responding to roots/list request with ${this._roots.length} roots`);
523
+ return { roots: this._roots };
524
+ });
525
+ }
526
+ /**
527
+ * Get the currently configured roots.
528
+ *
529
+ * @returns Array of configured filesystem roots
530
+ */
531
+ get roots() {
532
+ return [...this._roots];
533
+ }
534
+ /**
535
+ * Update the list of filesystem roots and notify the server.
536
+ *
537
+ * Per MCP spec, when roots change, the client sends a `notifications/roots/list_changed`
538
+ * notification to inform the server that it should re-fetch the roots list.
539
+ *
540
+ * @param roots - New list of filesystem roots
541
+ *
542
+ * @example
543
+ * ```typescript
544
+ * await client.setRoots([
545
+ * { uri: 'file:///home/user/projects', name: 'Projects' },
546
+ * { uri: 'file:///tmp', name: 'Temp' }
547
+ * ]);
548
+ * ```
549
+ */
550
+ async setRoots(roots) {
551
+ this.log("debug", `Updating roots to ${roots.length} entries`);
552
+ this._roots = [...roots];
553
+ await this.sendRootsListChanged();
554
+ }
555
+ /**
556
+ * Send a roots/list_changed notification to the server.
557
+ *
558
+ * Per MCP spec, clients that support `listChanged` MUST send this notification
559
+ * when the list of roots changes. The server will then call roots/list to get
560
+ * the updated list.
561
+ */
562
+ async sendRootsListChanged() {
563
+ if (!this.transport) {
564
+ this.log("debug", "Cannot send roots/list_changed: not connected");
565
+ return;
566
+ }
567
+ this.log("debug", "Sending notifications/roots/list_changed");
568
+ await this.client.notification({ method: "notifications/roots/list_changed" });
569
+ }
480
570
  async connectStdio(command) {
481
571
  this.log("debug", `Using Stdio transport for command: ${command}`);
482
572
  try {
483
- this.transport = new stdio_js$1.StdioClientTransport({
573
+ this.transport = new stdio_js.StdioClientTransport({
484
574
  command,
485
575
  args: this.serverConfig.args,
486
- env: { ...stdio_js$1.getDefaultEnvironment(), ...this.serverConfig.env || {} }
576
+ env: { ...stdio_js.getDefaultEnvironment(), ...this.serverConfig.env || {} }
487
577
  });
488
578
  await this.client.connect(this.transport, { timeout: this.serverConfig.timeout ?? this.timeout });
489
579
  this.log("debug", `Successfully connected to MCP server via Stdio`);
@@ -499,7 +589,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
499
589
  if (!shouldTrySSE) {
500
590
  try {
501
591
  this.log("debug", "Trying Streamable HTTP transport...");
502
- const streamableTransport = new streamableHttp_js$1.StreamableHTTPClientTransport(url, {
592
+ const streamableTransport = new streamableHttp_js.StreamableHTTPClientTransport(url, {
503
593
  requestInit,
504
594
  reconnectionOptions: this.serverConfig.reconnectionOptions,
505
595
  authProvider
@@ -517,7 +607,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
517
607
  if (shouldTrySSE) {
518
608
  this.log("debug", "Falling back to deprecated HTTP+SSE transport...");
519
609
  try {
520
- const sseTransport = new sse_js$1.SSEClientTransport(url, { requestInit, eventSourceInit, authProvider });
610
+ const sseTransport = new sse_js.SSEClientTransport(url, { requestInit, eventSourceInit, authProvider });
521
611
  await this.client.connect(sseTransport, { timeout: this.serverConfig.timeout ?? this.timeout });
522
612
  this.transport = sseTransport;
523
613
  this.log("debug", "Successfully connected using deprecated HTTP+SSE transport.");
@@ -596,7 +686,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
596
686
  * @internal
597
687
  */
598
688
  get sessionId() {
599
- if (this.transport instanceof streamableHttp_js$1.StreamableHTTPClientTransport) {
689
+ if (this.transport instanceof streamableHttp_js.StreamableHTTPClientTransport) {
600
690
  return this.transport.sessionId;
601
691
  }
602
692
  return void 0;
@@ -617,7 +707,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
617
707
  throw e;
618
708
  } finally {
619
709
  this.transport = void 0;
620
- this.isConnected = Promise.resolve(false);
710
+ this.isConnected = null;
621
711
  if (this.exitHookUnsubscribe) {
622
712
  this.exitHookUnsubscribe();
623
713
  this.exitHookUnsubscribe = void 0;
@@ -628,6 +718,53 @@ var InternalMastraMCPClient = class extends base.MastraBase {
628
718
  }
629
719
  }
630
720
  }
721
+ /**
722
+ * Checks if an error indicates a session invalidation that requires reconnection.
723
+ *
724
+ * Common session-related errors include:
725
+ * - "No valid session ID provided" (HTTP 400)
726
+ * - "Server not initialized" (HTTP 400)
727
+ * - Connection refused errors
728
+ *
729
+ * @param error - The error to check
730
+ * @returns true if the error indicates a session problem requiring reconnection
731
+ *
732
+ * @internal
733
+ */
734
+ isSessionError(error) {
735
+ if (!(error instanceof Error)) {
736
+ return false;
737
+ }
738
+ const errorMessage = error.message.toLowerCase();
739
+ return errorMessage.includes("no valid session") || errorMessage.includes("session") || errorMessage.includes("server not initialized") || errorMessage.includes("http 400") || errorMessage.includes("http 401") || errorMessage.includes("http 403") || errorMessage.includes("econnrefused") || errorMessage.includes("fetch failed") || errorMessage.includes("connection refused");
740
+ }
741
+ /**
742
+ * Forces a reconnection to the MCP server by disconnecting and reconnecting.
743
+ *
744
+ * This is useful when the session becomes invalid (e.g., after server restart)
745
+ * and the client needs to establish a fresh connection.
746
+ *
747
+ * @returns Promise resolving when reconnection is complete
748
+ * @throws {Error} If reconnection fails
749
+ *
750
+ * @internal
751
+ */
752
+ async forceReconnect() {
753
+ this.log("debug", "Forcing reconnection to MCP server...");
754
+ try {
755
+ if (this.transport) {
756
+ await this.transport.close();
757
+ }
758
+ } catch (e) {
759
+ this.log("debug", "Error during force disconnect (ignored)", {
760
+ error: e instanceof Error ? e.message : String(e)
761
+ });
762
+ }
763
+ this.transport = void 0;
764
+ this.isConnected = null;
765
+ await this.connect();
766
+ this.log("debug", "Successfully reconnected to MCP server");
767
+ }
631
768
  async listResources() {
632
769
  this.log("debug", `Requesting resources from MCP server`);
633
770
  return await this.client.request({ method: "resources/list" }, types_js.ListResourcesResultSchema, {
@@ -714,6 +851,12 @@ var InternalMastraMCPClient = class extends base.MastraBase {
714
851
  return handler(request.params);
715
852
  });
716
853
  }
854
+ setProgressNotificationHandler(handler) {
855
+ this.log("debug", "Setting progress notification handler");
856
+ this.client.setNotificationHandler(types_js.ProgressNotificationSchema, (notification) => {
857
+ handler(notification.params);
858
+ });
859
+ }
717
860
  async convertInputSchema(inputSchema) {
718
861
  if (utils.isZodType(inputSchema)) {
719
862
  return inputSchema;
@@ -787,7 +930,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
787
930
  }
788
931
  async tools() {
789
932
  this.log("debug", `Requesting tools from MCP server`);
790
- const { tools: tools$1 } = await this.client.listTools({ timeout: this.timeout });
933
+ const { tools: tools$1 } = await this.client.listTools({}, { timeout: this.timeout });
791
934
  const toolsRes = {};
792
935
  for (const tool of tools$1) {
793
936
  this.log("debug", `Processing tool: ${tool.name}`);
@@ -800,12 +943,14 @@ var InternalMastraMCPClient = class extends base.MastraBase {
800
943
  execute: async (input, context) => {
801
944
  const previousContext = this.currentOperationContext;
802
945
  this.currentOperationContext = context?.requestContext || null;
803
- try {
804
- this.log("debug", `Executing tool: ${tool.name}`, { toolArgs: input });
946
+ const executeToolCall = async () => {
947
+ this.log("debug", `Executing tool: ${tool.name}`, { toolArgs: input, runId: context?.runId });
805
948
  const res = await this.client.callTool(
806
949
  {
807
950
  name: tool.name,
808
- arguments: input
951
+ arguments: input,
952
+ // Use runId as progress token if available, otherwise generate a random UUID
953
+ ...this.enableProgressTracking ? { _meta: { progressToken: context?.runId || crypto.randomUUID() } } : {}
809
954
  },
810
955
  types_js.CallToolResultSchema,
811
956
  {
@@ -817,7 +962,27 @@ var InternalMastraMCPClient = class extends base.MastraBase {
817
962
  return res.structuredContent;
818
963
  }
819
964
  return res;
965
+ };
966
+ try {
967
+ return await executeToolCall();
820
968
  } catch (e) {
969
+ if (this.isSessionError(e)) {
970
+ this.log("debug", `Session error detected for tool ${tool.name}, attempting reconnection...`, {
971
+ error: e instanceof Error ? e.message : String(e)
972
+ });
973
+ try {
974
+ await this.forceReconnect();
975
+ this.log("debug", `Retrying tool ${tool.name} after reconnection...`);
976
+ return await executeToolCall();
977
+ } catch (reconnectError) {
978
+ this.log("error", `Reconnection or retry failed for tool ${tool.name}`, {
979
+ originalError: e instanceof Error ? e.message : String(e),
980
+ reconnectError: reconnectError instanceof Error ? reconnectError.stack : String(reconnectError),
981
+ toolArgs: input
982
+ });
983
+ throw e;
984
+ }
985
+ }
821
986
  this.log("error", `Error calling tool: ${tool.name}`, {
822
987
  error: e instanceof Error ? e.stack : JSON.stringify(e, null, 2),
823
988
  toolArgs: input
@@ -841,8 +1006,6 @@ var InternalMastraMCPClient = class extends base.MastraBase {
841
1006
  return toolsRes;
842
1007
  }
843
1008
  };
844
-
845
- // src/client/configuration.ts
846
1009
  var mcpClientInstances = /* @__PURE__ */ new Map();
847
1010
  var MCPClient = class extends base.MastraBase {
848
1011
  serverConfigs = {};
@@ -915,6 +1078,48 @@ To fix this you have three different options:
915
1078
  this.addToInstanceCache();
916
1079
  return this;
917
1080
  }
1081
+ /**
1082
+ * Provides access to progress-related operations for tracking long-running operations.
1083
+ *
1084
+ * Progress tracking allows MCP servers to send updates about the status of ongoing operations,
1085
+ * providing real-time feedback to users about task completion and current state.
1086
+ *
1087
+ * @example
1088
+ * ```typescript
1089
+ * // Set up handler for progress updates from a server
1090
+ * await mcp.progress.onUpdate('serverName', (params) => {
1091
+ * console.log(`Progress: ${params.progress}%`);
1092
+ * console.log(`Status: ${params.message}`);
1093
+ *
1094
+ * if (params.total) {
1095
+ * console.log(`Completed ${params.progress} of ${params.total} items`);
1096
+ * }
1097
+ * });
1098
+ * ```
1099
+ */
1100
+ get progress() {
1101
+ this.addToInstanceCache();
1102
+ return {
1103
+ onUpdate: async (serverName, handler) => {
1104
+ try {
1105
+ const internalClient = await this.getConnectedClientForServer(serverName);
1106
+ return internalClient.progress.onUpdate(handler);
1107
+ } catch (err) {
1108
+ throw new error.MastraError(
1109
+ {
1110
+ id: "MCP_CLIENT_ON_UPDATE_PROGRESS_FAILED",
1111
+ domain: error.ErrorDomain.MCP,
1112
+ category: error.ErrorCategory.THIRD_PARTY,
1113
+ details: {
1114
+ serverName
1115
+ }
1116
+ },
1117
+ err
1118
+ );
1119
+ }
1120
+ }
1121
+ };
1122
+ }
918
1123
  /**
919
1124
  * Provides access to elicitation-related operations for interactive user input collection.
920
1125
  *
@@ -2160,7 +2365,7 @@ var MCPServer = class extends mcp.MCPServerBase {
2160
2365
  if (opts.prompts) {
2161
2366
  capabilities.prompts = { listChanged: true };
2162
2367
  }
2163
- this.server = new index_js.Server({ name: this.name, version: this.version }, { capabilities });
2368
+ this.server = new index_js$1.Server({ name: this.name, version: this.version }, { capabilities });
2164
2369
  this.logger.info(
2165
2370
  `Initialized MCPServer '${this.name}' v${this.version} (ID: ${this.id}) with tools: ${Object.keys(this.convertedTools).join(", ")} and resources. Capabilities: ${JSON.stringify(capabilities)}`
2166
2371
  );
@@ -2205,6 +2410,41 @@ var MCPServer = class extends mcp.MCPServerBase {
2205
2410
  this.logger.debug(`Received elicitation response: ${JSON.stringify(response)}`);
2206
2411
  return response;
2207
2412
  }
2413
+ /**
2414
+ * Reads and parses the JSON body from an HTTP request.
2415
+ * If the request body was already parsed by middleware (e.g., express.json()),
2416
+ * it uses the pre-parsed body from req.body. Otherwise, it reads from the stream.
2417
+ *
2418
+ * This allows the MCP server to work with Express apps that use express.json()
2419
+ * globally without requiring special route exclusions.
2420
+ *
2421
+ * @param req - The incoming HTTP request
2422
+ * @param options - Optional configuration
2423
+ * @param options.preParsedOnly - If true, only return pre-parsed body from middleware,
2424
+ * returning undefined if not available. This allows the caller to fall back to
2425
+ * their own body reading logic (e.g., SDK's getRawBody with size limits).
2426
+ */
2427
+ async readJsonBody(req, options) {
2428
+ const reqWithBody = req;
2429
+ if (reqWithBody.body !== void 0) {
2430
+ return reqWithBody.body;
2431
+ }
2432
+ if (options?.preParsedOnly) {
2433
+ return void 0;
2434
+ }
2435
+ return new Promise((resolve, reject) => {
2436
+ let data = "";
2437
+ req.on("data", (chunk) => data += chunk);
2438
+ req.on("end", () => {
2439
+ try {
2440
+ resolve(JSON.parse(data));
2441
+ } catch (e) {
2442
+ reject(e);
2443
+ }
2444
+ });
2445
+ req.on("error", reject);
2446
+ });
2447
+ }
2208
2448
  /**
2209
2449
  * Creates a new Server instance configured with all handlers for HTTP sessions.
2210
2450
  * Each HTTP client connection gets its own Server instance to avoid routing conflicts.
@@ -2221,7 +2461,7 @@ var MCPServer = class extends mcp.MCPServerBase {
2221
2461
  if (this.promptOptions) {
2222
2462
  capabilities.prompts = { listChanged: true };
2223
2463
  }
2224
- const serverInstance = new index_js.Server({ name: this.name, version: this.version }, { capabilities });
2464
+ const serverInstance = new index_js$1.Server({ name: this.name, version: this.version }, { capabilities });
2225
2465
  this.registerHandlersOnServer(serverInstance);
2226
2466
  return serverInstance;
2227
2467
  }
@@ -2593,7 +2833,9 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2593
2833
  try {
2594
2834
  const proxiedContext = context?.requestContext || new requestContext.RequestContext();
2595
2835
  if (context?.mcp?.extra) {
2596
- proxiedContext.set("mcp.extra", context.mcp.extra);
2836
+ Object.entries(context.mcp.extra).forEach(([key, value]) => {
2837
+ proxiedContext.set(key, value);
2838
+ });
2597
2839
  }
2598
2840
  const response = await agent.generate(inputData.message, {
2599
2841
  ...context ?? {},
@@ -2662,10 +2904,16 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2662
2904
  inputData
2663
2905
  );
2664
2906
  try {
2665
- const run2 = await workflow.createRun({ runId: context?.requestContext?.get("runId") });
2907
+ const proxiedContext = context?.requestContext || new requestContext.RequestContext();
2908
+ if (context?.mcp?.extra) {
2909
+ Object.entries(context.mcp.extra).forEach(([key, value]) => {
2910
+ proxiedContext.set(key, value);
2911
+ });
2912
+ }
2913
+ const run2 = await workflow.createRun({ runId: proxiedContext?.get("runId") });
2666
2914
  const response = await run2.start({
2667
2915
  inputData,
2668
- requestContext: context?.requestContext,
2916
+ requestContext: proxiedContext,
2669
2917
  tracingContext: context?.tracingContext
2670
2918
  });
2671
2919
  return response;
@@ -2784,7 +3032,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2784
3032
  * ```
2785
3033
  */
2786
3034
  async startStdio() {
2787
- this.stdioTransport = new stdio_js.StdioServerTransport();
3035
+ this.stdioTransport = new stdio_js$1.StdioServerTransport();
2788
3036
  try {
2789
3037
  await this.server.connect(this.stdioTransport);
2790
3038
  } catch (error$1) {
@@ -2821,7 +3069,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2821
3069
  *
2822
3070
  * @example
2823
3071
  * ```typescript
2824
- * import http from 'http';
3072
+ * import http from 'node:http';
2825
3073
  *
2826
3074
  * const httpServer = http.createServer(async (req, res) => {
2827
3075
  * await server.startSSE({
@@ -2852,7 +3100,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2852
3100
  res.end("SSE connection not established");
2853
3101
  return;
2854
3102
  }
2855
- await this.sseTransport.handlePostMessage(req, res);
3103
+ const parsedBody = await this.readJsonBody(req, { preParsedOnly: true });
3104
+ await this.sseTransport.handlePostMessage(req, res, parsedBody);
2856
3105
  } else {
2857
3106
  this.logger.debug("Unknown path:", { path: url.pathname });
2858
3107
  res.writeHead(404);
@@ -2979,8 +3228,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
2979
3228
  *
2980
3229
  * @example
2981
3230
  * ```typescript
2982
- * import http from 'http';
2983
- * import { randomUUID } from 'crypto';
3231
+ * import http from 'node:http';
3232
+ * import { randomUUID } from 'node:crypto';
2984
3233
  *
2985
3234
  * const httpServer = http.createServer(async (req, res) => {
2986
3235
  * await server.startHTTP({
@@ -3059,38 +3308,16 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
3059
3308
  `startHTTP: Handling GET request for existing session ${sessionId}. Calling transport.handleRequest.`
3060
3309
  );
3061
3310
  }
3062
- const body = req.method === "POST" ? await new Promise((resolve, reject) => {
3063
- let data = "";
3064
- req.on("data", (chunk) => data += chunk);
3065
- req.on("end", () => {
3066
- try {
3067
- resolve(JSON.parse(data));
3068
- } catch (e) {
3069
- reject(e);
3070
- }
3071
- });
3072
- req.on("error", reject);
3073
- }) : void 0;
3311
+ const body = req.method === "POST" ? await this.readJsonBody(req) : void 0;
3074
3312
  await transport.handleRequest(req, res, body);
3075
3313
  } else {
3076
3314
  this.logger.debug(`startHTTP: No existing Streamable HTTP session ID found. ${req.method}`);
3077
3315
  if (req.method === "POST") {
3078
- const body = await new Promise((resolve, reject) => {
3079
- let data = "";
3080
- req.on("data", (chunk) => data += chunk);
3081
- req.on("end", () => {
3082
- try {
3083
- resolve(JSON.parse(data));
3084
- } catch (e) {
3085
- reject(e);
3086
- }
3087
- });
3088
- req.on("error", reject);
3089
- });
3316
+ const body = await this.readJsonBody(req);
3090
3317
  const { isInitializeRequest } = await import('@modelcontextprotocol/sdk/types.js');
3091
3318
  if (isInitializeRequest(body)) {
3092
3319
  this.logger.debug("startHTTP: Received Streamable HTTP initialize request, creating new transport.");
3093
- transport = new streamableHttp_js.StreamableHTTPServerTransport({
3320
+ transport = new streamableHttp_js$1.StreamableHTTPServerTransport({
3094
3321
  ...mergedOptions,
3095
3322
  sessionIdGenerator: mergedOptions.sessionIdGenerator,
3096
3323
  onsessioninitialized: (id) => {
@@ -3196,24 +3423,13 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
3196
3423
  async handleServerlessRequest(req, res) {
3197
3424
  try {
3198
3425
  this.logger.debug(`handleServerlessRequest: Received ${req.method} request`);
3199
- const body = req.method === "POST" ? await new Promise((resolve, reject) => {
3200
- let data = "";
3201
- req.on("data", (chunk) => data += chunk);
3202
- req.on("end", () => {
3203
- try {
3204
- resolve(JSON.parse(data));
3205
- } catch (e) {
3206
- reject(new Error(`Invalid JSON in request body: ${e instanceof Error ? e.message : String(e)}`));
3207
- }
3208
- });
3209
- req.on("error", reject);
3210
- }) : void 0;
3426
+ const body = req.method === "POST" ? await this.readJsonBody(req) : void 0;
3211
3427
  this.logger.debug(`handleServerlessRequest: Processing ${req.method} request`, {
3212
3428
  method: body?.method,
3213
3429
  id: body?.id
3214
3430
  });
3215
3431
  const transientServer = this.createServerInstance();
3216
- const tempTransport = new streamableHttp_js.StreamableHTTPServerTransport({
3432
+ const tempTransport = new streamableHttp_js$1.StreamableHTTPServerTransport({
3217
3433
  sessionIdGenerator: void 0,
3218
3434
  enableJsonResponse: true
3219
3435
  });
@@ -3275,7 +3491,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
3275
3491
  }) {
3276
3492
  try {
3277
3493
  this.logger.debug("Received SSE connection");
3278
- this.sseTransport = new sse_js.SSEServerTransport(messagePath, res);
3494
+ this.sseTransport = new sse_js$1.SSEServerTransport(messagePath, res);
3279
3495
  await this.server.connect(this.sseTransport);
3280
3496
  this.server.onclose = async () => {
3281
3497
  this.sseTransport = void 0;
@@ -3638,6 +3854,7 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
3638
3854
  }
3639
3855
  };
3640
3856
 
3857
+ exports.InternalMastraMCPClient = InternalMastraMCPClient;
3641
3858
  exports.MCPClient = MCPClient;
3642
3859
  exports.MCPServer = MCPServer;
3643
3860
  //# sourceMappingURL=index.cjs.map