@mastra/mcp 0.10.4-alpha.0 → 0.10.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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/mcp@0.10.4-alpha.0 build /home/runner/work/mastra/mastra/packages/mcp
2
+ > @mastra/mcp@0.10.4-alpha.1 build /home/runner/work/mastra/mastra/packages/mcp
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 20174ms
9
+ TSC ⚡️ Build success in 20537ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/packages/mcp/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/packages/mcp/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 20211ms
16
+ DTS ⚡️ Build success in 21141ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 71.81 KB
21
- ESM ⚡️ Build success in 1802ms
22
- CJS dist/index.cjs 71.95 KB
23
- CJS ⚡️ Build success in 1784ms
20
+ ESM dist/index.js 71.61 KB
21
+ ESM ⚡️ Build success in 1942ms
22
+ CJS dist/index.cjs 71.73 KB
23
+ CJS ⚡️ Build success in 1942ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @mastra/mcp
2
2
 
3
+ ## 0.10.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 63f6b7d: dependencies updates:
8
+ - Updated dependency [`@modelcontextprotocol/sdk@^1.12.1` ↗︎](https://www.npmjs.com/package/@modelcontextprotocol/sdk/v/1.12.1) (from `^1.10.2`, in `dependencies`)
9
+ - Updated dependency [`hono@^4.7.11` ↗︎](https://www.npmjs.com/package/hono/v/4.7.11) (from `^4.7.4`, in `dependencies`)
10
+ - 36f1c36: MCP Client and Server streamable http fixes
11
+ - bd1674f: Change how connection promise works for client connection
12
+ - 69f76f7: Fix Agents as tools when building mastra mcp server
13
+ - Updated dependencies [63f6b7d]
14
+ - Updated dependencies [12a95fc]
15
+ - Updated dependencies [4b0f8a6]
16
+ - Updated dependencies [51264a5]
17
+ - Updated dependencies [8e6f677]
18
+ - Updated dependencies [d70c420]
19
+ - Updated dependencies [ee9af57]
20
+ - Updated dependencies [36f1c36]
21
+ - Updated dependencies [2a16996]
22
+ - Updated dependencies [10d352e]
23
+ - Updated dependencies [9589624]
24
+ - Updated dependencies [53d3c37]
25
+ - Updated dependencies [751c894]
26
+ - Updated dependencies [577ce3a]
27
+ - Updated dependencies [9260b3a]
28
+ - @mastra/core@0.10.6
29
+
30
+ ## 0.10.4-alpha.1
31
+
32
+ ### Patch Changes
33
+
34
+ - bd1674f: Change how connection promise works for client connection
35
+ - 69f76f7: Fix Agents as tools when building mastra mcp server
36
+
3
37
  ## 0.10.4-alpha.0
4
38
 
5
39
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { Agent } from '@mastra/core/agent';
1
+ import type { Agent } from '@mastra/core/agent';
2
2
  import type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';
3
3
  import type { ConvertedTool } from '@mastra/core/mcp';
4
4
  import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
@@ -86,7 +86,7 @@ export declare class InternalMastraMCPClient extends MastraBase {
86
86
  private connectStdio;
87
87
  private connectHttp;
88
88
  private isConnected;
89
- connect(): Promise<void>;
89
+ connect(): Promise<boolean>;
90
90
  /**
91
91
  * Get the current session ID if using the Streamable HTTP transport.
92
92
  * Returns undefined if not connected or not using Streamable HTTP.
@@ -1,4 +1,4 @@
1
- import { Agent } from '@mastra/core/agent';
1
+ import type { Agent } from '@mastra/core/agent';
2
2
  import type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';
3
3
  import type { ConvertedTool } from '@mastra/core/mcp';
4
4
  import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
@@ -86,7 +86,7 @@ export declare class InternalMastraMCPClient extends MastraBase {
86
86
  private connectStdio;
87
87
  private connectHttp;
88
88
  private isConnected;
89
- connect(): Promise<void>;
89
+ connect(): Promise<boolean>;
90
90
  /**
91
91
  * Get the current session ID if using the Streamable HTTP transport.
92
92
  * Returns undefined if not connected or not using Streamable HTTP.
package/dist/index.cjs CHANGED
@@ -16,7 +16,6 @@ var equal = require('fast-deep-equal');
16
16
  var uuid = require('uuid');
17
17
  var crypto$1 = require('crypto');
18
18
  var core = require('@mastra/core');
19
- var agent = require('@mastra/core/agent');
20
19
  var mcp = require('@mastra/core/mcp');
21
20
  var runtimeContext = require('@mastra/core/runtime-context');
22
21
  var index_js = require('@modelcontextprotocol/sdk/server/index.js');
@@ -332,42 +331,33 @@ var InternalMastraMCPClient = class extends base.MastraBase {
332
331
  }
333
332
  isConnected = null;
334
333
  async connect() {
335
- let res = () => {
336
- };
337
- let rej = () => {
338
- };
339
- if (this.isConnected === null) {
340
- this.log("debug", `Creating new isConnected promise`);
341
- this.isConnected = new Promise((resolve, reject) => {
342
- res = resolve;
343
- rej = reject;
344
- });
345
- } else if (await this.isConnected) {
346
- this.log("debug", `MCP server already connected`);
347
- return;
334
+ if (await this.isConnected) {
335
+ return true;
348
336
  }
349
- const { command, url } = this.serverConfig;
350
- if (command) {
351
- await this.connectStdio(command).catch((e) => {
352
- rej(e);
353
- });
354
- } else if (url) {
355
- await this.connectHttp(url).catch((e) => {
356
- rej(e);
357
- });
358
- } else {
359
- rej(false);
360
- throw new Error("Server configuration must include either a command or a url.");
361
- }
362
- res(true);
363
- const originalOnClose = this.client.onclose;
364
- this.client.onclose = () => {
365
- this.log("debug", `MCP server connection closed`);
366
- rej(false);
367
- if (typeof originalOnClose === `function`) {
368
- originalOnClose();
337
+ this.isConnected = new Promise(async (resolve, reject) => {
338
+ try {
339
+ const { command, url } = this.serverConfig;
340
+ if (command) {
341
+ await this.connectStdio(command);
342
+ } else if (url) {
343
+ await this.connectHttp(url);
344
+ } else {
345
+ throw new Error("Server configuration must include either a command or a url.");
346
+ }
347
+ resolve(true);
348
+ const originalOnClose = this.client.onclose;
349
+ this.client.onclose = () => {
350
+ this.log("debug", `MCP server connection closed`);
351
+ this.isConnected = null;
352
+ if (typeof originalOnClose === "function") {
353
+ originalOnClose();
354
+ }
355
+ };
356
+ } catch (e) {
357
+ this.isConnected = null;
358
+ reject(e);
369
359
  }
370
- };
360
+ });
371
361
  exitHook.asyncExitHook(
372
362
  async () => {
373
363
  this.log("debug", `Disconnecting MCP server during exit`);
@@ -377,6 +367,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
377
367
  );
378
368
  process.on("SIGTERM", () => exitHook.gracefulExit());
379
369
  this.log("debug", `Successfully connected to MCP server`);
370
+ return this.isConnected;
380
371
  }
381
372
  /**
382
373
  * Get the current session ID if using the Streamable HTTP transport.
@@ -1089,15 +1080,15 @@ var MCPServer = class extends mcp.MCPServerBase {
1089
1080
  return agentTools;
1090
1081
  }
1091
1082
  for (const agentKey in agentsConfig) {
1092
- const agent$1 = agentsConfig[agentKey];
1093
- if (!agent$1 || !(agent$1 instanceof agent.Agent)) {
1083
+ const agent = agentsConfig[agentKey];
1084
+ if (!agent || !("generate" in agent)) {
1094
1085
  this.logger.warn(`Agent instance for '${agentKey}' is invalid or missing a generate function. Skipping.`);
1095
1086
  continue;
1096
1087
  }
1097
- const agentDescription = agent$1.getDescription();
1088
+ const agentDescription = agent.getDescription();
1098
1089
  if (!agentDescription) {
1099
1090
  throw new Error(
1100
- `Agent '${agent$1.name}' (key: '${agentKey}') must have a non-empty description to be used in an MCPServer.`
1091
+ `Agent '${agent.name}' (key: '${agentKey}') must have a non-empty description to be used in an MCPServer.`
1101
1092
  );
1102
1093
  }
1103
1094
  const agentToolName = `ask_${agentKey}`;
@@ -1109,19 +1100,19 @@ var MCPServer = class extends mcp.MCPServerBase {
1109
1100
  }
1110
1101
  const agentToolDefinition = core.createTool({
1111
1102
  id: agentToolName,
1112
- description: `Ask agent '${agent$1.name}' a question. Agent description: ${agentDescription}`,
1103
+ description: `Ask agent '${agent.name}' a question. Agent description: ${agentDescription}`,
1113
1104
  inputSchema: zod.z.object({
1114
1105
  message: zod.z.string().describe("The question or input for the agent.")
1115
1106
  }),
1116
1107
  execute: async ({ context, runtimeContext }) => {
1117
1108
  this.logger.debug(
1118
- `Executing agent tool '${agentToolName}' for agent '${agent$1.name}' with message: "${context.message}"`
1109
+ `Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${context.message}"`
1119
1110
  );
1120
1111
  try {
1121
- const response = await agent$1.generate(context.message, { runtimeContext });
1112
+ const response = await agent.generate(context.message, { runtimeContext });
1122
1113
  return response;
1123
1114
  } catch (error) {
1124
- this.logger.error(`Error executing agent tool '${agentToolName}' for agent '${agent$1.name}':`, error);
1115
+ this.logger.error(`Error executing agent tool '${agentToolName}' for agent '${agent.name}':`, error);
1125
1116
  throw error;
1126
1117
  }
1127
1118
  }
@@ -1141,7 +1132,7 @@ var MCPServer = class extends mcp.MCPServerBase {
1141
1132
  execute: coreTool.execute,
1142
1133
  toolType: "agent"
1143
1134
  };
1144
- this.logger.info(`Registered agent '${agent$1.name}' (key: '${agentKey}') as tool: '${agentToolName}'`);
1135
+ this.logger.info(`Registered agent '${agent.name}' (key: '${agentKey}') as tool: '${agentToolName}'`);
1145
1136
  }
1146
1137
  return agentTools;
1147
1138
  }
package/dist/index.js CHANGED
@@ -14,7 +14,6 @@ import equal from 'fast-deep-equal';
14
14
  import { v5 } from 'uuid';
15
15
  import { randomUUID } from 'crypto';
16
16
  import { createTool, makeCoreTool } from '@mastra/core';
17
- import { Agent } from '@mastra/core/agent';
18
17
  import { MCPServerBase } from '@mastra/core/mcp';
19
18
  import { RuntimeContext } from '@mastra/core/runtime-context';
20
19
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
@@ -326,42 +325,33 @@ var InternalMastraMCPClient = class extends MastraBase {
326
325
  }
327
326
  isConnected = null;
328
327
  async connect() {
329
- let res = () => {
330
- };
331
- let rej = () => {
332
- };
333
- if (this.isConnected === null) {
334
- this.log("debug", `Creating new isConnected promise`);
335
- this.isConnected = new Promise((resolve, reject) => {
336
- res = resolve;
337
- rej = reject;
338
- });
339
- } else if (await this.isConnected) {
340
- this.log("debug", `MCP server already connected`);
341
- return;
328
+ if (await this.isConnected) {
329
+ return true;
342
330
  }
343
- const { command, url } = this.serverConfig;
344
- if (command) {
345
- await this.connectStdio(command).catch((e) => {
346
- rej(e);
347
- });
348
- } else if (url) {
349
- await this.connectHttp(url).catch((e) => {
350
- rej(e);
351
- });
352
- } else {
353
- rej(false);
354
- throw new Error("Server configuration must include either a command or a url.");
355
- }
356
- res(true);
357
- const originalOnClose = this.client.onclose;
358
- this.client.onclose = () => {
359
- this.log("debug", `MCP server connection closed`);
360
- rej(false);
361
- if (typeof originalOnClose === `function`) {
362
- originalOnClose();
331
+ this.isConnected = new Promise(async (resolve, reject) => {
332
+ try {
333
+ const { command, url } = this.serverConfig;
334
+ if (command) {
335
+ await this.connectStdio(command);
336
+ } else if (url) {
337
+ await this.connectHttp(url);
338
+ } else {
339
+ throw new Error("Server configuration must include either a command or a url.");
340
+ }
341
+ resolve(true);
342
+ const originalOnClose = this.client.onclose;
343
+ this.client.onclose = () => {
344
+ this.log("debug", `MCP server connection closed`);
345
+ this.isConnected = null;
346
+ if (typeof originalOnClose === "function") {
347
+ originalOnClose();
348
+ }
349
+ };
350
+ } catch (e) {
351
+ this.isConnected = null;
352
+ reject(e);
363
353
  }
364
- };
354
+ });
365
355
  asyncExitHook(
366
356
  async () => {
367
357
  this.log("debug", `Disconnecting MCP server during exit`);
@@ -371,6 +361,7 @@ var InternalMastraMCPClient = class extends MastraBase {
371
361
  );
372
362
  process.on("SIGTERM", () => gracefulExit());
373
363
  this.log("debug", `Successfully connected to MCP server`);
364
+ return this.isConnected;
374
365
  }
375
366
  /**
376
367
  * Get the current session ID if using the Streamable HTTP transport.
@@ -1084,7 +1075,7 @@ var MCPServer = class extends MCPServerBase {
1084
1075
  }
1085
1076
  for (const agentKey in agentsConfig) {
1086
1077
  const agent = agentsConfig[agentKey];
1087
- if (!agent || !(agent instanceof Agent)) {
1078
+ if (!agent || !("generate" in agent)) {
1088
1079
  this.logger.warn(`Agent instance for '${agentKey}' is invalid or missing a generate function. Skipping.`);
1089
1080
  continue;
1090
1081
  }
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
+
4
+ case `uname` in
5
+ *CYGWIN*|*MINGW*|*MSYS*)
6
+ if command -v cygpath > /dev/null 2>&1; then
7
+ basedir=`cygpath -w "$basedir"`
8
+ fi
9
+ ;;
10
+ esac
11
+
12
+ if [ -z "$NODE_PATH" ]; then
13
+ export NODE_PATH="/home/runner/work/mastra/mastra/packages/cli/dist/node_modules:/home/runner/work/mastra/mastra/packages/cli/node_modules:/home/runner/work/mastra/mastra/packages/node_modules:/home/runner/work/mastra/mastra/node_modules:/home/runner/work/mastra/node_modules:/home/runner/work/node_modules:/home/runner/node_modules:/home/node_modules:/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules"
14
+ else
15
+ export NODE_PATH="/home/runner/work/mastra/mastra/packages/cli/dist/node_modules:/home/runner/work/mastra/mastra/packages/cli/node_modules:/home/runner/work/mastra/mastra/packages/node_modules:/home/runner/work/mastra/mastra/node_modules:/home/runner/work/mastra/node_modules:/home/runner/work/node_modules:/home/runner/node_modules:/home/node_modules:/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules:$NODE_PATH"
16
+ fi
17
+ if [ -x "$basedir/node" ]; then
18
+ exec "$basedir/node" "$basedir/../mastra/dist/index.js" "$@"
19
+ else
20
+ exec node "$basedir/../mastra/dist/index.js" "$@"
21
+ fi
@@ -10,9 +10,9 @@ case `uname` in
10
10
  esac
11
11
 
12
12
  if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_693b2e3fc65baebd9dc5fe66abed9401/node_modules/vitest/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_693b2e3fc65baebd9dc5fe66abed9401/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules"
13
+ export NODE_PATH="/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_3e45f0297eeb1f6a4ee30770ed0f557b/node_modules/vitest/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_3e45f0297eeb1f6a4ee30770ed0f557b/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules"
14
14
  else
15
- export NODE_PATH="/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_693b2e3fc65baebd9dc5fe66abed9401/node_modules/vitest/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_693b2e3fc65baebd9dc5fe66abed9401/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules:$NODE_PATH"
15
+ export NODE_PATH="/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_3e45f0297eeb1f6a4ee30770ed0f557b/node_modules/vitest/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/vitest@3.2.3_@edge-runtime+vm@3.2.0_@types+debug@4.1.12_@types+node@20.19.0_@vitest+ui@_3e45f0297eeb1f6a4ee30770ed0f557b/node_modules:/home/runner/work/mastra/mastra/node_modules/.pnpm/node_modules:$NODE_PATH"
16
16
  fi
17
17
  if [ -x "$basedir/node" ]; then
18
18
  exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
@@ -7,8 +7,8 @@
7
7
  "dev": "mastra dev"
8
8
  },
9
9
  "dependencies": {
10
- "@ai-sdk/openai": "^1.3.21",
11
- "@ai-sdk/react": "^1.2.11",
10
+ "@ai-sdk/openai": "^1.3.22",
11
+ "@ai-sdk/react": "^1.2.12",
12
12
  "@mastra/client-js": "workspace:*",
13
13
  "@mastra/mcp": "workspace:*",
14
14
  "dotenv": "^16.5.0",
@@ -21,7 +21,7 @@
21
21
  "get-port": "^7.1.0",
22
22
  "mastra": "workspace:*",
23
23
  "typescript": "^5.8.2",
24
- "vitest": "^3.2.2"
24
+ "vitest": "^3.2.3"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@mastra/core": "^0.10.0-alpha.0"
@@ -1,9 +1,9 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { createServer } from 'node:http';
3
2
  import { MCPClient } from '@mastra/mcp';
4
3
  import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
5
4
  import { ServerInfo } from '@mastra/core/mcp';
6
5
  import getPort from 'get-port';
6
+ import path from 'node:path';
7
7
 
8
8
  vi.setConfig({ testTimeout: 20000, hookTimeout: 20000 });
9
9
 
@@ -17,10 +17,19 @@ describe('MCPServer through Mastra HTTP Integration (Subprocess)', () => {
17
17
  beforeAll(async () => {
18
18
  port = await getPort();
19
19
 
20
- mastraServer = spawn('pnpm', ['mastra', 'dev', '--port', port.toString()], {
21
- stdio: 'pipe',
22
- detached: true, // Run in a new process group so we can kill it and children
23
- });
20
+ mastraServer = spawn(
21
+ 'pnpm',
22
+ [
23
+ path.resolve(import.meta.dirname, `..`, `..`, `..`, `cli`, `dist`, `index.js`),
24
+ 'dev',
25
+ '--port',
26
+ port.toString(),
27
+ ],
28
+ {
29
+ stdio: 'pipe',
30
+ detached: true, // Run in a new process group so we can kill it and children
31
+ },
32
+ );
24
33
 
25
34
  // Wait for server to be ready
26
35
  await new Promise<void>((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp",
3
- "version": "0.10.4-alpha.0",
3
+ "version": "0.10.4",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -50,8 +50,8 @@
50
50
  "vitest": "^3.2.3",
51
51
  "zod": "^3.25.57",
52
52
  "zod-to-json-schema": "^3.24.5",
53
- "@internal/lint": "0.0.12",
54
- "@mastra/core": "0.10.6-alpha.0"
53
+ "@internal/lint": "0.0.13",
54
+ "@mastra/core": "0.10.6"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
@@ -274,44 +274,42 @@ export class InternalMastraMCPClient extends MastraBase {
274
274
  private isConnected: Promise<boolean> | null = null;
275
275
 
276
276
  async connect() {
277
- let res: (value: boolean) => void = () => {};
278
- let rej: (reason?: any) => void = () => {};
279
-
280
- if (this.isConnected === null) {
281
- this.log('debug', `Creating new isConnected promise`);
282
- this.isConnected = new Promise<boolean>((resolve, reject) => {
283
- res = resolve;
284
- rej = reject;
285
- });
286
- } else if (await this.isConnected) {
287
- this.log('debug', `MCP server already connected`);
288
- return;
277
+ // If a connection attempt is in progress, wait for it.
278
+ if (await this.isConnected) {
279
+ return true;
289
280
  }
290
281
 
291
- const { command, url } = this.serverConfig;
292
-
293
- if (command) {
294
- await this.connectStdio(command).catch(e => {
295
- rej(e);
296
- });
297
- } else if (url) {
298
- await this.connectHttp(url).catch(e => {
299
- rej(e);
300
- });
301
- } else {
302
- rej(false);
303
- throw new Error('Server configuration must include either a command or a url.');
304
- }
282
+ // Start new connection attempt.
283
+ this.isConnected = new Promise<boolean>(async (resolve, reject) => {
284
+ try {
285
+ const { command, url } = this.serverConfig;
286
+
287
+ if (command) {
288
+ await this.connectStdio(command);
289
+ } else if (url) {
290
+ await this.connectHttp(url);
291
+ } else {
292
+ throw new Error('Server configuration must include either a command or a url.');
293
+ }
305
294
 
306
- res(true);
307
- const originalOnClose = this.client.onclose;
308
- this.client.onclose = () => {
309
- this.log('debug', `MCP server connection closed`);
310
- rej(false);
311
- if (typeof originalOnClose === `function`) {
312
- originalOnClose();
295
+ resolve(true);
296
+
297
+ // Set up disconnect handler to reset state.
298
+ const originalOnClose = this.client.onclose;
299
+ this.client.onclose = () => {
300
+ this.log('debug', `MCP server connection closed`);
301
+ this.isConnected = null;
302
+ if (typeof originalOnClose === 'function') {
303
+ originalOnClose();
304
+ }
305
+ };
306
+
307
+ } catch (e) {
308
+ this.isConnected = null;
309
+ reject(e);
313
310
  }
314
- };
311
+ });
312
+
315
313
  asyncExitHook(
316
314
  async () => {
317
315
  this.log('debug', `Disconnecting MCP server during exit`);
@@ -322,6 +320,7 @@ export class InternalMastraMCPClient extends MastraBase {
322
320
 
323
321
  process.on('SIGTERM', () => gracefulExit());
324
322
  this.log('debug', `Successfully connected to MCP server`);
323
+ return this.isConnected;
325
324
  }
326
325
 
327
326
  /**
@@ -2,8 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import type * as http from 'node:http';
3
3
  import type { InternalCoreTool } from '@mastra/core';
4
4
  import { createTool, makeCoreTool } from '@mastra/core';
5
- import type { ToolsInput } from '@mastra/core/agent';
6
- import { Agent } from '@mastra/core/agent';
5
+ import type { ToolsInput, Agent } from '@mastra/core/agent';
7
6
  import { MCPServerBase } from '@mastra/core/mcp';
8
7
  import type {
9
8
  MCPServerConfig,
@@ -187,7 +186,7 @@ export class MCPServer extends MCPServerBase {
187
186
 
188
187
  for (const agentKey in agentsConfig) {
189
188
  const agent = agentsConfig[agentKey];
190
- if (!agent || !(agent instanceof Agent)) {
189
+ if (!agent || !('generate' in agent)) {
191
190
  this.logger.warn(`Agent instance for '${agentKey}' is invalid or missing a generate function. Skipping.`);
192
191
  continue;
193
192
  }