@mastra/mcp 2.8.0-alpha.2 → 2.9.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/dist/client/client.d.ts.map +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +193 -2
- package/dist/docs/references/docs-connections-mcp.md +99 -0
- package/dist/docs/references/reference-tools-mcp-client.md +4 -0
- package/dist/index.cjs +202 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +203 -127
- package/dist/index.js.map +1 -1
- package/dist/server/request.d.ts +3 -1
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/tasks/workflow-runs.d.ts +7 -0
- package/dist/server/tasks/workflow-runs.d.ts.map +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from "module";
|
|
|
2
2
|
import { AsyncLocalStorage } from "async_hooks";
|
|
3
3
|
import { MastraBase } from "@mastra/core/base";
|
|
4
4
|
import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
|
|
5
|
-
import { createTool, isValidationError, noopObserve, validateToolInput, validateToolOutput } from "@mastra/core/tools";
|
|
5
|
+
import { createTool, getValidationIssuePaths, isValidationError, noopObserve, validateToolInput, validateToolOutput } from "@mastra/core/tools";
|
|
6
6
|
import z3, { ZodFirstPartyTypeKind } from "zod/v3";
|
|
7
7
|
import { toJSONSchema, z } from "zod/v4";
|
|
8
8
|
import { z as z$1 } from "zod";
|
|
@@ -30,101 +30,6 @@ import { SignalProvider } from "@mastra/core/signals";
|
|
|
30
30
|
// src/client/types.ts
|
|
31
31
|
/** The current protocol revision; the one `/mcp` servers speak. */
|
|
32
32
|
const MCP_CLIENT_PROTOCOL_VERSION = "2026-07-28";
|
|
33
|
-
// ../schema-compat/dist/json-schema-traverse-D0CId4oM.js
|
|
34
|
-
var __create$1 = Object.create;
|
|
35
|
-
var __defProp$2 = Object.defineProperty;
|
|
36
|
-
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
37
|
-
var __getOwnPropNames$1 = Object.getOwnPropertyNames;
|
|
38
|
-
var __getProtoOf$1 = Object.getPrototypeOf;
|
|
39
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
40
|
-
var __commonJSMin$1 = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
|
|
41
|
-
var __copyProps$1 = (to, from, except, desc) => {
|
|
42
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames$1(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
43
|
-
key = keys[i];
|
|
44
|
-
if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$2(to, key, {
|
|
45
|
-
get: ((k) => from[k]).bind(null, key),
|
|
46
|
-
enumerable: !(desc = __getOwnPropDesc$1(from, key)) || desc.enumerable
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return to;
|
|
50
|
-
};
|
|
51
|
-
var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(__getProtoOf$1(mod)) : {}, __copyProps$1(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp$1.call(mod, "default") ? __defProp$2(target, "default", {
|
|
52
|
-
value: mod,
|
|
53
|
-
enumerable: true
|
|
54
|
-
}) : target, mod));
|
|
55
|
-
var require_json_schema_traverse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
56
|
-
var traverse = module.exports = function(schema, opts, cb) {
|
|
57
|
-
if (typeof opts == "function") {
|
|
58
|
-
cb = opts;
|
|
59
|
-
opts = {};
|
|
60
|
-
}
|
|
61
|
-
cb = opts.cb || cb;
|
|
62
|
-
var pre = typeof cb == "function" ? cb : cb.pre || function() {};
|
|
63
|
-
var post = cb.post || function() {};
|
|
64
|
-
_traverse(opts, pre, post, schema, "", schema);
|
|
65
|
-
};
|
|
66
|
-
traverse.keywords = {
|
|
67
|
-
additionalItems: true,
|
|
68
|
-
items: true,
|
|
69
|
-
contains: true,
|
|
70
|
-
additionalProperties: true,
|
|
71
|
-
propertyNames: true,
|
|
72
|
-
not: true,
|
|
73
|
-
if: true,
|
|
74
|
-
then: true,
|
|
75
|
-
else: true
|
|
76
|
-
};
|
|
77
|
-
traverse.arrayKeywords = {
|
|
78
|
-
items: true,
|
|
79
|
-
allOf: true,
|
|
80
|
-
anyOf: true,
|
|
81
|
-
oneOf: true
|
|
82
|
-
};
|
|
83
|
-
traverse.propsKeywords = {
|
|
84
|
-
$defs: true,
|
|
85
|
-
definitions: true,
|
|
86
|
-
properties: true,
|
|
87
|
-
patternProperties: true,
|
|
88
|
-
dependencies: true
|
|
89
|
-
};
|
|
90
|
-
traverse.skipKeywords = {
|
|
91
|
-
default: true,
|
|
92
|
-
enum: true,
|
|
93
|
-
const: true,
|
|
94
|
-
required: true,
|
|
95
|
-
maximum: true,
|
|
96
|
-
minimum: true,
|
|
97
|
-
exclusiveMaximum: true,
|
|
98
|
-
exclusiveMinimum: true,
|
|
99
|
-
multipleOf: true,
|
|
100
|
-
maxLength: true,
|
|
101
|
-
minLength: true,
|
|
102
|
-
pattern: true,
|
|
103
|
-
format: true,
|
|
104
|
-
maxItems: true,
|
|
105
|
-
minItems: true,
|
|
106
|
-
uniqueItems: true,
|
|
107
|
-
maxProperties: true,
|
|
108
|
-
minProperties: true
|
|
109
|
-
};
|
|
110
|
-
function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
|
|
111
|
-
if (schema && typeof schema == "object" && !Array.isArray(schema)) {
|
|
112
|
-
pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
113
|
-
for (var key in schema) {
|
|
114
|
-
var sch = schema[key];
|
|
115
|
-
if (Array.isArray(sch)) {
|
|
116
|
-
if (key in traverse.arrayKeywords) for (var i = 0; i < sch.length; i++) _traverse(opts, pre, post, sch[i], jsonPtr + "/" + key + "/" + i, rootSchema, jsonPtr, key, schema, i);
|
|
117
|
-
} else if (key in traverse.propsKeywords) {
|
|
118
|
-
if (sch && typeof sch == "object") for (var prop in sch) _traverse(opts, pre, post, sch[prop], jsonPtr + "/" + key + "/" + escapeJsonPtr(prop), rootSchema, jsonPtr, key, schema, prop);
|
|
119
|
-
} else if (key in traverse.keywords || opts.allKeys && !(key in traverse.skipKeywords)) _traverse(opts, pre, post, sch, jsonPtr + "/" + key, rootSchema, jsonPtr, key, schema);
|
|
120
|
-
}
|
|
121
|
-
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
function escapeJsonPtr(str) {
|
|
125
|
-
return str.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
126
|
-
}
|
|
127
|
-
}));
|
|
128
33
|
// ../schema-compat/dist/esm-BG70JlG8.js
|
|
129
34
|
const ignoreOverride$1 = Symbol("Let zodToJsonSchema decide on which parser to use");
|
|
130
35
|
const defaultOptions$1 = {
|
|
@@ -1330,6 +1235,101 @@ var AiSdkSchemaWrapper = class {
|
|
|
1330
1235
|
function toStandardSchema$4(schema) {
|
|
1331
1236
|
return new AiSdkSchemaWrapper(schema);
|
|
1332
1237
|
}
|
|
1238
|
+
// ../schema-compat/dist/json-schema-traverse-D0CId4oM.js
|
|
1239
|
+
var __create$1 = Object.create;
|
|
1240
|
+
var __defProp$2 = Object.defineProperty;
|
|
1241
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
1242
|
+
var __getOwnPropNames$1 = Object.getOwnPropertyNames;
|
|
1243
|
+
var __getProtoOf$1 = Object.getPrototypeOf;
|
|
1244
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
1245
|
+
var __commonJSMin$1 = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
|
|
1246
|
+
var __copyProps$1 = (to, from, except, desc) => {
|
|
1247
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames$1(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
1248
|
+
key = keys[i];
|
|
1249
|
+
if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$2(to, key, {
|
|
1250
|
+
get: ((k) => from[k]).bind(null, key),
|
|
1251
|
+
enumerable: !(desc = __getOwnPropDesc$1(from, key)) || desc.enumerable
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
return to;
|
|
1255
|
+
};
|
|
1256
|
+
var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(__getProtoOf$1(mod)) : {}, __copyProps$1(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp$1.call(mod, "default") ? __defProp$2(target, "default", {
|
|
1257
|
+
value: mod,
|
|
1258
|
+
enumerable: true
|
|
1259
|
+
}) : target, mod));
|
|
1260
|
+
var require_json_schema_traverse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
1261
|
+
var traverse = module.exports = function(schema, opts, cb) {
|
|
1262
|
+
if (typeof opts == "function") {
|
|
1263
|
+
cb = opts;
|
|
1264
|
+
opts = {};
|
|
1265
|
+
}
|
|
1266
|
+
cb = opts.cb || cb;
|
|
1267
|
+
var pre = typeof cb == "function" ? cb : cb.pre || function() {};
|
|
1268
|
+
var post = cb.post || function() {};
|
|
1269
|
+
_traverse(opts, pre, post, schema, "", schema);
|
|
1270
|
+
};
|
|
1271
|
+
traverse.keywords = {
|
|
1272
|
+
additionalItems: true,
|
|
1273
|
+
items: true,
|
|
1274
|
+
contains: true,
|
|
1275
|
+
additionalProperties: true,
|
|
1276
|
+
propertyNames: true,
|
|
1277
|
+
not: true,
|
|
1278
|
+
if: true,
|
|
1279
|
+
then: true,
|
|
1280
|
+
else: true
|
|
1281
|
+
};
|
|
1282
|
+
traverse.arrayKeywords = {
|
|
1283
|
+
items: true,
|
|
1284
|
+
allOf: true,
|
|
1285
|
+
anyOf: true,
|
|
1286
|
+
oneOf: true
|
|
1287
|
+
};
|
|
1288
|
+
traverse.propsKeywords = {
|
|
1289
|
+
$defs: true,
|
|
1290
|
+
definitions: true,
|
|
1291
|
+
properties: true,
|
|
1292
|
+
patternProperties: true,
|
|
1293
|
+
dependencies: true
|
|
1294
|
+
};
|
|
1295
|
+
traverse.skipKeywords = {
|
|
1296
|
+
default: true,
|
|
1297
|
+
enum: true,
|
|
1298
|
+
const: true,
|
|
1299
|
+
required: true,
|
|
1300
|
+
maximum: true,
|
|
1301
|
+
minimum: true,
|
|
1302
|
+
exclusiveMaximum: true,
|
|
1303
|
+
exclusiveMinimum: true,
|
|
1304
|
+
multipleOf: true,
|
|
1305
|
+
maxLength: true,
|
|
1306
|
+
minLength: true,
|
|
1307
|
+
pattern: true,
|
|
1308
|
+
format: true,
|
|
1309
|
+
maxItems: true,
|
|
1310
|
+
minItems: true,
|
|
1311
|
+
uniqueItems: true,
|
|
1312
|
+
maxProperties: true,
|
|
1313
|
+
minProperties: true
|
|
1314
|
+
};
|
|
1315
|
+
function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
|
|
1316
|
+
if (schema && typeof schema == "object" && !Array.isArray(schema)) {
|
|
1317
|
+
pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
1318
|
+
for (var key in schema) {
|
|
1319
|
+
var sch = schema[key];
|
|
1320
|
+
if (Array.isArray(sch)) {
|
|
1321
|
+
if (key in traverse.arrayKeywords) for (var i = 0; i < sch.length; i++) _traverse(opts, pre, post, sch[i], jsonPtr + "/" + key + "/" + i, rootSchema, jsonPtr, key, schema, i);
|
|
1322
|
+
} else if (key in traverse.propsKeywords) {
|
|
1323
|
+
if (sch && typeof sch == "object") for (var prop in sch) _traverse(opts, pre, post, sch[prop], jsonPtr + "/" + key + "/" + escapeJsonPtr(prop), rootSchema, jsonPtr, key, schema, prop);
|
|
1324
|
+
} else if (key in traverse.keywords || opts.allKeys && !(key in traverse.skipKeywords)) _traverse(opts, pre, post, sch, jsonPtr + "/" + key, rootSchema, jsonPtr, key, schema);
|
|
1325
|
+
}
|
|
1326
|
+
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
function escapeJsonPtr(str) {
|
|
1330
|
+
return str.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
1331
|
+
}
|
|
1332
|
+
}));
|
|
1333
1333
|
// ../schema-compat/dist/json-schema-BdCwqjfN.js
|
|
1334
1334
|
var require_code$1 = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
1335
1335
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -15951,6 +15951,50 @@ function runOutsideDatadogTraceScope(callback) {
|
|
|
15951
15951
|
if (!scope) return callback();
|
|
15952
15952
|
return scope.activate(null, callback);
|
|
15953
15953
|
}
|
|
15954
|
+
const LOGGABLE_ERROR_NAMES = /* @__PURE__ */ new Set([
|
|
15955
|
+
"Error",
|
|
15956
|
+
"TypeError",
|
|
15957
|
+
"RangeError",
|
|
15958
|
+
"SyntaxError",
|
|
15959
|
+
"AbortError",
|
|
15960
|
+
"TimeoutError",
|
|
15961
|
+
"McpError",
|
|
15962
|
+
"ProtocolError",
|
|
15963
|
+
"SdkError",
|
|
15964
|
+
"SdkHttpError",
|
|
15965
|
+
"SseError",
|
|
15966
|
+
"StreamableHTTPError",
|
|
15967
|
+
"UnauthorizedError",
|
|
15968
|
+
"OAuthError",
|
|
15969
|
+
"UnsupportedProtocolVersionError"
|
|
15970
|
+
]);
|
|
15971
|
+
const LOGGABLE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
15972
|
+
"ECONNRESET",
|
|
15973
|
+
"ECONNREFUSED",
|
|
15974
|
+
"ECONNABORTED",
|
|
15975
|
+
"ETIMEDOUT",
|
|
15976
|
+
"ENOTFOUND",
|
|
15977
|
+
"EPIPE",
|
|
15978
|
+
"EAI_AGAIN",
|
|
15979
|
+
"ABORT_ERR",
|
|
15980
|
+
"UND_ERR_SOCKET",
|
|
15981
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
15982
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
15983
|
+
"UND_ERR_BODY_TIMEOUT"
|
|
15984
|
+
]);
|
|
15985
|
+
/**
|
|
15986
|
+
* Names a tool-call failure for logs without its message: server error text can echo the submitted
|
|
15987
|
+
* arguments back (Issue #29318). The full error still reaches the caller.
|
|
15988
|
+
*/
|
|
15989
|
+
function errorKind(error) {
|
|
15990
|
+
if (error instanceof MastraError) return error.id;
|
|
15991
|
+
if (error instanceof Error) {
|
|
15992
|
+
const name = LOGGABLE_ERROR_NAMES.has(error.name) ? error.name : "Error";
|
|
15993
|
+
const code = error.code;
|
|
15994
|
+
return typeof code === "number" || typeof code === "string" && LOGGABLE_ERROR_CODES.has(code) ? `${name} (${code})` : name;
|
|
15995
|
+
}
|
|
15996
|
+
return typeof error;
|
|
15997
|
+
}
|
|
15954
15998
|
/**
|
|
15955
15999
|
* Convert an MCP LoggingLevel to a logger method name that exists in our logger
|
|
15956
16000
|
*/
|
|
@@ -17097,10 +17141,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
17097
17141
|
});
|
|
17098
17142
|
return res && finishToolCall(res);
|
|
17099
17143
|
}
|
|
17100
|
-
this.log("debug", `Executing tool: ${tool.name}`, {
|
|
17101
|
-
toolArgs: input,
|
|
17102
|
-
runId: context?.runId
|
|
17103
|
-
});
|
|
17144
|
+
this.log("debug", `Executing tool: ${tool.name}`, { runId: context?.runId });
|
|
17104
17145
|
const progressMeta = this.enableProgressTracking ? { progressToken: context?.runId || crypto.randomUUID() } : void 0;
|
|
17105
17146
|
const _meta = this.requestMeta({
|
|
17106
17147
|
...context?._meta,
|
|
@@ -17129,7 +17170,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
17129
17170
|
const finishToolCall = async (res) => {
|
|
17130
17171
|
if (res.isError && this.onToolError === "throw") {
|
|
17131
17172
|
const errorText = extractToolErrorText(res.content);
|
|
17132
|
-
this.log("debug", `Tool reported an error: ${tool.name}
|
|
17173
|
+
this.log("debug", `Tool reported an error: ${tool.name}`);
|
|
17133
17174
|
throw new MastraError({
|
|
17134
17175
|
id: "MCP_CLIENT_TOOL_EXECUTION_FAILED",
|
|
17135
17176
|
domain: ErrorDomain.MCP,
|
|
@@ -17148,7 +17189,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
17148
17189
|
const validationSchema = await getOutputValidationSchema();
|
|
17149
17190
|
const validation = validateToolOutput(validationSchema, res.structuredContent, tool.name);
|
|
17150
17191
|
if (validation.error) {
|
|
17151
|
-
this.log("debug", `Tool output failed schema validation: ${tool.name}`, {
|
|
17192
|
+
this.log("debug", `Tool output failed schema validation: ${tool.name}`, { issuePaths: getValidationIssuePaths(validation.error, validationSchema, "output") });
|
|
17152
17193
|
return validation.error;
|
|
17153
17194
|
}
|
|
17154
17195
|
}
|
|
@@ -17162,24 +17203,20 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
17162
17203
|
return await executeToolCall();
|
|
17163
17204
|
} catch (e) {
|
|
17164
17205
|
if (!(e instanceof MastraError && (e.id === "MCP_CLIENT_TOOL_EXECUTION_FAILED" || e.id.startsWith("MCP_CLIENT_TOOL_TASK_"))) && isReconnectableMCPError(e)) {
|
|
17165
|
-
this.log("debug", `Transport error detected for tool ${tool.name}, attempting reconnection...`, { error:
|
|
17206
|
+
this.log("debug", `Transport error detected for tool ${tool.name}, attempting reconnection...`, { error: errorKind(e) });
|
|
17166
17207
|
try {
|
|
17167
17208
|
await this.reconnectAfterTransportFailure(failedTransport, lifecycleGeneration);
|
|
17168
17209
|
this.log("debug", `Retrying tool ${tool.name} after reconnection...`);
|
|
17169
17210
|
return await executeToolCall();
|
|
17170
17211
|
} catch (reconnectError) {
|
|
17171
17212
|
this.log("error", `Reconnection or retry failed for tool ${tool.name}`, {
|
|
17172
|
-
originalError:
|
|
17173
|
-
reconnectError:
|
|
17174
|
-
toolArgs: input
|
|
17213
|
+
originalError: errorKind(e),
|
|
17214
|
+
reconnectError: errorKind(reconnectError)
|
|
17175
17215
|
});
|
|
17176
17216
|
throw reconnectError;
|
|
17177
17217
|
}
|
|
17178
17218
|
}
|
|
17179
|
-
this.log("error", `Error calling tool: ${tool.name}`, {
|
|
17180
|
-
error: e instanceof Error ? e.stack : JSON.stringify(e, null, 2),
|
|
17181
|
-
toolArgs: input
|
|
17182
|
-
});
|
|
17219
|
+
this.log("error", `Error calling tool: ${tool.name}`, { error: errorKind(e) });
|
|
17183
17220
|
throw e;
|
|
17184
17221
|
}
|
|
17185
17222
|
});
|
|
@@ -18981,7 +19018,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
18981
19018
|
const errors = {};
|
|
18982
19019
|
const errorDetails = {};
|
|
18983
19020
|
const durations = {};
|
|
18984
|
-
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
19021
|
+
const settled = await this.discoverAcrossServers(async (serverName) => modelVisibleTools(await this.getToolsForServer(serverName)), {
|
|
18985
19022
|
errorId: "MCP_CLIENT_GET_TOOLS_FAILED",
|
|
18986
19023
|
logMessage: "Failed to list tools from server:"
|
|
18987
19024
|
}, options);
|
|
@@ -19036,7 +19073,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
19036
19073
|
const errors = {};
|
|
19037
19074
|
const errorDetails = {};
|
|
19038
19075
|
const durations = {};
|
|
19039
|
-
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
19076
|
+
const settled = await this.discoverAcrossServers(async (serverName) => modelVisibleTools(await this.getToolsForServer(serverName)), {
|
|
19040
19077
|
errorId: "MCP_CLIENT_GET_TOOLSETS_FAILED",
|
|
19041
19078
|
logMessage: "Failed to list toolsets from server:"
|
|
19042
19079
|
}, options);
|
|
@@ -19100,7 +19137,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
19100
19137
|
const errorDetails = {};
|
|
19101
19138
|
const durations = {};
|
|
19102
19139
|
const settled = await this.discoverAcrossServers(async (serverName) => {
|
|
19103
|
-
return (await this.getConnectedClientForServer(serverName)).toolDefinitions();
|
|
19140
|
+
return modelVisibleDefinitions(await (await this.getConnectedClientForServer(serverName)).toolDefinitions());
|
|
19104
19141
|
}, {
|
|
19105
19142
|
errorId: "MCP_CLIENT_GET_TOOL_DEFINITIONS_FAILED",
|
|
19106
19143
|
logMessage: "Failed to list tool definitions from server:"
|
|
@@ -19169,7 +19206,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
19169
19206
|
this.logger.warn("Skipping cached MCP tool definitions for a server that is no longer configured", { serverName });
|
|
19170
19207
|
continue;
|
|
19171
19208
|
}
|
|
19172
|
-
for (const [toolName, definition] of Object.entries(definitions)) try {
|
|
19209
|
+
for (const [toolName, definition] of Object.entries(modelVisibleDefinitions(definitions))) try {
|
|
19173
19210
|
tools[`${serverName}_${toolName}`] = await this.toolFromDefinition({
|
|
19174
19211
|
serverName,
|
|
19175
19212
|
definition
|
|
@@ -19437,6 +19474,22 @@ onListChanged: async (serverName, handler) => {
|
|
|
19437
19474
|
return {};
|
|
19438
19475
|
}
|
|
19439
19476
|
};
|
|
19477
|
+
/**
|
|
19478
|
+
* Whether a tool may be handed to the model. MCP App servers mark helpers their app calls itself
|
|
19479
|
+
* with `_meta.ui.visibility` lacking `'model'`; per the MCP Apps spec, hosts must not give those
|
|
19480
|
+
* to the model. They stay callable by the app through the server.
|
|
19481
|
+
*/
|
|
19482
|
+
function isModelVisible(meta) {
|
|
19483
|
+
const ui = meta?.ui;
|
|
19484
|
+
const visibility = ui && typeof ui === "object" && "visibility" in ui ? ui.visibility : void 0;
|
|
19485
|
+
return !Array.isArray(visibility) || visibility.includes("model");
|
|
19486
|
+
}
|
|
19487
|
+
function modelVisibleTools(tools) {
|
|
19488
|
+
return Object.fromEntries(Object.entries(tools).filter(([, tool]) => isModelVisible(tool.mcp?._meta)));
|
|
19489
|
+
}
|
|
19490
|
+
function modelVisibleDefinitions(definitions) {
|
|
19491
|
+
return Object.fromEntries(Object.entries(definitions).filter(([, definition]) => isModelVisible(definition._meta)));
|
|
19492
|
+
}
|
|
19440
19493
|
// src/server/actions.ts
|
|
19441
19494
|
/** Runtime tool catalogue mutations. Every change is published to listening clients. */
|
|
19442
19495
|
var ServerToolActions = class {
|
|
@@ -19568,8 +19621,17 @@ function callerTrace(ctx) {
|
|
|
19568
19621
|
return callerTraceContext(meta?.traceparent, meta?.tracestate) ?? callerTraceContext(headers?.get("traceparent"), headers?.get("tracestate"));
|
|
19569
19622
|
}
|
|
19570
19623
|
/**
|
|
19624
|
+
* Where `@mastra/server` attaches, on `req.auth`, the request context its auth
|
|
19625
|
+
* resolved (user, permissions, roles, resource id, tenant, auth mode). A symbol
|
|
19626
|
+
* cannot come out of a token or JSON payload, so only server code can supply it.
|
|
19627
|
+
*/
|
|
19628
|
+
const MCP_TRUSTED_REQUEST_CONTEXT = Symbol.for("mastra.mcp.trustedRequestContext");
|
|
19629
|
+
const MASTRA_USER_KEY = "mastra__user";
|
|
19630
|
+
/**
|
|
19571
19631
|
* Builds the trusted application context for one request. Auth is re-derived from
|
|
19572
|
-
* the transport every time; nothing is carried between continuation rounds.
|
|
19632
|
+
* the transport every time; nothing is carried between continuation rounds. When
|
|
19633
|
+
* the request came through a Mastra server route, the values its auth resolved are
|
|
19634
|
+
* copied in, so tools are authorized the same way as that server's routes. The W3C
|
|
19573
19635
|
* trace fields sent by the client are exposed under `traceContext` as opaque
|
|
19574
19636
|
* strings for observability only; they are never consulted for authorization.
|
|
19575
19637
|
*/
|
|
@@ -19579,6 +19641,12 @@ async function toRequestContext(ctx, mapAuthInfoToUser) {
|
|
|
19579
19641
|
if (traceContext) requestContext.set("traceContext", traceContext);
|
|
19580
19642
|
const authInfo = ctx.http?.authInfo;
|
|
19581
19643
|
if (!authInfo) return requestContext;
|
|
19644
|
+
const trusted = authInfo[MCP_TRUSTED_REQUEST_CONTEXT];
|
|
19645
|
+
if (trusted && typeof trusted === "object") {
|
|
19646
|
+
for (const [key, value] of Object.entries(trusted)) requestContext.set(key, value);
|
|
19647
|
+
const trustedUser = trusted[MASTRA_USER_KEY];
|
|
19648
|
+
if (trustedUser) requestContext.set("user", trustedUser);
|
|
19649
|
+
}
|
|
19582
19650
|
requestContext.set("authInfo", authInfo);
|
|
19583
19651
|
const user = await mapAuthInfoToUser?.({
|
|
19584
19652
|
authInfo,
|
|
@@ -22781,6 +22849,17 @@ function toSummary(listing) {
|
|
|
22781
22849
|
function isWorkflowTaskContext(context) {
|
|
22782
22850
|
return context?.kind === "workflow" && typeof context.runId === "string" && typeof context.workflowKey === "string";
|
|
22783
22851
|
}
|
|
22852
|
+
/**
|
|
22853
|
+
* A run's result with its step results read: a storage v2 result's `steps` is a loader that reads
|
|
22854
|
+
* them from storage, so a view, and the text a tool answers with, gets them as for v1.
|
|
22855
|
+
*/
|
|
22856
|
+
async function withLoadedSteps(result) {
|
|
22857
|
+
const steps = result.steps;
|
|
22858
|
+
return typeof steps === "function" ? {
|
|
22859
|
+
...result,
|
|
22860
|
+
steps: await steps()
|
|
22861
|
+
} : result;
|
|
22862
|
+
}
|
|
22784
22863
|
/** Statuses a run never leaves. */
|
|
22785
22864
|
const FINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
22786
22865
|
"success",
|
|
@@ -23050,11 +23129,11 @@ var MCPServer = class extends MCPServerBase {
|
|
|
23050
23129
|
inputSchema: workflow.inputSchema,
|
|
23051
23130
|
mcp: { toolType: "workflow" },
|
|
23052
23131
|
execute: async (inputData, context) => {
|
|
23053
|
-
return (await workflow.createRun({ runId: context?.requestContext?.get("runId") })).start({
|
|
23132
|
+
return withLoadedSteps(await (await workflow.createRun({ runId: context?.requestContext?.get("runId") })).start({
|
|
23054
23133
|
inputData,
|
|
23055
23134
|
requestContext: context?.requestContext,
|
|
23056
23135
|
tracingContext: context?.tracingContext
|
|
23057
|
-
});
|
|
23136
|
+
}));
|
|
23058
23137
|
}
|
|
23059
23138
|
}));
|
|
23060
23139
|
}
|
|
@@ -23844,7 +23923,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
23844
23923
|
if (!workflow) throw new Error(`Workflow '${workflowKey}' is not served`);
|
|
23845
23924
|
const input = validateToolInput(workflow.inputSchema, args, name);
|
|
23846
23925
|
if (input.error) {
|
|
23847
|
-
this.logger.warn(`Tool '${name}' rejected its input.`, {
|
|
23926
|
+
this.logger.warn(`Tool '${name}' rejected its input.`, { issuePaths: getValidationIssuePaths(input.error, workflow.inputSchema) });
|
|
23848
23927
|
return errorResult$1(input.error.message);
|
|
23849
23928
|
}
|
|
23850
23929
|
const context = {
|
|
@@ -23867,11 +23946,11 @@ var MCPServer = class extends MCPServerBase {
|
|
|
23867
23946
|
};
|
|
23868
23947
|
const start = (runTracing) => {
|
|
23869
23948
|
const run = workflow.createRun({ runId: context.runId });
|
|
23870
|
-
const result = run.then((started) => started.start({
|
|
23949
|
+
const result = run.then(async (started) => withLoadedSteps(await started.start({
|
|
23871
23950
|
inputData: input.data,
|
|
23872
23951
|
requestContext,
|
|
23873
23952
|
tracingContext: runTracing
|
|
23874
|
-
}));
|
|
23953
|
+
})));
|
|
23875
23954
|
const cancel = () => void run.then((started) => started.cancel()).catch((error) => this.logger.warn("Could not cancel workflow run", {
|
|
23876
23955
|
tool: name,
|
|
23877
23956
|
error
|
|
@@ -24000,12 +24079,12 @@ var MCPServer = class extends MCPServerBase {
|
|
|
24000
24079
|
error
|
|
24001
24080
|
})));
|
|
24002
24081
|
try {
|
|
24003
|
-
view = await run.resume({
|
|
24082
|
+
view = await withLoadedSteps(await run.resume({
|
|
24004
24083
|
step: answered.step,
|
|
24005
24084
|
resumeData: answer.content ?? {},
|
|
24006
24085
|
requestContext,
|
|
24007
24086
|
...span && { tracingContext: { currentSpan: span } }
|
|
24008
|
-
});
|
|
24087
|
+
}));
|
|
24009
24088
|
} catch (error) {
|
|
24010
24089
|
if (isResumeClaimLost(error)) return this.watchWorkflowRun(workflow, context, attempt.signal);
|
|
24011
24090
|
const now = await workflow.getWorkflowRunById(context.runId, { withNestedWorkflows: false });
|
|
@@ -24173,7 +24252,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
24173
24252
|
}
|
|
24174
24253
|
toCallToolResult(name, tool, value) {
|
|
24175
24254
|
if (isValidationError(value)) {
|
|
24176
|
-
this.logger.warn(`Tool '${name}' rejected its input.`, {
|
|
24255
|
+
this.logger.warn(`Tool '${name}' rejected its input.`, { issuePaths: getValidationIssuePaths(value, tool.parameters) });
|
|
24177
24256
|
return errorResult$1(value.message);
|
|
24178
24257
|
}
|
|
24179
24258
|
const resourceUri = uiResourceUri(tool.mcp?._meta);
|
|
@@ -24618,10 +24697,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
24618
24697
|
id: "MCP_SERVER_TOOL_EXECUTE_FAILED",
|
|
24619
24698
|
domain: ErrorDomain.MCP,
|
|
24620
24699
|
category: ErrorCategory.USER,
|
|
24621
|
-
details: {
|
|
24622
|
-
toolId,
|
|
24623
|
-
args: JSON.stringify(args)
|
|
24624
|
-
}
|
|
24700
|
+
details: { toolId }
|
|
24625
24701
|
}, error);
|
|
24626
24702
|
this.logger.trackException(mastraError);
|
|
24627
24703
|
throw mastraError;
|