@mastra/mcp 1.6.1-alpha.1 → 1.7.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/CHANGELOG.md +100 -0
- package/dist/client/client.d.ts +1 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +26 -0
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/server-proxy.d.ts +88 -0
- package/dist/client/server-proxy.d.ts.map +1 -0
- package/dist/docs/SKILL.md +2 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-mcp-mcp-apps.md +304 -0
- package/dist/docs/references/docs-mcp-overview.md +7 -0
- package/dist/docs/references/reference-tools-mcp-client.md +32 -0
- package/dist/docs/references/reference-tools-mcp-server.md +64 -0
- package/dist/index.cjs +348 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +348 -7
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +59 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/types.d.ts +37 -0
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +8 -7
package/dist/index.js
CHANGED
|
@@ -13,9 +13,11 @@ import { createHash, randomUUID } from 'crypto';
|
|
|
13
13
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
14
14
|
import equal from 'fast-deep-equal';
|
|
15
15
|
import { MCPServerBase } from '@mastra/core/mcp';
|
|
16
|
-
import { RequestContext } from '@mastra/core/request-context';
|
|
17
16
|
import { isStandardSchemaWithJSON, standardSchemaToJSONSchema } from '@mastra/core/schema';
|
|
17
|
+
import { readFileSync } from 'fs';
|
|
18
|
+
import { RequestContext } from '@mastra/core/request-context';
|
|
18
19
|
import { makeCoreTool } from '@mastra/core/utils';
|
|
20
|
+
import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from '@modelcontextprotocol/ext-apps';
|
|
19
21
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
20
22
|
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
21
23
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -535,7 +537,12 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
535
537
|
...capabilities.elicitation ?? {}
|
|
536
538
|
},
|
|
537
539
|
// Auto-enable roots capability if roots are provided
|
|
538
|
-
...hasRoots ? { roots: { listChanged: true, ...capabilities.roots ?? {} } } : {}
|
|
540
|
+
...hasRoots ? { roots: { listChanged: true, ...capabilities.roots ?? {} } } : {},
|
|
541
|
+
// Advertise MCP Apps extension support so servers know we can render UI resources
|
|
542
|
+
extensions: {
|
|
543
|
+
...capabilities.extensions ?? {},
|
|
544
|
+
"io.modelcontextprotocol/ui": {}
|
|
545
|
+
}
|
|
539
546
|
};
|
|
540
547
|
this.client = new Client(
|
|
541
548
|
{
|
|
@@ -968,11 +975,16 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
968
975
|
} else if (this.requireToolApproval === true) {
|
|
969
976
|
requireApproval = true;
|
|
970
977
|
}
|
|
978
|
+
const rawMeta = tool._meta;
|
|
979
|
+
const toolMeta = rawMeta ? this.stampServerIdInMeta(rawMeta) : void 0;
|
|
971
980
|
const mastraTool = createTool({
|
|
972
981
|
id: `${this.name}_${tool.name}`,
|
|
973
982
|
description: tool.description || "",
|
|
974
983
|
inputSchema: await this.convertInputSchema(tool.inputSchema),
|
|
975
|
-
strict: getMastraToolStrictMeta(
|
|
984
|
+
strict: getMastraToolStrictMeta(toolMeta),
|
|
985
|
+
// Preserve the full _meta from the remote MCP server (including ui.resourceUri
|
|
986
|
+
// for MCP Apps) so downstream consumers (e.g. Studio) can detect app tools.
|
|
987
|
+
...toolMeta ? { mcp: { _meta: toolMeta } } : {},
|
|
976
988
|
// Don't pass outputSchema to createTool — the MCP SDK's Client.callTool()
|
|
977
989
|
// already validates structuredContent against the tool's outputSchema using AJV.
|
|
978
990
|
// Passing it here causes Zod to strip unrecognized keys from the CallToolResult
|
|
@@ -1052,7 +1064,152 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
1052
1064
|
}
|
|
1053
1065
|
return toolsRes;
|
|
1054
1066
|
}
|
|
1067
|
+
stampServerIdInMeta(meta) {
|
|
1068
|
+
const ui = meta.ui;
|
|
1069
|
+
if (!ui?.resourceUri) return meta;
|
|
1070
|
+
return {
|
|
1071
|
+
...meta,
|
|
1072
|
+
ui: { ...ui, serverId: this.name }
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
var MCPClientServerProxy = class extends MCPServerBase {
|
|
1077
|
+
clientGetter;
|
|
1078
|
+
cachedClient = null;
|
|
1079
|
+
_cachedToolList = null;
|
|
1080
|
+
constructor(config, clientGetter) {
|
|
1081
|
+
const serverConfig = {
|
|
1082
|
+
name: config.name,
|
|
1083
|
+
version: config.version ?? "1.0.0",
|
|
1084
|
+
id: config.id,
|
|
1085
|
+
description: config.description,
|
|
1086
|
+
tools: {}
|
|
1087
|
+
};
|
|
1088
|
+
super(serverConfig);
|
|
1089
|
+
this.clientGetter = clientGetter;
|
|
1090
|
+
}
|
|
1091
|
+
async getClient() {
|
|
1092
|
+
if (!this.cachedClient) {
|
|
1093
|
+
this.cachedClient = await this.clientGetter();
|
|
1094
|
+
}
|
|
1095
|
+
return this.cachedClient;
|
|
1096
|
+
}
|
|
1097
|
+
convertSchema(schema) {
|
|
1098
|
+
if (isStandardSchemaWithJSON(schema)) {
|
|
1099
|
+
return standardSchemaToJSONSchema(schema);
|
|
1100
|
+
}
|
|
1101
|
+
return schema?.jsonSchema || schema;
|
|
1102
|
+
}
|
|
1103
|
+
async fetchToolList() {
|
|
1104
|
+
if (this._cachedToolList) return this._cachedToolList;
|
|
1105
|
+
const client = await this.getClient();
|
|
1106
|
+
const tools = await client.tools();
|
|
1107
|
+
this._cachedToolList = {
|
|
1108
|
+
tools: Object.entries(tools).map(([toolName, tool]) => ({
|
|
1109
|
+
id: toolName,
|
|
1110
|
+
name: tool.id || toolName,
|
|
1111
|
+
description: tool.description,
|
|
1112
|
+
inputSchema: this.convertSchema(tool.inputSchema),
|
|
1113
|
+
outputSchema: this.convertSchema(tool.outputSchema),
|
|
1114
|
+
toolType: tool.mcp?.toolType,
|
|
1115
|
+
_meta: tool.mcp?._meta
|
|
1116
|
+
}))
|
|
1117
|
+
};
|
|
1118
|
+
this.convertedTools = tools;
|
|
1119
|
+
return this._cachedToolList;
|
|
1120
|
+
}
|
|
1121
|
+
// ---------- MCPServerBase abstract implementations ----------
|
|
1122
|
+
convertTools(_tools, _agents, _workflows) {
|
|
1123
|
+
return {};
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Returns the cached tool list synchronously, or triggers an async fetch.
|
|
1127
|
+
* The Studio API handlers are async and will auto-await a returned Promise.
|
|
1128
|
+
*/
|
|
1129
|
+
getToolListInfo() {
|
|
1130
|
+
if (this._cachedToolList) return this._cachedToolList;
|
|
1131
|
+
return this.fetchToolList();
|
|
1132
|
+
}
|
|
1133
|
+
getToolInfo(toolId) {
|
|
1134
|
+
if (this._cachedToolList) {
|
|
1135
|
+
return this._cachedToolList.tools.find((t) => t.id === toolId || t.name === toolId);
|
|
1136
|
+
}
|
|
1137
|
+
return this.fetchToolList().then((list) => list.tools.find((t) => t.id === toolId || t.name === toolId));
|
|
1138
|
+
}
|
|
1139
|
+
async executeTool(toolId, args, _executionContext) {
|
|
1140
|
+
const client = await this.getClient();
|
|
1141
|
+
const tools = await client.tools();
|
|
1142
|
+
const tool = tools[toolId];
|
|
1143
|
+
if (!tool) {
|
|
1144
|
+
throw new Error(`Tool '${toolId}' not found on remote MCP server '${this.name}'`);
|
|
1145
|
+
}
|
|
1146
|
+
if (!tool.execute) {
|
|
1147
|
+
throw new Error(`Tool '${toolId}' on remote MCP server '${this.name}' has no execute method`);
|
|
1148
|
+
}
|
|
1149
|
+
return tool.execute(args, _executionContext);
|
|
1150
|
+
}
|
|
1151
|
+
async listResources() {
|
|
1152
|
+
const client = await this.getClient();
|
|
1153
|
+
const resources = await client.resources.list();
|
|
1154
|
+
return {
|
|
1155
|
+
resources: resources.map((r) => ({
|
|
1156
|
+
uri: r.uri,
|
|
1157
|
+
name: r.name ?? r.uri,
|
|
1158
|
+
description: r.description,
|
|
1159
|
+
mimeType: r.mimeType,
|
|
1160
|
+
_meta: r._meta
|
|
1161
|
+
}))
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
async readResource(uri) {
|
|
1165
|
+
const client = await this.getClient();
|
|
1166
|
+
const result = await client.resources.read(uri);
|
|
1167
|
+
return {
|
|
1168
|
+
contents: (result.contents ?? []).map((c) => ({
|
|
1169
|
+
uri: c.uri ?? uri,
|
|
1170
|
+
...c.text !== void 0 ? { text: c.text } : {},
|
|
1171
|
+
...c.blob !== void 0 ? { blob: c.blob } : {}
|
|
1172
|
+
}))
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
// Transport methods — not applicable for client proxies
|
|
1176
|
+
async startStdio() {
|
|
1177
|
+
throw new Error("MCPClientServerProxy does not support stdio transport");
|
|
1178
|
+
}
|
|
1179
|
+
async startSSE(_options) {
|
|
1180
|
+
throw new Error("MCPClientServerProxy does not support SSE transport");
|
|
1181
|
+
}
|
|
1182
|
+
async startHonoSSE(_options) {
|
|
1183
|
+
throw new Error("MCPClientServerProxy does not support Hono SSE transport");
|
|
1184
|
+
}
|
|
1185
|
+
async startHTTP(_options) {
|
|
1186
|
+
throw new Error("MCPClientServerProxy does not support HTTP transport");
|
|
1187
|
+
}
|
|
1188
|
+
async close() {
|
|
1189
|
+
this.cachedClient = null;
|
|
1190
|
+
}
|
|
1191
|
+
getServerInfo() {
|
|
1192
|
+
return {
|
|
1193
|
+
id: this.id,
|
|
1194
|
+
name: this.name,
|
|
1195
|
+
description: this.description,
|
|
1196
|
+
version_detail: {
|
|
1197
|
+
version: this.version,
|
|
1198
|
+
release_date: this.releaseDate,
|
|
1199
|
+
is_latest: this.isLatest
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
getServerDetail() {
|
|
1204
|
+
return {
|
|
1205
|
+
...this.getServerInfo(),
|
|
1206
|
+
packages: this.packages ?? [],
|
|
1207
|
+
remotes: this.remotes ?? []
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1055
1210
|
};
|
|
1211
|
+
|
|
1212
|
+
// src/client/configuration.ts
|
|
1056
1213
|
var mcpClientInstances = /* @__PURE__ */ new Map();
|
|
1057
1214
|
var TOOL_DISCOVERY_MAX_ATTEMPTS = 2;
|
|
1058
1215
|
var MCPClient = class extends MastraBase {
|
|
@@ -1820,6 +1977,39 @@ To fix this you have three different options:
|
|
|
1820
1977
|
}
|
|
1821
1978
|
return { toolsets: connectedToolsets, errors };
|
|
1822
1979
|
}
|
|
1980
|
+
/**
|
|
1981
|
+
* Creates MCPServerBase-compatible proxy objects for each server connection
|
|
1982
|
+
* in this MCPClient. The returned record can be spread directly into
|
|
1983
|
+
* Mastra's `mcpServers` config so that external (non-Mastra) servers
|
|
1984
|
+
* appear in Studio alongside native MCPServer instances.
|
|
1985
|
+
*
|
|
1986
|
+
* @returns Record mapping server names to MCPServerBase proxy instances
|
|
1987
|
+
*
|
|
1988
|
+
* @example
|
|
1989
|
+
* ```typescript
|
|
1990
|
+
* const mcp = new MCPClient({
|
|
1991
|
+
* servers: {
|
|
1992
|
+
* trailhead: { command: 'npx', args: ['trailhead-server'] },
|
|
1993
|
+
* },
|
|
1994
|
+
* });
|
|
1995
|
+
*
|
|
1996
|
+
* const mastra = new Mastra({
|
|
1997
|
+
* mcpServers: {
|
|
1998
|
+
* ...mcp.toMCPServerProxies(),
|
|
1999
|
+
* },
|
|
2000
|
+
* });
|
|
2001
|
+
* ```
|
|
2002
|
+
*/
|
|
2003
|
+
toMCPServerProxies() {
|
|
2004
|
+
const proxies = {};
|
|
2005
|
+
for (const serverName of Object.keys(this.serverConfigs)) {
|
|
2006
|
+
proxies[serverName] = new MCPClientServerProxy(
|
|
2007
|
+
{ name: serverName, id: serverName },
|
|
2008
|
+
() => this.getConnectedClientForServer(serverName)
|
|
2009
|
+
);
|
|
2010
|
+
}
|
|
2011
|
+
return proxies;
|
|
2012
|
+
}
|
|
1823
2013
|
/**
|
|
1824
2014
|
* Gets current session IDs for all connected MCP clients using Streamable HTTP transport.
|
|
1825
2015
|
*
|
|
@@ -2677,19 +2867,28 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2677
2867
|
*/
|
|
2678
2868
|
constructor(opts) {
|
|
2679
2869
|
super(opts);
|
|
2680
|
-
this.resourceOptions = opts.resources;
|
|
2870
|
+
this.resourceOptions = this.mergeAppResources(opts.resources, opts.appResources);
|
|
2681
2871
|
this.promptOptions = opts.prompts;
|
|
2682
2872
|
this.jsonSchemaValidator = opts.jsonSchemaValidator;
|
|
2683
2873
|
const capabilities = {
|
|
2684
2874
|
tools: {},
|
|
2685
2875
|
logging: { enabled: true }
|
|
2686
2876
|
};
|
|
2687
|
-
if (
|
|
2877
|
+
if (this.resourceOptions) {
|
|
2688
2878
|
capabilities.resources = { subscribe: true, listChanged: true };
|
|
2689
2879
|
}
|
|
2690
2880
|
if (opts.prompts) {
|
|
2691
2881
|
capabilities.prompts = { listChanged: true };
|
|
2692
2882
|
}
|
|
2883
|
+
const hasUiTools = Object.values(this.convertedTools).some(
|
|
2884
|
+
(tool) => tool.mcp?._meta?.ui?.resourceUri
|
|
2885
|
+
);
|
|
2886
|
+
if (hasUiTools || opts.appResources) {
|
|
2887
|
+
capabilities.extensions = {
|
|
2888
|
+
...capabilities.extensions,
|
|
2889
|
+
"io.modelcontextprotocol/ui": {}
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2693
2892
|
this.server = new Server(
|
|
2694
2893
|
{
|
|
2695
2894
|
name: this.name,
|
|
@@ -2785,6 +2984,81 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2785
2984
|
req.on("error", reject);
|
|
2786
2985
|
});
|
|
2787
2986
|
}
|
|
2987
|
+
/**
|
|
2988
|
+
* Merges appResources into the resource system alongside any user-provided resources.
|
|
2989
|
+
*
|
|
2990
|
+
* App resources are auto-registered as `ui://` resources with the MCP Apps MIME type.
|
|
2991
|
+
* If the user also provides a `resources` config, the two are merged — user callbacks
|
|
2992
|
+
* take precedence for overlapping URIs.
|
|
2993
|
+
*/
|
|
2994
|
+
mergeAppResources(userResources, appResources) {
|
|
2995
|
+
if (!appResources || Object.keys(appResources).length === 0) {
|
|
2996
|
+
return userResources;
|
|
2997
|
+
}
|
|
2998
|
+
const resolvedAppResources = /* @__PURE__ */ new Map();
|
|
2999
|
+
for (const [uri, appResource] of Object.entries(appResources)) {
|
|
3000
|
+
let html;
|
|
3001
|
+
if (appResource.html) {
|
|
3002
|
+
html = appResource.html;
|
|
3003
|
+
} else if (appResource.htmlPath) {
|
|
3004
|
+
html = readFileSync(appResource.htmlPath, "utf-8");
|
|
3005
|
+
} else {
|
|
3006
|
+
this.logger.warn(`App resource '${uri}' has neither html nor htmlPath \u2014 skipping`);
|
|
3007
|
+
continue;
|
|
3008
|
+
}
|
|
3009
|
+
const resource = {
|
|
3010
|
+
uri,
|
|
3011
|
+
name: appResource.name,
|
|
3012
|
+
...appResource.description ? { description: appResource.description } : {},
|
|
3013
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
3014
|
+
...appResource.meta ? { _meta: { ui: appResource.meta } } : {}
|
|
3015
|
+
};
|
|
3016
|
+
resolvedAppResources.set(uri, { resource, html });
|
|
3017
|
+
}
|
|
3018
|
+
if (resolvedAppResources.size === 0) {
|
|
3019
|
+
return userResources;
|
|
3020
|
+
}
|
|
3021
|
+
const appListResources = async () => {
|
|
3022
|
+
return Array.from(resolvedAppResources.values()).map((r) => r.resource);
|
|
3023
|
+
};
|
|
3024
|
+
const appGetResourceContent = async ({ uri }) => {
|
|
3025
|
+
const appRes = resolvedAppResources.get(uri);
|
|
3026
|
+
if (appRes) {
|
|
3027
|
+
return { text: appRes.html };
|
|
3028
|
+
}
|
|
3029
|
+
throw new Error(`App resource not found: ${uri}`);
|
|
3030
|
+
};
|
|
3031
|
+
if (!userResources) {
|
|
3032
|
+
return {
|
|
3033
|
+
listResources: appListResources,
|
|
3034
|
+
getResourceContent: appGetResourceContent
|
|
3035
|
+
};
|
|
3036
|
+
}
|
|
3037
|
+
return {
|
|
3038
|
+
listResources: async ({ extra }) => {
|
|
3039
|
+
const userResourceList = await userResources.listResources({ extra });
|
|
3040
|
+
const appResourceList = await appListResources();
|
|
3041
|
+
const userUris = new Set(userResourceList.map((r) => r.uri));
|
|
3042
|
+
const nonConflicting = appResourceList.filter((r) => !userUris.has(r.uri));
|
|
3043
|
+
return [...userResourceList, ...nonConflicting];
|
|
3044
|
+
},
|
|
3045
|
+
getResourceContent: async ({ uri, extra }) => {
|
|
3046
|
+
const appRes = resolvedAppResources.get(uri);
|
|
3047
|
+
if (appRes) {
|
|
3048
|
+
try {
|
|
3049
|
+
const userResourceList = await userResources.listResources({ extra });
|
|
3050
|
+
if (userResourceList.some((r) => r.uri === uri)) {
|
|
3051
|
+
return userResources.getResourceContent({ uri, extra });
|
|
3052
|
+
}
|
|
3053
|
+
} catch {
|
|
3054
|
+
}
|
|
3055
|
+
return { text: appRes.html };
|
|
3056
|
+
}
|
|
3057
|
+
return userResources.getResourceContent({ uri, extra });
|
|
3058
|
+
},
|
|
3059
|
+
...userResources.resourceTemplates ? { resourceTemplates: userResources.resourceTemplates } : {}
|
|
3060
|
+
};
|
|
3061
|
+
}
|
|
2788
3062
|
/**
|
|
2789
3063
|
* Creates a new Server instance configured with all handlers for HTTP sessions.
|
|
2790
3064
|
* Each HTTP client connection gets its own Server instance to avoid routing conflicts.
|
|
@@ -2800,6 +3074,18 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2800
3074
|
if (this.promptOptions) {
|
|
2801
3075
|
capabilities.prompts = { listChanged: true };
|
|
2802
3076
|
}
|
|
3077
|
+
const hasUiTools = Object.values(this.convertedTools).some(
|
|
3078
|
+
(tool) => tool.mcp?._meta?.ui?.resourceUri
|
|
3079
|
+
);
|
|
3080
|
+
if (hasUiTools || this.resourceOptions) {
|
|
3081
|
+
const hasUiResources = this.definedResources?.some((r) => r.uri.startsWith("ui://"));
|
|
3082
|
+
if (hasUiTools || hasUiResources) {
|
|
3083
|
+
capabilities.extensions = {
|
|
3084
|
+
...capabilities.extensions,
|
|
3085
|
+
"io.modelcontextprotocol/ui": {}
|
|
3086
|
+
};
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
2803
3089
|
const serverInstance = new Server(
|
|
2804
3090
|
{
|
|
2805
3091
|
name: this.name,
|
|
@@ -2837,7 +3123,15 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2837
3123
|
}
|
|
2838
3124
|
const toolMeta = withMastraToolStrictMeta(tool.mcp?._meta, tool.strict);
|
|
2839
3125
|
if (toolMeta) {
|
|
2840
|
-
|
|
3126
|
+
const uiMeta = toolMeta.ui;
|
|
3127
|
+
const legacyUri = toolMeta[RESOURCE_URI_META_KEY];
|
|
3128
|
+
if (uiMeta?.resourceUri && !legacyUri) {
|
|
3129
|
+
toolSpec._meta = { ...toolMeta, [RESOURCE_URI_META_KEY]: uiMeta.resourceUri };
|
|
3130
|
+
} else if (legacyUri && !uiMeta?.resourceUri) {
|
|
3131
|
+
toolSpec._meta = { ...toolMeta, ui: { ...toolMeta.ui ?? {}, resourceUri: legacyUri } };
|
|
3132
|
+
} else {
|
|
3133
|
+
toolSpec._meta = toolMeta;
|
|
3134
|
+
}
|
|
2841
3135
|
}
|
|
2842
3136
|
return toolSpec;
|
|
2843
3137
|
})
|
|
@@ -4330,6 +4624,53 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
4330
4624
|
throw mastraError;
|
|
4331
4625
|
}
|
|
4332
4626
|
}
|
|
4627
|
+
/**
|
|
4628
|
+
* Reads the content of a resource by URI.
|
|
4629
|
+
*
|
|
4630
|
+
* Used by the Studio API to proxy `ui://` resource reads for MCP Apps rendering.
|
|
4631
|
+
*
|
|
4632
|
+
* @param uri - The resource URI to read (e.g. `ui://weather/dashboard`)
|
|
4633
|
+
* @returns Promise resolving to the resource content
|
|
4634
|
+
*/
|
|
4635
|
+
async readResource(uri) {
|
|
4636
|
+
if (!this.resourceOptions?.getResourceContent) {
|
|
4637
|
+
throw new MastraError({
|
|
4638
|
+
id: "MCP_SERVER_RESOURCES_NOT_CONFIGURED",
|
|
4639
|
+
domain: ErrorDomain.MCP,
|
|
4640
|
+
category: ErrorCategory.USER,
|
|
4641
|
+
details: { uri }
|
|
4642
|
+
});
|
|
4643
|
+
}
|
|
4644
|
+
const extra = {};
|
|
4645
|
+
const result = await this.resourceOptions.getResourceContent({ uri, extra });
|
|
4646
|
+
const contents = Array.isArray(result) ? result : [result];
|
|
4647
|
+
return {
|
|
4648
|
+
contents: contents.map((c) => ({
|
|
4649
|
+
uri,
|
|
4650
|
+
..."text" in c && c.text !== void 0 ? { text: c.text } : {},
|
|
4651
|
+
..."blob" in c && c.blob !== void 0 ? { blob: c.blob } : {}
|
|
4652
|
+
}))
|
|
4653
|
+
};
|
|
4654
|
+
}
|
|
4655
|
+
/**
|
|
4656
|
+
* Lists all resources available on this MCP server.
|
|
4657
|
+
*
|
|
4658
|
+
* Used by the Studio API to discover `ui://` resources for MCP Apps.
|
|
4659
|
+
*
|
|
4660
|
+
* @returns Promise resolving to the list of resources
|
|
4661
|
+
*/
|
|
4662
|
+
async listResources() {
|
|
4663
|
+
if (!this.resourceOptions?.listResources) {
|
|
4664
|
+
return { resources: [] };
|
|
4665
|
+
}
|
|
4666
|
+
const extra = {};
|
|
4667
|
+
if (this.definedResources) {
|
|
4668
|
+
return { resources: this.definedResources };
|
|
4669
|
+
}
|
|
4670
|
+
const resources = await this.resourceOptions.listResources({ extra });
|
|
4671
|
+
this.definedResources = resources;
|
|
4672
|
+
return { resources };
|
|
4673
|
+
}
|
|
4333
4674
|
};
|
|
4334
4675
|
function escapeHeaderValue(value) {
|
|
4335
4676
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
@@ -4535,6 +4876,6 @@ function createIntrospectionValidator(introspectionEndpoint, clientCredentials)
|
|
|
4535
4876
|
};
|
|
4536
4877
|
}
|
|
4537
4878
|
|
|
4538
|
-
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPOAuthClientProvider, MCPServer, createIntrospectionValidator, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, extractBearerToken, generateProtectedResourceMetadata, generateWWWAuthenticateHeader };
|
|
4879
|
+
export { InMemoryOAuthStorage, InternalMastraMCPClient, MCPClient, MCPClientServerProxy, MCPOAuthClientProvider, MCPServer, createIntrospectionValidator, createOAuthMiddleware, createSimpleTokenProvider, createStaticTokenValidator, extractBearerToken, generateProtectedResourceMetadata, generateWWWAuthenticateHeader };
|
|
4539
4880
|
//# sourceMappingURL=index.js.map
|
|
4540
4881
|
//# sourceMappingURL=index.js.map
|