@mastra/mcp 0.10.4 → 0.10.5-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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +13 -0
- package/dist/index.cjs +461 -143
- package/dist/index.js +451 -133
- package/package.json +2 -2
- package/src/client/configuration.ts +166 -35
- package/src/server/promptActions.ts +13 -2
- package/src/server/resourceActions.ts +32 -4
- package/src/server/server.ts +251 -98
- package/integration-tests/node_modules/.bin/mastra +0 -21
package/src/server/server.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type * as http from 'node:http';
|
|
|
3
3
|
import type { InternalCoreTool } from '@mastra/core';
|
|
4
4
|
import { createTool, makeCoreTool } from '@mastra/core';
|
|
5
5
|
import type { ToolsInput, Agent } from '@mastra/core/agent';
|
|
6
|
+
import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';
|
|
6
7
|
import { MCPServerBase } from '@mastra/core/mcp';
|
|
7
8
|
import type {
|
|
8
9
|
MCPServerConfig,
|
|
@@ -374,8 +375,26 @@ export class MCPServer extends MCPServerBase {
|
|
|
374
375
|
}
|
|
375
376
|
this.logger.info(`Total defined tools registered: ${Object.keys(definedConvertedTools).length}`);
|
|
376
377
|
|
|
377
|
-
|
|
378
|
-
|
|
378
|
+
let agentDerivedTools: Record<string, ConvertedTool> = {};
|
|
379
|
+
let workflowDerivedTools: Record<string, ConvertedTool> = {};
|
|
380
|
+
try {
|
|
381
|
+
agentDerivedTools = this.convertAgentsToTools(agentsConfig, definedConvertedTools);
|
|
382
|
+
workflowDerivedTools = this.convertWorkflowsToTools(workflowsConfig, definedConvertedTools);
|
|
383
|
+
} catch (e) {
|
|
384
|
+
const mastraError = new MastraError(
|
|
385
|
+
{
|
|
386
|
+
id: 'MCP_SERVER_AGENT_OR_WORKFLOW_TOOL_CONVERSION_FAILED',
|
|
387
|
+
domain: ErrorDomain.MCP,
|
|
388
|
+
category: ErrorCategory.USER,
|
|
389
|
+
},
|
|
390
|
+
e,
|
|
391
|
+
);
|
|
392
|
+
this.logger.trackException(mastraError);
|
|
393
|
+
this.logger.error('Failed to convert tools:', {
|
|
394
|
+
error: mastraError.toString(),
|
|
395
|
+
});
|
|
396
|
+
throw mastraError;
|
|
397
|
+
}
|
|
379
398
|
|
|
380
399
|
const allConvertedTools = { ...definedConvertedTools, ...agentDerivedTools, ...workflowDerivedTools };
|
|
381
400
|
|
|
@@ -776,7 +795,23 @@ export class MCPServer extends MCPServerBase {
|
|
|
776
795
|
*/
|
|
777
796
|
public async startStdio(): Promise<void> {
|
|
778
797
|
this.stdioTransport = new StdioServerTransport();
|
|
779
|
-
|
|
798
|
+
try {
|
|
799
|
+
await this.server.connect(this.stdioTransport);
|
|
800
|
+
} catch (error) {
|
|
801
|
+
const mastraError = new MastraError(
|
|
802
|
+
{
|
|
803
|
+
id: 'MCP_SERVER_STDIO_CONNECTION_FAILED',
|
|
804
|
+
domain: ErrorDomain.MCP,
|
|
805
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
806
|
+
},
|
|
807
|
+
error,
|
|
808
|
+
);
|
|
809
|
+
this.logger.trackException(mastraError);
|
|
810
|
+
this.logger.error('Failed to connect MCP server using stdio transport:', {
|
|
811
|
+
error: mastraError.toString(),
|
|
812
|
+
});
|
|
813
|
+
throw mastraError;
|
|
814
|
+
}
|
|
780
815
|
this.logger.info('Started MCP Server (stdio)');
|
|
781
816
|
}
|
|
782
817
|
|
|
@@ -791,23 +826,42 @@ export class MCPServer extends MCPServerBase {
|
|
|
791
826
|
* @param res HTTP response (must support .write/.end)
|
|
792
827
|
*/
|
|
793
828
|
public async startSSE({ url, ssePath, messagePath, req, res }: MCPServerSSEOptions): Promise<void> {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
829
|
+
try {
|
|
830
|
+
if (url.pathname === ssePath) {
|
|
831
|
+
await this.connectSSE({
|
|
832
|
+
messagePath,
|
|
833
|
+
res,
|
|
834
|
+
});
|
|
835
|
+
} else if (url.pathname === messagePath) {
|
|
836
|
+
this.logger.debug('Received message');
|
|
837
|
+
if (!this.sseTransport) {
|
|
838
|
+
res.writeHead(503);
|
|
839
|
+
res.end('SSE connection not established');
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
await this.sseTransport.handlePostMessage(req, res);
|
|
843
|
+
} else {
|
|
844
|
+
this.logger.debug('Unknown path:', { path: url.pathname });
|
|
845
|
+
res.writeHead(404);
|
|
846
|
+
res.end();
|
|
805
847
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
848
|
+
} catch (e) {
|
|
849
|
+
const mastraError = new MastraError(
|
|
850
|
+
{
|
|
851
|
+
id: 'MCP_SERVER_SSE_START_FAILED',
|
|
852
|
+
domain: ErrorDomain.MCP,
|
|
853
|
+
category: ErrorCategory.USER,
|
|
854
|
+
details: {
|
|
855
|
+
url: url.toString(),
|
|
856
|
+
ssePath,
|
|
857
|
+
messagePath,
|
|
858
|
+
},
|
|
859
|
+
},
|
|
860
|
+
e,
|
|
861
|
+
);
|
|
862
|
+
this.logger.trackException(mastraError);
|
|
863
|
+
this.logger.error('Failed to start MCP Server (SSE):', { error: mastraError.toString() });
|
|
864
|
+
throw mastraError;
|
|
811
865
|
}
|
|
812
866
|
}
|
|
813
867
|
|
|
@@ -821,31 +875,50 @@ export class MCPServer extends MCPServerBase {
|
|
|
821
875
|
* @param context Incoming Hono context
|
|
822
876
|
*/
|
|
823
877
|
public async startHonoSSE({ url, ssePath, messagePath, context }: MCPServerHonoSSEOptions) {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
878
|
+
try {
|
|
879
|
+
if (url.pathname === ssePath) {
|
|
880
|
+
return streamSSE(context, async stream => {
|
|
881
|
+
await this.connectHonoSSE({
|
|
882
|
+
messagePath,
|
|
883
|
+
stream,
|
|
884
|
+
});
|
|
829
885
|
});
|
|
830
|
-
})
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
886
|
+
} else if (url.pathname === messagePath) {
|
|
887
|
+
this.logger.debug('Received message');
|
|
888
|
+
const sessionId = context.req.query('sessionId');
|
|
889
|
+
this.logger.debug('Received message for sessionId', { sessionId });
|
|
890
|
+
if (!sessionId) {
|
|
891
|
+
return context.text('No sessionId provided', 400);
|
|
892
|
+
}
|
|
893
|
+
if (!this.sseHonoTransports.has(sessionId)) {
|
|
894
|
+
return context.text(`No transport found for sessionId ${sessionId}`, 400);
|
|
895
|
+
}
|
|
896
|
+
const message = await this.sseHonoTransports.get(sessionId)?.handlePostMessage(context);
|
|
897
|
+
if (!message) {
|
|
898
|
+
return context.text('Transport not found', 400);
|
|
899
|
+
}
|
|
900
|
+
return message;
|
|
901
|
+
} else {
|
|
902
|
+
this.logger.debug('Unknown path:', { path: url.pathname });
|
|
903
|
+
return context.text('Unknown path', 404);
|
|
844
904
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
905
|
+
} catch (e) {
|
|
906
|
+
const mastraError = new MastraError(
|
|
907
|
+
{
|
|
908
|
+
id: 'MCP_SERVER_HONO_SSE_START_FAILED',
|
|
909
|
+
domain: ErrorDomain.MCP,
|
|
910
|
+
category: ErrorCategory.USER,
|
|
911
|
+
details: {
|
|
912
|
+
url: url.toString(),
|
|
913
|
+
ssePath,
|
|
914
|
+
messagePath,
|
|
915
|
+
},
|
|
916
|
+
},
|
|
917
|
+
e,
|
|
918
|
+
);
|
|
919
|
+
this.logger.trackException(mastraError);
|
|
920
|
+
this.logger.error('Failed to start MCP Server (Hono SSE):', { error: mastraError.toString() });
|
|
921
|
+
throw mastraError;
|
|
849
922
|
}
|
|
850
923
|
}
|
|
851
924
|
|
|
@@ -1011,7 +1084,17 @@ export class MCPServer extends MCPServerBase {
|
|
|
1011
1084
|
}
|
|
1012
1085
|
}
|
|
1013
1086
|
} catch (error) {
|
|
1014
|
-
|
|
1087
|
+
const mastraError = new MastraError(
|
|
1088
|
+
{
|
|
1089
|
+
id: 'MCP_SERVER_HTTP_CONNECTION_FAILED',
|
|
1090
|
+
domain: ErrorDomain.MCP,
|
|
1091
|
+
category: ErrorCategory.USER,
|
|
1092
|
+
text: 'Failed to connect MCP server using HTTP transport',
|
|
1093
|
+
},
|
|
1094
|
+
error,
|
|
1095
|
+
);
|
|
1096
|
+
this.logger.trackException(mastraError);
|
|
1097
|
+
this.logger.error('startHTTP: Error handling Streamable HTTP request:', { error: mastraError });
|
|
1015
1098
|
// If headers haven't been sent, send an error response
|
|
1016
1099
|
if (!res.headersSent) {
|
|
1017
1100
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
@@ -1025,9 +1108,6 @@ export class MCPServer extends MCPServerBase {
|
|
|
1025
1108
|
id: null, // Cannot determine original request ID in catch
|
|
1026
1109
|
}),
|
|
1027
1110
|
);
|
|
1028
|
-
} else {
|
|
1029
|
-
// If headers were already sent (e.g., during SSE stream), just log the error
|
|
1030
|
-
this.logger.error('startHTTP: Error after headers sent:', error);
|
|
1031
1111
|
}
|
|
1032
1112
|
}
|
|
1033
1113
|
}
|
|
@@ -1039,18 +1119,35 @@ export class MCPServer extends MCPServerBase {
|
|
|
1039
1119
|
messagePath: string;
|
|
1040
1120
|
res: http.ServerResponse<http.IncomingMessage>;
|
|
1041
1121
|
}) {
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1122
|
+
try {
|
|
1123
|
+
this.logger.debug('Received SSE connection');
|
|
1124
|
+
this.sseTransport = new SSEServerTransport(messagePath, res);
|
|
1125
|
+
await this.server.connect(this.sseTransport);
|
|
1045
1126
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1127
|
+
this.server.onclose = async () => {
|
|
1128
|
+
this.sseTransport = undefined;
|
|
1129
|
+
await this.server.close();
|
|
1130
|
+
};
|
|
1050
1131
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1132
|
+
res.on('close', () => {
|
|
1133
|
+
this.sseTransport = undefined;
|
|
1134
|
+
});
|
|
1135
|
+
} catch (e) {
|
|
1136
|
+
const mastraError = new MastraError(
|
|
1137
|
+
{
|
|
1138
|
+
id: 'MCP_SERVER_SSE_CONNECT_FAILED',
|
|
1139
|
+
domain: ErrorDomain.MCP,
|
|
1140
|
+
category: ErrorCategory.USER,
|
|
1141
|
+
details: {
|
|
1142
|
+
messagePath,
|
|
1143
|
+
},
|
|
1144
|
+
},
|
|
1145
|
+
e,
|
|
1146
|
+
);
|
|
1147
|
+
this.logger.trackException(mastraError);
|
|
1148
|
+
this.logger.error('Failed to connect to MCP Server (SSE):', { error: mastraError });
|
|
1149
|
+
throw mastraError;
|
|
1150
|
+
}
|
|
1054
1151
|
}
|
|
1055
1152
|
|
|
1056
1153
|
public async connectHonoSSE({ messagePath, stream }: { messagePath: string; stream: SSEStreamingApi }) {
|
|
@@ -1064,21 +1161,37 @@ export class MCPServer extends MCPServerBase {
|
|
|
1064
1161
|
this.logger.debug('SSE Transport aborted with sessionId:', { sessionId });
|
|
1065
1162
|
this.sseHonoTransports.delete(sessionId);
|
|
1066
1163
|
});
|
|
1164
|
+
try {
|
|
1165
|
+
await this.server.connect(sseTransport);
|
|
1166
|
+
this.server.onclose = async () => {
|
|
1167
|
+
this.logger.debug('SSE Transport closed with sessionId:', { sessionId });
|
|
1168
|
+
this.sseHonoTransports.delete(sessionId);
|
|
1169
|
+
await this.server.close();
|
|
1170
|
+
};
|
|
1067
1171
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1172
|
+
while (true) {
|
|
1173
|
+
// This will keep the connection alive
|
|
1174
|
+
// You can also await for a promise that never resolves
|
|
1175
|
+
const sessionIds = Array.from(this.sseHonoTransports.keys() || []);
|
|
1176
|
+
this.logger.debug('Active Hono SSE sessions:', { sessionIds });
|
|
1177
|
+
await stream.write(':keep-alive\n\n');
|
|
1178
|
+
await stream.sleep(60_000);
|
|
1179
|
+
}
|
|
1180
|
+
} catch (e) {
|
|
1181
|
+
const mastraError = new MastraError(
|
|
1182
|
+
{
|
|
1183
|
+
id: 'MCP_SERVER_HONO_SSE_CONNECT_FAILED',
|
|
1184
|
+
domain: ErrorDomain.MCP,
|
|
1185
|
+
category: ErrorCategory.USER,
|
|
1186
|
+
details: {
|
|
1187
|
+
messagePath,
|
|
1188
|
+
},
|
|
1189
|
+
},
|
|
1190
|
+
e,
|
|
1191
|
+
);
|
|
1192
|
+
this.logger.trackException(mastraError);
|
|
1193
|
+
this.logger.error('Failed to connect to MCP Server (Hono SSE):', { error: mastraError });
|
|
1194
|
+
throw mastraError;
|
|
1082
1195
|
}
|
|
1083
1196
|
}
|
|
1084
1197
|
|
|
@@ -1119,7 +1232,17 @@ export class MCPServer extends MCPServerBase {
|
|
|
1119
1232
|
await this.server.close();
|
|
1120
1233
|
this.logger.info('MCP server closed.');
|
|
1121
1234
|
} catch (error) {
|
|
1122
|
-
|
|
1235
|
+
const mastraError = new MastraError(
|
|
1236
|
+
{
|
|
1237
|
+
id: 'MCP_SERVER_CLOSE_FAILED',
|
|
1238
|
+
domain: ErrorDomain.MCP,
|
|
1239
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1240
|
+
},
|
|
1241
|
+
error,
|
|
1242
|
+
);
|
|
1243
|
+
this.logger.trackException(mastraError);
|
|
1244
|
+
this.logger.error('Error closing MCP server:', { error: mastraError });
|
|
1245
|
+
throw mastraError;
|
|
1123
1246
|
}
|
|
1124
1247
|
}
|
|
1125
1248
|
|
|
@@ -1210,35 +1333,52 @@ export class MCPServer extends MCPServerBase {
|
|
|
1210
1333
|
executionContext?: { messages?: any[]; toolCallId?: string },
|
|
1211
1334
|
): Promise<any> {
|
|
1212
1335
|
const tool = this.convertedTools[toolId];
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1336
|
+
let validatedArgs: any;
|
|
1337
|
+
try {
|
|
1338
|
+
if (!tool) {
|
|
1339
|
+
this.logger.warn(`ExecuteTool: Unknown tool '${toolId}' requested on MCPServer '${this.name}'.`);
|
|
1340
|
+
throw new Error(`Unknown tool: ${toolId}`);
|
|
1341
|
+
}
|
|
1217
1342
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
.
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1343
|
+
this.logger.debug(`ExecuteTool: Invoking '${toolId}' with arguments:`, args);
|
|
1344
|
+
|
|
1345
|
+
if (tool.parameters instanceof z.ZodType && typeof tool.parameters.safeParse === 'function') {
|
|
1346
|
+
const validation = tool.parameters.safeParse(args ?? {});
|
|
1347
|
+
if (!validation.success) {
|
|
1348
|
+
const errorMessages = validation.error.errors
|
|
1349
|
+
.map((e: z.ZodIssue) => `${e.path.join('.')}: ${e.message}`)
|
|
1350
|
+
.join(', ');
|
|
1351
|
+
this.logger.warn(`ExecuteTool: Invalid tool arguments for '${toolId}': ${errorMessages}`, {
|
|
1352
|
+
errors: validation.error.format(),
|
|
1353
|
+
});
|
|
1354
|
+
throw new z.ZodError(validation.error.issues);
|
|
1355
|
+
}
|
|
1356
|
+
validatedArgs = validation.data;
|
|
1357
|
+
} else {
|
|
1358
|
+
this.logger.debug(
|
|
1359
|
+
`ExecuteTool: Tool '${toolId}' parameters is not a Zod schema with safeParse or is undefined. Skipping validation.`,
|
|
1360
|
+
);
|
|
1231
1361
|
}
|
|
1232
|
-
validatedArgs = validation.data;
|
|
1233
|
-
} else {
|
|
1234
|
-
this.logger.debug(
|
|
1235
|
-
`ExecuteTool: Tool '${toolId}' parameters is not a Zod schema with safeParse or is undefined. Skipping validation.`,
|
|
1236
|
-
);
|
|
1237
|
-
}
|
|
1238
1362
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1363
|
+
if (!tool.execute) {
|
|
1364
|
+
this.logger.error(`ExecuteTool: Tool '${toolId}' does not have an execute function.`);
|
|
1365
|
+
throw new Error(`Tool '${toolId}' cannot be executed.`);
|
|
1366
|
+
}
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
const mastraError = new MastraError(
|
|
1369
|
+
{
|
|
1370
|
+
id: 'MCP_SERVER_TOOL_EXECUTE_PREPARATION_FAILED',
|
|
1371
|
+
domain: ErrorDomain.MCP,
|
|
1372
|
+
category: ErrorCategory.USER,
|
|
1373
|
+
details: {
|
|
1374
|
+
toolId,
|
|
1375
|
+
args,
|
|
1376
|
+
},
|
|
1377
|
+
},
|
|
1378
|
+
error,
|
|
1379
|
+
);
|
|
1380
|
+
this.logger.trackException(mastraError);
|
|
1381
|
+
throw mastraError;
|
|
1242
1382
|
}
|
|
1243
1383
|
|
|
1244
1384
|
try {
|
|
@@ -1250,8 +1390,21 @@ export class MCPServer extends MCPServerBase {
|
|
|
1250
1390
|
this.logger.info(`ExecuteTool: Tool '${toolId}' executed successfully.`);
|
|
1251
1391
|
return result;
|
|
1252
1392
|
} catch (error) {
|
|
1393
|
+
const mastraError = new MastraError(
|
|
1394
|
+
{
|
|
1395
|
+
id: 'MCP_SERVER_TOOL_EXECUTE_FAILED',
|
|
1396
|
+
domain: ErrorDomain.MCP,
|
|
1397
|
+
category: ErrorCategory.USER,
|
|
1398
|
+
details: {
|
|
1399
|
+
toolId,
|
|
1400
|
+
validatedArgs: validatedArgs,
|
|
1401
|
+
},
|
|
1402
|
+
},
|
|
1403
|
+
error,
|
|
1404
|
+
);
|
|
1405
|
+
this.logger.trackException(mastraError);
|
|
1253
1406
|
this.logger.error(`ExecuteTool: Tool execution failed for '${toolId}':`, { error });
|
|
1254
|
-
throw
|
|
1407
|
+
throw mastraError;
|
|
1255
1408
|
}
|
|
1256
1409
|
}
|
|
1257
1410
|
}
|
|
@@ -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
|