@mastra/mcp 1.7.0-alpha.2 → 1.7.1-alpha.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 +58 -0
- 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 +47 -0
- package/dist/index.cjs +8 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @mastra/mcp
|
|
2
2
|
|
|
3
|
+
## 1.7.1-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Close previous SSE transport before accepting a new connection in `MCPServer.connectSSE()`. Previously, sequential SSE connections to the same server would fail with "Already connected to a transport" because the underlying protocol was never closed when the previous client disconnected. ([#16695](https://github.com/mastra-ai/mastra/pull/16695))
|
|
8
|
+
|
|
9
|
+
## 1.7.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Added MCP Apps support for interactive UI rendering over MCP. ([#16004](https://github.com/mastra-ai/mastra/pull/16004))
|
|
14
|
+
|
|
15
|
+
**MCPClientServerProxy** — a lightweight proxy that delegates resource and tool operations to remote MCP servers via `MCPClient`, enabling Studio to fetch app resources from any connected server.
|
|
16
|
+
|
|
17
|
+
**`toMCPServerProxies()`** — new convenience method on `MCPClient` that creates proxy objects for all configured servers, ready for Mastra-level registration.
|
|
18
|
+
|
|
19
|
+
**Automatic `serverId` stamping** — tools returned by `listTools()` now carry `_meta.ui.serverId`, allowing consumers to resolve `ui://` app resources from the correct MCP server in multi-server environments.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const mcp = new MCPClient({
|
|
23
|
+
servers: {
|
|
24
|
+
myApps: { url: new URL('https://my-mcp-server.example.com/mcp') },
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const mastra = new Mastra({
|
|
29
|
+
agents: { myAgent },
|
|
30
|
+
mcpServers: { ...mcp.toMCPServerProxies() },
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- Added MCP Apps extension support (SEP-1865). MCPServer now accepts an `appResources` config to register interactive `ui://` HTML resources. MCPClient preserves full tool `_meta` (including `ui.resourceUri`) when converting MCP tools to Mastra tools. Both advertise the `io.modelcontextprotocol/ui` extension capability. ([#16004](https://github.com/mastra-ai/mastra/pull/16004))
|
|
35
|
+
|
|
36
|
+
**Example — MCPServer with app resources:**
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const server = new MCPServer({
|
|
40
|
+
name: 'my-server',
|
|
41
|
+
tools: { myTool },
|
|
42
|
+
appResources: {
|
|
43
|
+
dashboard: {
|
|
44
|
+
name: 'Dashboard',
|
|
45
|
+
description: 'Interactive dashboard UI',
|
|
46
|
+
html: '<html>...</html>',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- 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))
|
|
55
|
+
|
|
56
|
+
- Fixed trace parenting for long-lived MCP Stream connections. ([#15716](https://github.com/mastra-ai/mastra/pull/15716))
|
|
57
|
+
|
|
58
|
+
- Updated dependencies [[`6dcd65f`](https://github.com/mastra-ai/mastra/commit/6dcd65f2a34069e6dc43ba35f1d11119b9b40bef), [`86c0298`](https://github.com/mastra-ai/mastra/commit/86c0298e647306423c842f9d5ac827bd616bd13d), [`c05c9a1`](https://github.com/mastra-ai/mastra/commit/c05c9a13230988cef6d438a62f37760f31927bc7), [`ca28c23`](https://github.com/mastra-ai/mastra/commit/ca28c232a2f18801a6cf20fe053479237b4d4fb0), [`e24aacb`](https://github.com/mastra-ai/mastra/commit/e24aacba07bd66f5d95b636dc24016fca26b52cf), [`7679a63`](https://github.com/mastra-ai/mastra/commit/7679a634eae8e8ca459fd87538fdf72b4389b07f), [`7fce309`](https://github.com/mastra-ai/mastra/commit/7fce30912b14170bfc41f0ac736cca0f39fe0cd4), [`1d64a76`](https://github.com/mastra-ai/mastra/commit/1d64a765861a0772ea187bab76e5ed37bf82d042), [`1c2dda8`](https://github.com/mastra-ai/mastra/commit/1c2dda805fbfccc0abf55d4cb20cc34402dc3f0c), [`c721164`](https://github.com/mastra-ai/mastra/commit/c7211643f7ac861f83b19a3757cc921487fc9d75), [`1b55954`](https://github.com/mastra-ai/mastra/commit/1b559541c1e08a10e49d01ffc51a634dfc37a286), [`7997c2e`](https://github.com/mastra-ai/mastra/commit/7997c2e55ddd121562a4098cd8d2b89c68433bf1), [`5adc55e`](https://github.com/mastra-ai/mastra/commit/5adc55e63407be8ee977914957d68bcc2a075ceb), [`7679a63`](https://github.com/mastra-ai/mastra/commit/7679a634eae8e8ca459fd87538fdf72b4389b07f), [`a0d9b6d`](https://github.com/mastra-ai/mastra/commit/a0d9b6d6b810aeaa9e177a0dcc99a4402e609634), [`e97ccb9`](https://github.com/mastra-ai/mastra/commit/e97ccb900f8b7a390ce82c9f8eb8d6eb2c5e3777), [`c5daf48`](https://github.com/mastra-ai/mastra/commit/c5daf48556e98c46ae06caf00f92c249912007e9), [`70017d7`](https://github.com/mastra-ai/mastra/commit/70017d72ab741b5d7040e2a15c251a317782e39e), [`cd96779`](https://github.com/mastra-ai/mastra/commit/cd9677937f113b2856dc8b9f3d4bdabcee58bb2e), [`b0c7022`](https://github.com/mastra-ai/mastra/commit/b0c70224f80dad7c0cdbfb22cbff22e0f75c064f), [`e4942bc`](https://github.com/mastra-ai/mastra/commit/e4942bc7fdc903572f7d84f26d5e15f9d39c763d)]:
|
|
59
|
+
- @mastra/core@1.32.0
|
|
60
|
+
|
|
3
61
|
## 1.7.0-alpha.2
|
|
4
62
|
|
|
5
63
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -987,6 +987,53 @@ await agent.generate('Hello!', {
|
|
|
987
987
|
})
|
|
988
988
|
```
|
|
989
989
|
|
|
990
|
+
## Handling auth failures inside custom fetch
|
|
991
|
+
|
|
992
|
+
A custom `fetch` should not `throw` when authentication is unavailable. The Streamable HTTP transport in the MCP SDK opens a long-lived `GET /mcp` "standalone listener" stream in the background to receive server-pushed notifications. Errors on that stream are retried with exponential backoff, and a thrown `fetch` or a cleanly-closed stream can produce an indefinite reconnect loop at roughly one attempt per second.
|
|
993
|
+
|
|
994
|
+
Return a synthetic `Response` instead. The [MCP Streamable HTTP specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports) defines `405 Method Not Allowed` as the signal a server returns when it does not offer the GET SSE stream, and the SDK honors it as a terminal status that stops the listener cleanly. Use this to disable the listener when your server does not push notifications.
|
|
995
|
+
|
|
996
|
+
The following pattern waits for an auth token on POST requests, attaches it to outgoing headers, and short-circuits the GET listener with a synthetic 405:
|
|
997
|
+
|
|
998
|
+
```typescript
|
|
999
|
+
async function waitForToken(timeoutMs = 5000): Promise<string | null> {
|
|
1000
|
+
// Replace with your token lookup. Return null if no token is available.
|
|
1001
|
+
return getAuthToken({ timeoutMs })
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
const mcpClient = new MCPClient({
|
|
1005
|
+
servers: {
|
|
1006
|
+
apiServer: {
|
|
1007
|
+
url: new URL('https://api.example.com/mcp'),
|
|
1008
|
+
fetch: async (url, init) => {
|
|
1009
|
+
const method = (init?.method || 'GET').toUpperCase()
|
|
1010
|
+
|
|
1011
|
+
// The SDK opens a background GET stream for server-pushed notifications.
|
|
1012
|
+
// If your server does not use it, short-circuit with 405 to stop reconnect attempts.
|
|
1013
|
+
if (method === 'GET') {
|
|
1014
|
+
return new Response(null, { status: 405, statusText: 'Method Not Allowed' })
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// POST: wait for the token, then forward the request with an Authorization header.
|
|
1018
|
+
const token = await waitForToken()
|
|
1019
|
+
if (!token) {
|
|
1020
|
+
// Forward the request without a token and let the server reject it.
|
|
1021
|
+
// The SDK surfaces non-2xx POST responses as errors to the caller of
|
|
1022
|
+
// tools/list, tools/call, etc., which is the desired behavior here.
|
|
1023
|
+
return fetch(url, init)
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
const headers = new Headers(init?.headers)
|
|
1027
|
+
headers.set('authorization', `Bearer ${token}`)
|
|
1028
|
+
return fetch(url, { ...init, headers })
|
|
1029
|
+
},
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
})
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
Return `405` for the GET listener only when your server does not push notifications back to the client. If your server uses the standalone GET stream, attach the auth token on `GET` requests as well and let the request through.
|
|
1036
|
+
|
|
990
1037
|
## Using SSE request headers
|
|
991
1038
|
|
|
992
1039
|
When using the legacy SSE MCP transport, you must configure both `requestInit` and `eventSourceInit` due to a bug in the MCP SDK. Alternatively, you can use a custom `fetch` function which will be automatically used for both POST requests and SSE connections:
|
package/dist/index.cjs
CHANGED
|
@@ -2314,7 +2314,7 @@ function createSimpleTokenProvider(accessToken, options) {
|
|
|
2314
2314
|
});
|
|
2315
2315
|
}
|
|
2316
2316
|
|
|
2317
|
-
// ../../node_modules/.pnpm/hono@4.12.
|
|
2317
|
+
// ../../node_modules/.pnpm/hono@4.12.18/node_modules/hono/dist/utils/stream.js
|
|
2318
2318
|
var StreamingApi = class {
|
|
2319
2319
|
writer;
|
|
2320
2320
|
encoder;
|
|
@@ -2391,7 +2391,7 @@ var StreamingApi = class {
|
|
|
2391
2391
|
}
|
|
2392
2392
|
};
|
|
2393
2393
|
|
|
2394
|
-
// ../../node_modules/.pnpm/hono@4.12.
|
|
2394
|
+
// ../../node_modules/.pnpm/hono@4.12.18/node_modules/hono/dist/helper/streaming/utils.js
|
|
2395
2395
|
var isOldBunVersion = () => {
|
|
2396
2396
|
const version = typeof Bun !== "undefined" ? Bun.version : void 0;
|
|
2397
2397
|
if (version === void 0) {
|
|
@@ -2402,7 +2402,7 @@ var isOldBunVersion = () => {
|
|
|
2402
2402
|
return result;
|
|
2403
2403
|
};
|
|
2404
2404
|
|
|
2405
|
-
// ../../node_modules/.pnpm/hono@4.12.
|
|
2405
|
+
// ../../node_modules/.pnpm/hono@4.12.18/node_modules/hono/dist/utils/html.js
|
|
2406
2406
|
var HtmlEscapedCallbackPhase = {
|
|
2407
2407
|
Stringify: 1};
|
|
2408
2408
|
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
|
@@ -2433,7 +2433,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
2433
2433
|
}
|
|
2434
2434
|
};
|
|
2435
2435
|
|
|
2436
|
-
// ../../node_modules/.pnpm/hono@4.12.
|
|
2436
|
+
// ../../node_modules/.pnpm/hono@4.12.18/node_modules/hono/dist/helper/streaming/sse.js
|
|
2437
2437
|
var SSEStreamingApi = class extends StreamingApi {
|
|
2438
2438
|
constructor(writable, readable) {
|
|
2439
2439
|
super(writable, readable);
|
|
@@ -4186,6 +4186,10 @@ Provided arguments: ${JSON.stringify(request.params.arguments, null, 2)}`
|
|
|
4186
4186
|
}) {
|
|
4187
4187
|
try {
|
|
4188
4188
|
this.logger.debug("Received SSE connection");
|
|
4189
|
+
if (this.sseTransport) {
|
|
4190
|
+
await this.sseTransport.close?.();
|
|
4191
|
+
this.sseTransport = void 0;
|
|
4192
|
+
}
|
|
4189
4193
|
this.sseTransport = new sse_js$1.SSEServerTransport(messagePath, res);
|
|
4190
4194
|
await this.server.connect(this.sseTransport);
|
|
4191
4195
|
this.server.onclose = async () => {
|