@mastra/mcp 2.4.0-alpha.0 → 2.4.1-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/client/configuration.d.ts.map +1 -1
- package/dist/client/input-schema-meta-schema.d.ts +29 -0
- package/dist/client/input-schema-meta-schema.d.ts.map +1 -0
- package/dist/client/input-schema-test-cases.d.ts +5 -0
- package/dist/client/input-schema-test-cases.d.ts.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +359 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +359 -19
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -22220,7 +22220,7 @@ require_json_schema_traverse();
|
|
|
22220
22220
|
const JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
|
|
22221
22221
|
const JSON_SCHEMA_2019_09 = /^https?:\/\/json-schema\.org\/draft\/2019-09\/schema#?$/;
|
|
22222
22222
|
/** Keywords whose value is a subschema (`items` may also be an array of subschemas). */
|
|
22223
|
-
const SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
22223
|
+
const SCHEMA_KEYWORDS$1 = /* @__PURE__ */ new Set([
|
|
22224
22224
|
"items",
|
|
22225
22225
|
"additionalItems",
|
|
22226
22226
|
"contains",
|
|
@@ -22234,13 +22234,13 @@ const SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
22234
22234
|
"not"
|
|
22235
22235
|
]);
|
|
22236
22236
|
/** Keywords whose value is an array of subschemas. */
|
|
22237
|
-
const SCHEMA_ARRAY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
22237
|
+
const SCHEMA_ARRAY_KEYWORDS$1 = /* @__PURE__ */ new Set([
|
|
22238
22238
|
"allOf",
|
|
22239
22239
|
"anyOf",
|
|
22240
22240
|
"oneOf"
|
|
22241
22241
|
]);
|
|
22242
22242
|
/** Keywords whose values map arbitrary names to subschemas. */
|
|
22243
|
-
const SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
22243
|
+
const SCHEMA_MAP_KEYWORDS$1 = /* @__PURE__ */ new Set([
|
|
22244
22244
|
"properties",
|
|
22245
22245
|
"patternProperties",
|
|
22246
22246
|
"$defs",
|
|
@@ -22284,11 +22284,11 @@ function rewrite(schema, depth, budget, isRoot = false) {
|
|
|
22284
22284
|
if ("$recursiveRef" in out || "$recursiveAnchor" in out) throw new Unconvertible();
|
|
22285
22285
|
if ("unevaluatedItems" in out || "prefixItems" in out || "contentSchema" in out) throw new Unconvertible();
|
|
22286
22286
|
if (typeof out.$ref === "string" && /\/(items\/\d+|additionalItems)(\/|$)/.test(out.$ref)) throw new Unconvertible();
|
|
22287
|
-
for (const [key, child] of Object.entries(out)) if (SCHEMA_KEYWORDS.has(key)) out[key] = Array.isArray(child) ? (checkBudget(depth + 1, budget), child.map((item) => rewrite(item, depth + 2, budget))) : rewrite(child, depth + 1, budget);
|
|
22288
|
-
else if (SCHEMA_ARRAY_KEYWORDS.has(key) && Array.isArray(child)) {
|
|
22287
|
+
for (const [key, child] of Object.entries(out)) if (SCHEMA_KEYWORDS$1.has(key)) out[key] = Array.isArray(child) ? (checkBudget(depth + 1, budget), child.map((item) => rewrite(item, depth + 2, budget))) : rewrite(child, depth + 1, budget);
|
|
22288
|
+
else if (SCHEMA_ARRAY_KEYWORDS$1.has(key) && Array.isArray(child)) {
|
|
22289
22289
|
checkBudget(depth + 1, budget);
|
|
22290
22290
|
out[key] = child.map((item) => rewrite(item, depth + 2, budget));
|
|
22291
|
-
} else if (SCHEMA_MAP_KEYWORDS.has(key) && child && typeof child === "object" && !Array.isArray(child)) {
|
|
22291
|
+
} else if (SCHEMA_MAP_KEYWORDS$1.has(key) && child && typeof child === "object" && !Array.isArray(child)) {
|
|
22292
22292
|
checkBudget(depth + 1, budget);
|
|
22293
22293
|
out[key] = Object.fromEntries(Object.entries(child).map(([name, sub]) => [name, rewrite(sub, depth + 2, budget)]));
|
|
22294
22294
|
}
|
|
@@ -22902,6 +22902,326 @@ function getMCPDiscoveryErrorDetails(error) {
|
|
|
22902
22902
|
};
|
|
22903
22903
|
}
|
|
22904
22904
|
//#endregion
|
|
22905
|
+
//#region src/client/input-schema-meta-schema.ts
|
|
22906
|
+
/**
|
|
22907
|
+
* Structural JSON Schema meta-schema, used to check that a server-supplied tool input schema is
|
|
22908
|
+
* shaped like a JSON Schema before it is handed to a model provider.
|
|
22909
|
+
*
|
|
22910
|
+
* Based on https://json-schema.org/draft-07/schema (`$schema`/`$id` dropped so the validator does
|
|
22911
|
+
* not try to resolve them). Draft-07 is used because its meta-schema is a single self-contained
|
|
22912
|
+
* document; the 2020-12 meta-schema is split across vocabulary documents. Changes from upstream:
|
|
22913
|
+
* - `format`, `uniqueItems` and the non-empty `enum` rule are removed, so only wrong value types
|
|
22914
|
+
* and non-schemas in schema positions drop a tool, not regex dialects, non-URI ids or duplicates;
|
|
22915
|
+
* - the block at the end of `properties` adds the 2019-09/2020-12 subschema keywords.
|
|
22916
|
+
* Unknown keywords stay allowed, as in every dialect.
|
|
22917
|
+
*/
|
|
22918
|
+
const INPUT_SCHEMA_META_SCHEMA = {
|
|
22919
|
+
title: "Core schema meta-schema",
|
|
22920
|
+
definitions: {
|
|
22921
|
+
schemaArray: {
|
|
22922
|
+
type: "array",
|
|
22923
|
+
minItems: 1,
|
|
22924
|
+
items: { $ref: "#" }
|
|
22925
|
+
},
|
|
22926
|
+
nonNegativeInteger: {
|
|
22927
|
+
type: "integer",
|
|
22928
|
+
minimum: 0
|
|
22929
|
+
},
|
|
22930
|
+
nonNegativeIntegerDefault0: { allOf: [{ $ref: "#/definitions/nonNegativeInteger" }, { default: 0 }] },
|
|
22931
|
+
simpleTypes: { enum: [
|
|
22932
|
+
"array",
|
|
22933
|
+
"boolean",
|
|
22934
|
+
"integer",
|
|
22935
|
+
"null",
|
|
22936
|
+
"number",
|
|
22937
|
+
"object",
|
|
22938
|
+
"string"
|
|
22939
|
+
] },
|
|
22940
|
+
stringArray: {
|
|
22941
|
+
type: "array",
|
|
22942
|
+
items: { type: "string" },
|
|
22943
|
+
default: []
|
|
22944
|
+
}
|
|
22945
|
+
},
|
|
22946
|
+
type: ["object", "boolean"],
|
|
22947
|
+
properties: {
|
|
22948
|
+
$id: { type: "string" },
|
|
22949
|
+
$schema: { type: "string" },
|
|
22950
|
+
$ref: { type: "string" },
|
|
22951
|
+
$comment: { type: "string" },
|
|
22952
|
+
title: { type: "string" },
|
|
22953
|
+
description: { type: "string" },
|
|
22954
|
+
default: true,
|
|
22955
|
+
readOnly: {
|
|
22956
|
+
type: "boolean",
|
|
22957
|
+
default: false
|
|
22958
|
+
},
|
|
22959
|
+
writeOnly: {
|
|
22960
|
+
type: "boolean",
|
|
22961
|
+
default: false
|
|
22962
|
+
},
|
|
22963
|
+
examples: {
|
|
22964
|
+
type: "array",
|
|
22965
|
+
items: true
|
|
22966
|
+
},
|
|
22967
|
+
multipleOf: {
|
|
22968
|
+
type: "number",
|
|
22969
|
+
exclusiveMinimum: 0
|
|
22970
|
+
},
|
|
22971
|
+
maximum: { type: "number" },
|
|
22972
|
+
exclusiveMaximum: { type: "number" },
|
|
22973
|
+
minimum: { type: "number" },
|
|
22974
|
+
exclusiveMinimum: { type: "number" },
|
|
22975
|
+
maxLength: { $ref: "#/definitions/nonNegativeInteger" },
|
|
22976
|
+
minLength: { $ref: "#/definitions/nonNegativeIntegerDefault0" },
|
|
22977
|
+
pattern: { type: "string" },
|
|
22978
|
+
additionalItems: { $ref: "#" },
|
|
22979
|
+
items: {
|
|
22980
|
+
anyOf: [{ $ref: "#" }, { $ref: "#/definitions/schemaArray" }],
|
|
22981
|
+
default: true
|
|
22982
|
+
},
|
|
22983
|
+
maxItems: { $ref: "#/definitions/nonNegativeInteger" },
|
|
22984
|
+
minItems: { $ref: "#/definitions/nonNegativeIntegerDefault0" },
|
|
22985
|
+
uniqueItems: {
|
|
22986
|
+
type: "boolean",
|
|
22987
|
+
default: false
|
|
22988
|
+
},
|
|
22989
|
+
contains: { $ref: "#" },
|
|
22990
|
+
maxProperties: { $ref: "#/definitions/nonNegativeInteger" },
|
|
22991
|
+
minProperties: { $ref: "#/definitions/nonNegativeIntegerDefault0" },
|
|
22992
|
+
required: { $ref: "#/definitions/stringArray" },
|
|
22993
|
+
additionalProperties: { $ref: "#" },
|
|
22994
|
+
definitions: {
|
|
22995
|
+
type: "object",
|
|
22996
|
+
additionalProperties: { $ref: "#" },
|
|
22997
|
+
default: {}
|
|
22998
|
+
},
|
|
22999
|
+
properties: {
|
|
23000
|
+
type: "object",
|
|
23001
|
+
additionalProperties: { $ref: "#" },
|
|
23002
|
+
default: {}
|
|
23003
|
+
},
|
|
23004
|
+
patternProperties: {
|
|
23005
|
+
type: "object",
|
|
23006
|
+
additionalProperties: { $ref: "#" },
|
|
23007
|
+
default: {}
|
|
23008
|
+
},
|
|
23009
|
+
dependencies: {
|
|
23010
|
+
type: "object",
|
|
23011
|
+
additionalProperties: { anyOf: [{ $ref: "#" }, { $ref: "#/definitions/stringArray" }] }
|
|
23012
|
+
},
|
|
23013
|
+
propertyNames: { $ref: "#" },
|
|
23014
|
+
const: true,
|
|
23015
|
+
enum: {
|
|
23016
|
+
type: "array",
|
|
23017
|
+
items: true
|
|
23018
|
+
},
|
|
23019
|
+
type: { anyOf: [{ $ref: "#/definitions/simpleTypes" }, {
|
|
23020
|
+
type: "array",
|
|
23021
|
+
items: { $ref: "#/definitions/simpleTypes" },
|
|
23022
|
+
minItems: 1
|
|
23023
|
+
}] },
|
|
23024
|
+
format: { type: "string" },
|
|
23025
|
+
contentMediaType: { type: "string" },
|
|
23026
|
+
contentEncoding: { type: "string" },
|
|
23027
|
+
if: { $ref: "#" },
|
|
23028
|
+
then: { $ref: "#" },
|
|
23029
|
+
else: { $ref: "#" },
|
|
23030
|
+
allOf: { $ref: "#/definitions/schemaArray" },
|
|
23031
|
+
anyOf: { $ref: "#/definitions/schemaArray" },
|
|
23032
|
+
oneOf: { $ref: "#/definitions/schemaArray" },
|
|
23033
|
+
not: { $ref: "#" },
|
|
23034
|
+
$defs: {
|
|
23035
|
+
type: "object",
|
|
23036
|
+
additionalProperties: { $ref: "#" },
|
|
23037
|
+
default: {}
|
|
23038
|
+
},
|
|
23039
|
+
prefixItems: { $ref: "#/definitions/schemaArray" },
|
|
23040
|
+
dependentSchemas: {
|
|
23041
|
+
type: "object",
|
|
23042
|
+
additionalProperties: { $ref: "#" }
|
|
23043
|
+
},
|
|
23044
|
+
dependentRequired: {
|
|
23045
|
+
type: "object",
|
|
23046
|
+
additionalProperties: { $ref: "#/definitions/stringArray" }
|
|
23047
|
+
},
|
|
23048
|
+
unevaluatedItems: { $ref: "#" },
|
|
23049
|
+
unevaluatedProperties: { $ref: "#" },
|
|
23050
|
+
contentSchema: { $ref: "#" }
|
|
23051
|
+
},
|
|
23052
|
+
default: true
|
|
23053
|
+
};
|
|
23054
|
+
let inputSchemaMetaValidator;
|
|
23055
|
+
let inputSchemaMetaValidatorLoad;
|
|
23056
|
+
const SCHEMA_TYPES = /* @__PURE__ */ new Set([
|
|
23057
|
+
"array",
|
|
23058
|
+
"boolean",
|
|
23059
|
+
"integer",
|
|
23060
|
+
"null",
|
|
23061
|
+
"number",
|
|
23062
|
+
"object",
|
|
23063
|
+
"string"
|
|
23064
|
+
]);
|
|
23065
|
+
const SCHEMA_MAP_KEYWORDS = [
|
|
23066
|
+
"$defs",
|
|
23067
|
+
"definitions",
|
|
23068
|
+
"properties",
|
|
23069
|
+
"patternProperties",
|
|
23070
|
+
"dependentSchemas",
|
|
23071
|
+
"dependencies"
|
|
23072
|
+
];
|
|
23073
|
+
const SCHEMA_ARRAY_KEYWORDS = [
|
|
23074
|
+
"prefixItems",
|
|
23075
|
+
"allOf",
|
|
23076
|
+
"anyOf",
|
|
23077
|
+
"oneOf"
|
|
23078
|
+
];
|
|
23079
|
+
const SCHEMA_KEYWORDS = [
|
|
23080
|
+
"additionalProperties",
|
|
23081
|
+
"unevaluatedProperties",
|
|
23082
|
+
"additionalItems",
|
|
23083
|
+
"unevaluatedItems",
|
|
23084
|
+
"contains",
|
|
23085
|
+
"propertyNames",
|
|
23086
|
+
"not",
|
|
23087
|
+
"if",
|
|
23088
|
+
"then",
|
|
23089
|
+
"else",
|
|
23090
|
+
"contentSchema"
|
|
23091
|
+
];
|
|
23092
|
+
const isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
23093
|
+
const isNumber = (value) => typeof value === "number";
|
|
23094
|
+
const isCount = (value) => Number.isInteger(value) && value >= 0;
|
|
23095
|
+
const isString = (value) => typeof value === "string";
|
|
23096
|
+
const isBoolean = (value) => typeof value === "boolean";
|
|
23097
|
+
/** Value types the meta-schema requires for the keywords that do not hold subschemas. */
|
|
23098
|
+
const KEYWORD_VALUE_CHECKS = {
|
|
23099
|
+
multipleOf: [(value) => isNumber(value) && value > 0, "a positive number"],
|
|
23100
|
+
...Object.fromEntries([
|
|
23101
|
+
"maximum",
|
|
23102
|
+
"exclusiveMaximum",
|
|
23103
|
+
"minimum",
|
|
23104
|
+
"exclusiveMinimum"
|
|
23105
|
+
].map((k) => [k, [isNumber, "a number"]])),
|
|
23106
|
+
...Object.fromEntries([
|
|
23107
|
+
"maxLength",
|
|
23108
|
+
"minLength",
|
|
23109
|
+
"maxItems",
|
|
23110
|
+
"minItems",
|
|
23111
|
+
"maxProperties",
|
|
23112
|
+
"minProperties"
|
|
23113
|
+
].map((k) => [k, [isCount, "a non-negative integer"]])),
|
|
23114
|
+
...Object.fromEntries([
|
|
23115
|
+
"$id",
|
|
23116
|
+
"$schema",
|
|
23117
|
+
"$ref",
|
|
23118
|
+
"$comment",
|
|
23119
|
+
"title",
|
|
23120
|
+
"description",
|
|
23121
|
+
"pattern",
|
|
23122
|
+
"format",
|
|
23123
|
+
"contentMediaType",
|
|
23124
|
+
"contentEncoding"
|
|
23125
|
+
].map((k) => [k, [isString, "a string"]])),
|
|
23126
|
+
...Object.fromEntries([
|
|
23127
|
+
"readOnly",
|
|
23128
|
+
"writeOnly",
|
|
23129
|
+
"uniqueItems"
|
|
23130
|
+
].map((k) => [k, [isBoolean, "a boolean"]])),
|
|
23131
|
+
examples: [Array.isArray, "an array"],
|
|
23132
|
+
enum: [Array.isArray, "an array"],
|
|
23133
|
+
required: [isStringArray, "an array of strings"]
|
|
23134
|
+
};
|
|
23135
|
+
/**
|
|
23136
|
+
* Fallback for runtimes where the cf-worker validator cannot be imported. Applies the same rules as
|
|
23137
|
+
* {@link INPUT_SCHEMA_META_SCHEMA}: every subschema is an object or boolean, and every known
|
|
23138
|
+
* keyword has a value of the right type.
|
|
23139
|
+
*/
|
|
23140
|
+
function getStructuralInputSchemaError(schema) {
|
|
23141
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23142
|
+
const stack = [{
|
|
23143
|
+
value: schema,
|
|
23144
|
+
path: "#"
|
|
23145
|
+
}];
|
|
23146
|
+
while (stack.length > 0) {
|
|
23147
|
+
const { value, path } = stack.pop();
|
|
23148
|
+
if (typeof value === "boolean") continue;
|
|
23149
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return `${path}: must be a JSON Schema object or boolean`;
|
|
23150
|
+
if (seen.has(value)) continue;
|
|
23151
|
+
seen.add(value);
|
|
23152
|
+
const record = value;
|
|
23153
|
+
const { type, dependentRequired } = record;
|
|
23154
|
+
const types = Array.isArray(type) ? type : [type];
|
|
23155
|
+
if (type !== void 0 && (types.length === 0 || !types.every((t) => SCHEMA_TYPES.has(t)))) return `${path}/type: must be a JSON Schema type name or a non-empty array of them`;
|
|
23156
|
+
for (const [keyword, [isValid, expected]] of Object.entries(KEYWORD_VALUE_CHECKS)) if (record[keyword] !== void 0 && !isValid(record[keyword])) return `${path}/${keyword}: must be ${expected}`;
|
|
23157
|
+
if (dependentRequired !== void 0 && (!dependentRequired || typeof dependentRequired !== "object" || Array.isArray(dependentRequired) || !Object.values(dependentRequired).every(isStringArray))) return `${path}/dependentRequired: must be an object of string arrays`;
|
|
23158
|
+
for (const keyword of SCHEMA_MAP_KEYWORDS) {
|
|
23159
|
+
const schemas = record[keyword];
|
|
23160
|
+
if (schemas === void 0) continue;
|
|
23161
|
+
if (!schemas || typeof schemas !== "object" || Array.isArray(schemas)) return `${path}/${keyword}: must be an object`;
|
|
23162
|
+
for (const [key, child] of Object.entries(schemas)) {
|
|
23163
|
+
if (keyword === "dependencies" && isStringArray(child)) continue;
|
|
23164
|
+
stack.push({
|
|
23165
|
+
value: child,
|
|
23166
|
+
path: `${path}/${keyword}/${key}`
|
|
23167
|
+
});
|
|
23168
|
+
}
|
|
23169
|
+
}
|
|
23170
|
+
for (const keyword of SCHEMA_ARRAY_KEYWORDS) {
|
|
23171
|
+
const schemas = record[keyword];
|
|
23172
|
+
if (schemas === void 0) continue;
|
|
23173
|
+
if (!Array.isArray(schemas) || schemas.length === 0) return `${path}/${keyword}: must be a non-empty array`;
|
|
23174
|
+
schemas.forEach((child, index) => stack.push({
|
|
23175
|
+
value: child,
|
|
23176
|
+
path: `${path}/${keyword}/${index}`
|
|
23177
|
+
}));
|
|
23178
|
+
}
|
|
23179
|
+
if (Array.isArray(record.items)) {
|
|
23180
|
+
if (record.items.length === 0) return `${path}/items: must be a schema or a non-empty array`;
|
|
23181
|
+
record.items.forEach((child, index) => stack.push({
|
|
23182
|
+
value: child,
|
|
23183
|
+
path: `${path}/items/${index}`
|
|
23184
|
+
}));
|
|
23185
|
+
} else if (record.items !== void 0) stack.push({
|
|
23186
|
+
value: record.items,
|
|
23187
|
+
path: `${path}/items`
|
|
23188
|
+
});
|
|
23189
|
+
for (const keyword of SCHEMA_KEYWORDS) if (record[keyword] !== void 0) stack.push({
|
|
23190
|
+
value: record[keyword],
|
|
23191
|
+
path: `${path}/${keyword}`
|
|
23192
|
+
});
|
|
23193
|
+
}
|
|
23194
|
+
}
|
|
23195
|
+
/**
|
|
23196
|
+
* Loads the SDK's cf-worker validator, which interprets schemas instead of compiling them with
|
|
23197
|
+
* `new Function`, so it also runs on Cloudflare Workers. It is imported lazily because
|
|
23198
|
+
* `@cfworker/json-schema` builds a URL from `self.location` at import time, which throws in some
|
|
23199
|
+
* browser worker locations; importing `@mastra/mcp` must not fail there. Until it has loaded, or
|
|
23200
|
+
* if it cannot load, the structural fallback check is used instead.
|
|
23201
|
+
*/
|
|
23202
|
+
function loadInputSchemaMetaValidator() {
|
|
23203
|
+
inputSchemaMetaValidatorLoad ??= import("@modelcontextprotocol/client/validators/cf-worker").then(({ CfWorkerJsonSchemaValidator }) => {
|
|
23204
|
+
inputSchemaMetaValidator = new CfWorkerJsonSchemaValidator({ draft: "7" }).getValidator(INPUT_SCHEMA_META_SCHEMA);
|
|
23205
|
+
}, () => {});
|
|
23206
|
+
return inputSchemaMetaValidatorLoad;
|
|
23207
|
+
}
|
|
23208
|
+
/**
|
|
23209
|
+
* Checks a server-supplied input schema against {@link INPUT_SCHEMA_META_SCHEMA}, falling back to
|
|
23210
|
+
* a structural check while the validator is not loaded. Callers must rule out oversized schemas
|
|
23211
|
+
* with getJsonSchemaComplexityError first.
|
|
23212
|
+
*/
|
|
23213
|
+
function getInputSchemaError(schema) {
|
|
23214
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) return "#: input schema must be a JSON object";
|
|
23215
|
+
if (!inputSchemaMetaValidator) return getStructuralInputSchemaError(schema);
|
|
23216
|
+
let result;
|
|
23217
|
+
try {
|
|
23218
|
+
result = inputSchemaMetaValidator(schema);
|
|
23219
|
+
} catch {
|
|
23220
|
+
return;
|
|
23221
|
+
}
|
|
23222
|
+
return result.valid ? void 0 : result.errorMessage.split("; ").at(-1);
|
|
23223
|
+
}
|
|
23224
|
+
//#endregion
|
|
22905
23225
|
//#region src/client/url-policy.ts
|
|
22906
23226
|
/**
|
|
22907
23227
|
* Redirect status codes the manual redirect loop follows. Other 3xx statuses
|
|
@@ -23359,6 +23679,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
23359
23679
|
*/
|
|
23360
23680
|
constructor({ name, version = "1.0.0", clientInfo, server, timeout = DEFAULT_REQUEST_TIMEOUT_MSEC }) {
|
|
23361
23681
|
super({ name: "MastraMCPClient" });
|
|
23682
|
+
loadInputSchemaMetaValidator();
|
|
23362
23683
|
this.name = name;
|
|
23363
23684
|
this.timeout = timeout;
|
|
23364
23685
|
this.logHandler = server.logger;
|
|
@@ -23991,14 +24312,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
23991
24312
|
return this.jsonSchemaValidator;
|
|
23992
24313
|
}
|
|
23993
24314
|
convertInputSchema(inputSchema) {
|
|
23994
|
-
|
|
23995
|
-
const standardSchema = toStandardSchema$2(schema);
|
|
23996
|
-
const complexityError = getJsonSchemaComplexityError(schema);
|
|
23997
|
-
if (!complexityError) return standardSchema;
|
|
23998
|
-
return { "~standard": {
|
|
23999
|
-
...standardSchema["~standard"],
|
|
24000
|
-
validate: () => ({ issues: [{ message: complexityError }] })
|
|
24001
|
-
} };
|
|
24315
|
+
return toStandardSchema$2(withDefaultDialect("jsonSchema" in inputSchema ? inputSchema.jsonSchema : inputSchema));
|
|
24002
24316
|
}
|
|
24003
24317
|
/**
|
|
24004
24318
|
* Wraps the output schema with a validator that always succeeds. The tool's execute wrapper
|
|
@@ -24080,6 +24394,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
24080
24394
|
async tools() {
|
|
24081
24395
|
this.log("debug", `Requesting tools from MCP server`);
|
|
24082
24396
|
const { tools } = await this.client.listTools({ _meta: this.requestMeta() }, { timeout: this.timeout });
|
|
24397
|
+
await loadInputSchemaMetaValidator();
|
|
24083
24398
|
const toolsRes = {};
|
|
24084
24399
|
for (const tool of tools) {
|
|
24085
24400
|
const mastraTool = this.buildToolFromListEntry(tool, {
|
|
@@ -24095,6 +24410,25 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
24095
24410
|
* tools behave identically to discovered ones.
|
|
24096
24411
|
*/
|
|
24097
24412
|
buildToolFromListEntry(tool, serverMeta) {
|
|
24413
|
+
const rawInputSchema = tool.inputSchema;
|
|
24414
|
+
const inputSchema = rawInputSchema && typeof rawInputSchema === "object" && "jsonSchema" in rawInputSchema ? rawInputSchema.jsonSchema : rawInputSchema;
|
|
24415
|
+
const inputSchemaError = getJsonSchemaComplexityError(inputSchema) ?? getInputSchemaError(inputSchema);
|
|
24416
|
+
if (inputSchemaError) {
|
|
24417
|
+
const details = {
|
|
24418
|
+
serverName: this.name,
|
|
24419
|
+
toolName: tool.name,
|
|
24420
|
+
reason: inputSchemaError
|
|
24421
|
+
};
|
|
24422
|
+
this.log("warning", `Skipping MCP tool "${tool.name}" with an invalid input schema: ${inputSchemaError}`, details);
|
|
24423
|
+
if (serverMeta.connectFirst) throw new MastraError({
|
|
24424
|
+
id: "MCP_CLIENT_INVALID_TOOL_INPUT_SCHEMA",
|
|
24425
|
+
domain: ErrorDomain.MCP,
|
|
24426
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
24427
|
+
text: `Invalid input schema for MCP tool "${tool.name}": ${inputSchemaError}`,
|
|
24428
|
+
details
|
|
24429
|
+
});
|
|
24430
|
+
return;
|
|
24431
|
+
}
|
|
24098
24432
|
try {
|
|
24099
24433
|
let requireApproval;
|
|
24100
24434
|
let needsApprovalFn;
|
|
@@ -25908,7 +26242,9 @@ onListChanged: async (serverName, handler) => {
|
|
|
25908
26242
|
*/
|
|
25909
26243
|
async toolFromDefinition({ serverName, definition }) {
|
|
25910
26244
|
this.addToInstanceCache();
|
|
25911
|
-
|
|
26245
|
+
const client = await this.getOrCreateClient(serverName, this.getServerConfig(serverName));
|
|
26246
|
+
await loadInputSchemaMetaValidator();
|
|
26247
|
+
return client.toolFromDefinition({ definition });
|
|
25912
26248
|
}
|
|
25913
26249
|
/**
|
|
25914
26250
|
* Rebuilds an entire cached catalog into a namespaced tool map, without connecting.
|
|
@@ -25934,10 +26270,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
25934
26270
|
this.logger.warn("Skipping cached MCP tool definitions for a server that is no longer configured", { serverName });
|
|
25935
26271
|
continue;
|
|
25936
26272
|
}
|
|
25937
|
-
for (const [toolName, definition] of Object.entries(definitions))
|
|
25938
|
-
serverName
|
|
25939
|
-
|
|
25940
|
-
|
|
26273
|
+
for (const [toolName, definition] of Object.entries(definitions)) try {
|
|
26274
|
+
tools[`${serverName}_${toolName}`] = await this.toolFromDefinition({
|
|
26275
|
+
serverName,
|
|
26276
|
+
definition
|
|
26277
|
+
});
|
|
26278
|
+
} catch (error) {
|
|
26279
|
+
if (!(error instanceof MastraError && error.id === "MCP_CLIENT_INVALID_TOOL_INPUT_SCHEMA")) throw error;
|
|
26280
|
+
}
|
|
25941
26281
|
}
|
|
25942
26282
|
return tools;
|
|
25943
26283
|
}
|