@mastra/mcp 0.14.2 → 1.0.0-beta.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 +74 -13
- package/README.md +8 -8
- package/dist/__fixtures__/tools.d.ts +1 -7
- package/dist/__fixtures__/tools.d.ts.map +1 -1
- package/dist/client/client.d.ts +4 -9
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +10 -64
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/index.cjs +175 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +175 -94
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +44 -6
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/types.d.ts +0 -54
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +8 -12
package/dist/index.cjs
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var $RefParser = require('@apidevtools/json-schema-ref-parser');
|
|
4
3
|
var base = require('@mastra/core/base');
|
|
5
4
|
var error = require('@mastra/core/error');
|
|
5
|
+
var protocol_js = require('@modelcontextprotocol/sdk/shared/protocol.js');
|
|
6
|
+
var equal = require('fast-deep-equal');
|
|
7
|
+
var uuid = require('uuid');
|
|
8
|
+
var $RefParser = require('@apidevtools/json-schema-ref-parser');
|
|
6
9
|
var tools = require('@mastra/core/tools');
|
|
7
10
|
var utils = require('@mastra/core/utils');
|
|
8
11
|
var index_js$1 = require('@modelcontextprotocol/sdk/client/index.js');
|
|
9
12
|
var sse_js$1 = require('@modelcontextprotocol/sdk/client/sse.js');
|
|
10
13
|
var stdio_js$1 = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
11
14
|
var streamableHttp_js$1 = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
12
|
-
var protocol_js = require('@modelcontextprotocol/sdk/shared/protocol.js');
|
|
13
15
|
var types_js = require('@modelcontextprotocol/sdk/types.js');
|
|
14
16
|
var exitHook = require('exit-hook');
|
|
15
17
|
var zod = require('zod');
|
|
16
18
|
var zodFromJsonSchema = require('zod-from-json-schema');
|
|
17
19
|
var zodFromJsonSchemaV3 = require('zod-from-json-schema-v3');
|
|
18
|
-
var equal = require('fast-deep-equal');
|
|
19
|
-
var uuid = require('uuid');
|
|
20
20
|
var crypto$1 = require('crypto');
|
|
21
21
|
var mcp = require('@mastra/core/mcp');
|
|
22
|
-
var
|
|
22
|
+
var requestContext = require('@mastra/core/request-context');
|
|
23
23
|
var index_js = require('@modelcontextprotocol/sdk/server/index.js');
|
|
24
24
|
var sse_js = require('@modelcontextprotocol/sdk/server/sse.js');
|
|
25
25
|
var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
@@ -27,10 +27,10 @@ var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp
|
|
|
27
27
|
|
|
28
28
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
29
|
|
|
30
|
-
var $RefParser__default = /*#__PURE__*/_interopDefault($RefParser);
|
|
31
30
|
var equal__default = /*#__PURE__*/_interopDefault(equal);
|
|
31
|
+
var $RefParser__default = /*#__PURE__*/_interopDefault($RefParser);
|
|
32
32
|
|
|
33
|
-
// src/client/
|
|
33
|
+
// src/client/configuration.ts
|
|
34
34
|
|
|
35
35
|
// src/client/elicitationActions.ts
|
|
36
36
|
var ElicitationClientActions = class {
|
|
@@ -454,7 +454,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
454
454
|
timestamp: /* @__PURE__ */ new Date(),
|
|
455
455
|
serverName: this.name,
|
|
456
456
|
details,
|
|
457
|
-
|
|
457
|
+
requestContext: this.currentOperationContext
|
|
458
458
|
});
|
|
459
459
|
}
|
|
460
460
|
}
|
|
@@ -784,15 +784,15 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
784
784
|
description: tool.description || "",
|
|
785
785
|
inputSchema: await this.convertInputSchema(tool.inputSchema),
|
|
786
786
|
outputSchema: await this.convertOutputSchema(tool.outputSchema),
|
|
787
|
-
execute: async (
|
|
787
|
+
execute: async (input, context) => {
|
|
788
788
|
const previousContext = this.currentOperationContext;
|
|
789
|
-
this.currentOperationContext =
|
|
789
|
+
this.currentOperationContext = context?.requestContext || null;
|
|
790
790
|
try {
|
|
791
|
-
this.log("debug", `Executing tool: ${tool.name}`, { toolArgs:
|
|
791
|
+
this.log("debug", `Executing tool: ${tool.name}`, { toolArgs: input });
|
|
792
792
|
const res = await this.client.callTool(
|
|
793
793
|
{
|
|
794
794
|
name: tool.name,
|
|
795
|
-
arguments:
|
|
795
|
+
arguments: input
|
|
796
796
|
},
|
|
797
797
|
types_js.CallToolResultSchema,
|
|
798
798
|
{
|
|
@@ -804,7 +804,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
804
804
|
} catch (e) {
|
|
805
805
|
this.log("error", `Error calling tool: ${tool.name}`, {
|
|
806
806
|
error: e instanceof Error ? e.stack : JSON.stringify(e, null, 2),
|
|
807
|
-
toolArgs:
|
|
807
|
+
toolArgs: input
|
|
808
808
|
});
|
|
809
809
|
throw e;
|
|
810
810
|
} finally {
|
|
@@ -825,19 +825,8 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
825
825
|
return toolsRes;
|
|
826
826
|
}
|
|
827
827
|
};
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
super(args);
|
|
831
|
-
throw new error.MastraError(
|
|
832
|
-
{
|
|
833
|
-
id: "MASTRA_MCP_CLIENT_DEPRECATED",
|
|
834
|
-
domain: error.ErrorDomain.MCP,
|
|
835
|
-
category: error.ErrorCategory.USER,
|
|
836
|
-
text: "[DEPRECATION] MastraMCPClient is deprecated and will be removed in a future release. Please use MCPClient instead."
|
|
837
|
-
}
|
|
838
|
-
);
|
|
839
|
-
}
|
|
840
|
-
};
|
|
828
|
+
|
|
829
|
+
// src/client/configuration.ts
|
|
841
830
|
var mcpClientInstances = /* @__PURE__ */ new Map();
|
|
842
831
|
var MCPClient = class extends base.MastraBase {
|
|
843
832
|
serverConfigs = {};
|
|
@@ -1438,14 +1427,15 @@ To fix this you have three different options:
|
|
|
1438
1427
|
* @example
|
|
1439
1428
|
* ```typescript
|
|
1440
1429
|
* const agent = new Agent({
|
|
1430
|
+
* id: 'multi-tool-agent',
|
|
1441
1431
|
* name: 'Multi-tool Agent',
|
|
1442
1432
|
* instructions: 'You have access to weather and stock tools.',
|
|
1443
1433
|
* model: 'openai/gpt-4',
|
|
1444
|
-
* tools: await mcp.
|
|
1434
|
+
* tools: await mcp.listTools(), // weather_getWeather, stockPrice_getPrice
|
|
1445
1435
|
* });
|
|
1446
1436
|
* ```
|
|
1447
1437
|
*/
|
|
1448
|
-
async
|
|
1438
|
+
async listTools() {
|
|
1449
1439
|
this.addToInstanceCache();
|
|
1450
1440
|
const connectedTools = {};
|
|
1451
1441
|
try {
|
|
@@ -1469,7 +1459,7 @@ To fix this you have three different options:
|
|
|
1469
1459
|
/**
|
|
1470
1460
|
* Returns toolsets organized by server name for dynamic tool injection.
|
|
1471
1461
|
*
|
|
1472
|
-
* Unlike
|
|
1462
|
+
* Unlike listTools(), this returns tools grouped by server without namespacing.
|
|
1473
1463
|
* This is intended to be passed dynamically to the generate() or stream() method.
|
|
1474
1464
|
*
|
|
1475
1465
|
* @returns Object mapping server names to their tool collections
|
|
@@ -1478,17 +1468,18 @@ To fix this you have three different options:
|
|
|
1478
1468
|
* @example
|
|
1479
1469
|
* ```typescript
|
|
1480
1470
|
* const agent = new Agent({
|
|
1471
|
+
* id: 'dynamic-agent',
|
|
1481
1472
|
* name: 'Dynamic Agent',
|
|
1482
1473
|
* instructions: 'You can use tools dynamically.',
|
|
1483
1474
|
* model: 'openai/gpt-4',
|
|
1484
1475
|
* });
|
|
1485
1476
|
*
|
|
1486
1477
|
* const response = await agent.stream(prompt, {
|
|
1487
|
-
* toolsets: await mcp.
|
|
1478
|
+
* toolsets: await mcp.listToolsets(), // { weather: {...}, stockPrice: {...} }
|
|
1488
1479
|
* });
|
|
1489
1480
|
* ```
|
|
1490
1481
|
*/
|
|
1491
|
-
async
|
|
1482
|
+
async listToolsets() {
|
|
1492
1483
|
this.addToInstanceCache();
|
|
1493
1484
|
const connectedToolsets = {};
|
|
1494
1485
|
try {
|
|
@@ -1509,12 +1500,6 @@ To fix this you have three different options:
|
|
|
1509
1500
|
}
|
|
1510
1501
|
return connectedToolsets;
|
|
1511
1502
|
}
|
|
1512
|
-
/**
|
|
1513
|
-
* @deprecated all resource actions have been moved to the this.resources object. Use this.resources.list() instead.
|
|
1514
|
-
*/
|
|
1515
|
-
async getResources() {
|
|
1516
|
-
return this.resources.list();
|
|
1517
|
-
}
|
|
1518
1503
|
/**
|
|
1519
1504
|
* Gets current session IDs for all connected MCP clients using Streamable HTTP transport.
|
|
1520
1505
|
*
|
|
@@ -1601,24 +1586,8 @@ To fix this you have three different options:
|
|
|
1601
1586
|
);
|
|
1602
1587
|
}
|
|
1603
1588
|
};
|
|
1604
|
-
var MCPConfiguration = class extends MCPClient {
|
|
1605
|
-
/**
|
|
1606
|
-
* @deprecated Use MCPClient constructor instead
|
|
1607
|
-
*/
|
|
1608
|
-
constructor(args) {
|
|
1609
|
-
super(args);
|
|
1610
|
-
throw new error.MastraError(
|
|
1611
|
-
{
|
|
1612
|
-
id: "MCP_CLIENT_CONFIGURATION_DEPRECATED",
|
|
1613
|
-
domain: error.ErrorDomain.MCP,
|
|
1614
|
-
category: error.ErrorCategory.USER,
|
|
1615
|
-
text: "[DEPRECATION] MCPConfiguration has been renamed to MCPClient and MCPConfiguration is deprecated. The API is identical but the MCPConfiguration export will be removed in the future. Update your imports now to prevent future errors."
|
|
1616
|
-
}
|
|
1617
|
-
);
|
|
1618
|
-
}
|
|
1619
|
-
};
|
|
1620
1589
|
|
|
1621
|
-
// ../../node_modules/.pnpm/hono@4.10.
|
|
1590
|
+
// ../../node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/stream.js
|
|
1622
1591
|
var StreamingApi = class {
|
|
1623
1592
|
writer;
|
|
1624
1593
|
encoder;
|
|
@@ -1685,7 +1654,7 @@ var StreamingApi = class {
|
|
|
1685
1654
|
}
|
|
1686
1655
|
};
|
|
1687
1656
|
|
|
1688
|
-
// ../../node_modules/.pnpm/hono@4.10.
|
|
1657
|
+
// ../../node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/helper/streaming/utils.js
|
|
1689
1658
|
var isOldBunVersion = () => {
|
|
1690
1659
|
const version = typeof Bun !== "undefined" ? Bun.version : void 0;
|
|
1691
1660
|
if (version === void 0) {
|
|
@@ -1696,7 +1665,7 @@ var isOldBunVersion = () => {
|
|
|
1696
1665
|
return result;
|
|
1697
1666
|
};
|
|
1698
1667
|
|
|
1699
|
-
// ../../node_modules/.pnpm/hono@4.10.
|
|
1668
|
+
// ../../node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/html.js
|
|
1700
1669
|
var HtmlEscapedCallbackPhase = {
|
|
1701
1670
|
Stringify: 1};
|
|
1702
1671
|
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
|
@@ -1727,7 +1696,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
1727
1696
|
}
|
|
1728
1697
|
};
|
|
1729
1698
|
|
|
1730
|
-
// ../../node_modules/.pnpm/hono@4.10.
|
|
1699
|
+
// ../../node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/helper/streaming/sse.js
|
|
1731
1700
|
var SSEStreamingApi = class extends StreamingApi {
|
|
1732
1701
|
constructor(writable, readable) {
|
|
1733
1702
|
super(writable, readable);
|
|
@@ -2138,7 +2107,8 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2138
2107
|
* import { z } from 'zod';
|
|
2139
2108
|
*
|
|
2140
2109
|
* const myAgent = new Agent({
|
|
2141
|
-
*
|
|
2110
|
+
* id: 'helper',
|
|
2111
|
+
* name: 'Helper Agent',
|
|
2142
2112
|
* description: 'A helpful assistant',
|
|
2143
2113
|
* instructions: 'You are helpful.',
|
|
2144
2114
|
* model: 'openai/gpt-4o-mini',
|
|
@@ -2152,7 +2122,7 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2152
2122
|
* id: 'getWeather',
|
|
2153
2123
|
* description: 'Gets weather',
|
|
2154
2124
|
* inputSchema: z.object({ location: z.string() }),
|
|
2155
|
-
* execute: async (
|
|
2125
|
+
* execute: async (inputData) => `Sunny in ${inputData.location}`,
|
|
2156
2126
|
* })
|
|
2157
2127
|
* },
|
|
2158
2128
|
* agents: { myAgent },
|
|
@@ -2249,7 +2219,7 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2249
2219
|
return {
|
|
2250
2220
|
tools: Object.values(this.convertedTools).map((tool) => {
|
|
2251
2221
|
const toolSpec = {
|
|
2252
|
-
name: tool.
|
|
2222
|
+
name: tool.id || "unknown",
|
|
2253
2223
|
description: tool.description,
|
|
2254
2224
|
inputSchema: tool.parameters.jsonSchema
|
|
2255
2225
|
};
|
|
@@ -2308,12 +2278,23 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2308
2278
|
return this.handleElicitationRequest(request2, serverInstance);
|
|
2309
2279
|
}
|
|
2310
2280
|
};
|
|
2311
|
-
const
|
|
2281
|
+
const mcpOptions = {
|
|
2312
2282
|
messages: [],
|
|
2313
2283
|
toolCallId: "",
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2284
|
+
// Pass MCP-specific context through the mcp property
|
|
2285
|
+
mcp: {
|
|
2286
|
+
elicitation: sessionElicitation,
|
|
2287
|
+
extra
|
|
2288
|
+
},
|
|
2289
|
+
// @ts-ignore this is to let people know that the elicitation and extra keys are now nested under mcp.elicitation and mcp.extra in tool arguments
|
|
2290
|
+
get elicitation() {
|
|
2291
|
+
throw new Error(`The "elicitation" key is now nested under "mcp.elicitation" in tool arguments`);
|
|
2292
|
+
},
|
|
2293
|
+
get extra() {
|
|
2294
|
+
throw new Error(`The "extra" key is now nested under "mcp.extra" in tool arguments`);
|
|
2295
|
+
}
|
|
2296
|
+
};
|
|
2297
|
+
const result = await tool.execute(validation?.value ?? request.params.arguments ?? {}, mcpOptions);
|
|
2317
2298
|
this.logger.debug(`CallTool: Tool '${request.params.name}' executed successfully with result:`, result);
|
|
2318
2299
|
const duration = Date.now() - startTime;
|
|
2319
2300
|
this.logger.info(`Tool '${request.params.name}' executed successfully in ${duration}ms.`);
|
|
@@ -2589,12 +2570,19 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2589
2570
|
inputSchema: zod.z.object({
|
|
2590
2571
|
message: zod.z.string().describe("The question or input for the agent.")
|
|
2591
2572
|
}),
|
|
2592
|
-
execute: async (
|
|
2573
|
+
execute: async (inputData, context) => {
|
|
2593
2574
|
this.logger.debug(
|
|
2594
|
-
`Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${
|
|
2575
|
+
`Executing agent tool '${agentToolName}' for agent '${agent.name}' with message: "${inputData.message}"`
|
|
2595
2576
|
);
|
|
2596
2577
|
try {
|
|
2597
|
-
const
|
|
2578
|
+
const proxiedContext = context?.requestContext || new requestContext.RequestContext();
|
|
2579
|
+
if (context?.mcp?.extra) {
|
|
2580
|
+
proxiedContext.set("mcp.extra", context.mcp.extra);
|
|
2581
|
+
}
|
|
2582
|
+
const response = await agent.generate(inputData.message, {
|
|
2583
|
+
...context ?? {},
|
|
2584
|
+
requestContext: proxiedContext
|
|
2585
|
+
});
|
|
2598
2586
|
return response;
|
|
2599
2587
|
} catch (error) {
|
|
2600
2588
|
this.logger.error(`Error executing agent tool '${agentToolName}' for agent '${agent.name}':`, error);
|
|
@@ -2606,17 +2594,17 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2606
2594
|
name: agentToolName,
|
|
2607
2595
|
logger: this.logger,
|
|
2608
2596
|
mastra: this.mastra,
|
|
2609
|
-
|
|
2597
|
+
requestContext: new requestContext.RequestContext(),
|
|
2610
2598
|
tracingContext: {},
|
|
2611
2599
|
description: agentToolDefinition.description
|
|
2612
2600
|
};
|
|
2613
2601
|
const coreTool = utils.makeCoreTool(agentToolDefinition, options);
|
|
2614
2602
|
agentTools[agentToolName] = {
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2603
|
+
...coreTool,
|
|
2604
|
+
id: agentToolName,
|
|
2605
|
+
mcp: {
|
|
2606
|
+
toolType: "agent"
|
|
2607
|
+
}
|
|
2620
2608
|
};
|
|
2621
2609
|
this.logger.info(`Registered agent '${agent.name}' (key: '${agentKey}') as tool: '${agentToolName}'`);
|
|
2622
2610
|
}
|
|
@@ -2652,14 +2640,18 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2652
2640
|
id: workflowToolName,
|
|
2653
2641
|
description: `Run workflow '${workflowKey}'. Workflow description: ${workflowDescription}`,
|
|
2654
2642
|
inputSchema: workflow.inputSchema,
|
|
2655
|
-
execute: async (
|
|
2643
|
+
execute: async (inputData, context) => {
|
|
2656
2644
|
this.logger.debug(
|
|
2657
2645
|
`Executing workflow tool '${workflowToolName}' for workflow '${workflow.id}' with input:`,
|
|
2658
|
-
|
|
2646
|
+
inputData
|
|
2659
2647
|
);
|
|
2660
2648
|
try {
|
|
2661
|
-
const run2 = await workflow.
|
|
2662
|
-
const response = await run2.start({
|
|
2649
|
+
const run2 = await workflow.createRun({ runId: context?.requestContext?.get("runId") });
|
|
2650
|
+
const response = await run2.start({
|
|
2651
|
+
inputData,
|
|
2652
|
+
requestContext: context?.requestContext,
|
|
2653
|
+
tracingContext: context?.tracingContext
|
|
2654
|
+
});
|
|
2663
2655
|
return response;
|
|
2664
2656
|
} catch (error) {
|
|
2665
2657
|
this.logger.error(
|
|
@@ -2674,18 +2666,17 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2674
2666
|
name: workflowToolName,
|
|
2675
2667
|
logger: this.logger,
|
|
2676
2668
|
mastra: this.mastra,
|
|
2677
|
-
|
|
2669
|
+
requestContext: new requestContext.RequestContext(),
|
|
2678
2670
|
tracingContext: {},
|
|
2679
2671
|
description: workflowToolDefinition.description
|
|
2680
2672
|
};
|
|
2681
2673
|
const coreTool = utils.makeCoreTool(workflowToolDefinition, options);
|
|
2682
2674
|
workflowTools[workflowToolName] = {
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
toolType: "workflow"
|
|
2675
|
+
...coreTool,
|
|
2676
|
+
id: workflowToolName,
|
|
2677
|
+
mcp: {
|
|
2678
|
+
toolType: "workflow"
|
|
2679
|
+
}
|
|
2689
2680
|
};
|
|
2690
2681
|
this.logger.info(`Registered workflow '${workflow.id}' (key: '${workflowKey}') as tool: '${workflowToolName}'`);
|
|
2691
2682
|
}
|
|
@@ -2713,7 +2704,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2713
2704
|
}
|
|
2714
2705
|
const options = {
|
|
2715
2706
|
name: toolName,
|
|
2716
|
-
|
|
2707
|
+
requestContext: new requestContext.RequestContext(),
|
|
2717
2708
|
tracingContext: {},
|
|
2718
2709
|
mastra: this.mastra,
|
|
2719
2710
|
logger: this.logger,
|
|
@@ -2721,11 +2712,8 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2721
2712
|
};
|
|
2722
2713
|
const coreTool = utils.makeCoreTool(toolInstance, options);
|
|
2723
2714
|
definedConvertedTools[toolName] = {
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
parameters: coreTool.parameters,
|
|
2727
|
-
outputSchema: coreTool.outputSchema,
|
|
2728
|
-
execute: coreTool.execute
|
|
2715
|
+
...coreTool,
|
|
2716
|
+
id: toolName
|
|
2729
2717
|
};
|
|
2730
2718
|
this.logger.info(`Registered explicit tool: '${toolName}'`);
|
|
2731
2719
|
}
|
|
@@ -2969,6 +2957,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2969
2957
|
* @param options.options.onsessioninitialized - Callback when a new session is initialized
|
|
2970
2958
|
* @param options.options.enableJsonResponse - If true, return JSON instead of SSE streaming
|
|
2971
2959
|
* @param options.options.eventStore - Event store for message resumability
|
|
2960
|
+
* @param options.options.serverless - If true, run in stateless mode without session management (ideal for serverless environments)
|
|
2972
2961
|
*
|
|
2973
2962
|
* @throws {MastraError} If HTTP connection setup fails
|
|
2974
2963
|
*
|
|
@@ -2994,6 +2983,25 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2994
2983
|
*
|
|
2995
2984
|
* httpServer.listen(1234);
|
|
2996
2985
|
* ```
|
|
2986
|
+
*
|
|
2987
|
+
* @example Serverless mode (Cloudflare Workers, Vercel Edge, etc.)
|
|
2988
|
+
* ```typescript
|
|
2989
|
+
* export default {
|
|
2990
|
+
* async fetch(request: Request) {
|
|
2991
|
+
* const url = new URL(request.url);
|
|
2992
|
+
* if (url.pathname === '/mcp') {
|
|
2993
|
+
* await server.startHTTP({
|
|
2994
|
+
* url,
|
|
2995
|
+
* httpPath: '/mcp',
|
|
2996
|
+
* req: request,
|
|
2997
|
+
* res: response,
|
|
2998
|
+
* options: { serverless: true },
|
|
2999
|
+
* });
|
|
3000
|
+
* }
|
|
3001
|
+
* return new Response('Not found', { status: 404 });
|
|
3002
|
+
* },
|
|
3003
|
+
* };
|
|
3004
|
+
* ```
|
|
2997
3005
|
*/
|
|
2998
3006
|
async startHTTP({
|
|
2999
3007
|
url,
|
|
@@ -3009,6 +3017,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3009
3017
|
res.end();
|
|
3010
3018
|
return;
|
|
3011
3019
|
}
|
|
3020
|
+
if (options?.serverless) {
|
|
3021
|
+
this.logger.debug("startHTTP: Running in serverless (stateless) mode");
|
|
3022
|
+
await this.handleServerlessRequest(req, res);
|
|
3023
|
+
return;
|
|
3024
|
+
}
|
|
3012
3025
|
const sessionId = req.headers["mcp-session-id"];
|
|
3013
3026
|
let transport;
|
|
3014
3027
|
this.logger.debug(
|
|
@@ -3144,6 +3157,74 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3144
3157
|
}
|
|
3145
3158
|
}
|
|
3146
3159
|
}
|
|
3160
|
+
/**
|
|
3161
|
+
* Handles a stateless, serverless HTTP request without session management.
|
|
3162
|
+
*
|
|
3163
|
+
* This method bypasses all session/transport state and handles each request independently.
|
|
3164
|
+
* For serverless environments (Cloudflare Workers, Vercel Edge, etc.) where
|
|
3165
|
+
* persistent connections and session state cannot be maintained across requests.
|
|
3166
|
+
*
|
|
3167
|
+
* Each request gets a fresh transport and server instance that are discarded after the response.
|
|
3168
|
+
*
|
|
3169
|
+
* @param req - Incoming HTTP request
|
|
3170
|
+
* @param res - HTTP response object
|
|
3171
|
+
* @private
|
|
3172
|
+
*/
|
|
3173
|
+
async handleServerlessRequest(req, res) {
|
|
3174
|
+
try {
|
|
3175
|
+
this.logger.debug(`handleServerlessRequest: Received ${req.method} request`);
|
|
3176
|
+
const body = req.method === "POST" ? await new Promise((resolve, reject) => {
|
|
3177
|
+
let data = "";
|
|
3178
|
+
req.on("data", (chunk) => data += chunk);
|
|
3179
|
+
req.on("end", () => {
|
|
3180
|
+
try {
|
|
3181
|
+
resolve(JSON.parse(data));
|
|
3182
|
+
} catch (e) {
|
|
3183
|
+
reject(new Error(`Invalid JSON in request body: ${e instanceof Error ? e.message : String(e)}`));
|
|
3184
|
+
}
|
|
3185
|
+
});
|
|
3186
|
+
req.on("error", reject);
|
|
3187
|
+
}) : void 0;
|
|
3188
|
+
this.logger.debug(`handleServerlessRequest: Processing ${req.method} request`, {
|
|
3189
|
+
method: body?.method,
|
|
3190
|
+
id: body?.id
|
|
3191
|
+
});
|
|
3192
|
+
const transientServer = this.createServerInstance();
|
|
3193
|
+
const tempTransport = new streamableHttp_js.StreamableHTTPServerTransport({
|
|
3194
|
+
sessionIdGenerator: void 0,
|
|
3195
|
+
enableJsonResponse: true
|
|
3196
|
+
});
|
|
3197
|
+
await transientServer.connect(tempTransport);
|
|
3198
|
+
await tempTransport.handleRequest(req, res, body);
|
|
3199
|
+
this.logger.debug(`handleServerlessRequest: Completed ${body?.method} request`, { id: body?.id });
|
|
3200
|
+
} catch (error$1) {
|
|
3201
|
+
const mastraError = new error.MastraError(
|
|
3202
|
+
{
|
|
3203
|
+
id: "MCP_SERVER_SERVERLESS_REQUEST_FAILED",
|
|
3204
|
+
domain: error.ErrorDomain.MCP,
|
|
3205
|
+
category: error.ErrorCategory.USER,
|
|
3206
|
+
text: "Failed to handle serverless MCP request"
|
|
3207
|
+
},
|
|
3208
|
+
error$1
|
|
3209
|
+
);
|
|
3210
|
+
this.logger.trackException(mastraError);
|
|
3211
|
+
this.logger.error("handleServerlessRequest: Error handling request:", { error: mastraError });
|
|
3212
|
+
if (!res.headersSent) {
|
|
3213
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
3214
|
+
res.end(
|
|
3215
|
+
JSON.stringify({
|
|
3216
|
+
jsonrpc: "2.0",
|
|
3217
|
+
error: {
|
|
3218
|
+
code: -32603,
|
|
3219
|
+
message: "Internal server error",
|
|
3220
|
+
data: error$1 instanceof Error ? error$1.message : String(error$1)
|
|
3221
|
+
},
|
|
3222
|
+
id: null
|
|
3223
|
+
})
|
|
3224
|
+
);
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3147
3228
|
/**
|
|
3148
3229
|
* Establishes the SSE connection for the MCP server.
|
|
3149
3230
|
*
|
|
@@ -3392,11 +3473,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3392
3473
|
return {
|
|
3393
3474
|
tools: Object.entries(this.convertedTools).map(([toolId, tool]) => ({
|
|
3394
3475
|
id: toolId,
|
|
3395
|
-
name: tool.
|
|
3476
|
+
name: tool.id || toolId,
|
|
3396
3477
|
description: tool.description,
|
|
3397
3478
|
inputSchema: tool.parameters?.jsonSchema || tool.parameters,
|
|
3398
3479
|
outputSchema: tool.outputSchema?.jsonSchema || tool.outputSchema,
|
|
3399
|
-
toolType: tool.toolType
|
|
3480
|
+
toolType: tool.mcp?.toolType
|
|
3400
3481
|
}))
|
|
3401
3482
|
};
|
|
3402
3483
|
}
|
|
@@ -3426,11 +3507,11 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3426
3507
|
}
|
|
3427
3508
|
this.logger.debug(`Getting info for tool '${toolId}' on MCPServer '${this.name}'`);
|
|
3428
3509
|
return {
|
|
3429
|
-
name: tool.
|
|
3510
|
+
name: tool.id || toolId,
|
|
3430
3511
|
description: tool.description,
|
|
3431
3512
|
inputSchema: tool.parameters?.jsonSchema || tool.parameters,
|
|
3432
3513
|
outputSchema: tool.outputSchema?.jsonSchema || tool.outputSchema,
|
|
3433
|
-
toolType: tool.toolType
|
|
3514
|
+
toolType: tool.mcp?.toolType
|
|
3434
3515
|
};
|
|
3435
3516
|
}
|
|
3436
3517
|
/**
|
|
@@ -3535,8 +3616,6 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
3535
3616
|
};
|
|
3536
3617
|
|
|
3537
3618
|
exports.MCPClient = MCPClient;
|
|
3538
|
-
exports.MCPConfiguration = MCPConfiguration;
|
|
3539
3619
|
exports.MCPServer = MCPServer;
|
|
3540
|
-
exports.MastraMCPClient = MastraMCPClient;
|
|
3541
3620
|
//# sourceMappingURL=index.cjs.map
|
|
3542
3621
|
//# sourceMappingURL=index.cjs.map
|