@mastra/mcp 1.6.0 → 1.6.1-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 +18 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/docs/SKILL.md +1 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-mcp-overview.md +25 -0
- package/dist/docs/references/reference-tools-mcp-server.md +1 -3
- package/dist/index.cjs +137 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +136 -7
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +16 -2
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/docs/references/docs-mcp-publishing-mcp-server.md +0 -115
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @mastra/mcp
|
|
2
2
|
|
|
3
|
+
## 1.6.1-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Added Fine-Grained Authorization (FGA) enforcement to MCP tool execution. Both transport-driven calls and direct `executeTool()` calls now run the same authorization checks when a request user is present, and typed FGA permission constants are accepted in MCP server authorization config. ([#15410](https://github.com/mastra-ai/mastra/pull/15410))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`86c0298`](https://github.com/mastra-ai/mastra/commit/86c0298e647306423c842f9d5ac827bd616bd13d), [`7fce309`](https://github.com/mastra-ai/mastra/commit/7fce30912b14170bfc41f0ac736cca0f39fe0cd4), [`7997c2e`](https://github.com/mastra-ai/mastra/commit/7997c2e55ddd121562a4098cd8d2b89c68433bf1), [`e97ccb9`](https://github.com/mastra-ai/mastra/commit/e97ccb900f8b7a390ce82c9f8eb8d6eb2c5e3777), [`c5daf48`](https://github.com/mastra-ai/mastra/commit/c5daf48556e98c46ae06caf00f92c249912007e9), [`cd96779`](https://github.com/mastra-ai/mastra/commit/cd9677937f113b2856dc8b9f3d4bdabcee58bb2e)]:
|
|
10
|
+
- @mastra/core@1.32.0-alpha.2
|
|
11
|
+
|
|
12
|
+
## 1.6.1-alpha.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Fixed trace parenting for long-lived MCP Stream connections. ([#15716](https://github.com/mastra-ai/mastra/pull/15716))
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`6dcd65f`](https://github.com/mastra-ai/mastra/commit/6dcd65f2a34069e6dc43ba35f1d11119b9b40bef), [`1c2dda8`](https://github.com/mastra-ai/mastra/commit/1c2dda805fbfccc0abf55d4cb20cc34402dc3f0c)]:
|
|
19
|
+
- @mastra/core@1.31.1-alpha.0
|
|
20
|
+
|
|
3
21
|
## 1.6.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-mcp
|
|
|
3
3
|
description: Documentation for @mastra/mcp. Use when working with @mastra/mcp APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/mcp"
|
|
6
|
-
version: "1.6.
|
|
6
|
+
version: "1.6.1-alpha.1"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -17,7 +17,6 @@ Read the individual reference documents for detailed explanations and code examp
|
|
|
17
17
|
### Docs
|
|
18
18
|
|
|
19
19
|
- [MCP overview](references/docs-mcp-overview.md) - Learn about the Model Context Protocol (MCP), how to use third-party tools via MCPClient, connect to registries, and share your own tools using MCPServer.
|
|
20
|
-
- [Publishing an MCP server](references/docs-mcp-publishing-mcp-server.md) - Guide to setting up and building a Mastra MCP server using the stdio transport, and publishing it to NPM.
|
|
21
20
|
|
|
22
21
|
### Reference
|
|
23
22
|
|
|
@@ -332,6 +332,31 @@ const mcp = new MCPClient({
|
|
|
332
332
|
})
|
|
333
333
|
```
|
|
334
334
|
|
|
335
|
+
**Apify**:
|
|
336
|
+
|
|
337
|
+
[Apify](https://apify.com) is the largest marketplace of tools for AI, with thousands of ready-made [Actors](https://apify.com/store) to extract real-time data from any website, track competitors, generate leads, analyze sentiment, or orchestrate your apps. Connect your agent through the [Apify MCP Server](https://mcp.apify.com).
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { MCPClient } from '@mastra/mcp'
|
|
341
|
+
|
|
342
|
+
export const mcp = new MCPClient({
|
|
343
|
+
servers: {
|
|
344
|
+
apify: {
|
|
345
|
+
url: new URL('https://mcp.apify.com'),
|
|
346
|
+
requestInit: {
|
|
347
|
+
headers: {
|
|
348
|
+
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
})
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Get your API token from the [Apify Console](https://console.apify.com/settings/integrations) and store it as `APIFY_TOKEN` in your environment.
|
|
357
|
+
|
|
358
|
+
To pick specific Actors and tools, use the [Apify MCP server configurator](https://mcp.apify.com) and copy the generated URL.
|
|
359
|
+
|
|
335
360
|
**Ampersand**:
|
|
336
361
|
|
|
337
362
|
[Ampersand](https://withampersand.com?utm_source=mastra-docs) offers an [MCP Server](https://docs.withampersand.com/mcp) that allows you to connect your agent to 150+ integrations with SaaS products like Salesforce, Hubspot, and Zendesk.
|
|
@@ -768,11 +768,9 @@ await serverWithPrompts.prompts.notifyListChanged()
|
|
|
768
768
|
- Handle errors with informative messages.
|
|
769
769
|
- Document argument expectations and available versions.
|
|
770
770
|
|
|
771
|
-
***
|
|
772
|
-
|
|
773
771
|
## Examples
|
|
774
772
|
|
|
775
|
-
For practical examples of setting up and deploying an MCPServer, see the [Publishing an MCP Server guide](https://mastra.ai/
|
|
773
|
+
For practical examples of setting up and deploying an MCPServer, see the [Publishing an MCP Server guide](https://mastra.ai/guides/guide/publishing-mcp-server).
|
|
776
774
|
|
|
777
775
|
The example at the beginning of this page also demonstrates how to instantiate `MCPServer` with both tools and agents.
|
|
778
776
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var async_hooks = require('async_hooks');
|
|
4
|
+
var module$1 = require('module');
|
|
4
5
|
var base = require('@mastra/core/base');
|
|
5
6
|
var tools = require('@mastra/core/tools');
|
|
6
7
|
var index_js = require('@modelcontextprotocol/sdk/client/index.js');
|
|
@@ -23,6 +24,7 @@ var stdio_js$1 = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
|
23
24
|
var streamableHttp_js$1 = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
24
25
|
var auth_js = require('@modelcontextprotocol/sdk/client/auth.js');
|
|
25
26
|
|
|
27
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
26
28
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
27
29
|
|
|
28
30
|
var equal__default = /*#__PURE__*/_interopDefault(equal);
|
|
@@ -421,7 +423,57 @@ function isReconnectableMCPError(error) {
|
|
|
421
423
|
|
|
422
424
|
// src/client/client.ts
|
|
423
425
|
var DEFAULT_SERVER_CONNECT_TIMEOUT_MSEC = 3e3;
|
|
426
|
+
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
424
427
|
var SSE_FALLBACK_STATUS_CODES = [400, 404, 405];
|
|
428
|
+
var DATADOG_TRACER_TEST_SYMBOL = /* @__PURE__ */ Symbol.for("mastra.mcp.dd-trace-test-tracer");
|
|
429
|
+
function shouldDetachPersistentTransportRequest(init) {
|
|
430
|
+
return (init?.method ?? "GET").toUpperCase() === "GET";
|
|
431
|
+
}
|
|
432
|
+
function getDatadogScope() {
|
|
433
|
+
const testTracer = globalThis[DATADOG_TRACER_TEST_SYMBOL];
|
|
434
|
+
const tracer = testTracer ?? loadDatadogTracer();
|
|
435
|
+
if (typeof tracer?.scope === "function") {
|
|
436
|
+
return tracer.scope();
|
|
437
|
+
}
|
|
438
|
+
if (typeof tracer?.default?.scope === "function") {
|
|
439
|
+
return tracer.default.scope();
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
function loadDatadogTracer() {
|
|
444
|
+
if (!isDatadogTracerLikelyLoaded()) {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
return require2("dd-trace");
|
|
449
|
+
} catch {
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function isDatadogTracerLikelyLoaded() {
|
|
454
|
+
if (globalThis[DATADOG_TRACER_TEST_SYMBOL]) {
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
if (process.execArgv.some((arg) => arg.includes("dd-trace"))) {
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
if (process.env.NODE_OPTIONS?.includes("dd-trace")) {
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
try {
|
|
464
|
+
const resolvedPath = require2.resolve("dd-trace");
|
|
465
|
+
return Boolean(require2.cache[resolvedPath]);
|
|
466
|
+
} catch {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function runOutsideDatadogTraceScope(callback) {
|
|
471
|
+
const scope = getDatadogScope();
|
|
472
|
+
if (!scope) {
|
|
473
|
+
return callback();
|
|
474
|
+
}
|
|
475
|
+
return scope.activate(null, callback);
|
|
476
|
+
}
|
|
425
477
|
function convertLogLevelToLoggerMethod(level) {
|
|
426
478
|
switch (level) {
|
|
427
479
|
case "debug":
|
|
@@ -616,7 +668,11 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
616
668
|
}
|
|
617
669
|
async connectHttp(url) {
|
|
618
670
|
const { requestInit, eventSourceInit, authProvider, connectTimeout, fetch: userFetch } = this.serverConfig;
|
|
619
|
-
const fetch2 =
|
|
671
|
+
const fetch2 = (requestUrl, init) => {
|
|
672
|
+
const requestContext = this.operationContextStore.getStore() ?? null;
|
|
673
|
+
const executeFetch = () => userFetch ? userFetch(requestUrl, init, requestContext) : globalThis.fetch(requestUrl, init);
|
|
674
|
+
return shouldDetachPersistentTransportRequest(init) ? runOutsideDatadogTraceScope(executeFetch) : executeFetch();
|
|
675
|
+
};
|
|
620
676
|
this.log("debug", `Attempting to connect to URL: ${url}`);
|
|
621
677
|
let shouldTrySSE = url.pathname.endsWith(`/sse`);
|
|
622
678
|
if (!shouldTrySSE) {
|
|
@@ -645,7 +701,7 @@ var InternalMastraMCPClient = class extends base.MastraBase {
|
|
|
645
701
|
if (shouldTrySSE) {
|
|
646
702
|
this.log("debug", "Falling back to deprecated HTTP+SSE transport...");
|
|
647
703
|
try {
|
|
648
|
-
const sseEventSourceInit =
|
|
704
|
+
const sseEventSourceInit = { ...eventSourceInit, fetch: fetch2 };
|
|
649
705
|
const sseTransport = new sse_js.SSEClientTransport(url, {
|
|
650
706
|
requestInit,
|
|
651
707
|
eventSourceInit: sseEventSourceInit,
|
|
@@ -2770,9 +2826,11 @@ var MCPServer = class extends mcp.MCPServerBase {
|
|
|
2770
2826
|
* This allows us to create multiple server instances with identical functionality.
|
|
2771
2827
|
*/
|
|
2772
2828
|
registerHandlersOnServer(serverInstance) {
|
|
2773
|
-
serverInstance.setRequestHandler(types_js.ListToolsRequestSchema, async () => {
|
|
2829
|
+
serverInstance.setRequestHandler(types_js.ListToolsRequestSchema, async (_request, extra) => {
|
|
2830
|
+
const proxiedContext = this.createProxiedRequestContext(extra);
|
|
2831
|
+
const tools = await this.getAuthorizedConvertedToolEntries(proxiedContext);
|
|
2774
2832
|
return {
|
|
2775
|
-
tools:
|
|
2833
|
+
tools: tools.map(([, tool]) => {
|
|
2776
2834
|
const toolSpec = {
|
|
2777
2835
|
name: tool.id || "unknown",
|
|
2778
2836
|
description: tool.description,
|
|
@@ -2864,6 +2922,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
2864
2922
|
throw new Error(`The "extra" key is now nested under "mcp.extra" in tool arguments`);
|
|
2865
2923
|
}
|
|
2866
2924
|
};
|
|
2925
|
+
await this.enforceToolExecutionFGA(request.params.name, proxiedContext);
|
|
2867
2926
|
const result = await tool.execute(validation?.value ?? request.params.arguments ?? {}, mcpOptions);
|
|
2868
2927
|
const duration = Date.now() - startTime;
|
|
2869
2928
|
if (tools.isValidationError(result)) {
|
|
@@ -4055,7 +4114,24 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4055
4114
|
* });
|
|
4056
4115
|
* ```
|
|
4057
4116
|
*/
|
|
4058
|
-
getToolListInfo() {
|
|
4117
|
+
getToolListInfo(requestContext) {
|
|
4118
|
+
const fgaProvider = this.mastra?.getServer?.()?.fga;
|
|
4119
|
+
if (fgaProvider && requestContext) {
|
|
4120
|
+
return this.getAuthorizedConvertedToolEntries(requestContext).then((tools) => ({
|
|
4121
|
+
tools: tools.map(([toolId, tool]) => ({
|
|
4122
|
+
id: toolId,
|
|
4123
|
+
name: tool.id || toolId,
|
|
4124
|
+
description: tool.description,
|
|
4125
|
+
inputSchema: this.convertSchema(tool.parameters),
|
|
4126
|
+
outputSchema: this.convertSchema(tool.outputSchema),
|
|
4127
|
+
toolType: tool.mcp?.toolType,
|
|
4128
|
+
_meta: withMastraToolStrictMeta(tool.mcp?._meta, tool.strict)
|
|
4129
|
+
}))
|
|
4130
|
+
}));
|
|
4131
|
+
}
|
|
4132
|
+
if (fgaProvider && !requestContext) {
|
|
4133
|
+
return { tools: [] };
|
|
4134
|
+
}
|
|
4059
4135
|
this.logger.debug("Getting tool list", { server: this.name });
|
|
4060
4136
|
return {
|
|
4061
4137
|
tools: Object.entries(this.convertedTools).map(([toolId, tool]) => ({
|
|
@@ -4063,7 +4139,7 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4063
4139
|
name: tool.id || toolId,
|
|
4064
4140
|
description: tool.description,
|
|
4065
4141
|
inputSchema: this.convertSchema(tool.parameters),
|
|
4066
|
-
outputSchema: this.convertSchema(tool.
|
|
4142
|
+
outputSchema: this.convertSchema(tool.outputSchema),
|
|
4067
4143
|
toolType: tool.mcp?.toolType,
|
|
4068
4144
|
_meta: withMastraToolStrictMeta(tool.mcp?._meta, tool.strict)
|
|
4069
4145
|
}))
|
|
@@ -4103,6 +4179,58 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4103
4179
|
_meta: withMastraToolStrictMeta(tool.mcp?._meta, tool.strict)
|
|
4104
4180
|
};
|
|
4105
4181
|
}
|
|
4182
|
+
createProxiedRequestContext(extra) {
|
|
4183
|
+
const proxiedContext = new requestContext.RequestContext();
|
|
4184
|
+
if (extra && typeof extra === "object") {
|
|
4185
|
+
Object.entries(extra).forEach(([key, value]) => {
|
|
4186
|
+
proxiedContext.set(key, value);
|
|
4187
|
+
});
|
|
4188
|
+
}
|
|
4189
|
+
return proxiedContext;
|
|
4190
|
+
}
|
|
4191
|
+
async getAuthorizedConvertedToolEntries(requestContext) {
|
|
4192
|
+
const entries = Object.entries(this.convertedTools);
|
|
4193
|
+
const fgaProvider = this.mastra?.getServer?.()?.fga;
|
|
4194
|
+
if (!fgaProvider) {
|
|
4195
|
+
return entries;
|
|
4196
|
+
}
|
|
4197
|
+
const user = requestContext.get("user");
|
|
4198
|
+
if (!user) {
|
|
4199
|
+
return [];
|
|
4200
|
+
}
|
|
4201
|
+
const accessible = await Promise.all(
|
|
4202
|
+
entries.map(async ([toolId, tool]) => {
|
|
4203
|
+
try {
|
|
4204
|
+
await this.enforceToolExecutionFGA(toolId, requestContext);
|
|
4205
|
+
return [toolId, tool];
|
|
4206
|
+
} catch (error) {
|
|
4207
|
+
if (error instanceof Error && error.name === "FGADeniedError") {
|
|
4208
|
+
return null;
|
|
4209
|
+
}
|
|
4210
|
+
throw error;
|
|
4211
|
+
}
|
|
4212
|
+
})
|
|
4213
|
+
);
|
|
4214
|
+
return accessible.filter((entry) => entry !== null);
|
|
4215
|
+
}
|
|
4216
|
+
async enforceToolExecutionFGA(toolId, requestContext) {
|
|
4217
|
+
const fgaProvider = this.mastra?.getServer?.()?.fga;
|
|
4218
|
+
if (!fgaProvider) {
|
|
4219
|
+
return;
|
|
4220
|
+
}
|
|
4221
|
+
const { checkFGA, FGADeniedError, MastraFGAPermissions } = await import('@mastra/core/auth/ee');
|
|
4222
|
+
const resourceId = JSON.stringify([this.id, toolId]);
|
|
4223
|
+
const user = requestContext?.get("user");
|
|
4224
|
+
if (!user) {
|
|
4225
|
+
throw new FGADeniedError({ id: "unknown" }, { type: "tool", id: resourceId }, MastraFGAPermissions.TOOLS_EXECUTE);
|
|
4226
|
+
}
|
|
4227
|
+
await checkFGA({
|
|
4228
|
+
fgaProvider,
|
|
4229
|
+
user,
|
|
4230
|
+
resource: { type: "tool", id: resourceId },
|
|
4231
|
+
permission: MastraFGAPermissions.TOOLS_EXECUTE
|
|
4232
|
+
});
|
|
4233
|
+
}
|
|
4106
4234
|
/**
|
|
4107
4235
|
* Executes a specific tool provided by this MCP server.
|
|
4108
4236
|
*
|
|
@@ -4185,8 +4313,10 @@ Provided arguments: ${JSON.stringify(args, null, 2)}`,
|
|
|
4185
4313
|
try {
|
|
4186
4314
|
const finalExecutionContext = {
|
|
4187
4315
|
messages: executionContext?.messages || [],
|
|
4188
|
-
toolCallId: executionContext?.toolCallId || crypto$1.randomUUID()
|
|
4316
|
+
toolCallId: executionContext?.toolCallId || crypto$1.randomUUID(),
|
|
4317
|
+
requestContext: executionContext?.requestContext
|
|
4189
4318
|
};
|
|
4319
|
+
await this.enforceToolExecutionFGA(toolId, finalExecutionContext.requestContext);
|
|
4190
4320
|
const result = await tool.execute(validatedArgs, finalExecutionContext);
|
|
4191
4321
|
this.logger.info("Tool executed successfully", { tool: toolId });
|
|
4192
4322
|
return result;
|