@mastra/mcp 0.10.10 → 0.10.11-alpha.0

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 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp",
3
- "version": "0.10.10",
3
+ "version": "0.10.11-alpha.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,9 +51,9 @@
51
51
  "vitest": "^3.2.4",
52
52
  "zod": "^3.25.67",
53
53
  "zod-to-json-schema": "^3.24.5",
54
- "@internal/types-builder": "0.0.2",
55
- "@mastra/core": "0.13.0",
56
- "@internal/lint": "0.0.27"
54
+ "@mastra/core": "0.13.2-alpha.2",
55
+ "@internal/types-builder": "0.0.3",
56
+ "@internal/lint": "0.0.28"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsup --silent --config tsup.config.ts",
@@ -169,7 +169,6 @@ export class InternalMastraMCPClient extends MastraBase {
169
169
  // Set up log message capturing
170
170
  this.setupLogging();
171
171
 
172
-
173
172
  this.resources = new ResourceClientActions({ client: this, logger: this.logger });
174
173
  this.prompts = new PromptClientActions({ client: this, logger: this.logger });
175
174
  this.elicitation = new ElicitationClientActions({ client: this, logger: this.logger });
@@ -318,7 +317,6 @@ export class InternalMastraMCPClient extends MastraBase {
318
317
  originalOnClose();
319
318
  }
320
319
  };
321
-
322
320
  } catch (e) {
323
321
  this.isConnected = null;
324
322
  reject(e);
@@ -466,12 +464,12 @@ export class InternalMastraMCPClient extends MastraBase {
466
464
 
467
465
  setElicitationRequestHandler(handler: ElicitationHandler): void {
468
466
  this.log('debug', 'Setting elicitation request handler');
469
- this.client.setRequestHandler(ElicitRequestSchema, async (request) => {
467
+ this.client.setRequestHandler(ElicitRequestSchema, async request => {
470
468
  this.log('debug', `Received elicitation request: ${request.params.message}`);
471
469
  return handler(request.params);
472
470
  });
473
471
  }
474
-
472
+
475
473
  private async convertInputSchema(
476
474
  inputSchema: Awaited<ReturnType<Client['listTools']>>['tools'][0]['inputSchema'] | JSONSchema,
477
475
  ): Promise<z.ZodType> {
@@ -480,7 +478,7 @@ export class InternalMastraMCPClient extends MastraBase {
480
478
  }
481
479
 
482
480
  try {
483
- await $RefParser.dereference(inputSchema)
481
+ await $RefParser.dereference(inputSchema);
484
482
  return convertJsonSchemaToZod(inputSchema as JSONSchema);
485
483
  } catch (error: unknown) {
486
484
  let errorDetails: string | undefined;
@@ -511,13 +509,13 @@ export class InternalMastraMCPClient extends MastraBase {
511
509
  private async convertOutputSchema(
512
510
  outputSchema: Awaited<ReturnType<Client['listTools']>>['tools'][0]['outputSchema'] | JSONSchema,
513
511
  ): Promise<z.ZodType | undefined> {
514
- if (!outputSchema) return
512
+ if (!outputSchema) return;
515
513
  if (isZodType(outputSchema)) {
516
514
  return outputSchema;
517
515
  }
518
516
 
519
517
  try {
520
- await $RefParser.dereference(outputSchema)
518
+ await $RefParser.dereference(outputSchema);
521
519
  return convertJsonSchemaToZod(outputSchema as JSONSchema);
522
520
  } catch (error: unknown) {
523
521
  let errorDetails: string | undefined;
@@ -1347,7 +1347,7 @@ describe('MCPServer - Workflow to Tool Conversion', () => {
1347
1347
  });
1348
1348
 
1349
1349
  it('should call workflow.createRun().start() when the derived tool is executed', async () => {
1350
- const testWorkflow = createMockWorkflow('MyExecWorkflow', 'Executable workflow');
1350
+ const testWorkflow = createMockWorkflow('MyExecWorkflow', 'Executable workflow', z.object({ data: z.string() }));
1351
1351
  const step = createStep({
1352
1352
  id: 'my-step',
1353
1353
  description: 'My step description',
@@ -1855,3 +1855,288 @@ describe('MCPServer with Tool Output Schema', () => {
1855
1855
  expect(JSON.parse(result.content[0].text)).toEqual(result.structuredContent);
1856
1856
  });
1857
1857
  });
1858
+
1859
+ describe('MCPServer - Tool Input Validation', () => {
1860
+ let validationServer: MCPServer;
1861
+ let validationClient: InternalMastraMCPClient;
1862
+ let httpValidationServer: ServerType;
1863
+ let tools: Record<string, any>;
1864
+ const VALIDATION_PORT = 9700 + Math.floor(Math.random() * 100);
1865
+
1866
+ const toolsWithValidation: ToolsInput = {
1867
+ stringTool: {
1868
+ description: 'Tool that requires a string input',
1869
+ parameters: z.object({
1870
+ message: z.string().min(3, 'Message must be at least 3 characters'),
1871
+ optional: z.string().optional(),
1872
+ }),
1873
+ execute: async args => ({
1874
+ result: `Received: ${args.message}`,
1875
+ }),
1876
+ },
1877
+ numberTool: {
1878
+ description: 'Tool that requires number inputs',
1879
+ parameters: z.object({
1880
+ age: z.number().min(0).max(150),
1881
+ score: z.number().optional(),
1882
+ }),
1883
+ execute: async args => ({
1884
+ result: `Age: ${args.age}, Score: ${args.score ?? 'N/A'}`,
1885
+ }),
1886
+ },
1887
+ complexTool: {
1888
+ description: 'Tool with complex validation',
1889
+ parameters: z.object({
1890
+ email: z.string().email('Invalid email format'),
1891
+ tags: z.array(z.string()).min(1, 'At least one tag required'),
1892
+ metadata: z.object({
1893
+ priority: z.enum(['low', 'medium', 'high']),
1894
+ deadline: z.string().datetime().optional(),
1895
+ }),
1896
+ }),
1897
+ execute: async args => ({
1898
+ result: `Processing ${args.email} with ${args.tags.length} tags`,
1899
+ }),
1900
+ },
1901
+ };
1902
+
1903
+ beforeAll(async () => {
1904
+ const app = new Hono();
1905
+ validationServer = new MCPServer({
1906
+ name: 'ValidationTestServer',
1907
+ version: '1.0.0',
1908
+ description: 'Server for testing tool validation',
1909
+ tools: toolsWithValidation,
1910
+ });
1911
+
1912
+ app.get('/sse', async c => {
1913
+ const url = new URL(c.req.url, `http://localhost:${VALIDATION_PORT}`);
1914
+ return await validationServer.startHonoSSE({
1915
+ url,
1916
+ ssePath: '/sse',
1917
+ messagePath: '/message',
1918
+ context: c,
1919
+ });
1920
+ });
1921
+
1922
+ app.post('/message', async c => {
1923
+ const url = new URL(c.req.url, `http://localhost:${VALIDATION_PORT}`);
1924
+ return await validationServer.startHonoSSE({
1925
+ url,
1926
+ ssePath: '/sse',
1927
+ messagePath: '/message',
1928
+ context: c,
1929
+ });
1930
+ });
1931
+
1932
+ httpValidationServer = serve({
1933
+ fetch: app.fetch,
1934
+ port: VALIDATION_PORT,
1935
+ });
1936
+
1937
+ validationClient = new InternalMastraMCPClient({
1938
+ name: 'validation-test-client',
1939
+ server: { url: new URL(`http://localhost:${VALIDATION_PORT}/sse`) },
1940
+ });
1941
+
1942
+ await validationClient.connect();
1943
+ tools = await validationClient.tools();
1944
+ });
1945
+
1946
+ afterAll(async () => {
1947
+ await validationClient.disconnect();
1948
+ httpValidationServer.close();
1949
+ });
1950
+
1951
+ it('should successfully execute tool with valid inputs', async () => {
1952
+ const stringTool = tools['stringTool'];
1953
+ expect(stringTool).toBeDefined();
1954
+
1955
+ const result = await stringTool.execute({
1956
+ context: {
1957
+ message: 'Hello world',
1958
+ optional: 'optional value',
1959
+ },
1960
+ });
1961
+
1962
+ expect(result).toBeDefined();
1963
+ expect(result.content[0].text).toContain('Received: Hello world');
1964
+ });
1965
+
1966
+ it('should return validation error for missing required parameters', async () => {
1967
+ const stringTool = tools['stringTool'];
1968
+ const result = await stringTool.execute({
1969
+ context: {},
1970
+ });
1971
+
1972
+ expect(result).toBeDefined();
1973
+ // Handle both client-side and server-side error formats
1974
+ if (result.error) {
1975
+ expect(result.error).toBe(true);
1976
+ expect(result.message).toContain('Tool validation failed');
1977
+ expect(result.message).toContain('Please fix the following errors');
1978
+ } else {
1979
+ expect(result.isError).toBe(true);
1980
+ expect(result.content[0].text).toContain('Tool validation failed');
1981
+ expect(result.content[0].text).toContain('Please fix the following errors');
1982
+ }
1983
+ });
1984
+
1985
+ it('should return validation error for invalid string length', async () => {
1986
+ const stringTool = tools['stringTool'];
1987
+ const result = await stringTool.execute({
1988
+ context: {
1989
+ message: 'Hi', // Too short, min is 3
1990
+ },
1991
+ });
1992
+
1993
+ expect(result).toBeDefined();
1994
+ // Handle both client-side and server-side error formats
1995
+ if (result.error) {
1996
+ expect(result.error).toBe(true);
1997
+ expect(result.message).toContain('Tool validation failed');
1998
+ expect(result.message).toContain('String must contain at least 3 character(s)');
1999
+ } else {
2000
+ expect(result.isError).toBe(true);
2001
+ expect(result.content[0].text).toContain('Tool validation failed');
2002
+ expect(result.content[0].text).toContain('Message must be at least 3 characters');
2003
+ }
2004
+ });
2005
+
2006
+ it('should return validation error for invalid number range', async () => {
2007
+ const numberTool = tools['numberTool'];
2008
+ const result = await numberTool.execute({
2009
+ context: {
2010
+ age: -5, // Negative age not allowed
2011
+ },
2012
+ });
2013
+
2014
+ expect(result).toBeDefined();
2015
+ // Handle both client-side and server-side error formats
2016
+ if (result.error) {
2017
+ expect(result.error).toBe(true);
2018
+ expect(result.message).toContain('Tool validation failed');
2019
+ } else {
2020
+ expect(result.isError).toBe(true);
2021
+ expect(result.content[0].text).toContain('Tool validation failed');
2022
+ }
2023
+ });
2024
+
2025
+ it('should return validation error for invalid email format', async () => {
2026
+ const complexTool = tools['complexTool'];
2027
+ const result = await complexTool.execute({
2028
+ context: {
2029
+ email: 'not-an-email',
2030
+ tags: ['tag1'],
2031
+ metadata: {
2032
+ priority: 'medium',
2033
+ },
2034
+ },
2035
+ });
2036
+
2037
+ expect(result).toBeDefined();
2038
+ expect(result.isError).toBe(true);
2039
+ expect(result.content[0].text).toContain('Tool validation failed');
2040
+ expect(result.content[0].text).toContain('Invalid email format');
2041
+ });
2042
+
2043
+ it('should return validation error for empty array when minimum required', async () => {
2044
+ const complexTool = tools['complexTool'];
2045
+ const result = await complexTool.execute({
2046
+ context: {
2047
+ email: 'test@example.com',
2048
+ tags: [], // Empty array, min 1 required
2049
+ metadata: {
2050
+ priority: 'low',
2051
+ },
2052
+ },
2053
+ });
2054
+
2055
+ expect(result).toBeDefined();
2056
+ // Handle both client-side and server-side error formats
2057
+ if (result.error) {
2058
+ expect(result.error).toBe(true);
2059
+ expect(result.message).toContain('Tool validation failed');
2060
+ expect(result.message).toContain('Array must contain at least 1 element(s)');
2061
+ } else {
2062
+ expect(result.isError).toBe(true);
2063
+ expect(result.content[0].text).toContain('Tool validation failed');
2064
+ expect(result.content[0].text).toContain('Array must contain at least 1 element(s)');
2065
+ }
2066
+ });
2067
+
2068
+ it('should return validation error for invalid enum value', async () => {
2069
+ const complexTool = tools['complexTool'];
2070
+ const result = await complexTool.execute({
2071
+ context: {
2072
+ email: 'test@example.com',
2073
+ tags: ['tag1'],
2074
+ metadata: {
2075
+ priority: 'urgent', // Not in enum ['low', 'medium', 'high']
2076
+ },
2077
+ },
2078
+ });
2079
+
2080
+ expect(result).toBeDefined();
2081
+ // Handle both client-side and server-side error formats
2082
+ if (result.error) {
2083
+ expect(result.error).toBe(true);
2084
+ expect(result.message).toContain('Tool validation failed');
2085
+ } else {
2086
+ expect(result.isError).toBe(true);
2087
+ expect(result.content[0].text).toContain('Tool validation failed');
2088
+ }
2089
+ });
2090
+
2091
+ it('should handle multiple validation errors', async () => {
2092
+ const complexTool = tools['complexTool'];
2093
+ const result = await complexTool.execute({
2094
+ context: {
2095
+ email: 'invalid-email',
2096
+ tags: [],
2097
+ metadata: {
2098
+ priority: 'invalid',
2099
+ },
2100
+ },
2101
+ });
2102
+
2103
+ expect(result).toBeDefined();
2104
+ // Handle both client-side and server-side error formats
2105
+ if (result.error) {
2106
+ expect(result.error).toBe(true);
2107
+ const errorText = result.message;
2108
+ expect(errorText).toContain('Tool validation failed');
2109
+ // Should contain multiple validation errors
2110
+ // Note: Some validations might not trigger when there are other errors
2111
+ expect(errorText).toContain('- tags: Array must contain at least 1 element(s)');
2112
+ expect(errorText).toContain('Provided arguments:');
2113
+ } else {
2114
+ expect(result.isError).toBe(true);
2115
+ const errorText = result.content[0].text;
2116
+ expect(errorText).toContain('Tool validation failed');
2117
+ // Should contain multiple validation errors
2118
+ // Note: Some validations might not trigger when there are other errors
2119
+ expect(errorText).toContain('- tags: Array must contain at least 1 element(s)');
2120
+ expect(errorText).toContain('Provided arguments:');
2121
+ }
2122
+ });
2123
+
2124
+ it('should work with executeTool method directly', async () => {
2125
+ // Test valid input
2126
+ const validResult = await validationServer.executeTool('stringTool', {
2127
+ message: 'Valid message',
2128
+ });
2129
+ // executeTool returns result directly, not in MCP format
2130
+ expect(validResult.result).toBe('Received: Valid message');
2131
+
2132
+ // Test invalid input - should return validation error (not throw)
2133
+ const invalidResult = await validationServer.executeTool('stringTool', {
2134
+ message: 'No', // Too short
2135
+ });
2136
+
2137
+ // executeTool returns client-side validation format
2138
+ expect(invalidResult.error).toBe(true);
2139
+ expect(invalidResult.message).toContain('Tool validation failed');
2140
+ expect(invalidResult.message).toContain('Message must be at least 3 characters');
2141
+ });
2142
+ });
@@ -248,9 +248,25 @@ export class MCPServer extends MCPServerBase {
248
248
  this.logger.warn(`CallTool: Invalid tool arguments for '${request.params.name}'`, {
249
249
  errors: validation.error,
250
250
  });
251
+
252
+ // Format validation errors for agent understanding
253
+ let errorMessages = 'Validation failed';
254
+ if ('errors' in validation.error && Array.isArray(validation.error.errors)) {
255
+ errorMessages = validation.error.errors
256
+ .map((e: any) => `- ${e.path?.join('.') || 'root'}: ${e.message}`)
257
+ .join('\n');
258
+ } else if (validation.error instanceof Error) {
259
+ errorMessages = validation.error.message;
260
+ }
261
+
251
262
  return {
252
- content: [{ type: 'text', text: `Invalid tool arguments: ${JSON.stringify(validation.error)}` }],
253
- isError: true,
263
+ content: [
264
+ {
265
+ type: 'text',
266
+ text: `Tool validation failed. Please fix the following errors and try again:\n${errorMessages}\n\nProvided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`,
267
+ },
268
+ ],
269
+ isError: true, // Set to true so the LLM sees the error and can self-correct
254
270
  };
255
271
  }
256
272
  if (!tool.execute) {
@@ -268,7 +284,7 @@ export class MCPServer extends MCPServerBase {
268
284
  },
269
285
  };
270
286
 
271
- const result = await tool.execute(validation?.value, {
287
+ const result = await tool.execute(validation?.value ?? request.params.arguments ?? {}, {
272
288
  messages: [],
273
289
  toolCallId: '',
274
290
  elicitation: sessionElicitation,
@@ -1356,12 +1372,17 @@ export class MCPServer extends MCPServerBase {
1356
1372
  const validation = tool.parameters.safeParse(args ?? {});
1357
1373
  if (!validation.success) {
1358
1374
  const errorMessages = validation.error.errors
1359
- .map((e: z.ZodIssue) => `${e.path.join('.')}: ${e.message}`)
1360
- .join(', ');
1375
+ .map((e: z.ZodIssue) => `- ${e.path?.join('.') || 'root'}: ${e.message}`)
1376
+ .join('\n');
1361
1377
  this.logger.warn(`ExecuteTool: Invalid tool arguments for '${toolId}': ${errorMessages}`, {
1362
1378
  errors: validation.error.format(),
1363
1379
  });
1364
- throw new z.ZodError(validation.error.issues);
1380
+ // Return validation error as a result instead of throwing
1381
+ return {
1382
+ error: true,
1383
+ message: `Tool validation failed. Please fix the following errors and try again:\n${errorMessages}\n\nProvided arguments: ${JSON.stringify(args, null, 2)}`,
1384
+ validationErrors: validation.error.format(),
1385
+ };
1365
1386
  }
1366
1387
  validatedArgs = validation.data;
1367
1388
  } else {
@@ -1,21 +0,0 @@
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