@mastra/mcp 1.17.1 → 1.17.2
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 +54 -0
- package/dist/client/client.d.ts +24 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +47 -7
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/error-utils.d.ts +20 -0
- package/dist/client/error-utils.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-tools-mcp-client.md +41 -9
- package/dist/index.cjs +240 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +238 -81
- package/dist/index.js.map +1 -1
- package/dist/server/promptActions.d.ts +2 -4
- package/dist/server/promptActions.d.ts.map +1 -1
- package/dist/server/server.d.ts +0 -1
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -17332,7 +17332,7 @@ var _AISDKError = class _AISDKError extends Error {
|
|
|
17332
17332
|
};
|
|
17333
17333
|
_a$1 = symbol$1;
|
|
17334
17334
|
var AISDKError = _AISDKError;
|
|
17335
|
-
function getErrorMessage(error) {
|
|
17335
|
+
function getErrorMessage$1(error) {
|
|
17336
17336
|
if (error == null) return "unknown error";
|
|
17337
17337
|
if (typeof error === "string") return error;
|
|
17338
17338
|
if (error instanceof Error) return error.message;
|
|
@@ -17366,7 +17366,7 @@ var JSONParseError = class extends AISDKError {
|
|
|
17366
17366
|
super({
|
|
17367
17367
|
name: name6$1,
|
|
17368
17368
|
message: `JSON parsing failed: Text: ${text}.
|
|
17369
|
-
Error message: ${getErrorMessage(cause)}`,
|
|
17369
|
+
Error message: ${getErrorMessage$1(cause)}`,
|
|
17370
17370
|
cause
|
|
17371
17371
|
});
|
|
17372
17372
|
this[_a7$1] = true;
|
|
@@ -17386,7 +17386,7 @@ var _TypeValidationError = class _TypeValidationError extends AISDKError {
|
|
|
17386
17386
|
super({
|
|
17387
17387
|
name: name12$1,
|
|
17388
17388
|
message: `Type validation failed: Value: ${JSON.stringify(value)}.
|
|
17389
|
-
Error message: ${getErrorMessage(cause)}`,
|
|
17389
|
+
Error message: ${getErrorMessage$1(cause)}`,
|
|
17390
17390
|
cause
|
|
17391
17391
|
});
|
|
17392
17392
|
this[_a13$1] = true;
|
|
@@ -20998,6 +20998,72 @@ function isReconnectableMCPError(error) {
|
|
|
20998
20998
|
const errorMessage = error.message.toLowerCase();
|
|
20999
20999
|
return errorMessage.includes("no valid session") || errorMessage.includes("session") || errorMessage.includes("server not initialized") || errorMessage.includes("not connected") || errorMessage.includes("http 400") || errorMessage.includes("http 401") || errorMessage.includes("http 403") || errorMessage.includes("http 404") || errorMessage.includes("econnrefused") || errorMessage.includes("fetch failed") || errorMessage.includes("connection refused") || errorMessage.includes("connection closed") || errorMessage.includes("sse stream disconnected") || errorMessage.includes("typeerror: terminated");
|
|
21000
21000
|
}
|
|
21001
|
+
const MAX_DISCOVERY_ERROR_CAUSE_DEPTH = 8;
|
|
21002
|
+
function isHttpStatus(value) {
|
|
21003
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599;
|
|
21004
|
+
}
|
|
21005
|
+
function asErrorRecord(value) {
|
|
21006
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
21007
|
+
}
|
|
21008
|
+
function getErrorProperty(record, property) {
|
|
21009
|
+
if (!record) return void 0;
|
|
21010
|
+
try {
|
|
21011
|
+
return record[property];
|
|
21012
|
+
} catch {
|
|
21013
|
+
return;
|
|
21014
|
+
}
|
|
21015
|
+
}
|
|
21016
|
+
function getErrorMessage(error) {
|
|
21017
|
+
const message = getErrorProperty(asErrorRecord(error), "message");
|
|
21018
|
+
if (typeof message === "string") return message;
|
|
21019
|
+
try {
|
|
21020
|
+
return String(error);
|
|
21021
|
+
} catch {
|
|
21022
|
+
return "Unknown error";
|
|
21023
|
+
}
|
|
21024
|
+
}
|
|
21025
|
+
/**
|
|
21026
|
+
* Preserve machine-readable transport metadata before aggregate discovery turns
|
|
21027
|
+
* a thrown error into its legacy per-server string.
|
|
21028
|
+
*
|
|
21029
|
+
* MCP SDK 2 keeps an HTTP response status on `SdkHttpError.status` while
|
|
21030
|
+
* `code` is a string SDK code. Older transports and wrappers have also used
|
|
21031
|
+
* `statusCode`; only explicit status fields are treated as HTTP metadata so a
|
|
21032
|
+
* numeric SDK or application `code` is not mislabeled. The walk is bounded and
|
|
21033
|
+
* cycle-safe because application errors may wrap arbitrary third-party causes.
|
|
21034
|
+
*/
|
|
21035
|
+
function getMCPDiscoveryErrorDetails(error) {
|
|
21036
|
+
let message = getErrorMessage(error);
|
|
21037
|
+
let httpStatus;
|
|
21038
|
+
let code;
|
|
21039
|
+
let current = error;
|
|
21040
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21041
|
+
for (let depth = 0; depth < MAX_DISCOVERY_ERROR_CAUSE_DEPTH && current !== void 0 && current !== null && !seen.has(current); depth++) {
|
|
21042
|
+
seen.add(current);
|
|
21043
|
+
const record = asErrorRecord(current);
|
|
21044
|
+
if (!record) break;
|
|
21045
|
+
const data = asErrorRecord(getErrorProperty(record, "data"));
|
|
21046
|
+
if (httpStatus === void 0) {
|
|
21047
|
+
for (const candidate of [
|
|
21048
|
+
getErrorProperty(record, "status"),
|
|
21049
|
+
getErrorProperty(record, "statusCode"),
|
|
21050
|
+
getErrorProperty(data, "status"),
|
|
21051
|
+
getErrorProperty(data, "statusCode")
|
|
21052
|
+
]) if (isHttpStatus(candidate)) {
|
|
21053
|
+
httpStatus = candidate;
|
|
21054
|
+
break;
|
|
21055
|
+
}
|
|
21056
|
+
}
|
|
21057
|
+
for (const candidate of [getErrorProperty(record, "code"), getErrorProperty(data, "code")]) if (typeof candidate === "string" || typeof candidate === "number") code = candidate;
|
|
21058
|
+
current = getErrorProperty(record, "cause");
|
|
21059
|
+
}
|
|
21060
|
+
if (httpStatus !== void 0 && !message.includes(`(HTTP ${httpStatus})`)) message += ` (HTTP ${httpStatus})`;
|
|
21061
|
+
return {
|
|
21062
|
+
message,
|
|
21063
|
+
...httpStatus !== void 0 ? { httpStatus } : {},
|
|
21064
|
+
...code !== void 0 ? { code } : {}
|
|
21065
|
+
};
|
|
21066
|
+
}
|
|
21001
21067
|
//#endregion
|
|
21002
21068
|
//#region src/client/url-policy.ts
|
|
21003
21069
|
/**
|
|
@@ -21231,20 +21297,53 @@ function extractModelTextFromToolContent(content) {
|
|
|
21231
21297
|
/**
|
|
21232
21298
|
* Non-enumerable metadata attached to structured tool execute results so
|
|
21233
21299
|
* `toModelOutput` can read MCP `content` without changing the execute return shape.
|
|
21300
|
+
*
|
|
21301
|
+
* When a tool has an `outputSchema` and the server returns `structuredContent`,
|
|
21302
|
+
* `execute()` returns that structured value directly. The rest of the
|
|
21303
|
+
* CallToolResult envelope is preserved on non-enumerable symbols:
|
|
21304
|
+
* - {@link MCP_CALL_TOOL_CONTENT} holds the MCP `content` blocks (model-facing text).
|
|
21305
|
+
* - {@link MCP_CALL_TOOL_META} holds the result-level `_meta` (e.g. `ui.resourceUri`
|
|
21306
|
+
* used by MCP Apps hosts), with `ui.serverId` stamped by the client.
|
|
21307
|
+
*
|
|
21308
|
+
* Read them with {@link getMcpCallToolContent} and {@link getMcpCallToolMeta}.
|
|
21309
|
+
* Note: scalar or `null` structured results cannot carry properties, so these
|
|
21310
|
+
* channels are only available when `structuredContent` is an object or array.
|
|
21234
21311
|
*/
|
|
21235
21312
|
const MCP_CALL_TOOL_CONTENT = Symbol.for("mastra.mcp.callToolContent");
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21313
|
+
/** Non-enumerable result-level `_meta` attached to structured tool execute results. */
|
|
21314
|
+
const MCP_CALL_TOOL_META = Symbol.for("mastra.mcp.callToolMeta");
|
|
21315
|
+
function attachMcpCallToolContent(structuredContent, content, _meta) {
|
|
21316
|
+
if (structuredContent !== null && typeof structuredContent === "object") {
|
|
21317
|
+
Object.defineProperty(structuredContent, MCP_CALL_TOOL_CONTENT, {
|
|
21318
|
+
value: content,
|
|
21319
|
+
enumerable: false,
|
|
21320
|
+
configurable: true
|
|
21321
|
+
});
|
|
21322
|
+
if (_meta !== void 0) Object.defineProperty(structuredContent, MCP_CALL_TOOL_META, {
|
|
21323
|
+
value: _meta,
|
|
21324
|
+
enumerable: false,
|
|
21325
|
+
configurable: true
|
|
21326
|
+
});
|
|
21327
|
+
}
|
|
21242
21328
|
return structuredContent;
|
|
21243
21329
|
}
|
|
21330
|
+
/**
|
|
21331
|
+
* Read the MCP `content` blocks preserved on a structured tool execute result.
|
|
21332
|
+
* Returns `undefined` for scalar results or results without a hidden content channel.
|
|
21333
|
+
*/
|
|
21244
21334
|
function getMcpCallToolContent(output) {
|
|
21245
21335
|
if (output === null || typeof output !== "object") return void 0;
|
|
21246
21336
|
return output[MCP_CALL_TOOL_CONTENT];
|
|
21247
21337
|
}
|
|
21338
|
+
/**
|
|
21339
|
+
* Read the result-level `_meta` preserved on a structured tool execute result
|
|
21340
|
+
* (e.g. `_meta.ui.resourceUri` for MCP Apps detection). Returns `undefined` for
|
|
21341
|
+
* scalar results or results whose CallToolResult had no `_meta`.
|
|
21342
|
+
*/
|
|
21343
|
+
function getMcpCallToolMeta(output) {
|
|
21344
|
+
if (output === null || typeof output !== "object") return void 0;
|
|
21345
|
+
return output[MCP_CALL_TOOL_META];
|
|
21346
|
+
}
|
|
21248
21347
|
function createStructuredToolToModelOutput() {
|
|
21249
21348
|
return (output) => {
|
|
21250
21349
|
const modelText = extractModelTextFromToolContent(getMcpCallToolContent(output));
|
|
@@ -22151,7 +22250,7 @@ var InternalMastraMCPClient = class extends _mastra_core_base.MastraBase {
|
|
|
22151
22250
|
});
|
|
22152
22251
|
}
|
|
22153
22252
|
this.log("debug", `Tool executed successfully: ${tool.name}`);
|
|
22154
|
-
if (res.structuredContent !== void 0) return attachMcpCallToolContent(res.structuredContent, res.content);
|
|
22253
|
+
if (res.structuredContent !== void 0) return attachMcpCallToolContent(res.structuredContent, res.content, res._meta ? this.stampServerIdInMeta(res._meta) : void 0);
|
|
22155
22254
|
return res;
|
|
22156
22255
|
};
|
|
22157
22256
|
const failedTransport = this.transport;
|
|
@@ -23072,15 +23171,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23072
23171
|
* console.log(resources.weatherServer); // Array of resources
|
|
23073
23172
|
* ```
|
|
23074
23173
|
*/
|
|
23075
|
-
list: async () =>
|
|
23076
|
-
|
|
23077
|
-
|
|
23078
|
-
|
|
23079
|
-
|
|
23080
|
-
|
|
23081
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allResources[serverName] = value;
|
|
23082
|
-
return allResources;
|
|
23083
|
-
},
|
|
23174
|
+
list: async () => (await this.listResourcesWithErrors()).resources,
|
|
23175
|
+
/**
|
|
23176
|
+
* Lists resources while preserving per-server discovery failures.
|
|
23177
|
+
* The existing `list()` method remains the success-only convenience API.
|
|
23178
|
+
*/
|
|
23179
|
+
listWithErrors: (options) => this.listResourcesWithErrors(options),
|
|
23084
23180
|
/**
|
|
23085
23181
|
* Lists all available resource templates from all configured servers.
|
|
23086
23182
|
*
|
|
@@ -23095,15 +23191,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23095
23191
|
* console.log(templates.weatherServer); // Array of resource templates
|
|
23096
23192
|
* ```
|
|
23097
23193
|
*/
|
|
23098
|
-
templates: async () =>
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allTemplates[serverName] = value;
|
|
23105
|
-
return allTemplates;
|
|
23106
|
-
},
|
|
23194
|
+
templates: async () => (await this.listResourceTemplatesWithErrors()).templates,
|
|
23195
|
+
/**
|
|
23196
|
+
* Lists resource templates while preserving per-server discovery failures.
|
|
23197
|
+
* The existing `templates()` method remains the success-only convenience API.
|
|
23198
|
+
*/
|
|
23199
|
+
templatesWithErrors: (options) => this.listResourceTemplatesWithErrors(options),
|
|
23107
23200
|
/**
|
|
23108
23201
|
* Reads the content of a specific resource from a server.
|
|
23109
23202
|
*
|
|
@@ -23286,15 +23379,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23286
23379
|
* console.log(prompts.weatherServer); // Array of prompts
|
|
23287
23380
|
* ```
|
|
23288
23381
|
*/
|
|
23289
|
-
list: async () =>
|
|
23290
|
-
|
|
23291
|
-
|
|
23292
|
-
|
|
23293
|
-
|
|
23294
|
-
|
|
23295
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allPrompts[serverName] = value;
|
|
23296
|
-
return allPrompts;
|
|
23297
|
-
},
|
|
23382
|
+
list: async () => (await this.listPromptsWithErrors()).prompts,
|
|
23383
|
+
/**
|
|
23384
|
+
* Lists prompts while preserving per-server discovery failures.
|
|
23385
|
+
* The existing `list()` method remains the success-only convenience API.
|
|
23386
|
+
*/
|
|
23387
|
+
listWithErrors: (options) => this.listPromptsWithErrors(options),
|
|
23298
23388
|
/**
|
|
23299
23389
|
* Retrieves a specific prompt with its messages from a server.
|
|
23300
23390
|
*
|
|
@@ -23636,14 +23726,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23636
23726
|
* Like listTools(), but also returns errors for servers that failed to connect
|
|
23637
23727
|
* or list tools. This allows callers to report specific failure reasons per server.
|
|
23638
23728
|
*
|
|
23639
|
-
* @returns Object with `tools
|
|
23729
|
+
* @returns Object with successful `tools`, legacy string `errors`, and structured `errorDetails`.
|
|
23640
23730
|
* Transient connection failures are retried once after reconnecting the affected server.
|
|
23641
23731
|
*
|
|
23642
23732
|
* @example
|
|
23643
23733
|
* ```typescript
|
|
23644
|
-
* const { tools, errors } = await mcp.listToolsWithErrors();
|
|
23734
|
+
* const { tools, errors, errorDetails } = await mcp.listToolsWithErrors();
|
|
23645
23735
|
* for (const [name, err] of Object.entries(errors)) {
|
|
23646
|
-
* console.error(`Server ${name} failed: ${err}
|
|
23736
|
+
* console.error(`Server ${name} failed: ${err}`, errorDetails[name]);
|
|
23647
23737
|
* }
|
|
23648
23738
|
* ```
|
|
23649
23739
|
*/
|
|
@@ -23651,6 +23741,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
23651
23741
|
this.addToInstanceCache();
|
|
23652
23742
|
const connectedTools = {};
|
|
23653
23743
|
const errors = {};
|
|
23744
|
+
const errorDetails = {};
|
|
23654
23745
|
const durations = {};
|
|
23655
23746
|
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
23656
23747
|
errorId: "MCP_CLIENT_GET_TOOLS_FAILED",
|
|
@@ -23659,14 +23750,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23659
23750
|
for (const { serverName, value, error, duration } of settled) {
|
|
23660
23751
|
durations[serverName] = duration;
|
|
23661
23752
|
if (error !== void 0) {
|
|
23662
|
-
errors[serverName] = error;
|
|
23753
|
+
errors[serverName] = error.message;
|
|
23754
|
+
errorDetails[serverName] = error;
|
|
23663
23755
|
continue;
|
|
23664
23756
|
}
|
|
23665
23757
|
for (const [toolName, toolConfig] of Object.entries(value)) connectedTools[`${serverName}_${toolName}`] = toolConfig;
|
|
23666
23758
|
}
|
|
23667
23759
|
const result = {
|
|
23668
23760
|
tools: connectedTools,
|
|
23669
|
-
errors
|
|
23761
|
+
errors,
|
|
23762
|
+
errorDetails
|
|
23670
23763
|
};
|
|
23671
23764
|
return options ? {
|
|
23672
23765
|
...result,
|
|
@@ -23705,14 +23798,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23705
23798
|
* Like listToolsets(), but also returns errors for servers that failed to connect
|
|
23706
23799
|
* or list tools. This allows callers to report specific failure reasons per server.
|
|
23707
23800
|
*
|
|
23708
|
-
* @returns Object with `toolsets
|
|
23801
|
+
* @returns Object with successful `toolsets`, legacy string `errors`, and structured `errorDetails`.
|
|
23709
23802
|
* Transient connection failures are retried once after reconnecting the affected server.
|
|
23710
23803
|
*
|
|
23711
23804
|
* @example
|
|
23712
23805
|
* ```typescript
|
|
23713
|
-
* const { toolsets, errors } = await mcp.listToolsetsWithErrors();
|
|
23806
|
+
* const { toolsets, errors, errorDetails } = await mcp.listToolsetsWithErrors();
|
|
23714
23807
|
* for (const [name, err] of Object.entries(errors)) {
|
|
23715
|
-
* console.error(`Server ${name} failed: ${err}
|
|
23808
|
+
* console.error(`Server ${name} failed: ${err}`, errorDetails[name]);
|
|
23716
23809
|
* }
|
|
23717
23810
|
* ```
|
|
23718
23811
|
*/
|
|
@@ -23720,6 +23813,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
23720
23813
|
this.addToInstanceCache();
|
|
23721
23814
|
const connectedToolsets = {};
|
|
23722
23815
|
const errors = {};
|
|
23816
|
+
const errorDetails = {};
|
|
23723
23817
|
const durations = {};
|
|
23724
23818
|
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
23725
23819
|
errorId: "MCP_CLIENT_GET_TOOLSETS_FAILED",
|
|
@@ -23728,14 +23822,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23728
23822
|
for (const { serverName, value, error, duration } of settled) {
|
|
23729
23823
|
durations[serverName] = duration;
|
|
23730
23824
|
if (error !== void 0) {
|
|
23731
|
-
errors[serverName] = error;
|
|
23825
|
+
errors[serverName] = error.message;
|
|
23826
|
+
errorDetails[serverName] = error;
|
|
23732
23827
|
continue;
|
|
23733
23828
|
}
|
|
23734
23829
|
connectedToolsets[serverName] = value;
|
|
23735
23830
|
}
|
|
23736
23831
|
const result = {
|
|
23737
23832
|
toolsets: connectedToolsets,
|
|
23738
|
-
errors
|
|
23833
|
+
errors,
|
|
23834
|
+
errorDetails
|
|
23739
23835
|
};
|
|
23740
23836
|
return options ? {
|
|
23741
23837
|
...result,
|
|
@@ -23773,11 +23869,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23773
23869
|
*
|
|
23774
23870
|
* Useful when caching a catalog, since it lets you avoid persisting a partial manifest that
|
|
23775
23871
|
* silently omits a server which happened to be down at discovery time.
|
|
23872
|
+
* `errors` remains a string map for compatibility; `errorDetails` preserves
|
|
23873
|
+
* machine-readable transport status and error codes when available.
|
|
23776
23874
|
*/
|
|
23777
23875
|
async listToolDefinitionsWithErrors(options) {
|
|
23778
23876
|
this.addToInstanceCache();
|
|
23779
23877
|
const definitions = {};
|
|
23780
23878
|
const errors = {};
|
|
23879
|
+
const errorDetails = {};
|
|
23781
23880
|
const durations = {};
|
|
23782
23881
|
const settled = await this.discoverAcrossServers(async (serverName) => {
|
|
23783
23882
|
return (await this.getConnectedClientForServer(serverName)).toolDefinitions();
|
|
@@ -23788,14 +23887,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23788
23887
|
for (const { serverName, value, error, duration } of settled) {
|
|
23789
23888
|
durations[serverName] = duration;
|
|
23790
23889
|
if (error !== void 0) {
|
|
23791
|
-
errors[serverName] = error;
|
|
23890
|
+
errors[serverName] = error.message;
|
|
23891
|
+
errorDetails[serverName] = error;
|
|
23792
23892
|
continue;
|
|
23793
23893
|
}
|
|
23794
23894
|
definitions[serverName] = value;
|
|
23795
23895
|
}
|
|
23796
23896
|
const result = {
|
|
23797
23897
|
definitions,
|
|
23798
|
-
errors
|
|
23898
|
+
errors,
|
|
23899
|
+
errorDetails
|
|
23799
23900
|
};
|
|
23800
23901
|
return options ? {
|
|
23801
23902
|
...result,
|
|
@@ -23852,6 +23953,59 @@ onListChanged: async (serverName, handler) => {
|
|
|
23852
23953
|
}
|
|
23853
23954
|
return tools;
|
|
23854
23955
|
}
|
|
23956
|
+
async listResourcesWithErrors(options) {
|
|
23957
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).resources.list(), {
|
|
23958
|
+
errorId: "MCP_CLIENT_LIST_RESOURCES_FAILED",
|
|
23959
|
+
logMessage: "Failed to list resources from server:"
|
|
23960
|
+
}, options);
|
|
23961
|
+
return {
|
|
23962
|
+
resources: values,
|
|
23963
|
+
...diagnostics
|
|
23964
|
+
};
|
|
23965
|
+
}
|
|
23966
|
+
async listResourceTemplatesWithErrors(options) {
|
|
23967
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).resources.templates(), {
|
|
23968
|
+
errorId: "MCP_CLIENT_LIST_RESOURCE_TEMPLATES_FAILED",
|
|
23969
|
+
logMessage: "Failed to list resource templates from server:"
|
|
23970
|
+
}, options);
|
|
23971
|
+
return {
|
|
23972
|
+
templates: values,
|
|
23973
|
+
...diagnostics
|
|
23974
|
+
};
|
|
23975
|
+
}
|
|
23976
|
+
async listPromptsWithErrors(options) {
|
|
23977
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).prompts.list(), {
|
|
23978
|
+
errorId: "MCP_CLIENT_LIST_PROMPTS_FAILED",
|
|
23979
|
+
logMessage: "Failed to list prompts from server:"
|
|
23980
|
+
}, options);
|
|
23981
|
+
return {
|
|
23982
|
+
prompts: values,
|
|
23983
|
+
...diagnostics
|
|
23984
|
+
};
|
|
23985
|
+
}
|
|
23986
|
+
async discoverValuesWithErrors(operation, onError, options) {
|
|
23987
|
+
const values = {};
|
|
23988
|
+
const errors = {};
|
|
23989
|
+
const errorDetails = {};
|
|
23990
|
+
const durations = {};
|
|
23991
|
+
const settled = await this.discoverAcrossServers(operation, onError, options);
|
|
23992
|
+
for (const { serverName, value, error, duration } of settled) {
|
|
23993
|
+
durations[serverName] = duration;
|
|
23994
|
+
if (error !== void 0) {
|
|
23995
|
+
errors[serverName] = error.message;
|
|
23996
|
+
errorDetails[serverName] = error;
|
|
23997
|
+
} else values[serverName] = value;
|
|
23998
|
+
}
|
|
23999
|
+
const result = {
|
|
24000
|
+
values,
|
|
24001
|
+
errors,
|
|
24002
|
+
errorDetails
|
|
24003
|
+
};
|
|
24004
|
+
return options ? {
|
|
24005
|
+
...result,
|
|
24006
|
+
durations
|
|
24007
|
+
} : result;
|
|
24008
|
+
}
|
|
23855
24009
|
/**
|
|
23856
24010
|
* Runs a per-server discovery `operation` against every configured server
|
|
23857
24011
|
* concurrently, isolating and logging per-server failures. Results are
|
|
@@ -23881,18 +24035,31 @@ onListChanged: async (serverName, handler) => {
|
|
|
23881
24035
|
duration: performance.now() - startedAt
|
|
23882
24036
|
};
|
|
23883
24037
|
} catch (error) {
|
|
23884
|
-
const
|
|
23885
|
-
|
|
23886
|
-
|
|
23887
|
-
|
|
23888
|
-
|
|
23889
|
-
|
|
23890
|
-
|
|
23891
|
-
|
|
24038
|
+
const discoveryError = getMCPDiscoveryErrorDetails(error);
|
|
24039
|
+
try {
|
|
24040
|
+
const mastraError = new _mastra_core_error.MastraError({
|
|
24041
|
+
id: onError.errorId,
|
|
24042
|
+
domain: _mastra_core_error.ErrorDomain.MCP,
|
|
24043
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
24044
|
+
details: { serverName }
|
|
24045
|
+
}, error);
|
|
24046
|
+
this.logger.trackException(mastraError);
|
|
24047
|
+
this.logger.error(onError.logMessage, { error: mastraError.toString() });
|
|
24048
|
+
} catch {
|
|
24049
|
+
const fallbackError = new _mastra_core_error.MastraError({
|
|
24050
|
+
id: onError.errorId,
|
|
24051
|
+
domain: _mastra_core_error.ErrorDomain.MCP,
|
|
24052
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
24053
|
+
text: discoveryError.message,
|
|
24054
|
+
details: { serverName }
|
|
24055
|
+
});
|
|
24056
|
+
this.logger.trackException(fallbackError);
|
|
24057
|
+
this.logger.error(onError.logMessage, { error: fallbackError.toString() });
|
|
24058
|
+
}
|
|
23892
24059
|
return {
|
|
23893
24060
|
serverName,
|
|
23894
24061
|
value: void 0,
|
|
23895
|
-
error:
|
|
24062
|
+
error: discoveryError,
|
|
23896
24063
|
duration: performance.now() - startedAt
|
|
23897
24064
|
};
|
|
23898
24065
|
} finally {
|
|
@@ -24461,7 +24628,6 @@ async function broadcastNotification({ servers, send, logger, errorId, errorText
|
|
|
24461
24628
|
var ServerPromptActions = class {
|
|
24462
24629
|
getLogger;
|
|
24463
24630
|
getSdkServers;
|
|
24464
|
-
clearDefinedPrompts;
|
|
24465
24631
|
getModernEraNotifier;
|
|
24466
24632
|
/**
|
|
24467
24633
|
* @internal
|
|
@@ -24469,14 +24635,13 @@ var ServerPromptActions = class {
|
|
|
24469
24635
|
constructor(dependencies) {
|
|
24470
24636
|
this.getLogger = dependencies.getLogger;
|
|
24471
24637
|
this.getSdkServers = dependencies.getSdkServers;
|
|
24472
|
-
this.clearDefinedPrompts = dependencies.clearDefinedPrompts;
|
|
24473
24638
|
this.getModernEraNotifier = dependencies.getModernEraNotifier;
|
|
24474
24639
|
}
|
|
24475
24640
|
/**
|
|
24476
24641
|
* Notifies clients that the overall list of available prompts has changed.
|
|
24477
24642
|
*
|
|
24478
|
-
* This
|
|
24479
|
-
*
|
|
24643
|
+
* This sends a `notifications/prompts/list_changed` message to all clients,
|
|
24644
|
+
* prompting them to re-fetch the prompt list.
|
|
24480
24645
|
*
|
|
24481
24646
|
* @throws {MastraError} If sending the notification fails on all server instances
|
|
24482
24647
|
*
|
|
@@ -24487,8 +24652,7 @@ var ServerPromptActions = class {
|
|
|
24487
24652
|
* ```
|
|
24488
24653
|
*/
|
|
24489
24654
|
async notifyListChanged() {
|
|
24490
|
-
this.getLogger().info("Prompt list change externally notified.
|
|
24491
|
-
this.clearDefinedPrompts();
|
|
24655
|
+
this.getLogger().info("Prompt list change externally notified. Sending notification.");
|
|
24492
24656
|
this.getModernEraNotifier?.()?.promptsChanged();
|
|
24493
24657
|
await broadcastNotification({
|
|
24494
24658
|
servers: this.getSdkServers(),
|
|
@@ -24759,7 +24923,6 @@ var MCPServer = class extends _mastra_core_mcp.MCPServerBase {
|
|
|
24759
24923
|
httpServerInstances = /* @__PURE__ */ new Map();
|
|
24760
24924
|
resourceOptions;
|
|
24761
24925
|
hasUiResources = false;
|
|
24762
|
-
definedPrompts;
|
|
24763
24926
|
promptOptions;
|
|
24764
24927
|
jsonSchemaValidator;
|
|
24765
24928
|
mapAuthInfoToUser;
|
|
@@ -24972,9 +25135,6 @@ var MCPServer = class extends _mastra_core_mcp.MCPServerBase {
|
|
|
24972
25135
|
this.prompts = new ServerPromptActions({
|
|
24973
25136
|
getLogger: () => this.logger,
|
|
24974
25137
|
getSdkServers: () => this.getAllSdkServers(),
|
|
24975
|
-
clearDefinedPrompts: () => {
|
|
24976
|
-
this.definedPrompts = void 0;
|
|
24977
|
-
},
|
|
24978
25138
|
getModernEraNotifier
|
|
24979
25139
|
});
|
|
24980
25140
|
this.toolActions = new ServerToolActions({
|
|
@@ -25634,13 +25794,11 @@ var MCPServer = class extends _mastra_core_mcp.MCPServerBase {
|
|
|
25634
25794
|
if (!capturedPromptOptions) return;
|
|
25635
25795
|
if (capturedPromptOptions.listPrompts) serverInstance.setRequestHandler("prompts/list", async (_request, ctx) => {
|
|
25636
25796
|
this.logger.debug("Handling ListPrompts request");
|
|
25637
|
-
|
|
25638
|
-
else try {
|
|
25797
|
+
try {
|
|
25639
25798
|
const prompts = await capturedPromptOptions.listPrompts({ extra: toMCPRequestHandlerExtra(ctx) });
|
|
25640
25799
|
for (const prompt of prompts) _modelcontextprotocol_core.PromptSchema.parse(prompt);
|
|
25641
|
-
this.
|
|
25642
|
-
|
|
25643
|
-
return { prompts: this.definedPrompts };
|
|
25800
|
+
this.logger.debug("Fetched prompts", { count: prompts.length });
|
|
25801
|
+
return { prompts };
|
|
25644
25802
|
} catch (error) {
|
|
25645
25803
|
this.logger.error("Error fetching prompts via listPrompts():", { error: error instanceof Error ? error.message : String(error) });
|
|
25646
25804
|
throw error;
|
|
@@ -25649,12 +25807,11 @@ var MCPServer = class extends _mastra_core_mcp.MCPServerBase {
|
|
|
25649
25807
|
if (capturedPromptOptions.getPromptMessages) serverInstance.setRequestHandler("prompts/get", async (request, ctx) => {
|
|
25650
25808
|
const startTime = Date.now();
|
|
25651
25809
|
const { name, arguments: args } = request.params;
|
|
25652
|
-
|
|
25653
|
-
|
|
25654
|
-
|
|
25655
|
-
|
|
25656
|
-
|
|
25657
|
-
const prompt = this.definedPrompts?.find((p) => p.name === name);
|
|
25810
|
+
const extra = toMCPRequestHandlerExtra(ctx);
|
|
25811
|
+
const prompts = await capturedPromptOptions.listPrompts?.({ extra });
|
|
25812
|
+
if (!prompts) throw new Error("Failed to load prompts");
|
|
25813
|
+
for (const definedPrompt of prompts) _modelcontextprotocol_core.PromptSchema.parse(definedPrompt);
|
|
25814
|
+
const prompt = prompts.find((p) => p.name === name);
|
|
25658
25815
|
if (!prompt) throw new Error(`Prompt "${name}" not found`);
|
|
25659
25816
|
if (prompt.arguments) {
|
|
25660
25817
|
for (const arg of prompt.arguments) if (arg.required && (args?.[arg.name] === void 0 || args?.[arg.name] === null)) throw new _modelcontextprotocol_server.ProtocolError(_modelcontextprotocol_server.ProtocolErrorCode.InvalidParams, `Missing required argument: ${arg.name}`);
|
|
@@ -25665,7 +25822,7 @@ var MCPServer = class extends _mastra_core_mcp.MCPServerBase {
|
|
|
25665
25822
|
name,
|
|
25666
25823
|
version: prompt.version,
|
|
25667
25824
|
args,
|
|
25668
|
-
extra
|
|
25825
|
+
extra
|
|
25669
25826
|
});
|
|
25670
25827
|
const duration = Date.now() - startTime;
|
|
25671
25828
|
this.logger.info("Prompt retrieved successfully", {
|
|
@@ -27155,6 +27312,7 @@ exports.MCPClientServerProxy = MCPClientServerProxy;
|
|
|
27155
27312
|
exports.MCPOAuthClientProvider = MCPOAuthClientProvider;
|
|
27156
27313
|
exports.MCPServer = MCPServer;
|
|
27157
27314
|
exports.MCP_CALL_TOOL_CONTENT = MCP_CALL_TOOL_CONTENT;
|
|
27315
|
+
exports.MCP_CALL_TOOL_META = MCP_CALL_TOOL_META;
|
|
27158
27316
|
Object.defineProperty(exports, "UnauthorizedError", {
|
|
27159
27317
|
enumerable: true,
|
|
27160
27318
|
get: function() {
|
|
@@ -27212,6 +27370,8 @@ Object.defineProperty(exports, "extractResourceMetadataUrl", {
|
|
|
27212
27370
|
exports.generateProtectedResourceMetadata = generateProtectedResourceMetadata;
|
|
27213
27371
|
exports.generateWWWAuthenticateHeader = generateWWWAuthenticateHeader;
|
|
27214
27372
|
exports.getCallbackUrlCandidates = getCallbackUrlCandidates;
|
|
27373
|
+
exports.getMcpCallToolContent = getMcpCallToolContent;
|
|
27374
|
+
exports.getMcpCallToolMeta = getMcpCallToolMeta;
|
|
27215
27375
|
Object.defineProperty(exports, "parseErrorResponse", {
|
|
27216
27376
|
enumerable: true,
|
|
27217
27377
|
get: function() {
|