@mastra/mcp 1.4.0 → 1.4.1
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 +22 -0
- package/dist/client/actions/prompt.d.ts.map +1 -1
- package/dist/client/actions/resource.d.ts.map +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +95 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -92
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -134,7 +134,8 @@ var PromptClientActions = class {
|
|
|
134
134
|
if (response && response.prompts && Array.isArray(response.prompts)) {
|
|
135
135
|
return response.prompts.map((prompt) => ({ ...prompt }));
|
|
136
136
|
} else {
|
|
137
|
-
this.logger.warn(
|
|
137
|
+
this.logger.warn("Prompts response did not have expected structure", {
|
|
138
|
+
server: this.client.name,
|
|
138
139
|
response
|
|
139
140
|
});
|
|
140
141
|
return [];
|
|
@@ -143,7 +144,8 @@ var PromptClientActions = class {
|
|
|
143
144
|
if (e.code === types_js.ErrorCode.MethodNotFound) {
|
|
144
145
|
return [];
|
|
145
146
|
}
|
|
146
|
-
this.logger.error(
|
|
147
|
+
this.logger.error("Error getting prompts from server", {
|
|
148
|
+
server: this.client.name,
|
|
147
149
|
error: e instanceof Error ? e.message : String(e)
|
|
148
150
|
});
|
|
149
151
|
throw new Error(
|
|
@@ -232,7 +234,8 @@ var ResourceClientActions = class {
|
|
|
232
234
|
if (response && response.resources && Array.isArray(response.resources)) {
|
|
233
235
|
return response.resources;
|
|
234
236
|
} else {
|
|
235
|
-
this.logger.warn(
|
|
237
|
+
this.logger.warn("Resources response did not have expected structure", {
|
|
238
|
+
server: this.client.name,
|
|
236
239
|
response
|
|
237
240
|
});
|
|
238
241
|
return [];
|
|
@@ -241,7 +244,8 @@ var ResourceClientActions = class {
|
|
|
241
244
|
if (e.code === types_js.ErrorCode.MethodNotFound) {
|
|
242
245
|
return [];
|
|
243
246
|
}
|
|
244
|
-
this.logger.error(
|
|
247
|
+
this.logger.error("Error getting resources from server", {
|
|
248
|
+
server: this.client.name,
|
|
245
249
|
error: e instanceof Error ? e.message : String(e)
|
|
246
250
|
});
|
|
247
251
|
throw new Error(
|
|
@@ -272,17 +276,18 @@ var ResourceClientActions = class {
|
|
|
272
276
|
if (response && response.resourceTemplates && Array.isArray(response.resourceTemplates)) {
|
|
273
277
|
return response.resourceTemplates;
|
|
274
278
|
} else {
|
|
275
|
-
this.logger.warn(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
);
|
|
279
|
+
this.logger.warn("Resource templates response did not have expected structure", {
|
|
280
|
+
server: this.client.name,
|
|
281
|
+
response
|
|
282
|
+
});
|
|
279
283
|
return [];
|
|
280
284
|
}
|
|
281
285
|
} catch (e) {
|
|
282
286
|
if (e.code === types_js.ErrorCode.MethodNotFound) {
|
|
283
287
|
return [];
|
|
284
288
|
}
|
|
285
|
-
this.logger.error(
|
|
289
|
+
this.logger.error("Error getting resource templates from server", {
|
|
290
|
+
server: this.client.name,
|
|
286
291
|
error: e instanceof Error ? e.message : String(e)
|
|
287
292
|
});
|
|
288
293
|
throw new Error(
|
|
@@ -1801,7 +1806,7 @@ To fix this you have three different options:
|
|
|
1801
1806
|
}
|
|
1802
1807
|
const exists = this.mcpClientsById.has(name);
|
|
1803
1808
|
const existingClient = this.mcpClientsById.get(name);
|
|
1804
|
-
this.logger.debug(
|
|
1809
|
+
this.logger.debug("Checking connected client", { name, exists });
|
|
1805
1810
|
if (exists) {
|
|
1806
1811
|
if (!existingClient) {
|
|
1807
1812
|
throw new Error(`Client ${name} exists but is undefined`);
|
|
@@ -1809,7 +1814,7 @@ To fix this you have three different options:
|
|
|
1809
1814
|
await existingClient.connect();
|
|
1810
1815
|
return existingClient;
|
|
1811
1816
|
}
|
|
1812
|
-
this.logger.debug(
|
|
1817
|
+
this.logger.debug("Connecting to MCP server", { name });
|
|
1813
1818
|
const mcpClient = new InternalMastraMCPClient({
|
|
1814
1819
|
name,
|
|
1815
1820
|
server: config,
|
|
@@ -1837,7 +1842,7 @@ To fix this you have three different options:
|
|
|
1837
1842
|
this.mcpClientsById.delete(name);
|
|
1838
1843
|
throw mastraError;
|
|
1839
1844
|
}
|
|
1840
|
-
this.logger.debug(
|
|
1845
|
+
this.logger.debug("Connected to MCP server", { name });
|
|
1841
1846
|
return mcpClient;
|
|
1842
1847
|
}
|
|
1843
1848
|
async getConnectedClientForServer(serverName) {
|
|
@@ -2614,9 +2619,13 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2614
2619
|
...this.instructions ? { instructions: this.instructions } : {}
|
|
2615
2620
|
}
|
|
2616
2621
|
);
|
|
2617
|
-
this.logger.info(
|
|
2618
|
-
|
|
2619
|
-
|
|
2622
|
+
this.logger.info("Initialized MCPServer", {
|
|
2623
|
+
name: this.name,
|
|
2624
|
+
version: this.version,
|
|
2625
|
+
id: this.id,
|
|
2626
|
+
tools: Object.keys(this.convertedTools),
|
|
2627
|
+
capabilities
|
|
2628
|
+
});
|
|
2620
2629
|
this.sseHonoTransports = /* @__PURE__ */ new Map();
|
|
2621
2630
|
this.registerHandlersOnServer(this.server);
|
|
2622
2631
|
this.resources = new ServerResourceActions({
|
|
@@ -2653,10 +2662,10 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2653
2662
|
* @returns Promise that resolves to the client's response
|
|
2654
2663
|
*/
|
|
2655
2664
|
async handleElicitationRequest(request, serverInstance, options) {
|
|
2656
|
-
this.logger.debug(
|
|
2665
|
+
this.logger.debug("Sending elicitation request", { message: request.message });
|
|
2657
2666
|
const server = serverInstance || this.server;
|
|
2658
2667
|
const response = await server.elicitInput(request, options);
|
|
2659
|
-
this.logger.debug(
|
|
2668
|
+
this.logger.debug("Received elicitation response", { response });
|
|
2660
2669
|
return response;
|
|
2661
2670
|
}
|
|
2662
2671
|
/**
|
|
@@ -2728,7 +2737,6 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2728
2737
|
*/
|
|
2729
2738
|
registerHandlersOnServer(serverInstance) {
|
|
2730
2739
|
serverInstance.setRequestHandler(types_js.ListToolsRequestSchema, async () => {
|
|
2731
|
-
this.logger.debug("Handling ListTools request");
|
|
2732
2740
|
return {
|
|
2733
2741
|
tools: Object.values(this.convertedTools).map((tool) => {
|
|
2734
2742
|
const toolSpec = {
|
|
@@ -2754,7 +2762,7 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2754
2762
|
try {
|
|
2755
2763
|
const tool = this.convertedTools[request.params.name];
|
|
2756
2764
|
if (!tool) {
|
|
2757
|
-
this.logger.warn(
|
|
2765
|
+
this.logger.warn("Unknown tool requested", { tool: request.params.name });
|
|
2758
2766
|
return {
|
|
2759
2767
|
content: [{ type: "text", text: `Unknown tool: ${request.params.name}` }],
|
|
2760
2768
|
isError: true
|
|
@@ -2762,7 +2770,8 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2762
2770
|
}
|
|
2763
2771
|
const validation = tool.parameters.validate?.(request.params.arguments ?? {});
|
|
2764
2772
|
if (validation && !validation.success) {
|
|
2765
|
-
this.logger.warn(
|
|
2773
|
+
this.logger.warn("Invalid tool arguments", {
|
|
2774
|
+
tool: request.params.name,
|
|
2766
2775
|
errors: validation.error
|
|
2767
2776
|
});
|
|
2768
2777
|
let errorMessages = "Validation failed";
|
|
@@ -2786,7 +2795,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2786
2795
|
};
|
|
2787
2796
|
}
|
|
2788
2797
|
if (!tool.execute) {
|
|
2789
|
-
this.logger.warn(
|
|
2798
|
+
this.logger.warn("Tool does not have an execute function", { tool: request.params.name });
|
|
2790
2799
|
return {
|
|
2791
2800
|
content: [{ type: "text", text: `Tool '${request.params.name}' does not have an execute function.` }],
|
|
2792
2801
|
isError: true
|
|
@@ -2843,7 +2852,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2843
2852
|
}
|
|
2844
2853
|
const outputValidation = tool.outputSchema.validate?.(structuredContent ?? {});
|
|
2845
2854
|
if (outputValidation && !outputValidation.success) {
|
|
2846
|
-
this.logger.warn(
|
|
2855
|
+
this.logger.warn("Invalid structured content", {
|
|
2856
|
+
tool: request.params.name,
|
|
2847
2857
|
errors: outputValidation.error
|
|
2848
2858
|
});
|
|
2849
2859
|
throw new Error(
|
|
@@ -2882,7 +2892,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2882
2892
|
isError: true
|
|
2883
2893
|
};
|
|
2884
2894
|
}
|
|
2885
|
-
this.logger.error(
|
|
2895
|
+
this.logger.error("Tool execution failed", { tool: request.params.name, error: error$1 });
|
|
2886
2896
|
if (error$1 instanceof error.MastraError) {
|
|
2887
2897
|
return {
|
|
2888
2898
|
content: [{ type: "text", text: JSON.stringify(error$1.toJSON()) }],
|
|
@@ -2897,7 +2907,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2897
2907
|
});
|
|
2898
2908
|
serverInstance.setRequestHandler(types_js.SetLevelRequestSchema, async (request) => {
|
|
2899
2909
|
this.currentLoggingLevel = request.params.level;
|
|
2900
|
-
this.logger.debug(
|
|
2910
|
+
this.logger.debug("Logging level set", { level: request.params.level });
|
|
2901
2911
|
return {};
|
|
2902
2912
|
});
|
|
2903
2913
|
if (this.resourceOptions) {
|
|
@@ -2915,17 +2925,16 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2915
2925
|
if (!capturedResourceOptions) return;
|
|
2916
2926
|
if (capturedResourceOptions.listResources) {
|
|
2917
2927
|
serverInstance.setRequestHandler(types_js.ListResourcesRequestSchema, async (_request, extra) => {
|
|
2918
|
-
this.logger.debug("Handling ListResources request");
|
|
2919
2928
|
if (this.definedResources) {
|
|
2920
2929
|
return { resources: this.definedResources };
|
|
2921
2930
|
} else {
|
|
2922
2931
|
try {
|
|
2923
2932
|
const resources = await capturedResourceOptions.listResources({ extra });
|
|
2924
2933
|
this.definedResources = resources;
|
|
2925
|
-
this.logger.debug(
|
|
2934
|
+
this.logger.debug("Fetched and cached resources", { count: this.definedResources.length });
|
|
2926
2935
|
return { resources: this.definedResources };
|
|
2927
2936
|
} catch (error) {
|
|
2928
|
-
this.logger.error("Error fetching resources
|
|
2937
|
+
this.logger.error("Error fetching resources", { error });
|
|
2929
2938
|
throw error;
|
|
2930
2939
|
}
|
|
2931
2940
|
}
|
|
@@ -2935,7 +2944,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2935
2944
|
serverInstance.setRequestHandler(types_js.ReadResourceRequestSchema, async (request, extra) => {
|
|
2936
2945
|
const startTime = Date.now();
|
|
2937
2946
|
const uri = request.params.uri;
|
|
2938
|
-
this.logger.debug(
|
|
2947
|
+
this.logger.debug("Handling ReadResource request", { uri });
|
|
2939
2948
|
if (!this.definedResources) {
|
|
2940
2949
|
const resources = await this.resourceOptions?.listResources?.({ extra });
|
|
2941
2950
|
if (!resources) throw new Error("Failed to load resources");
|
|
@@ -2943,7 +2952,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2943
2952
|
}
|
|
2944
2953
|
const resource = this.definedResources?.find((r) => r.uri === uri);
|
|
2945
2954
|
if (!resource) {
|
|
2946
|
-
this.logger.warn(
|
|
2955
|
+
this.logger.warn("Unknown resource URI requested", { uri });
|
|
2947
2956
|
throw new Error(`Resource not found: ${uri}`);
|
|
2948
2957
|
}
|
|
2949
2958
|
try {
|
|
@@ -2968,27 +2977,26 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2968
2977
|
};
|
|
2969
2978
|
});
|
|
2970
2979
|
const duration = Date.now() - startTime;
|
|
2971
|
-
this.logger.info(
|
|
2980
|
+
this.logger.info("Resource read successfully", { uri, duration });
|
|
2972
2981
|
return {
|
|
2973
2982
|
contents
|
|
2974
2983
|
};
|
|
2975
2984
|
} catch (error) {
|
|
2976
2985
|
const duration = Date.now() - startTime;
|
|
2977
|
-
this.logger.error(
|
|
2986
|
+
this.logger.error("Failed to get content for resource", { uri, duration, error });
|
|
2978
2987
|
throw error;
|
|
2979
2988
|
}
|
|
2980
2989
|
});
|
|
2981
2990
|
}
|
|
2982
2991
|
if (capturedResourceOptions.resourceTemplates) {
|
|
2983
2992
|
serverInstance.setRequestHandler(types_js.ListResourceTemplatesRequestSchema, async (_request, extra) => {
|
|
2984
|
-
this.logger.debug("Handling ListResourceTemplates request");
|
|
2985
2993
|
if (this.definedResourceTemplates) {
|
|
2986
2994
|
return { resourceTemplates: this.definedResourceTemplates };
|
|
2987
2995
|
} else {
|
|
2988
2996
|
try {
|
|
2989
2997
|
const templates = await capturedResourceOptions.resourceTemplates({ extra });
|
|
2990
2998
|
this.definedResourceTemplates = templates;
|
|
2991
|
-
this.logger.debug(
|
|
2999
|
+
this.logger.debug("Fetched and cached resource templates", { count: this.definedResourceTemplates.length });
|
|
2992
3000
|
return { resourceTemplates: this.definedResourceTemplates };
|
|
2993
3001
|
} catch (error) {
|
|
2994
3002
|
this.logger.error("Error fetching resource templates via resourceTemplates():", { error });
|
|
@@ -2999,13 +3007,13 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2999
3007
|
}
|
|
3000
3008
|
serverInstance.setRequestHandler(types_js.SubscribeRequestSchema, async (request) => {
|
|
3001
3009
|
const uri = request.params.uri;
|
|
3002
|
-
this.logger.info(
|
|
3010
|
+
this.logger.info("Received resources/subscribe request", { uri });
|
|
3003
3011
|
this.subscriptions.add(uri);
|
|
3004
3012
|
return {};
|
|
3005
3013
|
});
|
|
3006
3014
|
serverInstance.setRequestHandler(types_js.UnsubscribeRequestSchema, async (request) => {
|
|
3007
3015
|
const uri = request.params.uri;
|
|
3008
|
-
this.logger.info(
|
|
3016
|
+
this.logger.info("Received resources/unsubscribe request", { uri });
|
|
3009
3017
|
this.subscriptions.delete(uri);
|
|
3010
3018
|
return {};
|
|
3011
3019
|
});
|
|
@@ -3030,7 +3038,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3030
3038
|
types_js.PromptSchema.parse(prompt);
|
|
3031
3039
|
}
|
|
3032
3040
|
this.definedPrompts = prompts;
|
|
3033
|
-
this.logger.debug(
|
|
3041
|
+
this.logger.debug("Fetched and cached prompts", { count: this.definedPrompts.length });
|
|
3034
3042
|
return {
|
|
3035
3043
|
prompts: this.definedPrompts
|
|
3036
3044
|
};
|
|
@@ -3069,11 +3077,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3069
3077
|
messages = await capturedPromptOptions.getPromptMessages({ name, version: prompt.version, args, extra });
|
|
3070
3078
|
}
|
|
3071
3079
|
const duration = Date.now() - startTime;
|
|
3072
|
-
this.logger.info(
|
|
3080
|
+
this.logger.info("Prompt retrieved successfully", { prompt: name, duration });
|
|
3073
3081
|
return { description: prompt.description, messages };
|
|
3074
3082
|
} catch (error) {
|
|
3075
3083
|
const duration = Date.now() - startTime;
|
|
3076
|
-
this.logger.error(
|
|
3084
|
+
this.logger.error("Failed to get prompt content", { prompt: name, duration, error });
|
|
3077
3085
|
throw error;
|
|
3078
3086
|
}
|
|
3079
3087
|
}
|
|
@@ -3088,7 +3096,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3088
3096
|
for (const agentKey in agentsConfig) {
|
|
3089
3097
|
const agent = agentsConfig[agentKey];
|
|
3090
3098
|
if (!agent || !("generate" in agent)) {
|
|
3091
|
-
this.logger.warn(
|
|
3099
|
+
this.logger.warn("Invalid agent instance, skipping", { agentKey });
|
|
3092
3100
|
continue;
|
|
3093
3101
|
}
|
|
3094
3102
|
const agentDescription = agent.getDescription();
|
|
@@ -3099,9 +3107,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3099
3107
|
}
|
|
3100
3108
|
const agentToolName = `ask_${agentKey}`;
|
|
3101
3109
|
if (definedConvertedTools?.[agentToolName] || agentTools[agentToolName]) {
|
|
3102
|
-
this.logger.warn(
|
|
3103
|
-
`Tool with name '${agentToolName}' already exists. Agent '${agentKey}' will not be added as a duplicate tool.`
|
|
3104
|
-
);
|
|
3110
|
+
this.logger.warn("Duplicate tool name, skipping agent", { tool: agentToolName, agentKey });
|
|
3105
3111
|
continue;
|
|
3106
3112
|
}
|
|
3107
3113
|
const agentToolDefinition = tools.createTool({
|
|
@@ -3117,9 +3123,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3117
3123
|
},
|
|
3118
3124
|
execute: async (inputData, context) => {
|
|
3119
3125
|
const { message } = inputData;
|
|
3120
|
-
this.logger.debug(
|
|
3121
|
-
`Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${message}"`
|
|
3122
|
-
);
|
|
3126
|
+
this.logger.debug("Executing agent tool", { tool: agentToolName, agent: agent.name, message });
|
|
3123
3127
|
try {
|
|
3124
3128
|
const proxiedContext = context?.requestContext || new requestContext.RequestContext();
|
|
3125
3129
|
if (context?.mcp?.extra) {
|
|
@@ -3133,7 +3137,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3133
3137
|
});
|
|
3134
3138
|
return response;
|
|
3135
3139
|
} catch (error) {
|
|
3136
|
-
this.logger.error(
|
|
3140
|
+
this.logger.error("Error executing agent tool", { tool: agentToolName, agent: agent.name, error });
|
|
3137
3141
|
throw error;
|
|
3138
3142
|
}
|
|
3139
3143
|
}
|
|
@@ -3154,7 +3158,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3154
3158
|
toolType: "agent"
|
|
3155
3159
|
}
|
|
3156
3160
|
};
|
|
3157
|
-
this.logger.info(
|
|
3161
|
+
this.logger.info("Registered agent as tool", { agent: agent.name, key: agentKey, tool: agentToolName });
|
|
3158
3162
|
}
|
|
3159
3163
|
return agentTools;
|
|
3160
3164
|
}
|
|
@@ -3232,7 +3236,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3232
3236
|
toolType: "workflow"
|
|
3233
3237
|
}
|
|
3234
3238
|
};
|
|
3235
|
-
this.logger.info(
|
|
3239
|
+
this.logger.info("Registered workflow as tool", {
|
|
3240
|
+
workflow: workflow.id,
|
|
3241
|
+
key: workflowKey,
|
|
3242
|
+
tool: workflowToolName
|
|
3243
|
+
});
|
|
3236
3244
|
}
|
|
3237
3245
|
return workflowTools;
|
|
3238
3246
|
}
|
|
@@ -3249,11 +3257,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3249
3257
|
for (const toolName of Object.keys(tools)) {
|
|
3250
3258
|
const toolInstance = tools[toolName];
|
|
3251
3259
|
if (!toolInstance) {
|
|
3252
|
-
this.logger.warn(
|
|
3260
|
+
this.logger.warn("Tool instance is undefined, skipping", { tool: toolName });
|
|
3253
3261
|
continue;
|
|
3254
3262
|
}
|
|
3255
3263
|
if (typeof toolInstance.execute !== "function") {
|
|
3256
|
-
this.logger.warn(
|
|
3264
|
+
this.logger.warn("Tool has no execute function, skipping", { tool: toolName });
|
|
3257
3265
|
continue;
|
|
3258
3266
|
}
|
|
3259
3267
|
const options = {
|
|
@@ -3269,9 +3277,9 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3269
3277
|
...coreTool,
|
|
3270
3278
|
id: toolName
|
|
3271
3279
|
};
|
|
3272
|
-
this.logger.info(
|
|
3280
|
+
this.logger.info("Registered explicit tool", { tool: toolName });
|
|
3273
3281
|
}
|
|
3274
|
-
this.logger.info(
|
|
3282
|
+
this.logger.info("Total defined tools registered", { count: Object.keys(definedConvertedTools).length });
|
|
3275
3283
|
let agentDerivedTools = {};
|
|
3276
3284
|
let workflowDerivedTools = {};
|
|
3277
3285
|
try {
|
|
@@ -3565,16 +3573,16 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3565
3573
|
res,
|
|
3566
3574
|
options
|
|
3567
3575
|
}) {
|
|
3568
|
-
this.logger.debug(
|
|
3576
|
+
this.logger.debug("Received HTTP request", { method: req.method, path: url.pathname });
|
|
3569
3577
|
if (url.pathname !== httpPath) {
|
|
3570
|
-
this.logger.debug(
|
|
3578
|
+
this.logger.debug("Pathname does not match httpPath, returning 404", { path: url.pathname, httpPath });
|
|
3571
3579
|
res.writeHead(404);
|
|
3572
3580
|
res.end();
|
|
3573
3581
|
return;
|
|
3574
3582
|
}
|
|
3575
3583
|
const isStatelessMode = options?.serverless || options && "sessionIdGenerator" in options && options.sessionIdGenerator === void 0;
|
|
3576
3584
|
if (isStatelessMode) {
|
|
3577
|
-
this.logger.debug("
|
|
3585
|
+
this.logger.debug("Running in stateless mode");
|
|
3578
3586
|
await this.handleServerlessRequest(req, res);
|
|
3579
3587
|
return;
|
|
3580
3588
|
}
|
|
@@ -3586,27 +3594,26 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3586
3594
|
};
|
|
3587
3595
|
const sessionId = req.headers["mcp-session-id"];
|
|
3588
3596
|
let transport;
|
|
3589
|
-
this.logger.debug(
|
|
3590
|
-
|
|
3591
|
-
|
|
3597
|
+
this.logger.debug("Session ID from headers", {
|
|
3598
|
+
sessionId,
|
|
3599
|
+
activeTransports: Array.from(this.streamableHTTPTransports.keys())
|
|
3600
|
+
});
|
|
3592
3601
|
try {
|
|
3593
3602
|
if (sessionId && this.streamableHTTPTransports.has(sessionId)) {
|
|
3594
3603
|
transport = this.streamableHTTPTransports.get(sessionId);
|
|
3595
|
-
this.logger.debug(
|
|
3604
|
+
this.logger.debug("Using existing transport for session", { sessionId });
|
|
3596
3605
|
if (req.method === "GET") {
|
|
3597
|
-
this.logger.debug(
|
|
3598
|
-
`startHTTP: Handling GET request for existing session ${sessionId}. Calling transport.handleRequest.`
|
|
3599
|
-
);
|
|
3606
|
+
this.logger.debug("Handling GET request for existing session", { sessionId });
|
|
3600
3607
|
}
|
|
3601
3608
|
const body = req.method === "POST" ? await this.readJsonBody(req) : void 0;
|
|
3602
3609
|
await transport.handleRequest(req, res, body);
|
|
3603
3610
|
} else {
|
|
3604
|
-
this.logger.debug(
|
|
3611
|
+
this.logger.debug("No existing session found", { method: req.method });
|
|
3605
3612
|
if (req.method === "POST") {
|
|
3606
3613
|
const body = await this.readJsonBody(req);
|
|
3607
3614
|
const { isInitializeRequest } = await import('@modelcontextprotocol/sdk/types.js');
|
|
3608
3615
|
if (isInitializeRequest(body)) {
|
|
3609
|
-
this.logger.debug("
|
|
3616
|
+
this.logger.debug("Received initialize request, creating new transport");
|
|
3610
3617
|
transport = new streamableHttp_js$1.StreamableHTTPServerTransport({
|
|
3611
3618
|
...mergedOptions,
|
|
3612
3619
|
sessionIdGenerator: mergedOptions.sessionIdGenerator,
|
|
@@ -3617,13 +3624,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3617
3624
|
transport.onclose = () => {
|
|
3618
3625
|
const closedSessionId = transport?.sessionId;
|
|
3619
3626
|
if (closedSessionId && this.streamableHTTPTransports.has(closedSessionId)) {
|
|
3620
|
-
this.logger.debug(
|
|
3621
|
-
`startHTTP: Streamable HTTP transport closed for session ${closedSessionId}, removing from map.`
|
|
3622
|
-
);
|
|
3627
|
+
this.logger.debug("Transport closed for session, removing from map", { sessionId: closedSessionId });
|
|
3623
3628
|
this.streamableHTTPTransports.delete(closedSessionId);
|
|
3624
3629
|
if (this.httpServerInstances.has(closedSessionId)) {
|
|
3625
3630
|
this.httpServerInstances.delete(closedSessionId);
|
|
3626
|
-
this.logger.debug(
|
|
3631
|
+
this.logger.debug("Cleaned up server instance for closed session", { sessionId: closedSessionId });
|
|
3627
3632
|
}
|
|
3628
3633
|
}
|
|
3629
3634
|
};
|
|
@@ -3632,15 +3637,13 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3632
3637
|
if (transport.sessionId) {
|
|
3633
3638
|
this.streamableHTTPTransports.set(transport.sessionId, transport);
|
|
3634
3639
|
this.httpServerInstances.set(transport.sessionId, sessionServerInstance);
|
|
3635
|
-
this.logger.debug(
|
|
3636
|
-
`startHTTP: Streamable HTTP session initialized and stored with ID: ${transport.sessionId}`
|
|
3637
|
-
);
|
|
3640
|
+
this.logger.debug("Session initialized and stored", { sessionId: transport.sessionId });
|
|
3638
3641
|
} else {
|
|
3639
|
-
this.logger.warn("
|
|
3642
|
+
this.logger.warn("Transport initialized without a session ID");
|
|
3640
3643
|
}
|
|
3641
3644
|
return await transport.handleRequest(req, res, body);
|
|
3642
3645
|
} else {
|
|
3643
|
-
this.logger.warn("
|
|
3646
|
+
this.logger.warn("Received non-initialize POST request without session ID");
|
|
3644
3647
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
3645
3648
|
res.end(
|
|
3646
3649
|
JSON.stringify({
|
|
@@ -3655,7 +3658,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3655
3658
|
);
|
|
3656
3659
|
}
|
|
3657
3660
|
} else {
|
|
3658
|
-
this.logger.warn(
|
|
3661
|
+
this.logger.warn("Received request without session ID", { method: req.method });
|
|
3659
3662
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
3660
3663
|
res.end(
|
|
3661
3664
|
JSON.stringify({
|
|
@@ -3680,7 +3683,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3680
3683
|
error$1
|
|
3681
3684
|
);
|
|
3682
3685
|
this.logger.trackException(mastraError);
|
|
3683
|
-
this.logger.error("
|
|
3686
|
+
this.logger.error("Error handling HTTP request", { error: mastraError });
|
|
3684
3687
|
if (!res.headersSent) {
|
|
3685
3688
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
3686
3689
|
res.end(
|
|
@@ -3712,10 +3715,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3712
3715
|
*/
|
|
3713
3716
|
async handleServerlessRequest(req, res) {
|
|
3714
3717
|
try {
|
|
3715
|
-
this.logger.debug(
|
|
3718
|
+
this.logger.debug("Received serverless request", { method: req.method });
|
|
3716
3719
|
const body = req.method === "POST" ? await this.readJsonBody(req) : void 0;
|
|
3717
|
-
this.logger.debug(
|
|
3718
|
-
method:
|
|
3720
|
+
this.logger.debug("Processing serverless request", {
|
|
3721
|
+
method: req.method,
|
|
3722
|
+
bodyMethod: body?.method,
|
|
3719
3723
|
id: body?.id
|
|
3720
3724
|
});
|
|
3721
3725
|
const transientServer = this.createServerInstance();
|
|
@@ -3725,7 +3729,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3725
3729
|
});
|
|
3726
3730
|
await transientServer.connect(tempTransport);
|
|
3727
3731
|
await tempTransport.handleRequest(req, res, body);
|
|
3728
|
-
this.logger.debug(
|
|
3732
|
+
this.logger.debug("Completed serverless request", { method: body?.method, id: body?.id });
|
|
3729
3733
|
} catch (error$1) {
|
|
3730
3734
|
const mastraError = new error.MastraError(
|
|
3731
3735
|
{
|
|
@@ -3737,7 +3741,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3737
3741
|
error$1
|
|
3738
3742
|
);
|
|
3739
3743
|
this.logger.trackException(mastraError);
|
|
3740
|
-
this.logger.error("
|
|
3744
|
+
this.logger.error("Error handling serverless request", { error: mastraError });
|
|
3741
3745
|
if (!res.headersSent) {
|
|
3742
3746
|
res.writeHead(500, { "Content-Type": "application/json" });
|
|
3743
3747
|
res.end(
|
|
@@ -4004,7 +4008,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4004
4008
|
* ```
|
|
4005
4009
|
*/
|
|
4006
4010
|
getToolListInfo() {
|
|
4007
|
-
this.logger.debug(
|
|
4011
|
+
this.logger.debug("Getting tool list", { server: this.name });
|
|
4008
4012
|
return {
|
|
4009
4013
|
tools: Object.entries(this.convertedTools).map(([toolId, tool]) => ({
|
|
4010
4014
|
id: toolId,
|
|
@@ -4037,10 +4041,10 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4037
4041
|
getToolInfo(toolId) {
|
|
4038
4042
|
const tool = this.convertedTools[toolId];
|
|
4039
4043
|
if (!tool) {
|
|
4040
|
-
this.logger.debug(
|
|
4044
|
+
this.logger.debug("Tool not found", { tool: toolId, server: this.name });
|
|
4041
4045
|
return void 0;
|
|
4042
4046
|
}
|
|
4043
|
-
this.logger.debug(
|
|
4047
|
+
this.logger.debug("Getting tool info", { tool: toolId, server: this.name });
|
|
4044
4048
|
return {
|
|
4045
4049
|
name: tool.id || toolId,
|
|
4046
4050
|
description: tool.description,
|
|
@@ -4076,10 +4080,10 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4076
4080
|
let validatedArgs = args;
|
|
4077
4081
|
try {
|
|
4078
4082
|
if (!tool) {
|
|
4079
|
-
this.logger.warn(
|
|
4083
|
+
this.logger.warn("Unknown tool requested", { tool: toolId, server: this.name });
|
|
4080
4084
|
throw new Error(`Unknown tool: ${toolId}`);
|
|
4081
4085
|
}
|
|
4082
|
-
this.logger.debug(
|
|
4086
|
+
this.logger.debug("Invoking tool", { tool: toolId, args });
|
|
4083
4087
|
const paramsSchema = tool.parameters;
|
|
4084
4088
|
const validation = typeof paramsSchema?.validate === "function" ? paramsSchema.validate(args ?? {}) : typeof paramsSchema?.safeParse === "function" ? paramsSchema.safeParse(args ?? {}) : null;
|
|
4085
4089
|
if (validation) {
|
|
@@ -4090,7 +4094,9 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4090
4094
|
(e) => `- ${e.path?.join(".") || "root"}: ${e.message}`
|
|
4091
4095
|
).join("\n");
|
|
4092
4096
|
const validationErrors = validation.error?.format?.() ?? validation.error ?? validation.issues;
|
|
4093
|
-
this.logger.warn(
|
|
4097
|
+
this.logger.warn("Invalid tool arguments", {
|
|
4098
|
+
tool: toolId,
|
|
4099
|
+
errorMessages,
|
|
4094
4100
|
errors: validationErrors
|
|
4095
4101
|
});
|
|
4096
4102
|
return {
|
|
@@ -4104,12 +4110,10 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
4104
4110
|
}
|
|
4105
4111
|
validatedArgs = validation.data ?? validation.value ?? args;
|
|
4106
4112
|
} else {
|
|
4107
|
-
this.logger.debug(
|
|
4108
|
-
`ExecuteTool: Tool '${toolId}' parameters is not a Zod schema with safeParse or is undefined. Skipping validation.`
|
|
4109
|
-
);
|
|
4113
|
+
this.logger.debug("Tool parameters missing schema, skipping validation", { tool: toolId });
|
|
4110
4114
|
}
|
|
4111
4115
|
if (!tool.execute) {
|
|
4112
|
-
this.logger.error(
|
|
4116
|
+
this.logger.error("Tool does not have an execute function", { tool: toolId });
|
|
4113
4117
|
throw new Error(`Tool '${toolId}' cannot be executed.`);
|
|
4114
4118
|
}
|
|
4115
4119
|
} catch (error$1) {
|
|
@@ -4134,7 +4138,7 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
4134
4138
|
toolCallId: executionContext?.toolCallId || crypto$1.randomUUID()
|
|
4135
4139
|
};
|
|
4136
4140
|
const result = await tool.execute(validatedArgs, finalExecutionContext);
|
|
4137
|
-
this.logger.info(
|
|
4141
|
+
this.logger.info("Tool executed successfully", { tool: toolId });
|
|
4138
4142
|
return result;
|
|
4139
4143
|
} catch (error$1) {
|
|
4140
4144
|
const mastraError = new error.MastraError(
|
|
@@ -4150,7 +4154,6 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
4150
4154
|
error$1
|
|
4151
4155
|
);
|
|
4152
4156
|
this.logger.trackException(mastraError);
|
|
4153
|
-
this.logger.error(`ExecuteTool: Tool execution failed for '${toolId}':`, { error: error$1 });
|
|
4154
4157
|
throw mastraError;
|
|
4155
4158
|
}
|
|
4156
4159
|
}
|