@mastra/mcp 1.1.0 → 1.2.0-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.
- package/CHANGELOG.md +28 -0
- package/dist/client/actions/progress.d.ts +2 -3
- package/dist/client/actions/progress.d.ts.map +1 -1
- package/dist/client/actions/resource.d.ts +6 -2
- package/dist/client/actions/resource.d.ts.map +1 -1
- package/dist/client/client.d.ts +171 -175
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +6 -2
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/types.d.ts +17 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/docs/SKILL.md +3 -3
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-mcp-overview.md +1 -1
- package/dist/docs/references/docs-mcp-publishing-mcp-server.md +4 -4
- package/dist/docs/references/reference-tools-mcp-client.md +13 -13
- package/dist/docs/references/reference-tools-mcp-server.md +27 -27
- package/dist/index.cjs +62 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +63 -90
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +10 -11
- package/dist/__fixtures__/fire-crawl-complex-schema.d.ts +0 -5
- package/dist/__fixtures__/fire-crawl-complex-schema.d.ts.map +0 -1
- package/dist/__fixtures__/server-weather.d.ts +0 -2
- package/dist/__fixtures__/server-weather.d.ts.map +0 -1
- package/dist/__fixtures__/stock-price.d.ts +0 -26
- package/dist/__fixtures__/stock-price.d.ts.map +0 -1
- package/dist/__fixtures__/tools.d.ts +0 -12
- package/dist/__fixtures__/tools.d.ts.map +0 -1
- package/dist/__fixtures__/weather.d.ts +0 -4
- package/dist/__fixtures__/weather.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,22 +3,20 @@ import $RefParser from '@apidevtools/json-schema-ref-parser';
|
|
|
3
3
|
import { MastraBase } from '@mastra/core/base';
|
|
4
4
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
5
5
|
import { createTool } from '@mastra/core/tools';
|
|
6
|
-
import { isZodType, makeCoreTool } from '@mastra/core/utils';
|
|
7
6
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
8
7
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
9
8
|
import { StdioClientTransport, getDefaultEnvironment } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
10
9
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
11
10
|
import { DEFAULT_REQUEST_TIMEOUT_MSEC } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
12
|
-
import { ListRootsRequestSchema, ListResourcesResultSchema, ReadResourceResultSchema, ListResourceTemplatesResultSchema, ListPromptsResultSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ResourceUpdatedNotificationSchema, ResourceListChangedNotificationSchema, ElicitRequestSchema, ProgressNotificationSchema, ListToolsRequestSchema, CallToolRequestSchema, SetLevelRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, ListPromptsRequestSchema, PromptSchema, GetPromptRequestSchema, CallToolResultSchema, ErrorCode, JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
+
import { LoggingMessageNotificationSchema, ListRootsRequestSchema, ListResourcesResultSchema, ReadResourceResultSchema, EmptyResultSchema, ListResourceTemplatesResultSchema, ListPromptsResultSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ResourceUpdatedNotificationSchema, ResourceListChangedNotificationSchema, ElicitRequestSchema, ProgressNotificationSchema, ListToolsRequestSchema, CallToolRequestSchema, SetLevelRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema, ListPromptsRequestSchema, PromptSchema, GetPromptRequestSchema, CallToolResultSchema, ErrorCode, JSONRPCMessageSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
13
12
|
import { asyncExitHook, gracefulExit } from 'exit-hook';
|
|
14
|
-
import { z } from 'zod';
|
|
15
|
-
import { convertJsonSchemaToZod } from 'zod-from-json-schema';
|
|
16
|
-
import { convertJsonSchemaToZod as convertJsonSchemaToZod$1 } from 'zod-from-json-schema-v3';
|
|
17
13
|
import equal from 'fast-deep-equal';
|
|
18
14
|
import { v5 } from 'uuid';
|
|
19
15
|
import { randomUUID } from 'crypto';
|
|
20
16
|
import { MCPServerBase } from '@mastra/core/mcp';
|
|
21
17
|
import { RequestContext } from '@mastra/core/request-context';
|
|
18
|
+
import { isStandardSchemaWithJSON, standardSchemaToJSONSchema } from '@mastra/core/schema';
|
|
19
|
+
import { makeCoreTool } from '@mastra/core/utils';
|
|
22
20
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
23
21
|
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
24
22
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -492,18 +490,10 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
492
490
|
}
|
|
493
491
|
setupLogging() {
|
|
494
492
|
if (this.enableServerLogs) {
|
|
495
|
-
this.client.setNotificationHandler(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
level: z.string()
|
|
500
|
-
}).passthrough()
|
|
501
|
-
}),
|
|
502
|
-
(notification) => {
|
|
503
|
-
const { level, ...params } = notification.params;
|
|
504
|
-
this.log(level, "[MCP SERVER LOG]", params);
|
|
505
|
-
}
|
|
506
|
-
);
|
|
493
|
+
this.client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => {
|
|
494
|
+
const { level, ...params } = notification.params;
|
|
495
|
+
this.log(level, "[MCP SERVER LOG]", params);
|
|
496
|
+
});
|
|
507
497
|
}
|
|
508
498
|
}
|
|
509
499
|
/**
|
|
@@ -569,7 +559,9 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
569
559
|
this.transport = new StdioClientTransport({
|
|
570
560
|
command,
|
|
571
561
|
args: this.serverConfig.args,
|
|
572
|
-
env: { ...getDefaultEnvironment(), ...this.serverConfig.env || {} }
|
|
562
|
+
env: { ...getDefaultEnvironment(), ...this.serverConfig.env || {} },
|
|
563
|
+
stderr: this.serverConfig.stderr,
|
|
564
|
+
cwd: this.serverConfig.cwd
|
|
573
565
|
});
|
|
574
566
|
await this.client.connect(this.transport, { timeout: this.serverConfig.timeout ?? this.timeout });
|
|
575
567
|
this.log("debug", `Successfully connected to MCP server via Stdio`);
|
|
@@ -788,13 +780,13 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
788
780
|
}
|
|
789
781
|
async subscribeResource(uri) {
|
|
790
782
|
this.log("debug", `Subscribing to resource on MCP server: ${uri}`);
|
|
791
|
-
return await this.client.request({ method: "resources/subscribe", params: { uri } },
|
|
783
|
+
return await this.client.request({ method: "resources/subscribe", params: { uri } }, EmptyResultSchema, {
|
|
792
784
|
timeout: this.timeout
|
|
793
785
|
});
|
|
794
786
|
}
|
|
795
787
|
async unsubscribeResource(uri) {
|
|
796
788
|
this.log("debug", `Unsubscribing from resource on MCP server: ${uri}`);
|
|
797
|
-
return await this.client.request({ method: "resources/unsubscribe", params: { uri } },
|
|
789
|
+
return await this.client.request({ method: "resources/unsubscribe", params: { uri } }, EmptyResultSchema, {
|
|
798
790
|
timeout: this.timeout
|
|
799
791
|
});
|
|
800
792
|
}
|
|
@@ -867,17 +859,9 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
867
859
|
});
|
|
868
860
|
}
|
|
869
861
|
async convertInputSchema(inputSchema) {
|
|
870
|
-
if (isZodType(inputSchema)) {
|
|
871
|
-
return inputSchema;
|
|
872
|
-
}
|
|
873
862
|
try {
|
|
874
863
|
await $RefParser.dereference(inputSchema);
|
|
875
|
-
|
|
876
|
-
if ("toJSONSchema" in z) {
|
|
877
|
-
return convertJsonSchemaToZod(jsonSchemaToConvert);
|
|
878
|
-
} else {
|
|
879
|
-
return convertJsonSchemaToZod$1(jsonSchemaToConvert);
|
|
880
|
-
}
|
|
864
|
+
return "jsonSchema" in inputSchema ? inputSchema.jsonSchema : inputSchema;
|
|
881
865
|
} catch (error) {
|
|
882
866
|
let errorDetails;
|
|
883
867
|
if (error instanceof Error) {
|
|
@@ -889,7 +873,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
889
873
|
errorDetails = String(error);
|
|
890
874
|
}
|
|
891
875
|
}
|
|
892
|
-
this.log("error", "Failed to
|
|
876
|
+
this.log("error", "Failed to dereference JSON schema", {
|
|
893
877
|
error: errorDetails,
|
|
894
878
|
originalJsonSchema: inputSchema
|
|
895
879
|
});
|
|
@@ -901,46 +885,11 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
901
885
|
});
|
|
902
886
|
}
|
|
903
887
|
}
|
|
904
|
-
/**
|
|
905
|
-
* Recursively applies `.passthrough()` to all ZodObject schemas so that
|
|
906
|
-
* unknown keys returned by an MCP server are preserved instead of being
|
|
907
|
-
* silently stripped by Zod's default "strip" mode.
|
|
908
|
-
*/
|
|
909
|
-
applyPassthrough(schema) {
|
|
910
|
-
if (schema instanceof z.ZodObject) {
|
|
911
|
-
const shape = schema.shape;
|
|
912
|
-
const newShape = {};
|
|
913
|
-
for (const key of Object.keys(shape)) {
|
|
914
|
-
newShape[key] = this.applyPassthrough(shape[key]);
|
|
915
|
-
}
|
|
916
|
-
return z.object(newShape).passthrough();
|
|
917
|
-
}
|
|
918
|
-
if (schema instanceof z.ZodArray) {
|
|
919
|
-
return z.array(this.applyPassthrough(schema.element));
|
|
920
|
-
}
|
|
921
|
-
if (schema instanceof z.ZodOptional) {
|
|
922
|
-
return this.applyPassthrough(schema.unwrap()).optional();
|
|
923
|
-
}
|
|
924
|
-
if (schema instanceof z.ZodNullable) {
|
|
925
|
-
return this.applyPassthrough(schema.unwrap()).nullable();
|
|
926
|
-
}
|
|
927
|
-
return schema;
|
|
928
|
-
}
|
|
929
888
|
async convertOutputSchema(outputSchema) {
|
|
930
889
|
if (!outputSchema) return;
|
|
931
|
-
if (isZodType(outputSchema)) {
|
|
932
|
-
return outputSchema;
|
|
933
|
-
}
|
|
934
890
|
try {
|
|
935
891
|
await $RefParser.dereference(outputSchema);
|
|
936
|
-
|
|
937
|
-
let zodSchema;
|
|
938
|
-
if ("toJSONSchema" in z) {
|
|
939
|
-
zodSchema = convertJsonSchemaToZod(jsonSchemaToConvert);
|
|
940
|
-
} else {
|
|
941
|
-
zodSchema = convertJsonSchemaToZod$1(jsonSchemaToConvert);
|
|
942
|
-
}
|
|
943
|
-
return this.applyPassthrough(zodSchema);
|
|
892
|
+
return "jsonSchema" in outputSchema ? outputSchema.jsonSchema : outputSchema;
|
|
944
893
|
} catch (error) {
|
|
945
894
|
let errorDetails;
|
|
946
895
|
if (error instanceof Error) {
|
|
@@ -952,7 +901,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
952
901
|
errorDetails = String(error);
|
|
953
902
|
}
|
|
954
903
|
}
|
|
955
|
-
this.log("error", "Failed to
|
|
904
|
+
this.log("error", "Failed to dereference JSON schema", {
|
|
956
905
|
error: errorDetails,
|
|
957
906
|
originalJsonSchema: outputSchema
|
|
958
907
|
});
|
|
@@ -976,6 +925,10 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
976
925
|
description: tool.description || "",
|
|
977
926
|
inputSchema: await this.convertInputSchema(tool.inputSchema),
|
|
978
927
|
outputSchema: await this.convertOutputSchema(tool.outputSchema),
|
|
928
|
+
mcpMetadata: {
|
|
929
|
+
serverName: this.name,
|
|
930
|
+
serverVersion: this.client.getServerVersion()?.version
|
|
931
|
+
},
|
|
979
932
|
execute: async (input, context) => {
|
|
980
933
|
const operationContext = context?.requestContext ?? null;
|
|
981
934
|
return this.operationContextStore.run(operationContext, async () => {
|
|
@@ -990,7 +943,8 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
990
943
|
},
|
|
991
944
|
CallToolResultSchema,
|
|
992
945
|
{
|
|
993
|
-
timeout: this.timeout
|
|
946
|
+
timeout: this.timeout,
|
|
947
|
+
signal: context?.abortSignal
|
|
994
948
|
}
|
|
995
949
|
);
|
|
996
950
|
this.log("debug", `Tool executed successfully: ${tool.name}`);
|
|
@@ -2740,10 +2694,10 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2740
2694
|
const toolSpec = {
|
|
2741
2695
|
name: tool.id || "unknown",
|
|
2742
2696
|
description: tool.description,
|
|
2743
|
-
inputSchema: tool.parameters
|
|
2697
|
+
inputSchema: this.convertSchema(tool.parameters)
|
|
2744
2698
|
};
|
|
2745
2699
|
if (tool.outputSchema) {
|
|
2746
|
-
toolSpec.outputSchema = tool.outputSchema
|
|
2700
|
+
toolSpec.outputSchema = this.convertSchema(tool.outputSchema);
|
|
2747
2701
|
}
|
|
2748
2702
|
if (tool.mcp?.annotations) {
|
|
2749
2703
|
toolSpec.annotations = tool.mcp.annotations;
|
|
@@ -2855,17 +2809,18 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2855
2809
|
return response;
|
|
2856
2810
|
} catch (error) {
|
|
2857
2811
|
const duration = Date.now() - startTime;
|
|
2858
|
-
if (error instanceof
|
|
2812
|
+
if (error instanceof Error && "issues" in error && Array.isArray(error.issues)) {
|
|
2813
|
+
const issues = error.issues;
|
|
2859
2814
|
this.logger.warn("Invalid tool arguments", {
|
|
2860
2815
|
tool: request.params.name,
|
|
2861
|
-
errors:
|
|
2816
|
+
errors: issues,
|
|
2862
2817
|
duration: `${duration}ms`
|
|
2863
2818
|
});
|
|
2864
2819
|
return {
|
|
2865
2820
|
content: [
|
|
2866
2821
|
{
|
|
2867
2822
|
type: "text",
|
|
2868
|
-
text: `Invalid arguments: ${
|
|
2823
|
+
text: `Invalid arguments: ${issues.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ")}`
|
|
2869
2824
|
}
|
|
2870
2825
|
],
|
|
2871
2826
|
isError: true
|
|
@@ -3098,12 +3053,18 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3098
3053
|
const agentToolDefinition = createTool({
|
|
3099
3054
|
id: agentToolName,
|
|
3100
3055
|
description: `Ask agent '${agent.name}' a question. Agent description: ${agentDescription}`,
|
|
3101
|
-
inputSchema:
|
|
3102
|
-
|
|
3103
|
-
|
|
3056
|
+
inputSchema: {
|
|
3057
|
+
type: "object",
|
|
3058
|
+
properties: {
|
|
3059
|
+
message: { type: "string", description: "The question or input for the agent." }
|
|
3060
|
+
},
|
|
3061
|
+
required: ["message"],
|
|
3062
|
+
additionalProperties: false
|
|
3063
|
+
},
|
|
3104
3064
|
execute: async (inputData, context) => {
|
|
3065
|
+
const { message } = inputData;
|
|
3105
3066
|
this.logger.debug(
|
|
3106
|
-
`Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${
|
|
3067
|
+
`Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${message}"`
|
|
3107
3068
|
);
|
|
3108
3069
|
try {
|
|
3109
3070
|
const proxiedContext = context?.requestContext || new RequestContext();
|
|
@@ -3112,7 +3073,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3112
3073
|
proxiedContext.set(key, value);
|
|
3113
3074
|
});
|
|
3114
3075
|
}
|
|
3115
|
-
const response = await agent.generate(
|
|
3076
|
+
const response = await agent.generate(message, {
|
|
3116
3077
|
...context ?? {},
|
|
3117
3078
|
requestContext: proxiedContext
|
|
3118
3079
|
});
|
|
@@ -3965,6 +3926,12 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3965
3926
|
remotes: this.remotes
|
|
3966
3927
|
};
|
|
3967
3928
|
}
|
|
3929
|
+
convertSchema(schema) {
|
|
3930
|
+
if (isStandardSchemaWithJSON(schema)) {
|
|
3931
|
+
return standardSchemaToJSONSchema(schema);
|
|
3932
|
+
}
|
|
3933
|
+
return schema?.jsonSchema || schema;
|
|
3934
|
+
}
|
|
3968
3935
|
/**
|
|
3969
3936
|
* Gets a list of all tools provided by this MCP server with their schemas.
|
|
3970
3937
|
*
|
|
@@ -3989,8 +3956,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3989
3956
|
id: toolId,
|
|
3990
3957
|
name: tool.id || toolId,
|
|
3991
3958
|
description: tool.description,
|
|
3992
|
-
inputSchema:
|
|
3993
|
-
outputSchema:
|
|
3959
|
+
inputSchema: this.convertSchema(tool.parameters),
|
|
3960
|
+
outputSchema: this.convertSchema(tool.parameters),
|
|
3994
3961
|
toolType: tool.mcp?.toolType
|
|
3995
3962
|
}))
|
|
3996
3963
|
};
|
|
@@ -4023,8 +3990,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4023
3990
|
return {
|
|
4024
3991
|
name: tool.id || toolId,
|
|
4025
3992
|
description: tool.description,
|
|
4026
|
-
inputSchema:
|
|
4027
|
-
outputSchema:
|
|
3993
|
+
inputSchema: this.convertSchema(tool.parameters),
|
|
3994
|
+
outputSchema: this.convertSchema(tool.outputSchema),
|
|
4028
3995
|
toolType: tool.mcp?.toolType
|
|
4029
3996
|
};
|
|
4030
3997
|
}
|
|
@@ -4059,23 +4026,29 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4059
4026
|
throw new Error(`Unknown tool: ${toolId}`);
|
|
4060
4027
|
}
|
|
4061
4028
|
this.logger.debug(`ExecuteTool: Invoking '${toolId}' with arguments:`, args);
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4029
|
+
const paramsSchema = tool.parameters;
|
|
4030
|
+
const validation = typeof paramsSchema?.validate === "function" ? paramsSchema.validate(args ?? {}) : typeof paramsSchema?.safeParse === "function" ? paramsSchema.safeParse(args ?? {}) : null;
|
|
4031
|
+
if (validation) {
|
|
4032
|
+
const success = typeof validation.success === "boolean" ? validation.success : !validation.issues?.length;
|
|
4033
|
+
if (!success) {
|
|
4034
|
+
const issues = validation.error?.issues ?? validation.error?.errors ?? validation.issues ?? [];
|
|
4035
|
+
const errorMessages = issues.map(
|
|
4036
|
+
(e) => `- ${e.path?.join(".") || "root"}: ${e.message}`
|
|
4037
|
+
).join("\n");
|
|
4038
|
+
const validationErrors = validation.error?.format?.() ?? validation.error ?? validation.issues;
|
|
4066
4039
|
this.logger.warn(`ExecuteTool: Invalid tool arguments for '${toolId}': ${errorMessages}`, {
|
|
4067
|
-
errors:
|
|
4040
|
+
errors: validationErrors
|
|
4068
4041
|
});
|
|
4069
4042
|
return {
|
|
4070
4043
|
error: true,
|
|
4071
4044
|
message: `Tool validation failed. Please fix the following errors and try again:
|
|
4072
|
-
${errorMessages}
|
|
4045
|
+
${errorMessages || "Validation failed"}
|
|
4073
4046
|
|
|
4074
4047
|
Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
4075
|
-
validationErrors
|
|
4048
|
+
validationErrors
|
|
4076
4049
|
};
|
|
4077
4050
|
}
|
|
4078
|
-
validatedArgs = validation.data;
|
|
4051
|
+
validatedArgs = validation.data ?? validation.value ?? args;
|
|
4079
4052
|
} else {
|
|
4080
4053
|
this.logger.debug(
|
|
4081
4054
|
`ExecuteTool: Tool '${toolId}' parameters is not a Zod schema with safeParse or is undefined. Skipping validation.`
|