@mastra/mcp 0.10.6-alpha.0 → 0.10.6

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.6-alpha.0 build /home/runner/work/mastra/mastra/packages/mcp
2
+ > @mastra/mcp@0.10.6-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 22958ms
9
+ TSC ⚡️ Build success in 22460ms
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 30106ms
16
+ DTS ⚡️ Build success in 29484ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 89.38 KB
21
- CJS ⚡️ Build success in 2235ms
22
- ESM dist/index.js 88.70 KB
23
- ESM ⚡️ Build success in 2236ms
20
+ ESM dist/index.js 88.94 KB
21
+ ESM ⚡️ Build success in 2100ms
22
+ CJS dist/index.cjs 89.72 KB
23
+ CJS ⚡️ Build success in 2103ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @mastra/mcp
2
2
 
3
+ ## 0.10.6
4
+
5
+ ### Patch Changes
6
+
7
+ - f5ec3a4: Fix tool calling args for mcp server to ensure validatedArgs are not undefined
8
+ - ab3bbff: Add support for extra arguments in mcp
9
+ - c0ba5e2: Handle json schema with $defs and $ref property for MCP tool schemas.
10
+ - cb16baf: Fix MCP tool output schema type and return value
11
+ - Updated dependencies [2873c7f]
12
+ - Updated dependencies [1c1c6a1]
13
+ - Updated dependencies [f8ce2cc]
14
+ - Updated dependencies [8c846b6]
15
+ - Updated dependencies [c7bbf1e]
16
+ - Updated dependencies [8722d53]
17
+ - Updated dependencies [565cc0c]
18
+ - Updated dependencies [b790fd1]
19
+ - Updated dependencies [132027f]
20
+ - Updated dependencies [0c85311]
21
+ - Updated dependencies [d7ed04d]
22
+ - Updated dependencies [cb16baf]
23
+ - Updated dependencies [f36e4f1]
24
+ - Updated dependencies [7f6e403]
25
+ - @mastra/core@0.10.11
26
+
27
+ ## 0.10.6-alpha.1
28
+
29
+ ### Patch Changes
30
+
31
+ - c0ba5e2: Handle json schema with $defs and $ref property for MCP tool schemas.
32
+ - cb16baf: Fix MCP tool output schema type and return value
33
+ - Updated dependencies [c7bbf1e]
34
+ - Updated dependencies [8722d53]
35
+ - Updated dependencies [132027f]
36
+ - Updated dependencies [0c85311]
37
+ - Updated dependencies [cb16baf]
38
+ - @mastra/core@0.10.11-alpha.3
39
+
3
40
  ## 0.10.6-alpha.0
4
41
 
5
42
  ### Patch Changes
package/LICENSE.md CHANGED
@@ -1,46 +1,15 @@
1
- # Elastic License 2.0 (ELv2)
1
+ # Apache License 2.0
2
2
 
3
- Copyright (c) 2025 Mastra AI, Inc.
3
+ Copyright (c) 2025 Kepler Software, Inc.
4
4
 
5
- **Acceptance**
6
- By using the software, you agree to all of the terms and conditions below.
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
7
8
 
8
- **Copyright License**
9
- The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
10
 
11
- **Limitations**
12
- You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
13
-
14
- You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key.
15
-
16
- You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
17
-
18
- **Patents**
19
- The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
20
-
21
- **Notices**
22
- You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
23
-
24
- If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
25
-
26
- **No Other Rights**
27
- These terms do not imply any licenses other than those expressly granted in these terms.
28
-
29
- **Termination**
30
- If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
31
-
32
- **No Liability**
33
- As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
34
-
35
- **Definitions**
36
- The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it.
37
-
38
- _you_ refers to the individual or entity agreeing to these terms.
39
-
40
- _your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
41
-
42
- _your licenses_ are all the licenses granted to you for the software under these terms.
43
-
44
- _use_ means anything you do with the software requiring one of your licenses.
45
-
46
- _trademark_ means trademarks, service marks, and similar rights.
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
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
6
  var tools = require('@mastra/core/tools');
@@ -26,6 +27,7 @@ var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp
26
27
 
27
28
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
28
29
 
30
+ var $RefParser__default = /*#__PURE__*/_interopDefault($RefParser);
29
31
  var equal__default = /*#__PURE__*/_interopDefault(equal);
30
32
 
31
33
  // src/client/client.ts
@@ -504,11 +506,12 @@ var InternalMastraMCPClient = class extends base.MastraBase {
504
506
  return handler(request.params);
505
507
  });
506
508
  }
507
- convertInputSchema(inputSchema) {
509
+ async convertInputSchema(inputSchema) {
508
510
  if (utils.isZodType(inputSchema)) {
509
511
  return inputSchema;
510
512
  }
511
513
  try {
514
+ await $RefParser__default.default.dereference(inputSchema);
512
515
  return zodFromJsonSchema.convertJsonSchemaToZod(inputSchema);
513
516
  } catch (error$1) {
514
517
  let errorDetails;
@@ -533,12 +536,13 @@ var InternalMastraMCPClient = class extends base.MastraBase {
533
536
  });
534
537
  }
535
538
  }
536
- convertOutputSchema(outputSchema) {
539
+ async convertOutputSchema(outputSchema) {
537
540
  if (!outputSchema) return;
538
541
  if (utils.isZodType(outputSchema)) {
539
542
  return outputSchema;
540
543
  }
541
544
  try {
545
+ await $RefParser__default.default.dereference(outputSchema);
542
546
  return zodFromJsonSchema.convertJsonSchemaToZod(outputSchema);
543
547
  } catch (error$1) {
544
548
  let errorDetails;
@@ -567,14 +571,14 @@ var InternalMastraMCPClient = class extends base.MastraBase {
567
571
  this.log("debug", `Requesting tools from MCP server`);
568
572
  const { tools: tools$1 } = await this.client.listTools({ timeout: this.timeout });
569
573
  const toolsRes = {};
570
- tools$1.forEach((tool) => {
574
+ for (const tool of tools$1) {
571
575
  this.log("debug", `Processing tool: ${tool.name}`);
572
576
  try {
573
577
  const mastraTool = tools.createTool({
574
578
  id: `${this.name}_${tool.name}`,
575
579
  description: tool.description || "",
576
- inputSchema: this.convertInputSchema(tool.inputSchema),
577
- outputSchema: this.convertOutputSchema(tool.outputSchema),
580
+ inputSchema: await this.convertInputSchema(tool.inputSchema),
581
+ outputSchema: await this.convertOutputSchema(tool.outputSchema),
578
582
  execute: async ({ context, runtimeContext }) => {
579
583
  const previousContext = this.currentOperationContext;
580
584
  this.currentOperationContext = runtimeContext || null;
@@ -612,7 +616,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
612
616
  mcpToolDefinition: tool
613
617
  });
614
618
  }
615
- });
619
+ }
616
620
  return toolsRes;
617
621
  }
618
622
  };
@@ -1567,10 +1571,13 @@ var MCPServer = class extends mcp.MCPServerBase {
1567
1571
  this.logger.info(`Tool '${request.params.name}' executed successfully in ${duration}ms.`);
1568
1572
  const response = { isError: false, content: [] };
1569
1573
  if (tool.outputSchema) {
1570
- if (!result.structuredContent) {
1571
- throw new Error(`Tool ${request.params.name} has an output schema but no structured content was provided.`);
1574
+ let structuredContent;
1575
+ if (result && typeof result === "object" && "structuredContent" in result) {
1576
+ structuredContent = result.structuredContent;
1577
+ } else {
1578
+ structuredContent = result;
1572
1579
  }
1573
- const outputValidation = tool.outputSchema.validate?.(result.structuredContent ?? {});
1580
+ const outputValidation = tool.outputSchema.validate?.(structuredContent ?? {});
1574
1581
  if (outputValidation && !outputValidation.success) {
1575
1582
  this.logger.warn(`CallTool: Invalid structured content for '${request.params.name}'`, {
1576
1583
  errors: outputValidation.error
@@ -1579,7 +1586,7 @@ var MCPServer = class extends mcp.MCPServerBase {
1579
1586
  `Invalid structured content for tool ${request.params.name}: ${JSON.stringify(outputValidation.error)}`
1580
1587
  );
1581
1588
  }
1582
- response.structuredContent = result.structuredContent;
1589
+ response.structuredContent = structuredContent;
1583
1590
  }
1584
1591
  if (response.structuredContent) {
1585
1592
  response.content = [{ type: "text", text: JSON.stringify(response.structuredContent) }];
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import $RefParser from '@apidevtools/json-schema-ref-parser';
1
2
  import { MastraBase } from '@mastra/core/base';
2
3
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
4
  import { createTool as createTool$1 } from '@mastra/core/tools';
@@ -498,11 +499,12 @@ var InternalMastraMCPClient = class extends MastraBase {
498
499
  return handler(request.params);
499
500
  });
500
501
  }
501
- convertInputSchema(inputSchema) {
502
+ async convertInputSchema(inputSchema) {
502
503
  if (isZodType(inputSchema)) {
503
504
  return inputSchema;
504
505
  }
505
506
  try {
507
+ await $RefParser.dereference(inputSchema);
506
508
  return convertJsonSchemaToZod(inputSchema);
507
509
  } catch (error) {
508
510
  let errorDetails;
@@ -527,12 +529,13 @@ var InternalMastraMCPClient = class extends MastraBase {
527
529
  });
528
530
  }
529
531
  }
530
- convertOutputSchema(outputSchema) {
532
+ async convertOutputSchema(outputSchema) {
531
533
  if (!outputSchema) return;
532
534
  if (isZodType(outputSchema)) {
533
535
  return outputSchema;
534
536
  }
535
537
  try {
538
+ await $RefParser.dereference(outputSchema);
536
539
  return convertJsonSchemaToZod(outputSchema);
537
540
  } catch (error) {
538
541
  let errorDetails;
@@ -561,14 +564,14 @@ var InternalMastraMCPClient = class extends MastraBase {
561
564
  this.log("debug", `Requesting tools from MCP server`);
562
565
  const { tools } = await this.client.listTools({ timeout: this.timeout });
563
566
  const toolsRes = {};
564
- tools.forEach((tool) => {
567
+ for (const tool of tools) {
565
568
  this.log("debug", `Processing tool: ${tool.name}`);
566
569
  try {
567
570
  const mastraTool = createTool$1({
568
571
  id: `${this.name}_${tool.name}`,
569
572
  description: tool.description || "",
570
- inputSchema: this.convertInputSchema(tool.inputSchema),
571
- outputSchema: this.convertOutputSchema(tool.outputSchema),
573
+ inputSchema: await this.convertInputSchema(tool.inputSchema),
574
+ outputSchema: await this.convertOutputSchema(tool.outputSchema),
572
575
  execute: async ({ context, runtimeContext }) => {
573
576
  const previousContext = this.currentOperationContext;
574
577
  this.currentOperationContext = runtimeContext || null;
@@ -606,7 +609,7 @@ var InternalMastraMCPClient = class extends MastraBase {
606
609
  mcpToolDefinition: tool
607
610
  });
608
611
  }
609
- });
612
+ }
610
613
  return toolsRes;
611
614
  }
612
615
  };
@@ -1561,10 +1564,13 @@ var MCPServer = class extends MCPServerBase {
1561
1564
  this.logger.info(`Tool '${request.params.name}' executed successfully in ${duration}ms.`);
1562
1565
  const response = { isError: false, content: [] };
1563
1566
  if (tool.outputSchema) {
1564
- if (!result.structuredContent) {
1565
- throw new Error(`Tool ${request.params.name} has an output schema but no structured content was provided.`);
1567
+ let structuredContent;
1568
+ if (result && typeof result === "object" && "structuredContent" in result) {
1569
+ structuredContent = result.structuredContent;
1570
+ } else {
1571
+ structuredContent = result;
1566
1572
  }
1567
- const outputValidation = tool.outputSchema.validate?.(result.structuredContent ?? {});
1573
+ const outputValidation = tool.outputSchema.validate?.(structuredContent ?? {});
1568
1574
  if (outputValidation && !outputValidation.success) {
1569
1575
  this.logger.warn(`CallTool: Invalid structured content for '${request.params.name}'`, {
1570
1576
  errors: outputValidation.error
@@ -1573,7 +1579,7 @@ var MCPServer = class extends MCPServerBase {
1573
1579
  `Invalid structured content for tool ${request.params.name}: ${JSON.stringify(outputValidation.error)}`
1574
1580
  );
1575
1581
  }
1576
- response.structuredContent = result.structuredContent;
1582
+ response.structuredContent = structuredContent;
1577
1583
  }
1578
1584
  if (response.structuredContent) {
1579
1585
  response.content = [{ type: "text", text: JSON.stringify(response.structuredContent) }];
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp",
3
- "version": "0.10.6-alpha.0",
3
+ "version": "0.10.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,8 +20,9 @@
20
20
  },
21
21
  "keywords": [],
22
22
  "author": "",
23
- "license": "Elastic-2.0",
23
+ "license": "Apache-2.0",
24
24
  "dependencies": {
25
+ "@apidevtools/json-schema-ref-parser": "^14.1.0",
25
26
  "@modelcontextprotocol/sdk": "^1.13.0",
26
27
  "date-fns": "^4.1.0",
27
28
  "exit-hook": "^4.0.0",
@@ -50,8 +51,8 @@
50
51
  "vitest": "^3.2.4",
51
52
  "zod": "^3.25.67",
52
53
  "zod-to-json-schema": "^3.24.5",
53
- "@internal/lint": "0.0.17",
54
- "@mastra/core": "0.10.11-alpha.2"
54
+ "@internal/lint": "0.0.18",
55
+ "@mastra/core": "0.10.11"
55
56
  },
56
57
  "scripts": {
57
58
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
@@ -1,5 +1,5 @@
1
+ import $RefParser from '@apidevtools/json-schema-ref-parser';
1
2
  import { MastraBase } from '@mastra/core/base';
2
-
3
3
  import type { RuntimeContext } from '@mastra/core/di';
4
4
  import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
5
5
  import { createTool } from '@mastra/core/tools';
@@ -468,15 +468,16 @@ export class InternalMastraMCPClient extends MastraBase {
468
468
  return handler(request.params);
469
469
  });
470
470
  }
471
-
472
- private convertInputSchema(
471
+
472
+ private async convertInputSchema(
473
473
  inputSchema: Awaited<ReturnType<Client['listTools']>>['tools'][0]['inputSchema'] | JSONSchema,
474
- ): z.ZodType {
474
+ ): Promise<z.ZodType> {
475
475
  if (isZodType(inputSchema)) {
476
476
  return inputSchema;
477
477
  }
478
478
 
479
479
  try {
480
+ await $RefParser.dereference(inputSchema)
480
481
  return convertJsonSchemaToZod(inputSchema as JSONSchema);
481
482
  } catch (error: unknown) {
482
483
  let errorDetails: string | undefined;
@@ -504,15 +505,16 @@ export class InternalMastraMCPClient extends MastraBase {
504
505
  }
505
506
  }
506
507
 
507
- private convertOutputSchema(
508
+ private async convertOutputSchema(
508
509
  outputSchema: Awaited<ReturnType<Client['listTools']>>['tools'][0]['outputSchema'] | JSONSchema,
509
- ): z.ZodType | undefined {
510
+ ): Promise<z.ZodType | undefined> {
510
511
  if (!outputSchema) return
511
512
  if (isZodType(outputSchema)) {
512
513
  return outputSchema;
513
514
  }
514
515
 
515
516
  try {
517
+ await $RefParser.dereference(outputSchema)
516
518
  return convertJsonSchemaToZod(outputSchema as JSONSchema);
517
519
  } catch (error: unknown) {
518
520
  let errorDetails: string | undefined;
@@ -544,14 +546,14 @@ export class InternalMastraMCPClient extends MastraBase {
544
546
  this.log('debug', `Requesting tools from MCP server`);
545
547
  const { tools } = await this.client.listTools({ timeout: this.timeout });
546
548
  const toolsRes: Record<string, any> = {};
547
- tools.forEach(tool => {
549
+ for (const tool of tools) {
548
550
  this.log('debug', `Processing tool: ${tool.name}`);
549
551
  try {
550
552
  const mastraTool = createTool({
551
553
  id: `${this.name}_${tool.name}`,
552
554
  description: tool.description || '',
553
- inputSchema: this.convertInputSchema(tool.inputSchema),
554
- outputSchema: this.convertOutputSchema(tool.outputSchema),
555
+ inputSchema: await this.convertInputSchema(tool.inputSchema),
556
+ outputSchema: await this.convertOutputSchema(tool.outputSchema),
555
557
  execute: async ({ context, runtimeContext }: { context: any; runtimeContext?: RuntimeContext | null }) => {
556
558
  const previousContext = this.currentOperationContext;
557
559
  this.currentOperationContext = runtimeContext || null; // Set current context
@@ -592,7 +594,7 @@ export class InternalMastraMCPClient extends MastraBase {
592
594
  mcpToolDefinition: tool,
593
595
  });
594
596
  }
595
- });
597
+ }
596
598
 
597
599
  return toolsRes;
598
600
  }
@@ -1789,10 +1789,8 @@ describe('MCPServer with Tool Output Schema', () => {
1789
1789
  timestamp: z.string(),
1790
1790
  }),
1791
1791
  execute: async ({ input }: { input: string }) => ({
1792
- structuredContent: {
1793
- processedInput: `processed: ${input}`,
1794
- timestamp: mockDateISO,
1795
- },
1792
+ processedInput: `processed: ${input}`,
1793
+ timestamp: mockDateISO,
1796
1794
  }),
1797
1795
  },
1798
1796
  };
@@ -282,10 +282,17 @@ export class MCPServer extends MCPServerBase {
282
282
  const response: CallToolResult = { isError: false, content: [] };
283
283
 
284
284
  if (tool.outputSchema) {
285
- if (!result.structuredContent) {
286
- throw new Error(`Tool ${request.params.name} has an output schema but no structured content was provided.`);
285
+ // Handle both cases: tools that return { structuredContent: ... } and tools that return the plain object
286
+ let structuredContent;
287
+ if (result && typeof result === 'object' && 'structuredContent' in result) {
288
+ // Tool returned { structuredContent: ... } format (MCP-aware tool)
289
+ structuredContent = result.structuredContent;
290
+ } else {
291
+ // Tool returned plain object, wrap it automatically for backward compatibility
292
+ structuredContent = result;
287
293
  }
288
- const outputValidation = tool.outputSchema.validate?.(result.structuredContent ?? {});
294
+
295
+ const outputValidation = tool.outputSchema.validate?.(structuredContent ?? {});
289
296
  if (outputValidation && !outputValidation.success) {
290
297
  this.logger.warn(`CallTool: Invalid structured content for '${request.params.name}'`, {
291
298
  errors: outputValidation.error,
@@ -294,7 +301,7 @@ export class MCPServer extends MCPServerBase {
294
301
  `Invalid structured content for tool ${request.params.name}: ${JSON.stringify(outputValidation.error)}`,
295
302
  );
296
303
  }
297
- response.structuredContent = result.structuredContent;
304
+ response.structuredContent = structuredContent;
298
305
  }
299
306
 
300
307
  if (response.structuredContent) {