@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.js
CHANGED
|
@@ -17311,7 +17311,7 @@ var _AISDKError = class _AISDKError extends Error {
|
|
|
17311
17311
|
};
|
|
17312
17312
|
_a$1 = symbol$1;
|
|
17313
17313
|
var AISDKError = _AISDKError;
|
|
17314
|
-
function getErrorMessage(error) {
|
|
17314
|
+
function getErrorMessage$1(error) {
|
|
17315
17315
|
if (error == null) return "unknown error";
|
|
17316
17316
|
if (typeof error === "string") return error;
|
|
17317
17317
|
if (error instanceof Error) return error.message;
|
|
@@ -17345,7 +17345,7 @@ var JSONParseError = class extends AISDKError {
|
|
|
17345
17345
|
super({
|
|
17346
17346
|
name: name6$1,
|
|
17347
17347
|
message: `JSON parsing failed: Text: ${text}.
|
|
17348
|
-
Error message: ${getErrorMessage(cause)}`,
|
|
17348
|
+
Error message: ${getErrorMessage$1(cause)}`,
|
|
17349
17349
|
cause
|
|
17350
17350
|
});
|
|
17351
17351
|
this[_a7$1] = true;
|
|
@@ -17365,7 +17365,7 @@ var _TypeValidationError = class _TypeValidationError extends AISDKError {
|
|
|
17365
17365
|
super({
|
|
17366
17366
|
name: name12$1,
|
|
17367
17367
|
message: `Type validation failed: Value: ${JSON.stringify(value)}.
|
|
17368
|
-
Error message: ${getErrorMessage(cause)}`,
|
|
17368
|
+
Error message: ${getErrorMessage$1(cause)}`,
|
|
17369
17369
|
cause
|
|
17370
17370
|
});
|
|
17371
17371
|
this[_a13$1] = true;
|
|
@@ -20977,6 +20977,72 @@ function isReconnectableMCPError(error) {
|
|
|
20977
20977
|
const errorMessage = error.message.toLowerCase();
|
|
20978
20978
|
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");
|
|
20979
20979
|
}
|
|
20980
|
+
const MAX_DISCOVERY_ERROR_CAUSE_DEPTH = 8;
|
|
20981
|
+
function isHttpStatus(value) {
|
|
20982
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599;
|
|
20983
|
+
}
|
|
20984
|
+
function asErrorRecord(value) {
|
|
20985
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
20986
|
+
}
|
|
20987
|
+
function getErrorProperty(record, property) {
|
|
20988
|
+
if (!record) return void 0;
|
|
20989
|
+
try {
|
|
20990
|
+
return record[property];
|
|
20991
|
+
} catch {
|
|
20992
|
+
return;
|
|
20993
|
+
}
|
|
20994
|
+
}
|
|
20995
|
+
function getErrorMessage(error) {
|
|
20996
|
+
const message = getErrorProperty(asErrorRecord(error), "message");
|
|
20997
|
+
if (typeof message === "string") return message;
|
|
20998
|
+
try {
|
|
20999
|
+
return String(error);
|
|
21000
|
+
} catch {
|
|
21001
|
+
return "Unknown error";
|
|
21002
|
+
}
|
|
21003
|
+
}
|
|
21004
|
+
/**
|
|
21005
|
+
* Preserve machine-readable transport metadata before aggregate discovery turns
|
|
21006
|
+
* a thrown error into its legacy per-server string.
|
|
21007
|
+
*
|
|
21008
|
+
* MCP SDK 2 keeps an HTTP response status on `SdkHttpError.status` while
|
|
21009
|
+
* `code` is a string SDK code. Older transports and wrappers have also used
|
|
21010
|
+
* `statusCode`; only explicit status fields are treated as HTTP metadata so a
|
|
21011
|
+
* numeric SDK or application `code` is not mislabeled. The walk is bounded and
|
|
21012
|
+
* cycle-safe because application errors may wrap arbitrary third-party causes.
|
|
21013
|
+
*/
|
|
21014
|
+
function getMCPDiscoveryErrorDetails(error) {
|
|
21015
|
+
let message = getErrorMessage(error);
|
|
21016
|
+
let httpStatus;
|
|
21017
|
+
let code;
|
|
21018
|
+
let current = error;
|
|
21019
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21020
|
+
for (let depth = 0; depth < MAX_DISCOVERY_ERROR_CAUSE_DEPTH && current !== void 0 && current !== null && !seen.has(current); depth++) {
|
|
21021
|
+
seen.add(current);
|
|
21022
|
+
const record = asErrorRecord(current);
|
|
21023
|
+
if (!record) break;
|
|
21024
|
+
const data = asErrorRecord(getErrorProperty(record, "data"));
|
|
21025
|
+
if (httpStatus === void 0) {
|
|
21026
|
+
for (const candidate of [
|
|
21027
|
+
getErrorProperty(record, "status"),
|
|
21028
|
+
getErrorProperty(record, "statusCode"),
|
|
21029
|
+
getErrorProperty(data, "status"),
|
|
21030
|
+
getErrorProperty(data, "statusCode")
|
|
21031
|
+
]) if (isHttpStatus(candidate)) {
|
|
21032
|
+
httpStatus = candidate;
|
|
21033
|
+
break;
|
|
21034
|
+
}
|
|
21035
|
+
}
|
|
21036
|
+
for (const candidate of [getErrorProperty(record, "code"), getErrorProperty(data, "code")]) if (typeof candidate === "string" || typeof candidate === "number") code = candidate;
|
|
21037
|
+
current = getErrorProperty(record, "cause");
|
|
21038
|
+
}
|
|
21039
|
+
if (httpStatus !== void 0 && !message.includes(`(HTTP ${httpStatus})`)) message += ` (HTTP ${httpStatus})`;
|
|
21040
|
+
return {
|
|
21041
|
+
message,
|
|
21042
|
+
...httpStatus !== void 0 ? { httpStatus } : {},
|
|
21043
|
+
...code !== void 0 ? { code } : {}
|
|
21044
|
+
};
|
|
21045
|
+
}
|
|
20980
21046
|
//#endregion
|
|
20981
21047
|
//#region src/client/url-policy.ts
|
|
20982
21048
|
/**
|
|
@@ -21210,20 +21276,53 @@ function extractModelTextFromToolContent(content) {
|
|
|
21210
21276
|
/**
|
|
21211
21277
|
* Non-enumerable metadata attached to structured tool execute results so
|
|
21212
21278
|
* `toModelOutput` can read MCP `content` without changing the execute return shape.
|
|
21279
|
+
*
|
|
21280
|
+
* When a tool has an `outputSchema` and the server returns `structuredContent`,
|
|
21281
|
+
* `execute()` returns that structured value directly. The rest of the
|
|
21282
|
+
* CallToolResult envelope is preserved on non-enumerable symbols:
|
|
21283
|
+
* - {@link MCP_CALL_TOOL_CONTENT} holds the MCP `content` blocks (model-facing text).
|
|
21284
|
+
* - {@link MCP_CALL_TOOL_META} holds the result-level `_meta` (e.g. `ui.resourceUri`
|
|
21285
|
+
* used by MCP Apps hosts), with `ui.serverId` stamped by the client.
|
|
21286
|
+
*
|
|
21287
|
+
* Read them with {@link getMcpCallToolContent} and {@link getMcpCallToolMeta}.
|
|
21288
|
+
* Note: scalar or `null` structured results cannot carry properties, so these
|
|
21289
|
+
* channels are only available when `structuredContent` is an object or array.
|
|
21213
21290
|
*/
|
|
21214
21291
|
const MCP_CALL_TOOL_CONTENT = Symbol.for("mastra.mcp.callToolContent");
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
|
|
21220
|
-
|
|
21292
|
+
/** Non-enumerable result-level `_meta` attached to structured tool execute results. */
|
|
21293
|
+
const MCP_CALL_TOOL_META = Symbol.for("mastra.mcp.callToolMeta");
|
|
21294
|
+
function attachMcpCallToolContent(structuredContent, content, _meta) {
|
|
21295
|
+
if (structuredContent !== null && typeof structuredContent === "object") {
|
|
21296
|
+
Object.defineProperty(structuredContent, MCP_CALL_TOOL_CONTENT, {
|
|
21297
|
+
value: content,
|
|
21298
|
+
enumerable: false,
|
|
21299
|
+
configurable: true
|
|
21300
|
+
});
|
|
21301
|
+
if (_meta !== void 0) Object.defineProperty(structuredContent, MCP_CALL_TOOL_META, {
|
|
21302
|
+
value: _meta,
|
|
21303
|
+
enumerable: false,
|
|
21304
|
+
configurable: true
|
|
21305
|
+
});
|
|
21306
|
+
}
|
|
21221
21307
|
return structuredContent;
|
|
21222
21308
|
}
|
|
21309
|
+
/**
|
|
21310
|
+
* Read the MCP `content` blocks preserved on a structured tool execute result.
|
|
21311
|
+
* Returns `undefined` for scalar results or results without a hidden content channel.
|
|
21312
|
+
*/
|
|
21223
21313
|
function getMcpCallToolContent(output) {
|
|
21224
21314
|
if (output === null || typeof output !== "object") return void 0;
|
|
21225
21315
|
return output[MCP_CALL_TOOL_CONTENT];
|
|
21226
21316
|
}
|
|
21317
|
+
/**
|
|
21318
|
+
* Read the result-level `_meta` preserved on a structured tool execute result
|
|
21319
|
+
* (e.g. `_meta.ui.resourceUri` for MCP Apps detection). Returns `undefined` for
|
|
21320
|
+
* scalar results or results whose CallToolResult had no `_meta`.
|
|
21321
|
+
*/
|
|
21322
|
+
function getMcpCallToolMeta(output) {
|
|
21323
|
+
if (output === null || typeof output !== "object") return void 0;
|
|
21324
|
+
return output[MCP_CALL_TOOL_META];
|
|
21325
|
+
}
|
|
21227
21326
|
function createStructuredToolToModelOutput() {
|
|
21228
21327
|
return (output) => {
|
|
21229
21328
|
const modelText = extractModelTextFromToolContent(getMcpCallToolContent(output));
|
|
@@ -22130,7 +22229,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
22130
22229
|
});
|
|
22131
22230
|
}
|
|
22132
22231
|
this.log("debug", `Tool executed successfully: ${tool.name}`);
|
|
22133
|
-
if (res.structuredContent !== void 0) return attachMcpCallToolContent(res.structuredContent, res.content);
|
|
22232
|
+
if (res.structuredContent !== void 0) return attachMcpCallToolContent(res.structuredContent, res.content, res._meta ? this.stampServerIdInMeta(res._meta) : void 0);
|
|
22134
22233
|
return res;
|
|
22135
22234
|
};
|
|
22136
22235
|
const failedTransport = this.transport;
|
|
@@ -23051,15 +23150,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23051
23150
|
* console.log(resources.weatherServer); // Array of resources
|
|
23052
23151
|
* ```
|
|
23053
23152
|
*/
|
|
23054
|
-
list: async () =>
|
|
23055
|
-
|
|
23056
|
-
|
|
23057
|
-
|
|
23058
|
-
|
|
23059
|
-
|
|
23060
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allResources[serverName] = value;
|
|
23061
|
-
return allResources;
|
|
23062
|
-
},
|
|
23153
|
+
list: async () => (await this.listResourcesWithErrors()).resources,
|
|
23154
|
+
/**
|
|
23155
|
+
* Lists resources while preserving per-server discovery failures.
|
|
23156
|
+
* The existing `list()` method remains the success-only convenience API.
|
|
23157
|
+
*/
|
|
23158
|
+
listWithErrors: (options) => this.listResourcesWithErrors(options),
|
|
23063
23159
|
/**
|
|
23064
23160
|
* Lists all available resource templates from all configured servers.
|
|
23065
23161
|
*
|
|
@@ -23074,15 +23170,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23074
23170
|
* console.log(templates.weatherServer); // Array of resource templates
|
|
23075
23171
|
* ```
|
|
23076
23172
|
*/
|
|
23077
|
-
templates: async () =>
|
|
23078
|
-
|
|
23079
|
-
|
|
23080
|
-
|
|
23081
|
-
|
|
23082
|
-
|
|
23083
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allTemplates[serverName] = value;
|
|
23084
|
-
return allTemplates;
|
|
23085
|
-
},
|
|
23173
|
+
templates: async () => (await this.listResourceTemplatesWithErrors()).templates,
|
|
23174
|
+
/**
|
|
23175
|
+
* Lists resource templates while preserving per-server discovery failures.
|
|
23176
|
+
* The existing `templates()` method remains the success-only convenience API.
|
|
23177
|
+
*/
|
|
23178
|
+
templatesWithErrors: (options) => this.listResourceTemplatesWithErrors(options),
|
|
23086
23179
|
/**
|
|
23087
23180
|
* Reads the content of a specific resource from a server.
|
|
23088
23181
|
*
|
|
@@ -23265,15 +23358,12 @@ onRequest: async (serverName, handler) => {
|
|
|
23265
23358
|
* console.log(prompts.weatherServer); // Array of prompts
|
|
23266
23359
|
* ```
|
|
23267
23360
|
*/
|
|
23268
|
-
list: async () =>
|
|
23269
|
-
|
|
23270
|
-
|
|
23271
|
-
|
|
23272
|
-
|
|
23273
|
-
|
|
23274
|
-
for (const { serverName, value, error } of settled) if (error === void 0) allPrompts[serverName] = value;
|
|
23275
|
-
return allPrompts;
|
|
23276
|
-
},
|
|
23361
|
+
list: async () => (await this.listPromptsWithErrors()).prompts,
|
|
23362
|
+
/**
|
|
23363
|
+
* Lists prompts while preserving per-server discovery failures.
|
|
23364
|
+
* The existing `list()` method remains the success-only convenience API.
|
|
23365
|
+
*/
|
|
23366
|
+
listWithErrors: (options) => this.listPromptsWithErrors(options),
|
|
23277
23367
|
/**
|
|
23278
23368
|
* Retrieves a specific prompt with its messages from a server.
|
|
23279
23369
|
*
|
|
@@ -23615,14 +23705,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23615
23705
|
* Like listTools(), but also returns errors for servers that failed to connect
|
|
23616
23706
|
* or list tools. This allows callers to report specific failure reasons per server.
|
|
23617
23707
|
*
|
|
23618
|
-
* @returns Object with `tools
|
|
23708
|
+
* @returns Object with successful `tools`, legacy string `errors`, and structured `errorDetails`.
|
|
23619
23709
|
* Transient connection failures are retried once after reconnecting the affected server.
|
|
23620
23710
|
*
|
|
23621
23711
|
* @example
|
|
23622
23712
|
* ```typescript
|
|
23623
|
-
* const { tools, errors } = await mcp.listToolsWithErrors();
|
|
23713
|
+
* const { tools, errors, errorDetails } = await mcp.listToolsWithErrors();
|
|
23624
23714
|
* for (const [name, err] of Object.entries(errors)) {
|
|
23625
|
-
* console.error(`Server ${name} failed: ${err}
|
|
23715
|
+
* console.error(`Server ${name} failed: ${err}`, errorDetails[name]);
|
|
23626
23716
|
* }
|
|
23627
23717
|
* ```
|
|
23628
23718
|
*/
|
|
@@ -23630,6 +23720,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
23630
23720
|
this.addToInstanceCache();
|
|
23631
23721
|
const connectedTools = {};
|
|
23632
23722
|
const errors = {};
|
|
23723
|
+
const errorDetails = {};
|
|
23633
23724
|
const durations = {};
|
|
23634
23725
|
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
23635
23726
|
errorId: "MCP_CLIENT_GET_TOOLS_FAILED",
|
|
@@ -23638,14 +23729,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23638
23729
|
for (const { serverName, value, error, duration } of settled) {
|
|
23639
23730
|
durations[serverName] = duration;
|
|
23640
23731
|
if (error !== void 0) {
|
|
23641
|
-
errors[serverName] = error;
|
|
23732
|
+
errors[serverName] = error.message;
|
|
23733
|
+
errorDetails[serverName] = error;
|
|
23642
23734
|
continue;
|
|
23643
23735
|
}
|
|
23644
23736
|
for (const [toolName, toolConfig] of Object.entries(value)) connectedTools[`${serverName}_${toolName}`] = toolConfig;
|
|
23645
23737
|
}
|
|
23646
23738
|
const result = {
|
|
23647
23739
|
tools: connectedTools,
|
|
23648
|
-
errors
|
|
23740
|
+
errors,
|
|
23741
|
+
errorDetails
|
|
23649
23742
|
};
|
|
23650
23743
|
return options ? {
|
|
23651
23744
|
...result,
|
|
@@ -23684,14 +23777,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23684
23777
|
* Like listToolsets(), but also returns errors for servers that failed to connect
|
|
23685
23778
|
* or list tools. This allows callers to report specific failure reasons per server.
|
|
23686
23779
|
*
|
|
23687
|
-
* @returns Object with `toolsets
|
|
23780
|
+
* @returns Object with successful `toolsets`, legacy string `errors`, and structured `errorDetails`.
|
|
23688
23781
|
* Transient connection failures are retried once after reconnecting the affected server.
|
|
23689
23782
|
*
|
|
23690
23783
|
* @example
|
|
23691
23784
|
* ```typescript
|
|
23692
|
-
* const { toolsets, errors } = await mcp.listToolsetsWithErrors();
|
|
23785
|
+
* const { toolsets, errors, errorDetails } = await mcp.listToolsetsWithErrors();
|
|
23693
23786
|
* for (const [name, err] of Object.entries(errors)) {
|
|
23694
|
-
* console.error(`Server ${name} failed: ${err}
|
|
23787
|
+
* console.error(`Server ${name} failed: ${err}`, errorDetails[name]);
|
|
23695
23788
|
* }
|
|
23696
23789
|
* ```
|
|
23697
23790
|
*/
|
|
@@ -23699,6 +23792,7 @@ onListChanged: async (serverName, handler) => {
|
|
|
23699
23792
|
this.addToInstanceCache();
|
|
23700
23793
|
const connectedToolsets = {};
|
|
23701
23794
|
const errors = {};
|
|
23795
|
+
const errorDetails = {};
|
|
23702
23796
|
const durations = {};
|
|
23703
23797
|
const settled = await this.discoverAcrossServers((serverName) => this.getToolsForServer(serverName), {
|
|
23704
23798
|
errorId: "MCP_CLIENT_GET_TOOLSETS_FAILED",
|
|
@@ -23707,14 +23801,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23707
23801
|
for (const { serverName, value, error, duration } of settled) {
|
|
23708
23802
|
durations[serverName] = duration;
|
|
23709
23803
|
if (error !== void 0) {
|
|
23710
|
-
errors[serverName] = error;
|
|
23804
|
+
errors[serverName] = error.message;
|
|
23805
|
+
errorDetails[serverName] = error;
|
|
23711
23806
|
continue;
|
|
23712
23807
|
}
|
|
23713
23808
|
connectedToolsets[serverName] = value;
|
|
23714
23809
|
}
|
|
23715
23810
|
const result = {
|
|
23716
23811
|
toolsets: connectedToolsets,
|
|
23717
|
-
errors
|
|
23812
|
+
errors,
|
|
23813
|
+
errorDetails
|
|
23718
23814
|
};
|
|
23719
23815
|
return options ? {
|
|
23720
23816
|
...result,
|
|
@@ -23752,11 +23848,14 @@ onListChanged: async (serverName, handler) => {
|
|
|
23752
23848
|
*
|
|
23753
23849
|
* Useful when caching a catalog, since it lets you avoid persisting a partial manifest that
|
|
23754
23850
|
* silently omits a server which happened to be down at discovery time.
|
|
23851
|
+
* `errors` remains a string map for compatibility; `errorDetails` preserves
|
|
23852
|
+
* machine-readable transport status and error codes when available.
|
|
23755
23853
|
*/
|
|
23756
23854
|
async listToolDefinitionsWithErrors(options) {
|
|
23757
23855
|
this.addToInstanceCache();
|
|
23758
23856
|
const definitions = {};
|
|
23759
23857
|
const errors = {};
|
|
23858
|
+
const errorDetails = {};
|
|
23760
23859
|
const durations = {};
|
|
23761
23860
|
const settled = await this.discoverAcrossServers(async (serverName) => {
|
|
23762
23861
|
return (await this.getConnectedClientForServer(serverName)).toolDefinitions();
|
|
@@ -23767,14 +23866,16 @@ onListChanged: async (serverName, handler) => {
|
|
|
23767
23866
|
for (const { serverName, value, error, duration } of settled) {
|
|
23768
23867
|
durations[serverName] = duration;
|
|
23769
23868
|
if (error !== void 0) {
|
|
23770
|
-
errors[serverName] = error;
|
|
23869
|
+
errors[serverName] = error.message;
|
|
23870
|
+
errorDetails[serverName] = error;
|
|
23771
23871
|
continue;
|
|
23772
23872
|
}
|
|
23773
23873
|
definitions[serverName] = value;
|
|
23774
23874
|
}
|
|
23775
23875
|
const result = {
|
|
23776
23876
|
definitions,
|
|
23777
|
-
errors
|
|
23877
|
+
errors,
|
|
23878
|
+
errorDetails
|
|
23778
23879
|
};
|
|
23779
23880
|
return options ? {
|
|
23780
23881
|
...result,
|
|
@@ -23831,6 +23932,59 @@ onListChanged: async (serverName, handler) => {
|
|
|
23831
23932
|
}
|
|
23832
23933
|
return tools;
|
|
23833
23934
|
}
|
|
23935
|
+
async listResourcesWithErrors(options) {
|
|
23936
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).resources.list(), {
|
|
23937
|
+
errorId: "MCP_CLIENT_LIST_RESOURCES_FAILED",
|
|
23938
|
+
logMessage: "Failed to list resources from server:"
|
|
23939
|
+
}, options);
|
|
23940
|
+
return {
|
|
23941
|
+
resources: values,
|
|
23942
|
+
...diagnostics
|
|
23943
|
+
};
|
|
23944
|
+
}
|
|
23945
|
+
async listResourceTemplatesWithErrors(options) {
|
|
23946
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).resources.templates(), {
|
|
23947
|
+
errorId: "MCP_CLIENT_LIST_RESOURCE_TEMPLATES_FAILED",
|
|
23948
|
+
logMessage: "Failed to list resource templates from server:"
|
|
23949
|
+
}, options);
|
|
23950
|
+
return {
|
|
23951
|
+
templates: values,
|
|
23952
|
+
...diagnostics
|
|
23953
|
+
};
|
|
23954
|
+
}
|
|
23955
|
+
async listPromptsWithErrors(options) {
|
|
23956
|
+
const { values, ...diagnostics } = await this.discoverValuesWithErrors(async (serverName) => (await this.getConnectedClientForServer(serverName)).prompts.list(), {
|
|
23957
|
+
errorId: "MCP_CLIENT_LIST_PROMPTS_FAILED",
|
|
23958
|
+
logMessage: "Failed to list prompts from server:"
|
|
23959
|
+
}, options);
|
|
23960
|
+
return {
|
|
23961
|
+
prompts: values,
|
|
23962
|
+
...diagnostics
|
|
23963
|
+
};
|
|
23964
|
+
}
|
|
23965
|
+
async discoverValuesWithErrors(operation, onError, options) {
|
|
23966
|
+
const values = {};
|
|
23967
|
+
const errors = {};
|
|
23968
|
+
const errorDetails = {};
|
|
23969
|
+
const durations = {};
|
|
23970
|
+
const settled = await this.discoverAcrossServers(operation, onError, options);
|
|
23971
|
+
for (const { serverName, value, error, duration } of settled) {
|
|
23972
|
+
durations[serverName] = duration;
|
|
23973
|
+
if (error !== void 0) {
|
|
23974
|
+
errors[serverName] = error.message;
|
|
23975
|
+
errorDetails[serverName] = error;
|
|
23976
|
+
} else values[serverName] = value;
|
|
23977
|
+
}
|
|
23978
|
+
const result = {
|
|
23979
|
+
values,
|
|
23980
|
+
errors,
|
|
23981
|
+
errorDetails
|
|
23982
|
+
};
|
|
23983
|
+
return options ? {
|
|
23984
|
+
...result,
|
|
23985
|
+
durations
|
|
23986
|
+
} : result;
|
|
23987
|
+
}
|
|
23834
23988
|
/**
|
|
23835
23989
|
* Runs a per-server discovery `operation` against every configured server
|
|
23836
23990
|
* concurrently, isolating and logging per-server failures. Results are
|
|
@@ -23860,18 +24014,31 @@ onListChanged: async (serverName, handler) => {
|
|
|
23860
24014
|
duration: performance.now() - startedAt
|
|
23861
24015
|
};
|
|
23862
24016
|
} catch (error) {
|
|
23863
|
-
const
|
|
23864
|
-
|
|
23865
|
-
|
|
23866
|
-
|
|
23867
|
-
|
|
23868
|
-
|
|
23869
|
-
|
|
23870
|
-
|
|
24017
|
+
const discoveryError = getMCPDiscoveryErrorDetails(error);
|
|
24018
|
+
try {
|
|
24019
|
+
const mastraError = new MastraError({
|
|
24020
|
+
id: onError.errorId,
|
|
24021
|
+
domain: ErrorDomain.MCP,
|
|
24022
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
24023
|
+
details: { serverName }
|
|
24024
|
+
}, error);
|
|
24025
|
+
this.logger.trackException(mastraError);
|
|
24026
|
+
this.logger.error(onError.logMessage, { error: mastraError.toString() });
|
|
24027
|
+
} catch {
|
|
24028
|
+
const fallbackError = new MastraError({
|
|
24029
|
+
id: onError.errorId,
|
|
24030
|
+
domain: ErrorDomain.MCP,
|
|
24031
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
24032
|
+
text: discoveryError.message,
|
|
24033
|
+
details: { serverName }
|
|
24034
|
+
});
|
|
24035
|
+
this.logger.trackException(fallbackError);
|
|
24036
|
+
this.logger.error(onError.logMessage, { error: fallbackError.toString() });
|
|
24037
|
+
}
|
|
23871
24038
|
return {
|
|
23872
24039
|
serverName,
|
|
23873
24040
|
value: void 0,
|
|
23874
|
-
error:
|
|
24041
|
+
error: discoveryError,
|
|
23875
24042
|
duration: performance.now() - startedAt
|
|
23876
24043
|
};
|
|
23877
24044
|
} finally {
|
|
@@ -24440,7 +24607,6 @@ async function broadcastNotification({ servers, send, logger, errorId, errorText
|
|
|
24440
24607
|
var ServerPromptActions = class {
|
|
24441
24608
|
getLogger;
|
|
24442
24609
|
getSdkServers;
|
|
24443
|
-
clearDefinedPrompts;
|
|
24444
24610
|
getModernEraNotifier;
|
|
24445
24611
|
/**
|
|
24446
24612
|
* @internal
|
|
@@ -24448,14 +24614,13 @@ var ServerPromptActions = class {
|
|
|
24448
24614
|
constructor(dependencies) {
|
|
24449
24615
|
this.getLogger = dependencies.getLogger;
|
|
24450
24616
|
this.getSdkServers = dependencies.getSdkServers;
|
|
24451
|
-
this.clearDefinedPrompts = dependencies.clearDefinedPrompts;
|
|
24452
24617
|
this.getModernEraNotifier = dependencies.getModernEraNotifier;
|
|
24453
24618
|
}
|
|
24454
24619
|
/**
|
|
24455
24620
|
* Notifies clients that the overall list of available prompts has changed.
|
|
24456
24621
|
*
|
|
24457
|
-
* This
|
|
24458
|
-
*
|
|
24622
|
+
* This sends a `notifications/prompts/list_changed` message to all clients,
|
|
24623
|
+
* prompting them to re-fetch the prompt list.
|
|
24459
24624
|
*
|
|
24460
24625
|
* @throws {MastraError} If sending the notification fails on all server instances
|
|
24461
24626
|
*
|
|
@@ -24466,8 +24631,7 @@ var ServerPromptActions = class {
|
|
|
24466
24631
|
* ```
|
|
24467
24632
|
*/
|
|
24468
24633
|
async notifyListChanged() {
|
|
24469
|
-
this.getLogger().info("Prompt list change externally notified.
|
|
24470
|
-
this.clearDefinedPrompts();
|
|
24634
|
+
this.getLogger().info("Prompt list change externally notified. Sending notification.");
|
|
24471
24635
|
this.getModernEraNotifier?.()?.promptsChanged();
|
|
24472
24636
|
await broadcastNotification({
|
|
24473
24637
|
servers: this.getSdkServers(),
|
|
@@ -24738,7 +24902,6 @@ var MCPServer = class extends MCPServerBase {
|
|
|
24738
24902
|
httpServerInstances = /* @__PURE__ */ new Map();
|
|
24739
24903
|
resourceOptions;
|
|
24740
24904
|
hasUiResources = false;
|
|
24741
|
-
definedPrompts;
|
|
24742
24905
|
promptOptions;
|
|
24743
24906
|
jsonSchemaValidator;
|
|
24744
24907
|
mapAuthInfoToUser;
|
|
@@ -24951,9 +25114,6 @@ var MCPServer = class extends MCPServerBase {
|
|
|
24951
25114
|
this.prompts = new ServerPromptActions({
|
|
24952
25115
|
getLogger: () => this.logger,
|
|
24953
25116
|
getSdkServers: () => this.getAllSdkServers(),
|
|
24954
|
-
clearDefinedPrompts: () => {
|
|
24955
|
-
this.definedPrompts = void 0;
|
|
24956
|
-
},
|
|
24957
25117
|
getModernEraNotifier
|
|
24958
25118
|
});
|
|
24959
25119
|
this.toolActions = new ServerToolActions({
|
|
@@ -25613,13 +25773,11 @@ var MCPServer = class extends MCPServerBase {
|
|
|
25613
25773
|
if (!capturedPromptOptions) return;
|
|
25614
25774
|
if (capturedPromptOptions.listPrompts) serverInstance.setRequestHandler("prompts/list", async (_request, ctx) => {
|
|
25615
25775
|
this.logger.debug("Handling ListPrompts request");
|
|
25616
|
-
|
|
25617
|
-
else try {
|
|
25776
|
+
try {
|
|
25618
25777
|
const prompts = await capturedPromptOptions.listPrompts({ extra: toMCPRequestHandlerExtra(ctx) });
|
|
25619
25778
|
for (const prompt of prompts) PromptSchema.parse(prompt);
|
|
25620
|
-
this.
|
|
25621
|
-
|
|
25622
|
-
return { prompts: this.definedPrompts };
|
|
25779
|
+
this.logger.debug("Fetched prompts", { count: prompts.length });
|
|
25780
|
+
return { prompts };
|
|
25623
25781
|
} catch (error) {
|
|
25624
25782
|
this.logger.error("Error fetching prompts via listPrompts():", { error: error instanceof Error ? error.message : String(error) });
|
|
25625
25783
|
throw error;
|
|
@@ -25628,12 +25786,11 @@ var MCPServer = class extends MCPServerBase {
|
|
|
25628
25786
|
if (capturedPromptOptions.getPromptMessages) serverInstance.setRequestHandler("prompts/get", async (request, ctx) => {
|
|
25629
25787
|
const startTime = Date.now();
|
|
25630
25788
|
const { name, arguments: args } = request.params;
|
|
25631
|
-
|
|
25632
|
-
|
|
25633
|
-
|
|
25634
|
-
|
|
25635
|
-
|
|
25636
|
-
const prompt = this.definedPrompts?.find((p) => p.name === name);
|
|
25789
|
+
const extra = toMCPRequestHandlerExtra(ctx);
|
|
25790
|
+
const prompts = await capturedPromptOptions.listPrompts?.({ extra });
|
|
25791
|
+
if (!prompts) throw new Error("Failed to load prompts");
|
|
25792
|
+
for (const definedPrompt of prompts) PromptSchema.parse(definedPrompt);
|
|
25793
|
+
const prompt = prompts.find((p) => p.name === name);
|
|
25637
25794
|
if (!prompt) throw new Error(`Prompt "${name}" not found`);
|
|
25638
25795
|
if (prompt.arguments) {
|
|
25639
25796
|
for (const arg of prompt.arguments) if (arg.required && (args?.[arg.name] === void 0 || args?.[arg.name] === null)) throw new ProtocolError(ProtocolErrorCode$1.InvalidParams, `Missing required argument: ${arg.name}`);
|
|
@@ -25644,7 +25801,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
25644
25801
|
name,
|
|
25645
25802
|
version: prompt.version,
|
|
25646
25803
|
args,
|
|
25647
|
-
extra
|
|
25804
|
+
extra
|
|
25648
25805
|
});
|
|
25649
25806
|
const duration = Date.now() - startTime;
|
|
25650
25807
|
this.logger.info("Prompt retrieved successfully", {
|
|
@@ -27127,6 +27284,6 @@ function createIntrospectionValidator(introspectionEndpoint, clientCredentials)
|
|
|
27127
27284
|
};
|
|
27128
27285
|
}
|
|
27129
27286
|
//#endregion
|
|
27130
|
-
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPClientServerProxy, MCPOAuthClientProvider, MCPServer, MCP_CALL_TOOL_CONTENT, UnauthorizedError, auth, buildDiscoveryUrls, createIntrospectionValidator, createOAuthCallbackServer, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, discoverAuthorizationServerMetadata, discoverOAuthMetadata, discoverOAuthProtectedResourceMetadata, exchangeAuthorization, extractBearerToken, extractResourceMetadataUrl, generateProtectedResourceMetadata, generateWWWAuthenticateHeader, getCallbackUrlCandidates, parseErrorResponse, refreshAuthorization, registerClient, selectResourceURL, startAuthorization };
|
|
27287
|
+
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPClientServerProxy, MCPOAuthClientProvider, MCPServer, MCP_CALL_TOOL_CONTENT, MCP_CALL_TOOL_META, UnauthorizedError, auth, buildDiscoveryUrls, createIntrospectionValidator, createOAuthCallbackServer, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, discoverAuthorizationServerMetadata, discoverOAuthMetadata, discoverOAuthProtectedResourceMetadata, exchangeAuthorization, extractBearerToken, extractResourceMetadataUrl, generateProtectedResourceMetadata, generateWWWAuthenticateHeader, getCallbackUrlCandidates, getMcpCallToolContent, getMcpCallToolMeta, parseErrorResponse, refreshAuthorization, registerClient, selectResourceURL, startAuthorization };
|
|
27131
27288
|
|
|
27132
27289
|
//# sourceMappingURL=index.js.map
|