@mastra/mcp 1.8.1 → 1.9.0-alpha.1
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 +77 -0
- package/dist/client/client.d.ts +5 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/configuration.d.ts +7 -0
- package/dist/client/configuration.d.ts.map +1 -1
- package/dist/client/types.d.ts +17 -0
- package/dist/client/types.d.ts.map +1 -1
- 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 +3 -3
- package/dist/docs/references/docs-mcp-overview.md +1 -1
- package/dist/docs/references/docs-server-auth-fga.md +258 -0
- package/dist/docs/references/reference-tools-mcp-client.md +53 -2
- package/dist/docs/references/reference-tools-mcp-server.md +33 -1
- package/dist/index.cjs +95 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -20
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +3 -0
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -418,6 +418,7 @@ function isReconnectableMCPError(error) {
|
|
|
418
418
|
|
|
419
419
|
// src/client/client.ts
|
|
420
420
|
var DEFAULT_SERVER_CONNECT_TIMEOUT_MSEC = 3e3;
|
|
421
|
+
var DEFAULT_INSTRUCTIONS_MAX_LENGTH = 512;
|
|
421
422
|
var require2 = createRequire(import.meta.url);
|
|
422
423
|
var SSE_FALLBACK_STATUS_CODES = [400, 404, 405];
|
|
423
424
|
var DATADOG_TRACER_TEST_SYMBOL = /* @__PURE__ */ Symbol.for("mastra.mcp.dd-trace-test-tracer");
|
|
@@ -500,6 +501,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
500
501
|
exitHookUnsubscribe;
|
|
501
502
|
sigTermHandler;
|
|
502
503
|
sigHupHandler;
|
|
504
|
+
serverInstructions;
|
|
503
505
|
_roots;
|
|
504
506
|
requireToolApproval;
|
|
505
507
|
/** Provides access to resource operations (list, read, subscribe, etc.) */
|
|
@@ -746,11 +748,19 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
746
748
|
} else {
|
|
747
749
|
throw new Error("Server configuration must include either a command or a url.");
|
|
748
750
|
}
|
|
751
|
+
this.refreshServerInstructions();
|
|
749
752
|
resolve(true);
|
|
750
753
|
const originalOnClose = this.client.onclose;
|
|
751
754
|
this.client.onclose = () => {
|
|
752
755
|
this.log("debug", `MCP server connection closed`);
|
|
756
|
+
const staleTransport = this.transport;
|
|
757
|
+
this.transport = void 0;
|
|
753
758
|
this.isConnected = null;
|
|
759
|
+
this.serverInstructions = void 0;
|
|
760
|
+
if (staleTransport) {
|
|
761
|
+
void staleTransport.close().catch(() => {
|
|
762
|
+
});
|
|
763
|
+
}
|
|
754
764
|
if (typeof originalOnClose === "function") {
|
|
755
765
|
originalOnClose();
|
|
756
766
|
}
|
|
@@ -808,6 +818,18 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
808
818
|
}
|
|
809
819
|
return null;
|
|
810
820
|
}
|
|
821
|
+
get instructions() {
|
|
822
|
+
return this.serverInstructions;
|
|
823
|
+
}
|
|
824
|
+
get forwardInstructions() {
|
|
825
|
+
return this.serverConfig.forwardInstructions ?? false;
|
|
826
|
+
}
|
|
827
|
+
get instructionsMaxLength() {
|
|
828
|
+
return this.serverConfig.instructionsMaxLength ?? DEFAULT_INSTRUCTIONS_MAX_LENGTH;
|
|
829
|
+
}
|
|
830
|
+
refreshServerInstructions() {
|
|
831
|
+
this.serverInstructions = this.client.getInstructions();
|
|
832
|
+
}
|
|
811
833
|
async disconnect() {
|
|
812
834
|
if (!this.transport) {
|
|
813
835
|
this.log("debug", "Disconnect called but no transport was connected.");
|
|
@@ -825,6 +847,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
825
847
|
} finally {
|
|
826
848
|
this.transport = void 0;
|
|
827
849
|
this.isConnected = null;
|
|
850
|
+
this.serverInstructions = void 0;
|
|
828
851
|
if (this.exitHookUnsubscribe) {
|
|
829
852
|
this.exitHookUnsubscribe();
|
|
830
853
|
this.exitHookUnsubscribe = void 0;
|
|
@@ -863,6 +886,7 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
863
886
|
}
|
|
864
887
|
this.transport = void 0;
|
|
865
888
|
this.isConnected = null;
|
|
889
|
+
this.serverInstructions = void 0;
|
|
866
890
|
await this.connect();
|
|
867
891
|
this.log("debug", "Successfully reconnected to MCP server");
|
|
868
892
|
}
|
|
@@ -1001,7 +1025,10 @@ var InternalMastraMCPClient = class extends MastraBase {
|
|
|
1001
1025
|
requireApproval,
|
|
1002
1026
|
mcpMetadata: {
|
|
1003
1027
|
serverName: this.name,
|
|
1004
|
-
serverVersion: this.client.getServerVersion()?.version
|
|
1028
|
+
serverVersion: this.client.getServerVersion()?.version,
|
|
1029
|
+
serverInstructions: this.serverInstructions,
|
|
1030
|
+
forwardInstructions: this.forwardInstructions,
|
|
1031
|
+
instructionsMaxLength: this.instructionsMaxLength
|
|
1005
1032
|
},
|
|
1006
1033
|
execute: async (input, context) => {
|
|
1007
1034
|
const operationContext = context?.requestContext ?? null;
|
|
@@ -1865,6 +1892,19 @@ To fix this you have three different options:
|
|
|
1865
1892
|
await this.getConnectedClientForServer(serverName);
|
|
1866
1893
|
}
|
|
1867
1894
|
}
|
|
1895
|
+
/**
|
|
1896
|
+
* Returns instructions advertised by connected MCP servers during initialize.
|
|
1897
|
+
*
|
|
1898
|
+
* Servers that have not connected yet, or did not advertise instructions,
|
|
1899
|
+
* return `undefined`.
|
|
1900
|
+
*/
|
|
1901
|
+
getServerInstructions() {
|
|
1902
|
+
const instructions = {};
|
|
1903
|
+
for (const serverName of Object.keys(this.serverConfigs)) {
|
|
1904
|
+
instructions[serverName] = this.mcpClientsById.get(serverName)?.instructions;
|
|
1905
|
+
}
|
|
1906
|
+
return instructions;
|
|
1907
|
+
}
|
|
1868
1908
|
/**
|
|
1869
1909
|
* Retrieves all tools from all configured servers with namespaced names.
|
|
1870
1910
|
*
|
|
@@ -2310,7 +2350,7 @@ function createSimpleTokenProvider(accessToken, options) {
|
|
|
2310
2350
|
});
|
|
2311
2351
|
}
|
|
2312
2352
|
|
|
2313
|
-
//
|
|
2353
|
+
// ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono/4.12.18/a4592d669eb2c33e4f24995614864047f2c1a155accc9d64dd2de0f4e8d608a9/node_modules/hono/dist/utils/stream.js
|
|
2314
2354
|
var StreamingApi = class {
|
|
2315
2355
|
writer;
|
|
2316
2356
|
encoder;
|
|
@@ -2387,7 +2427,7 @@ var StreamingApi = class {
|
|
|
2387
2427
|
}
|
|
2388
2428
|
};
|
|
2389
2429
|
|
|
2390
|
-
//
|
|
2430
|
+
// ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono/4.12.18/a4592d669eb2c33e4f24995614864047f2c1a155accc9d64dd2de0f4e8d608a9/node_modules/hono/dist/helper/streaming/utils.js
|
|
2391
2431
|
var isOldBunVersion = () => {
|
|
2392
2432
|
const version = typeof Bun !== "undefined" ? Bun.version : void 0;
|
|
2393
2433
|
if (version === void 0) {
|
|
@@ -2398,7 +2438,7 @@ var isOldBunVersion = () => {
|
|
|
2398
2438
|
return result;
|
|
2399
2439
|
};
|
|
2400
2440
|
|
|
2401
|
-
//
|
|
2441
|
+
// ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono/4.12.18/a4592d669eb2c33e4f24995614864047f2c1a155accc9d64dd2de0f4e8d608a9/node_modules/hono/dist/utils/html.js
|
|
2402
2442
|
var HtmlEscapedCallbackPhase = {
|
|
2403
2443
|
Stringify: 1};
|
|
2404
2444
|
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
|
@@ -2429,7 +2469,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
2429
2469
|
}
|
|
2430
2470
|
};
|
|
2431
2471
|
|
|
2432
|
-
//
|
|
2472
|
+
// ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/hono/4.12.18/a4592d669eb2c33e4f24995614864047f2c1a155accc9d64dd2de0f4e8d608a9/node_modules/hono/dist/helper/streaming/sse.js
|
|
2433
2473
|
var SSEStreamingApi = class extends StreamingApi {
|
|
2434
2474
|
constructor(writable, readable) {
|
|
2435
2475
|
super(writable, readable);
|
|
@@ -2736,6 +2776,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2736
2776
|
definedPrompts;
|
|
2737
2777
|
promptOptions;
|
|
2738
2778
|
jsonSchemaValidator;
|
|
2779
|
+
mapAuthInfoToUser;
|
|
2739
2780
|
subscriptions = /* @__PURE__ */ new Set();
|
|
2740
2781
|
currentLoggingLevel;
|
|
2741
2782
|
/**
|
|
@@ -2837,6 +2878,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2837
2878
|
* @param opts.prompts - Optional prompt configuration for exposing reusable templates
|
|
2838
2879
|
* @param opts.id - Optional unique identifier (generated if not provided)
|
|
2839
2880
|
* @param opts.description - Optional description of what the server does
|
|
2881
|
+
* @param opts.mapAuthInfoToUser - Optional mapper from MCP `extra.authInfo` to the FGA user context
|
|
2840
2882
|
*
|
|
2841
2883
|
* @example
|
|
2842
2884
|
* ```typescript
|
|
@@ -2873,6 +2915,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
2873
2915
|
this.resourceOptions = this.mergeAppResources(opts.resources, opts.appResources);
|
|
2874
2916
|
this.promptOptions = opts.prompts;
|
|
2875
2917
|
this.jsonSchemaValidator = opts.jsonSchemaValidator;
|
|
2918
|
+
this.mapAuthInfoToUser = opts.mapAuthInfoToUser;
|
|
2876
2919
|
const capabilities = {
|
|
2877
2920
|
tools: {},
|
|
2878
2921
|
logging: { enabled: true }
|
|
@@ -3109,7 +3152,7 @@ var MCPServer = class extends MCPServerBase {
|
|
|
3109
3152
|
*/
|
|
3110
3153
|
registerHandlersOnServer(serverInstance) {
|
|
3111
3154
|
serverInstance.setRequestHandler(ListToolsRequestSchema, async (_request, extra) => {
|
|
3112
|
-
const proxiedContext = this.createProxiedRequestContext(extra);
|
|
3155
|
+
const proxiedContext = await this.createProxiedRequestContext(extra);
|
|
3113
3156
|
const tools = await this.getAuthorizedConvertedToolEntries(proxiedContext);
|
|
3114
3157
|
return {
|
|
3115
3158
|
tools: tools.map(([, tool]) => {
|
|
@@ -3189,12 +3232,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
3189
3232
|
return this.handleElicitationRequest(request2, serverInstance, options);
|
|
3190
3233
|
}
|
|
3191
3234
|
};
|
|
3192
|
-
const proxiedContext =
|
|
3193
|
-
if (extra) {
|
|
3194
|
-
Object.entries(extra).forEach(([key, value]) => {
|
|
3195
|
-
proxiedContext.set(key, value);
|
|
3196
|
-
});
|
|
3197
|
-
}
|
|
3235
|
+
const proxiedContext = await this.createProxiedRequestContext(extra);
|
|
3198
3236
|
const mcpOptions = {
|
|
3199
3237
|
messages: [],
|
|
3200
3238
|
toolCallId: "",
|
|
@@ -4473,22 +4511,50 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4473
4511
|
_meta: withMastraToolStrictMeta(tool.mcp?._meta, tool.strict)
|
|
4474
4512
|
};
|
|
4475
4513
|
}
|
|
4476
|
-
createProxiedRequestContext(extra) {
|
|
4514
|
+
async createProxiedRequestContext(extra) {
|
|
4477
4515
|
const proxiedContext = new RequestContext();
|
|
4516
|
+
let extraRecord;
|
|
4478
4517
|
if (extra && typeof extra === "object") {
|
|
4479
|
-
|
|
4518
|
+
extraRecord = extra;
|
|
4519
|
+
Object.entries(extraRecord).forEach(([key, value]) => {
|
|
4480
4520
|
proxiedContext.set(key, value);
|
|
4481
4521
|
});
|
|
4482
4522
|
}
|
|
4523
|
+
await this.resolveMappedFGAUser(proxiedContext, extraRecord);
|
|
4483
4524
|
return proxiedContext;
|
|
4484
4525
|
}
|
|
4526
|
+
async resolveMappedFGAUser(requestContext, extra) {
|
|
4527
|
+
if (!requestContext) {
|
|
4528
|
+
return void 0;
|
|
4529
|
+
}
|
|
4530
|
+
const existingUser = requestContext.get("user");
|
|
4531
|
+
if (existingUser) {
|
|
4532
|
+
return existingUser;
|
|
4533
|
+
}
|
|
4534
|
+
if (!this.mapAuthInfoToUser) {
|
|
4535
|
+
return void 0;
|
|
4536
|
+
}
|
|
4537
|
+
const authInfo = extra && "authInfo" in extra ? extra.authInfo : requestContext.get("authInfo");
|
|
4538
|
+
if (!authInfo) {
|
|
4539
|
+
return void 0;
|
|
4540
|
+
}
|
|
4541
|
+
const user = await this.mapAuthInfoToUser({
|
|
4542
|
+
authInfo,
|
|
4543
|
+
extra: extra ?? { authInfo },
|
|
4544
|
+
requestContext
|
|
4545
|
+
});
|
|
4546
|
+
if (user) {
|
|
4547
|
+
requestContext.set("user", user);
|
|
4548
|
+
}
|
|
4549
|
+
return user;
|
|
4550
|
+
}
|
|
4485
4551
|
async getAuthorizedConvertedToolEntries(requestContext) {
|
|
4486
4552
|
const entries = Object.entries(this.convertedTools);
|
|
4487
4553
|
const fgaProvider = this.mastra?.getServer?.()?.fga;
|
|
4488
4554
|
if (!fgaProvider) {
|
|
4489
4555
|
return entries;
|
|
4490
4556
|
}
|
|
4491
|
-
const user =
|
|
4557
|
+
const user = await this.resolveMappedFGAUser(requestContext);
|
|
4492
4558
|
if (!user) {
|
|
4493
4559
|
return [];
|
|
4494
4560
|
}
|
|
@@ -4512,17 +4578,26 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4512
4578
|
if (!fgaProvider) {
|
|
4513
4579
|
return;
|
|
4514
4580
|
}
|
|
4515
|
-
const {
|
|
4516
|
-
const resourceId =
|
|
4517
|
-
const user = requestContext
|
|
4581
|
+
const { getMCPToolFGAResourceId, requireFGA, FGADeniedError, MastraFGAPermissions } = await import('@mastra/core/auth/ee');
|
|
4582
|
+
const resourceId = getMCPToolFGAResourceId(this.id, toolId);
|
|
4583
|
+
const user = await this.resolveMappedFGAUser(requestContext);
|
|
4518
4584
|
if (!user) {
|
|
4519
4585
|
throw new FGADeniedError({ id: "unknown" }, { type: "tool", id: resourceId }, MastraFGAPermissions.TOOLS_EXECUTE);
|
|
4520
4586
|
}
|
|
4521
|
-
await
|
|
4587
|
+
await requireFGA({
|
|
4522
4588
|
fgaProvider,
|
|
4523
4589
|
user,
|
|
4524
4590
|
resource: { type: "tool", id: resourceId },
|
|
4525
|
-
permission: MastraFGAPermissions.TOOLS_EXECUTE
|
|
4591
|
+
permission: MastraFGAPermissions.TOOLS_EXECUTE,
|
|
4592
|
+
requestContext,
|
|
4593
|
+
context: {
|
|
4594
|
+
resourceId
|
|
4595
|
+
},
|
|
4596
|
+
metadata: {
|
|
4597
|
+
mcpServerId: this.id,
|
|
4598
|
+
mcpServerName: this.name,
|
|
4599
|
+
toolId
|
|
4600
|
+
}
|
|
4526
4601
|
});
|
|
4527
4602
|
}
|
|
4528
4603
|
/**
|