@mastra/mcp-docs-server 1.2.8-alpha.7 → 1.2.8
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/.docs/docs/agent-builder/integrations.md +1 -3
- package/.docs/docs/agent-builder/overview.md +2 -0
- package/.docs/docs/agents/overview.md +17 -13
- package/.docs/docs/agents/skills.md +1 -3
- package/.docs/docs/agents/structured-output.md +2 -0
- package/.docs/docs/agents/using-tools.md +66 -49
- package/.docs/docs/browser/agent-browser.md +1 -0
- package/.docs/docs/browser/firecrawl.md +129 -0
- package/.docs/docs/browser/overview.md +16 -2
- package/.docs/docs/capabilities/channels/slack.md +111 -1
- package/.docs/docs/deployment/mastra-server.md +35 -0
- package/.docs/docs/deployment/monorepo.md +2 -0
- package/.docs/docs/deployment/overview.md +6 -0
- package/.docs/docs/deployment/sandbox.md +277 -0
- package/.docs/docs/editor/overview.md +2 -6
- package/.docs/docs/editor/tools.md +2 -6
- package/.docs/docs/evals/multi-turn.md +1 -1
- package/.docs/docs/evals/running-in-ci.md +3 -9
- package/.docs/docs/getting-started/build-with-ai.md +2 -6
- package/.docs/docs/getting-started/manual-install.md +1 -1
- package/.docs/docs/index.md +17 -13
- package/.docs/docs/long-running-agents/background-tasks.md +2 -2
- package/.docs/docs/long-running-agents/goals.md +3 -1
- package/.docs/docs/mastra-platform/database.md +12 -6
- package/.docs/docs/mastra-platform/deploy.md +14 -7
- package/.docs/docs/mastra-platform/environments.md +5 -4
- package/.docs/docs/mastra-platform/observability.md +4 -12
- package/.docs/docs/mastra-platform/overview.md +1 -1
- package/.docs/docs/mastra-platform/regions.md +73 -0
- package/.docs/docs/mastra-platform/workspace.md +111 -0
- package/.docs/docs/memory/observational-memory.md +77 -2
- package/.docs/docs/memory/overview.md +4 -0
- package/.docs/docs/observability/feedback.md +4 -0
- package/.docs/docs/observability/integrations/bridges/otel.md +1 -3
- package/.docs/docs/observability/integrations/exporters/otel.md +1 -3
- package/.docs/docs/server/auth/fga.md +40 -0
- package/.docs/docs/server/auth/simple-auth.md +1 -3
- package/.docs/docs/studio/overview.md +2 -0
- package/.docs/docs/workflows/control-flow.md +1 -3
- package/.docs/docs/workspace/filesystem.md +1 -0
- package/.docs/docs/workspace/sandbox.md +1 -0
- package/.docs/guides/getting-started/quickstart.md +40 -25
- package/.docs/guides/index.md +1 -1
- package/.docs/guides/migrations/vnext-to-standard-apis.md +1 -3
- package/.docs/models/environment-variables.md +3 -0
- package/.docs/models/gateways/netlify.md +3 -6
- package/.docs/models/gateways/openrouter.md +343 -344
- package/.docs/models/gateways/vercel.md +11 -5
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/aki-io.md +78 -0
- package/.docs/models/providers/alibaba-token-plan-cn.md +22 -21
- package/.docs/models/providers/alibaba-token-plan.md +22 -21
- package/.docs/models/providers/ambient.md +12 -10
- package/.docs/models/providers/baseten.md +3 -2
- package/.docs/models/providers/cline-pass.md +82 -0
- package/.docs/models/providers/cortecs.md +2 -1
- package/.docs/models/providers/crossmodel.md +2 -1
- package/.docs/models/providers/deepinfra.md +4 -7
- package/.docs/models/providers/deepseek.md +3 -1
- package/.docs/models/providers/empiriolabs.md +2 -1
- package/.docs/models/providers/evroc.md +3 -2
- package/.docs/models/providers/google.md +4 -2
- package/.docs/models/providers/huggingface.md +2 -1
- package/.docs/models/providers/inferx.md +3 -3
- package/.docs/models/providers/kenari.md +44 -29
- package/.docs/models/providers/kimi-for-coding.md +7 -9
- package/.docs/models/providers/llmgateway.md +4 -1
- package/.docs/models/providers/moonshotai-cn.md +3 -2
- package/.docs/models/providers/moonshotai.md +3 -2
- package/.docs/models/providers/nebius.md +3 -1
- package/.docs/models/providers/novita-ai.md +3 -1
- package/.docs/models/providers/opencode-go.md +6 -3
- package/.docs/models/providers/opencode.md +4 -2
- package/.docs/models/providers/poolside.md +2 -2
- package/.docs/models/providers/thinkingmachines.md +73 -0
- package/.docs/models/providers/togetherai.md +2 -6
- package/.docs/models/providers/wandb.md +2 -1
- package/.docs/models/providers/zenmux.md +3 -1
- package/.docs/models/providers.md +3 -0
- package/.docs/reference/agent-controller/session.md +13 -0
- package/.docs/reference/agents/agent.md +13 -1
- package/.docs/reference/agents/generate.md +18 -0
- package/.docs/reference/browser/firecrawl-browser.md +71 -0
- package/.docs/reference/cli/create-mastra.md +118 -43
- package/.docs/reference/cli/mastra.md +59 -5
- package/.docs/reference/code-sdk/mount-agent-controller.md +4 -4
- package/.docs/reference/core/getMCPServer.md +1 -3
- package/.docs/reference/core/getMCPServerById.md +1 -3
- package/.docs/reference/core/getWorkflow.md +1 -3
- package/.docs/reference/core/listMCPServers.md +2 -6
- package/.docs/reference/datasets/addItem.md +1 -3
- package/.docs/reference/datasets/addItems.md +1 -3
- package/.docs/reference/datasets/compareExperiments.md +1 -3
- package/.docs/reference/datasets/create.md +1 -3
- package/.docs/reference/datasets/dataset.md +2 -6
- package/.docs/reference/datasets/datasets-manager.md +5 -15
- package/.docs/reference/datasets/delete.md +1 -3
- package/.docs/reference/datasets/deleteExperiment.md +1 -3
- package/.docs/reference/datasets/deleteItem.md +1 -3
- package/.docs/reference/datasets/deleteItems.md +1 -3
- package/.docs/reference/datasets/get.md +1 -3
- package/.docs/reference/datasets/getDetails.md +1 -3
- package/.docs/reference/datasets/getExperiment.md +1 -3
- package/.docs/reference/datasets/getItem.md +1 -3
- package/.docs/reference/datasets/getItemHistory.md +1 -3
- package/.docs/reference/datasets/list.md +1 -3
- package/.docs/reference/datasets/listExperimentResults.md +1 -3
- package/.docs/reference/datasets/listExperiments.md +1 -3
- package/.docs/reference/datasets/listItems.md +1 -3
- package/.docs/reference/datasets/listVersions.md +1 -3
- package/.docs/reference/datasets/startExperiment.md +1 -3
- package/.docs/reference/datasets/startExperimentAsync.md +1 -3
- package/.docs/reference/datasets/update.md +1 -3
- package/.docs/reference/datasets/updateItem.md +1 -3
- package/.docs/reference/editor/mastra-editor.md +1 -3
- package/.docs/reference/evals/context-recall.md +205 -0
- package/.docs/reference/evals/create-scorer.md +3 -9
- package/.docs/reference/evals/mastra-scorer.md +1 -3
- package/.docs/reference/file-based-agents/tools.md +7 -6
- package/.docs/reference/index.md +5 -0
- package/.docs/reference/memory/observational-memory.md +21 -0
- package/.docs/reference/observability/tracing/exporters/posthog.md +39 -1
- package/.docs/reference/observability/tracing/processors/sensitive-data-filter.md +1 -3
- package/.docs/reference/processors/token-limiter-processor.md +1 -3
- package/.docs/reference/rag/database-config.md +12 -0
- package/.docs/reference/streaming/agents/stream.md +2 -0
- package/.docs/reference/templates/overview.md +6 -32
- package/.docs/reference/tools/create-tool.md +78 -52
- package/.docs/reference/tools/mcp-client.md +8 -24
- package/.docs/reference/tools/mcp-server.md +143 -44
- package/.docs/reference/tools/tavily.md +1 -1
- package/.docs/reference/tools/vector-query-tool.md +22 -0
- package/.docs/reference/vectors/mongodb.md +2 -0
- package/.docs/reference/vectors/turbopuffer.md +4 -0
- package/.docs/reference/voice/mistral.md +127 -0
- package/.docs/reference/workspace/daytona-sandbox.md +2 -6
- package/.docs/reference/workspace/platform-filesystem.md +182 -0
- package/.docs/reference/workspace/platform-sandbox.md +200 -0
- package/.docs/reference/workspace/railway-sandbox.md +37 -1
- package/CHANGELOG.md +78 -0
- package/dist/{chunk-GLPCVXXO.js → chunk-HGADBLKG.js} +2 -2
- package/dist/{chunk-GLPCVXXO.js.map → chunk-HGADBLKG.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/stdio.js +1 -1
- package/dist/tools/docs.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -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
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1446
|
-
|
|
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:
|
|
1449
|
-
|
|
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
|
|
1486
|
-
|
|
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
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
token
|
|
1492
|
-
|
|
1493
|
-
|
|
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) => {
|
|
@@ -59,7 +59,7 @@ All factory functions accept `TavilyClientOptions` from `@tavily/core`:
|
|
|
59
59
|
|
|
60
60
|
**apiKey** (`string`): Tavily API key. Falls back to the TAVILY\_API\_KEY environment variable.
|
|
61
61
|
|
|
62
|
-
**
|
|
62
|
+
**clientName** (`string`): Attribution string sent with each request in the X-Client-Name header. (Default: `'mastra'`)
|
|
63
63
|
|
|
64
64
|
**apiBaseURL** (`string`): Base URL for the Tavily API.
|
|
65
65
|
|
|
@@ -269,6 +269,28 @@ const chromaQueryTool = createVectorQueryTool({
|
|
|
269
269
|
- **whereDocument**: Filter by document content
|
|
270
270
|
- **Use Cases**: Advanced filtering, content-based search
|
|
271
271
|
|
|
272
|
+
**Turbopuffer**:
|
|
273
|
+
|
|
274
|
+
### Turbopuffer Configuration
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
const turbopufferQueryTool = createVectorQueryTool({
|
|
278
|
+
vectorStoreName: 'turbopuffer',
|
|
279
|
+
indexName: 'docs',
|
|
280
|
+
model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
281
|
+
databaseConfig: {
|
|
282
|
+
turbopuffer: {
|
|
283
|
+
consistency: 'eventual', // Lower latency, recently written data may not be visible yet
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
})
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Turbopuffer Features:**
|
|
290
|
+
|
|
291
|
+
- **consistency**: Choose between `strong` (default, read-your-writes) and `eventual` (lower latency)
|
|
292
|
+
- **Use Cases**: Latency-sensitive queries where slightly stale data is acceptable
|
|
293
|
+
|
|
272
294
|
**Multiple Configs**:
|
|
273
295
|
|
|
274
296
|
### Multiple Database Configurations
|
|
@@ -89,6 +89,8 @@ Creates a new vector index (collection) in MongoDB.
|
|
|
89
89
|
|
|
90
90
|
**metric** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search (Default: `cosine`)
|
|
91
91
|
|
|
92
|
+
**filterFields** (`string[]`): Metadata field names to declare as filter fields in the Atlas vectorSearch index (registered as metadata.\<field>). Queries that filter only on declared fields are pushed directly into $vectorSearch instead of pre-filtering candidate \_ids, avoiding the 16 MB BSON limit on large result sets. Filters that reference an undeclared field, or use an operator $vectorSearch does not support, fall back to the pre-filter automatically.
|
|
93
|
+
|
|
92
94
|
### `waitForIndexReady()`
|
|
93
95
|
|
|
94
96
|
Waits for an index to become ready after creation. Useful when you need to ensure an index is ready before performing operations.
|
|
@@ -18,6 +18,8 @@ The TurbopufferVector class provides vector search using [Turbopuffer](https://t
|
|
|
18
18
|
|
|
19
19
|
**compression** (`boolean`): Whether to compress requests and accept compressed responses. (Default: `true`)
|
|
20
20
|
|
|
21
|
+
**consistency** (`'strong' | 'eventual'`): The default consistency level for queries. Can be overridden per query. "strong" guarantees queries see all data written before the query started, at the cost of higher latency. "eventual" offers lower latency, but recently written data may not be visible yet. (Default: `strong`)
|
|
22
|
+
|
|
21
23
|
**schemaConfigForIndex** (`function`): A callback function that takes an index name and returns a config object for that index. This allows you to define explicit schemas per index.
|
|
22
24
|
|
|
23
25
|
## Methods
|
|
@@ -50,6 +52,8 @@ The TurbopufferVector class provides vector search using [Turbopuffer](https://t
|
|
|
50
52
|
|
|
51
53
|
**includeVector** (`boolean`): Whether to include vectors in the results (Default: `false`)
|
|
52
54
|
|
|
55
|
+
**consistency** (`'strong' | 'eventual'`): The consistency level for this query. Overrides the consistency level set in the constructor. Defaults to "strong".
|
|
56
|
+
|
|
53
57
|
### `listIndexes()`
|
|
54
58
|
|
|
55
59
|
Returns an array of index names as strings.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Mistral
|
|
4
|
+
|
|
5
|
+
The MistralVoice class provides text-to-speech and speech-to-text capabilities using Mistral's Voxtral audio models. It supports buffered and streaming TTS, batch transcription with diarization, and voice cloning via reference audio.
|
|
6
|
+
|
|
7
|
+
## Usage example
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { MistralVoice } from '@mastra/voice-mistral'
|
|
11
|
+
|
|
12
|
+
const voice = new MistralVoice()
|
|
13
|
+
|
|
14
|
+
// Text-to-speech
|
|
15
|
+
const audioStream = await voice.speak('Hello, how can I help you?', {
|
|
16
|
+
responseFormat: 'mp3',
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// Speech-to-text
|
|
20
|
+
const text = await voice.listen(audioStream, {
|
|
21
|
+
language: 'en',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// List available voices
|
|
25
|
+
const speakers = await voice.getSpeakers()
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { MistralVoice } from '@mastra/voice-mistral'
|
|
30
|
+
|
|
31
|
+
// Initialize with specific configuration
|
|
32
|
+
const voice = new MistralVoice({
|
|
33
|
+
speechModel: {
|
|
34
|
+
name: 'voxtral-mini-tts-2603',
|
|
35
|
+
apiKey: 'your-mistral-api-key',
|
|
36
|
+
},
|
|
37
|
+
listeningModel: {
|
|
38
|
+
name: 'voxtral-mini-latest',
|
|
39
|
+
apiKey: 'your-mistral-api-key',
|
|
40
|
+
},
|
|
41
|
+
speaker: 'en_paul_neutral',
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Constructor parameters
|
|
46
|
+
|
|
47
|
+
**speechModel** (`MistralModelConfig`): Configuration for text-to-speech synthesis. (Default: `{ name: 'voxtral-mini-tts-2603' }`)
|
|
48
|
+
|
|
49
|
+
**speechModel.name** (`string`): Model ID for speech synthesis.
|
|
50
|
+
|
|
51
|
+
**speechModel.apiKey** (`string`): Mistral API key. Falls back to MISTRAL\_API\_KEY environment variable.
|
|
52
|
+
|
|
53
|
+
**listeningModel** (`MistralModelConfig`): Configuration for speech-to-text recognition. (Default: `{ name: 'voxtral-mini-latest' }`)
|
|
54
|
+
|
|
55
|
+
**listeningModel.name** (`string`): Model ID for transcription. Use 'voxtral-mini-2507' for a pinned version.
|
|
56
|
+
|
|
57
|
+
**listeningModel.apiKey** (`string`): Mistral API key. Falls back to MISTRAL\_API\_KEY environment variable.
|
|
58
|
+
|
|
59
|
+
**speaker** (`string`): Default voice ID for speech synthesis. Retrieve available IDs from getSpeakers(). (Default: `'en_paul_neutral'`)
|
|
60
|
+
|
|
61
|
+
## Methods
|
|
62
|
+
|
|
63
|
+
### `speak(input, options?)`
|
|
64
|
+
|
|
65
|
+
Converts text to speech using Mistral's Voxtral TTS model. Supports both buffered and streaming output.
|
|
66
|
+
|
|
67
|
+
**input** (`string | NodeJS.ReadableStream`): Text or text stream to convert to speech.
|
|
68
|
+
|
|
69
|
+
**options** (`MistralSpeakOptions`): Configuration options.
|
|
70
|
+
|
|
71
|
+
**options.speaker** (`string`): Voice ID to use. Overrides the constructor default.
|
|
72
|
+
|
|
73
|
+
**options.responseFormat** (`'pcm' | 'wav' | 'mp3' | 'flac' | 'opus'`): Audio output format. Use 'pcm' for lowest latency streaming.
|
|
74
|
+
|
|
75
|
+
**options.refAudio** (`string`): Base64-encoded reference audio for one-off voice cloning (minimum 2-3 seconds).
|
|
76
|
+
|
|
77
|
+
**options.model** (`string`): Override the speech model for this call.
|
|
78
|
+
|
|
79
|
+
**options.stream** (`boolean`): Enable streaming TTS. Audio chunks are written to the stream as they arrive.
|
|
80
|
+
|
|
81
|
+
Returns: `Promise<NodeJS.ReadableStream>`
|
|
82
|
+
|
|
83
|
+
### `listen(audioStream, options?)`
|
|
84
|
+
|
|
85
|
+
Transcribes audio using Mistral's Voxtral transcription model. Supports diarization, context biasing, and timestamp granularity.
|
|
86
|
+
|
|
87
|
+
**audioStream** (`NodeJS.ReadableStream`): Audio stream to transcribe.
|
|
88
|
+
|
|
89
|
+
**options** (`MistralListenOptions`): Configuration options.
|
|
90
|
+
|
|
91
|
+
**options.language** (`string`): Language code (e.g., 'en'). Improves accuracy when specified.
|
|
92
|
+
|
|
93
|
+
**options.diarize** (`boolean`): Enable speaker diarization.
|
|
94
|
+
|
|
95
|
+
**options.contextBias** (`string[]`): Words or phrases for vocabulary guidance.
|
|
96
|
+
|
|
97
|
+
**options.timestampGranularities** (`('segment' | 'word')[]`): Timestamp detail level for transcription segments.
|
|
98
|
+
|
|
99
|
+
**options.filetype** (`string`): Audio file extension hint for the input stream.
|
|
100
|
+
|
|
101
|
+
Returns: `Promise<string>`
|
|
102
|
+
|
|
103
|
+
### `getSpeakers()`
|
|
104
|
+
|
|
105
|
+
Fetches available preset voices from the Mistral Voices API. Each entry contains:
|
|
106
|
+
|
|
107
|
+
**voiceId** (`string`): Unique identifier for the voice.
|
|
108
|
+
|
|
109
|
+
**name** (`string`): Display name of the voice.
|
|
110
|
+
|
|
111
|
+
**languages** (`string[]`): Languages supported by the voice.
|
|
112
|
+
|
|
113
|
+
**gender** (`string | null`): Gender of the voice.
|
|
114
|
+
|
|
115
|
+
### `getListener()`
|
|
116
|
+
|
|
117
|
+
Returns `{ enabled: true }`.
|
|
118
|
+
|
|
119
|
+
## Notes
|
|
120
|
+
|
|
121
|
+
- API keys can be provided via constructor options or the `MISTRAL_API_KEY` environment variable
|
|
122
|
+
- TTS supports 9 languages: English, French, Spanish, Portuguese, Italian, Dutch, German, Hindi, Arabic
|
|
123
|
+
- STT supports 13 languages: English, Chinese, Hindi, Spanish, Arabic, French, Portuguese, Russian, German, Japanese, Korean, Italian, Dutch
|
|
124
|
+
- TTS input text should be kept under 300 words per request for best results
|
|
125
|
+
- STT supports up to 3 hours of audio per request
|
|
126
|
+
- Voice cloning via `refAudio` requires a minimum of 2-3 seconds of reference audio
|
|
127
|
+
- `getSpeakers()` returns preset voices with UUID identifiers. The default `en_paul_neutral` is a named alias accepted by the TTS endpoint but not included in the list
|
|
@@ -440,12 +440,8 @@ Then use the snapshot name in your sandbox config:
|
|
|
440
440
|
```typescript
|
|
441
441
|
const workspace = new Workspace({
|
|
442
442
|
mounts: {
|
|
443
|
-
'/s3-data': new S3Filesystem({
|
|
444
|
-
|
|
445
|
-
}),
|
|
446
|
-
'/gcs-data': new GCSFilesystem({
|
|
447
|
-
/* ... */
|
|
448
|
-
}),
|
|
443
|
+
'/s3-data': new S3Filesystem({/* ... */}),
|
|
444
|
+
'/gcs-data': new GCSFilesystem({/* ... */}),
|
|
449
445
|
},
|
|
450
446
|
sandbox: new DaytonaSandbox({ snapshot: 'cloud-fs-mounting' }),
|
|
451
447
|
})
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# PlatformFilesystem
|
|
4
|
+
|
|
5
|
+
Stores files in a Mastra Platform workspace bucket. Each Mastra Platform environment can have one bucket, and `PlatformFilesystem` gives agents `read`, `write`, `list`, `delete`, and `move` operations against it.
|
|
6
|
+
|
|
7
|
+
Use `PlatformFilesystem` when your agent runs on a Mastra Platform deployment and you want the filesystem to be backed by the platform-provisioned bucket. For direct S3 access, see [`S3Filesystem`](https://mastra.ai/reference/workspace/s3-filesystem). For a local directory during development, see [`LocalFilesystem`](https://mastra.ai/reference/workspace/local-filesystem).
|
|
8
|
+
|
|
9
|
+
> **Info:** For interface details, see [WorkspaceFilesystem interface](https://mastra.ai/reference/workspace/filesystem).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
**npm**:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @mastra/platform-workspace
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**pnpm**:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @mastra/platform-workspace
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Yarn**:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @mastra/platform-workspace
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Bun**:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add @mastra/platform-workspace
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Configure the platform credentials. The access token, project ID, and bucket name fall back to environment variables, so a Mastra Platform deployment can pass zero constructor options.
|
|
38
|
+
|
|
39
|
+
**.env file**:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
MASTRA_PLATFORM_SECRET_KEY=your-platform-secret-key
|
|
43
|
+
MASTRA_PROJECT_ID=your-project-id
|
|
44
|
+
MASTRA_PLATFORM_BUCKET_NAME=your-bucket-name
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Constructor**:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
new PlatformFilesystem({
|
|
51
|
+
accessToken: 'your-platform-access-token',
|
|
52
|
+
projectId: 'your-project-id',
|
|
53
|
+
bucketName: 'your-bucket-name',
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
On a Mastra Platform deployment these variables are injected automatically, so the constructor can be called with no options.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
Add a `PlatformFilesystem` to a workspace and assign it to an agent:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Agent } from '@mastra/core/agent'
|
|
65
|
+
import { Workspace } from '@mastra/core/workspace'
|
|
66
|
+
import { PlatformFilesystem } from '@mastra/platform-workspace'
|
|
67
|
+
|
|
68
|
+
const workspace = new Workspace({
|
|
69
|
+
filesystem: new PlatformFilesystem({
|
|
70
|
+
// accessToken, projectId, bucketName all fall back to env vars
|
|
71
|
+
}),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const agent = new Agent({
|
|
75
|
+
id: 'file-agent',
|
|
76
|
+
name: 'File Agent',
|
|
77
|
+
instructions: 'You are a research assistant that reads and writes reports.',
|
|
78
|
+
model: 'anthropic/claude-sonnet-4-6',
|
|
79
|
+
workspace,
|
|
80
|
+
})
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Reading and writing files
|
|
84
|
+
|
|
85
|
+
Object keys are percent-encoded per segment, so filenames with `?`, `#`, `%`, `&`, `+`, or spaces are preserved end-to-end:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const fs = new PlatformFilesystem()
|
|
89
|
+
|
|
90
|
+
await fs.writeFile('/analyses/repo.md', markdown)
|
|
91
|
+
const content = await fs.readFile('/analyses/repo.md')
|
|
92
|
+
const entries = await fs.readdir('/analyses')
|
|
93
|
+
await fs.moveFile('/analyses/repo.md', '/analyses/repo-final.md')
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Read-only mode
|
|
97
|
+
|
|
98
|
+
Pass `readOnly: true` to mount the bucket read-only. Any mutating call throws `WorkspaceReadOnlyError`:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const fs = new PlatformFilesystem({ readOnly: true })
|
|
102
|
+
|
|
103
|
+
await fs.readFile('/analyses/repo.md') // ok
|
|
104
|
+
await fs.writeFile('/analyses/repo.md', 'x') // throws WorkspaceReadOnlyError
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Overwrite semantics
|
|
108
|
+
|
|
109
|
+
`writeFile` supports `overwrite: false` and throws `FileExistsError` when the destination already exists.
|
|
110
|
+
|
|
111
|
+
`copyFile` and `moveFile` always overwrite the destination. Passing `overwrite: false` to either method throws an error rather than silently overwriting.
|
|
112
|
+
|
|
113
|
+
### Appending files
|
|
114
|
+
|
|
115
|
+
`appendFile` is a read-modify-write and is not atomic. Concurrent appends to the same path can overwrite each other. For concurrent writers, use `writeFile` with distinct keys.
|
|
116
|
+
|
|
117
|
+
## Constructor parameters
|
|
118
|
+
|
|
119
|
+
**accessToken** (`string`): Platform secret key. Falls back to the MASTRA\_PLATFORM\_SECRET\_KEY environment variable (MASTRA\_PLATFORM\_ACCESS\_TOKEN is a deprecated fallback).
|
|
120
|
+
|
|
121
|
+
**projectId** (`string`): Platform project ID. Falls back to the MASTRA\_PROJECT\_ID environment variable.
|
|
122
|
+
|
|
123
|
+
**bucketName** (`string`): Platform bucket name to store files in. Falls back to the MASTRA\_PLATFORM\_BUCKET\_NAME environment variable.
|
|
124
|
+
|
|
125
|
+
**readOnly** (`boolean`): When true, all mutating calls throw WorkspaceReadOnlyError. (Default: `false`)
|
|
126
|
+
|
|
127
|
+
**displayName** (`string`): Human-readable name shown in workspace UIs.
|
|
128
|
+
|
|
129
|
+
**description** (`string`): Short description shown in workspace UIs.
|
|
130
|
+
|
|
131
|
+
**icon** (`FilesystemIcon`): Icon shown in workspace UIs.
|
|
132
|
+
|
|
133
|
+
**instructions** (`string | ((opts: { defaultInstructions: string; requestContext?: RequestContext }) => string)`): Custom instructions returned by getInstructions(). A string fully replaces the defaults; a function receives the defaults and can extend or customize them per-request.
|
|
134
|
+
|
|
135
|
+
**id** (`string`): Unique identifier for this filesystem instance. (Default: `Auto-generated`)
|
|
136
|
+
|
|
137
|
+
**fetch** (`typeof fetch`): Custom fetch implementation, mainly for testing.
|
|
138
|
+
|
|
139
|
+
## Properties
|
|
140
|
+
|
|
141
|
+
**id** (`string`): Filesystem instance identifier.
|
|
142
|
+
|
|
143
|
+
**name** (`string`): Provider name ('PlatformFilesystem').
|
|
144
|
+
|
|
145
|
+
**provider** (`string`): Provider identifier ('platform').
|
|
146
|
+
|
|
147
|
+
**readOnly** (`boolean | undefined`): Whether the filesystem was mounted read-only.
|
|
148
|
+
|
|
149
|
+
## Errors
|
|
150
|
+
|
|
151
|
+
Filesystem-specific errors match the standard workspace error types:
|
|
152
|
+
|
|
153
|
+
- `FileNotFoundError`: The path does not exist. Thrown by `readFile`, `stat`, and `deleteFile` (unless `force: true` is set).
|
|
154
|
+
- `FileExistsError`: `writeFile` was called with `overwrite: false` and the destination already exists.
|
|
155
|
+
- `WorkspaceReadOnlyError`: A mutating call was made on a read-only filesystem.
|
|
156
|
+
|
|
157
|
+
Other Platform API failures raise `PlatformApiError`. Structured `{ error: { message, type } }` responses are parsed into `.code` (machine-readable kind) and `.proxyMessage` (human string):
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { FileNotFoundError, PlatformApiError } from '@mastra/platform-workspace'
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
await fs.readFile('/missing.txt')
|
|
164
|
+
} catch (err) {
|
|
165
|
+
if (err instanceof FileNotFoundError) {
|
|
166
|
+
// handle missing file
|
|
167
|
+
} else if (err instanceof PlatformApiError) {
|
|
168
|
+
if (err.code === 'authentication_error') {
|
|
169
|
+
// refresh token
|
|
170
|
+
}
|
|
171
|
+
console.error(err.status, err.code, err.proxyMessage)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`code` and `proxyMessage` are `undefined` when the response body is not JSON, for example an HTML 502 from a load balancer.
|
|
177
|
+
|
|
178
|
+
## Related
|
|
179
|
+
|
|
180
|
+
- [PlatformSandbox reference](https://mastra.ai/reference/workspace/platform-sandbox)
|
|
181
|
+
- [S3Filesystem reference](https://mastra.ai/reference/workspace/s3-filesystem)
|
|
182
|
+
- [WorkspaceFilesystem interface](https://mastra.ai/reference/workspace/filesystem)
|