@mastra/mcp 1.15.0-alpha.0 → 1.15.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @mastra/mcp
2
2
 
3
+ ## 1.15.0-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed MCP clients getting stuck after a failed reconnect to streamable-HTTP-only servers. `listTools()`, `callTool()`, and `forceReconnect()` now work once the server is reachable again. Fixes https://github.com/mastra-ai/mastra/issues/19862 ([#19894](https://github.com/mastra-ai/mastra/pull/19894))
8
+
3
9
  ## 1.15.0-alpha.0
4
10
 
5
11
  ### Minor Changes
@@ -36,6 +36,8 @@ export declare class InternalMastraMCPClient extends MastraBase {
36
36
  private serverConfig;
37
37
  private transport?;
38
38
  private pendingAuthTransport?;
39
+ private clientBaseOnClose?;
40
+ private clientConnectionOnClose?;
39
41
  private _authState?;
40
42
  private operationContextStore;
41
43
  private exitHookUnsubscribe?;
@@ -106,6 +108,27 @@ export declare class InternalMastraMCPClient extends MastraBase {
106
108
  sendRootsListChanged(): Promise<void>;
107
109
  private connectStdio;
108
110
  private connectHttp;
111
+ /**
112
+ * Detaches whatever transport is still attached to the underlying SDK Client.
113
+ *
114
+ * The SDK assigns its internal `_transport` before `transport.start()` and never
115
+ * clears it when `start()` throws, and its cleanup after a failed initialize is a
116
+ * fire-and-forget `void this.close()`. Either way a stale transport can remain
117
+ * attached, making every subsequent `client.connect()` throw "Already connected
118
+ * to a transport" and permanently wedging this client (issue #19862). Mastra's
119
+ * own `this.transport` is only assigned after a successful connect, so
120
+ * disconnect/forceReconnect never see the stale one. Calling this before every
121
+ * connect attempt restores the invariant that a connect starts from a detached
122
+ * SDK client.
123
+ */
124
+ private detachStaleClientTransport;
125
+ /**
126
+ * Severs the mutual references between the SDK client and a stale transport
127
+ * without closing it. Clearing the transport's callbacks ensures a later
128
+ * close() of the stale transport cannot reach into the SDK client and clear
129
+ * the state of a newer live connection.
130
+ */
131
+ private severClientTransportLink;
109
132
  /**
110
133
  * Closes and clears any transport retained from an unfinished authorization
111
134
  * flow. Safe to call when nothing is pending. Centralizes the cleanup so
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/client/configuration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/client/configuration.ts"],"names":[],"mappings":"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"}
@@ -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.15.0-alpha.0"
6
+ version: "1.15.0-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.15.0-alpha.0",
2
+ "version": "1.15.0-alpha.1",
3
3
  "package": "@mastra/mcp",
4
4
  "exports": {
5
5
  "UnauthorizedError": {
@@ -254,6 +254,46 @@ class MyFGAProvider implements IFGAProvider {
254
254
  }
255
255
  ```
256
256
 
257
+ ## System actors
258
+
259
+ Autonomous and scheduled agents run without an end user. Mark these calls with an actor signal so FGA can tell them apart from user requests:
260
+
261
+ - `true` or `{ actorKind: 'system' }` identifies an anonymous system actor.
262
+ - The object form can also carry `agentId`, `permissions`, and `scope` to identify and constrain the acting agent.
263
+
264
+ By default, a trusted actor skips the user-centric `require()` check after a tenant-scope check. To enforce per-agent least privilege, implement the optional `requireActor` method on your provider. It receives the actor and the same `FGACheckParams` as `require`, and throws `FGADeniedError` to deny. When your provider doesn't implement `requireActor`, the trusted-actor bypass is preserved, so adding it is backward compatible.
265
+
266
+ ```typescript
267
+ import { FGADeniedError } from '@mastra/core/auth/ee'
268
+ import type { ActorSignal, FGACheckParams, IFGAProvider } from '@mastra/core/auth/ee'
269
+
270
+ class MyFGAProvider implements IFGAProvider {
271
+ // ...check, require, filterAccessible...
272
+
273
+ async requireActor(actor: ActorSignal, params: FGACheckParams): Promise<void> {
274
+ const agentId = actor === true ? undefined : actor.agentId
275
+ // Resolve the agent's real grants from a trusted source keyed by agentId.
276
+ const granted = await this.grantsForAgent(agentId)
277
+ const required = Array.isArray(params.permission) ? params.permission : [params.permission]
278
+ if (!required.some(permission => granted.includes(permission))) {
279
+ throw new FGADeniedError(null, params.resource, params.permission)
280
+ }
281
+ }
282
+ }
283
+ ```
284
+
285
+ ### Trust requirements
286
+
287
+ The actor signal is trusted input, so construct it server-side:
288
+
289
+ - Treat `actor` as a per-call signal. Durable workflows forward it when a run starts, but don't restore the initial actor on resume. Pass it explicitly on every trusted resume, or resolve a fresh actor through agent `defaultOptions`. Without a current actor, user authorization applies and a missing user fails closed.
290
+ - Mastra strips `actor` from execution options handled by its built-in agent HTTP routes. Set it in server-side code, for example a scheduled job or a workflow, never from client input.
291
+ - Establish tenant scope server-side. Built-in agent HTTP routes ignore a client-supplied `organizationId` in the request context, and the trusted-actor path requires an `organizationId` to be set.
292
+ - Durable resume keeps its existing request-context recovery and merge behavior. This doesn't make a persisted actor trusted for a later workflow segment.
293
+ - The tenant-scope check confirms that a trusted `organizationId` exists. It doesn't verify that `actor.agentId` belongs to that organization. When that relationship matters, verify it in `requireActor` using authoritative provider data.
294
+ - Treat `actor.permissions` as a claim, not a grant. A provider that enforces least privilege resolves the agent's authoritative permissions from a trusted source, for example a manifest or your FGA backend keyed by `agentId`, rather than trusting the inline values.
295
+ - Once a provider implements `requireActor`, errors from that method stop execution. Mastra doesn't fall back to organization-only authorization.
296
+
257
297
  ## Related
258
298
 
259
299
  - [Authentication overview](https://mastra.ai/docs/server/auth)
@@ -280,9 +280,7 @@ This is useful for connecting external MCP servers that implement the MCP Apps e
280
280
  The `MCPClient` instance has a `resources` property that provides access to resource-related operations.
281
281
 
282
282
  ```typescript
283
- const mcpClient = new MCPClient({
284
- /* ...servers configuration... */
285
- })
283
+ const mcpClient = new MCPClient({/* ...servers configuration... */})
286
284
 
287
285
  // Access resource methods via mcpClient.resources
288
286
  const allResourcesByServer = await mcpClient.resources.list()
@@ -411,9 +409,7 @@ mcpClient.resources.onListChanged('myWeatherServer', () => {
411
409
  The `MCPClient` instance has an `elicitation` property that provides access to elicitation-related operations. Elicitation allows MCP servers to request structured information from users.
412
410
 
413
411
  ```typescript
414
- const mcpClient = new MCPClient({
415
- /* ...servers configuration... */
416
- })
412
+ const mcpClient = new MCPClient({/* ...servers configuration... */})
417
413
 
418
414
  // Set up elicitation handler
419
415
  mcpClient.elicitation.onRequest('serverName', async request => {
@@ -552,9 +548,7 @@ await mcpClient.elicitation.onRequest('interactiveServer', async request => {
552
548
  The `MCPClient` instance has a `prompts` property that provides access to prompt-related operations.
553
549
 
554
550
  ```typescript
555
- const mcpClient = new MCPClient({
556
- /* ...servers configuration... */
557
- })
551
+ const mcpClient = new MCPClient({/* ...servers configuration... */})
558
552
 
559
553
  // Access prompt methods via mcpClient.prompts
560
554
  const allPromptsByServer = await mcpClient.prompts.list()
@@ -980,9 +974,7 @@ class DatabaseOAuthStorage implements OAuthStorage {
980
974
 
981
975
  const provider = new MCPOAuthClientProvider({
982
976
  redirectUrl: 'http://localhost:3000/callback',
983
- clientMetadata: {
984
- /* ... */
985
- },
977
+ clientMetadata: {/* ... */},
986
978
  storage: new DatabaseOAuthStorage(db, 'user-123'),
987
979
  })
988
980
  ```
@@ -1117,33 +1109,25 @@ For example, if you try to create multiple instances with the same configuration
1117
1109
  ```typescript
1118
1110
  // First instance - OK
1119
1111
  const mcp1 = new MCPClient({
1120
- servers: {
1121
- /* ... */
1122
- },
1112
+ servers: {/* ... */},
1123
1113
  })
1124
1114
 
1125
1115
  // Second instance with same config - Will throw an error
1126
1116
  const mcp2 = new MCPClient({
1127
- servers: {
1128
- /* ... */
1129
- },
1117
+ servers: {/* ... */},
1130
1118
  })
1131
1119
 
1132
1120
  // To fix, either:
1133
1121
  // 1. Add unique IDs
1134
1122
  const mcp3 = new MCPClient({
1135
1123
  id: 'instance-1',
1136
- servers: {
1137
- /* ... */
1138
- },
1124
+ servers: {/* ... */},
1139
1125
  })
1140
1126
 
1141
1127
  // 2. Or disconnect before recreating
1142
1128
  await mcp1.disconnect()
1143
1129
  const mcp4 = new MCPClient({
1144
- servers: {
1145
- /* ... */
1146
- },
1130
+ servers: {/* ... */},
1147
1131
  })
1148
1132
  ```
1149
1133
 
@@ -187,9 +187,7 @@ const server = new MCPServer({
187
187
  id: 'my-server',
188
188
  name: 'My Server',
189
189
  version: '1.0.0',
190
- tools: {
191
- /* ... */
192
- },
190
+ tools: {/* ... */},
193
191
  })
194
192
  await server.startStdio()
195
193
  ```
@@ -353,9 +351,7 @@ const server = new MCPServer({
353
351
  id: 'my-serverless-mcp',
354
352
  name: 'My Serverless MCP',
355
353
  version: '1.0.0',
356
- tools: {
357
- /* your tools */
358
- },
354
+ tools: {/* your tools */},
359
355
  })
360
356
 
361
357
  serve(async req => {
@@ -637,9 +633,7 @@ const serverWithResources = new MCPServer({
637
633
  id: 'resourceful-server',
638
634
  name: 'Resourceful Server',
639
635
  version: '1.0.0',
640
- tools: {
641
- /* ... your tools ... */
642
- },
636
+ tools: {/* ... your tools ... */},
643
637
  resources: myResourceHandlers,
644
638
  })
645
639
  ```
@@ -768,9 +762,7 @@ const serverWithPrompts = new MCPServer({
768
762
  id: 'promptful-server',
769
763
  name: 'Promptful Server',
770
764
  version: '1.0.0',
771
- tools: {
772
- /* ... */
773
- },
765
+ tools: {/* ... */},
774
766
  prompts: myPromptHandlers,
775
767
  })
776
768
  ```
@@ -966,9 +958,7 @@ execute: async (inputData, context) => {
966
958
  // Use elicitation capabilities
967
959
  const result = await context.mcp.elicitation.sendRequest({
968
960
  message: 'Please provide information',
969
- requestedSchema: {
970
- /* schema */
971
- },
961
+ requestedSchema: {/* schema */},
972
962
  })
973
963
 
974
964
  return result
@@ -1159,9 +1149,7 @@ const mcpServer = new MCPServer({
1159
1149
  id: 'protected-server',
1160
1150
  name: 'Protected MCP Server',
1161
1151
  version: '1.0.0',
1162
- tools: {
1163
- /* your tools */
1164
- },
1152
+ tools: {/* your tools */},
1165
1153
  })
1166
1154
 
1167
1155
  // Create OAuth middleware
@@ -1342,21 +1330,48 @@ To pass data to your tools, populate `req.auth` on the Node.js request object in
1342
1330
  ```typescript
1343
1331
  import express from 'express'
1344
1332
 
1333
+ type MCPAuthenticatedRequest = express.Request & {
1334
+ auth?: {
1335
+ token: string
1336
+ clientId: string
1337
+ scopes: string[]
1338
+ expiresAt?: number
1339
+ extra?: Record<string, unknown>
1340
+ }
1341
+ }
1342
+
1345
1343
  const app = express()
1346
1344
 
1347
1345
  // Auth middleware - set req.auth before the MCP handler
1348
- app.use('/mcp', (req, res, next) => {
1349
- const token = req.headers.authorization?.replace('Bearer ', '')
1350
- const user = verifyToken(token)
1351
-
1352
- // This entire object becomes context.mcp.extra.authInfo
1353
- // @ts-ignore - req.auth is read by the MCP SDK
1354
- req.auth = {
1355
- token,
1356
- userId: user.userId,
1357
- email: user.email,
1346
+ app.use('/mcp', async (req, res, next) => {
1347
+ const authorization = req.headers.authorization
1348
+
1349
+ if (!authorization?.startsWith('Bearer ')) {
1350
+ res.status(401).json({ error: 'Missing bearer token' })
1351
+ return
1352
+ }
1353
+
1354
+ const token = authorization.slice('Bearer '.length)
1355
+
1356
+ try {
1357
+ const user = await verifyToken(token)
1358
+
1359
+ // This entire object becomes context.mcp.extra.authInfo
1360
+ const authenticatedRequest = req as MCPAuthenticatedRequest
1361
+ authenticatedRequest.auth = {
1362
+ token,
1363
+ clientId: user.clientId,
1364
+ scopes: user.scopes,
1365
+ expiresAt: user.expiresAt,
1366
+ extra: {
1367
+ userId: user.userId,
1368
+ email: user.email,
1369
+ },
1370
+ }
1371
+ next()
1372
+ } catch {
1373
+ res.status(401).json({ error: 'Invalid or expired token' })
1358
1374
  }
1359
- next()
1360
1375
  })
1361
1376
 
1362
1377
  app.all('/mcp', async (req, res) => {
@@ -1434,19 +1449,86 @@ The full `context.mcp.extra` object contains:
1434
1449
 
1435
1450
  ### Complete Example
1436
1451
 
1437
- Here's a complete example showing the data flow from middleware to tool:
1452
+ Install [`jose`](https://github.com/panva/jose) to verify JSON Web Tokens (JWTs) against your identity provider's JSON Web Key Set (JWKS):
1453
+
1454
+ **npm**:
1455
+
1456
+ ```shell
1457
+ npm install jose
1458
+ ```
1459
+
1460
+ **pnpm**:
1461
+
1462
+ ```shell
1463
+ pnpm add jose
1464
+ ```
1465
+
1466
+ **Yarn**:
1467
+
1468
+ ```shell
1469
+ yarn add jose
1470
+ ```
1471
+
1472
+ **Bun**:
1473
+
1474
+ ```shell
1475
+ bun add jose
1476
+ ```
1477
+
1478
+ The following example validates the token's signature, issuer, audience, algorithm, expiration, and required claims before passing its user data to the tool:
1438
1479
 
1439
1480
  ```typescript
1440
1481
  import express from 'express'
1482
+ import { createRemoteJWKSet, jwtVerify } from 'jose'
1441
1483
  import { MCPServer } from '@mastra/mcp'
1442
1484
  import { createTool } from '@mastra/core/tools'
1443
1485
  import { z } from 'zod'
1444
1486
 
1445
- const verifyToken = (token: string) => {
1446
- // TODO: Implement token verification
1487
+ type MCPAuthenticatedRequest = express.Request & {
1488
+ auth?: {
1489
+ token: string
1490
+ clientId: string
1491
+ scopes: string[]
1492
+ expiresAt?: number
1493
+ extra?: Record<string, unknown>
1494
+ }
1495
+ }
1496
+
1497
+ const issuer = process.env.JWT_ISSUER
1498
+ const audience = process.env.JWT_AUDIENCE
1499
+ const jwksUri = process.env.JWT_JWKS_URI
1500
+
1501
+ if (!issuer || !audience || !jwksUri) {
1502
+ throw new Error('JWT_ISSUER, JWT_AUDIENCE, and JWT_JWKS_URI are required')
1503
+ }
1504
+
1505
+ const jwks = createRemoteJWKSet(new URL(jwksUri))
1506
+
1507
+ const verifyToken = async (token: string) => {
1508
+ const { payload } = await jwtVerify(token, jwks, {
1509
+ issuer,
1510
+ audience,
1511
+ algorithms: ['RS256'],
1512
+ requiredClaims: ['exp'],
1513
+ })
1514
+
1515
+ const clientId =
1516
+ typeof payload.client_id === 'string'
1517
+ ? payload.client_id
1518
+ : typeof payload.azp === 'string'
1519
+ ? payload.azp
1520
+ : undefined
1521
+
1522
+ if (!payload.sub || typeof payload.email !== 'string' || !clientId || !payload.exp) {
1523
+ throw new Error('Token must contain sub, email, exp, and client_id or azp claims')
1524
+ }
1525
+
1447
1526
  return {
1448
- userId: '123',
1449
- email: 'test@test.com',
1527
+ userId: payload.sub,
1528
+ clientId,
1529
+ email: payload.email,
1530
+ expiresAt: payload.exp,
1531
+ scopes: typeof payload.scope === 'string' ? payload.scope.split(' ') : [],
1450
1532
  }
1451
1533
  }
1452
1534
 
@@ -1481,18 +1563,35 @@ const server = new MCPServer({
1481
1563
  // 3. Set up Express with auth middleware
1482
1564
  const app = express()
1483
1565
 
1484
- app.use('/mcp', (req, res, next) => {
1485
- const token = req.headers.authorization?.replace('Bearer ', '')
1486
- const user = verifyToken(token)
1566
+ app.use('/mcp', async (req, res, next) => {
1567
+ const authorization = req.headers.authorization
1568
+
1569
+ if (!authorization?.startsWith('Bearer ')) {
1570
+ res.status(401).json({ error: 'Missing bearer token' })
1571
+ return
1572
+ }
1487
1573
 
1488
- // This entire object becomes context.mcp.extra.authInfo
1489
- // @ts-ignore - req.auth is read by the MCP SDK
1490
- req.auth = {
1491
- token,
1492
- userId: user.userId,
1493
- email: user.email,
1574
+ const token = authorization.slice('Bearer '.length)
1575
+
1576
+ try {
1577
+ const user = await verifyToken(token)
1578
+
1579
+ // This entire object becomes context.mcp.extra.authInfo
1580
+ const authenticatedRequest = req as MCPAuthenticatedRequest
1581
+ authenticatedRequest.auth = {
1582
+ token,
1583
+ clientId: user.clientId,
1584
+ scopes: user.scopes,
1585
+ expiresAt: user.expiresAt,
1586
+ extra: {
1587
+ userId: user.userId,
1588
+ email: user.email,
1589
+ },
1590
+ }
1591
+ next()
1592
+ } catch {
1593
+ res.status(401).json({ error: 'Invalid or expired token' })
1494
1594
  }
1495
- next()
1496
1595
  })
1497
1596
 
1498
1597
  app.all('/mcp', async (req, res) => {