@mastra/mcp-docs-server 1.2.19-alpha.0 → 1.2.19-alpha.13
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/deployment/mastra-server.md +19 -0
- package/.docs/docs/deployment/workers.md +2 -2
- package/.docs/docs/evals/built-in-scorers.md +1 -0
- package/.docs/docs/evals/multi-turn.md +84 -1
- package/.docs/docs/evals/overview.md +63 -1
- package/.docs/docs/harness/durable-agents.md +1 -1
- package/.docs/docs/mastra-platform/deploy.md +101 -0
- package/.docs/docs/mastra-platform/server.md +6 -11
- package/.docs/docs/mastra-platform/studio.md +8 -10
- package/.docs/docs/observability/integrations/exporters/mastra-storage.md +19 -14
- package/.docs/docs/sandbox/filesystem.md +8 -8
- package/.docs/docs/sandbox/overview.md +33 -66
- package/.docs/docs/server/middleware.md +4 -0
- package/.docs/docs/server/server-adapters.md +12 -8
- package/.docs/docs/storage.md +1 -0
- package/.docs/integrations/databases/mongodb.md +1 -1
- package/.docs/integrations/databases/postgresql.md +2 -0
- package/.docs/integrations/databases/valkey.md +99 -0
- package/.docs/integrations/deploy/render.md +47 -61
- package/.docs/integrations/sandboxes/e2b.md +2 -0
- package/.docs/integrations/tools/parallel.md +240 -0
- package/.docs/integrations.md +2 -0
- package/.docs/models/environment-variables.md +2 -0
- package/.docs/models/gateways/merge-gateway.md +2 -1
- package/.docs/models/gateways/netlify.md +9 -5
- package/.docs/models/gateways/openrouter.md +8 -9
- package/.docs/models/gateways/vercel.md +7 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/agentrouter.md +17 -34
- package/.docs/models/providers/aki-io.md +14 -13
- package/.docs/models/providers/chutes.md +2 -2
- package/.docs/models/providers/crof.md +3 -8
- package/.docs/models/providers/crossmodel.md +56 -55
- package/.docs/models/providers/deepseek.md +8 -7
- package/.docs/models/providers/digitalocean.md +8 -8
- package/.docs/models/providers/edenai.md +14 -14
- package/.docs/models/providers/google.md +3 -3
- package/.docs/models/providers/hyper.md +5 -5
- package/.docs/models/providers/inceptron.md +1 -1
- package/.docs/models/providers/kilo.md +24 -20
- package/.docs/models/providers/llmgateway-providers.md +11 -8
- package/.docs/models/providers/llmgateway.md +3 -5
- package/.docs/models/providers/nano-gpt.md +12 -6
- package/.docs/models/providers/nvidia.md +3 -1
- package/.docs/models/providers/ofox.md +114 -110
- package/.docs/models/providers/opencode-go.md +26 -23
- package/.docs/models/providers/opencode.md +1 -1
- package/.docs/models/providers/opper.md +112 -0
- package/.docs/models/providers/requesty.md +1 -1
- package/.docs/models/providers/scaleway.md +2 -1
- package/.docs/models/providers.md +2 -0
- package/.docs/reference/ai-sdk/handle-chat-stream.md +11 -0
- package/.docs/reference/ai-sdk/with-sse-heartbeat.md +47 -0
- package/.docs/reference/core/mastra-class.md +1 -1
- package/.docs/reference/evals/checks.md +6 -0
- package/.docs/reference/evals/multi-turn-judge.md +101 -0
- package/.docs/reference/index.md +4 -0
- package/.docs/reference/pubsub/valkey-streams.md +84 -0
- package/.docs/reference/rag/vector-databases.md +4 -4
- package/.docs/reference/server/express-adapter.md +6 -8
- package/.docs/reference/server/hono-adapter.md +19 -6
- package/.docs/reference/storage/turso.md +88 -0
- package/.docs/reference/streaming/ChunkType.md +29 -1
- package/.docs/reference/tools/mcp-client.md +41 -9
- package/.docs/reference/vectors/mongodb.md +11 -11
- package/.docs/reference/vectors/pg.md +2 -0
- package/.docs/reference/workspace/workspace-class.md +15 -3
- package/CHANGELOG.md +59 -0
- package/package.json +4 -4
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
# Sandboxes and filesystems
|
|
4
4
|
|
|
5
|
-
A sandbox gives your agent an environment where it can run commands, execute code, install dependencies, and manage processes.
|
|
5
|
+
A sandbox gives your agent an isolated environment where it can run commands, execute code, install dependencies, and manage processes. This lets agents perform work that would be risky, resource-intensive, or impractical to run directly inside your application.
|
|
6
6
|
|
|
7
|
-
[
|
|
7
|
+
Sandboxes are often temporary, so files created inside them may disappear when the environment stops. A [filesystem](https://mastra.ai/docs/sandbox/filesystem) gives the agent a place to read, write, and [search](https://mastra.ai/docs/sandbox/search) files that can outlive the sandbox. You can use one to keep outputs between runs, seed a new sandbox with existing files, or give the agent documents it can search while working. Filesystems also work without a sandbox, for example when an agent only needs a knowledge base or access to files in a service such as Google Drive.
|
|
8
8
|
|
|
9
9
|
## When to use sandboxes
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Use a sandbox when an agent needs to:
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
13
|
+
- Clone repositories and run shell, Git, build, or test workflows in a separate environment.
|
|
14
|
+
- Process PDFs, presentations, or other files with specialized libraries and produce new artifacts.
|
|
15
|
+
- Run long-lived or parallel work in separate environments with isolated files and processes.
|
|
16
16
|
|
|
17
17
|
If an agent only needs to read, write, or search files, configure [direct filesystem access](https://mastra.ai/docs/sandbox/filesystem).
|
|
18
18
|
|
|
19
19
|
## Quickstart
|
|
20
20
|
|
|
21
|
-
Give an agent a local sandbox
|
|
21
|
+
Give an agent a local sandbox:
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
24
|
import { Agent } from '@mastra/core/agent'
|
|
25
|
-
import {
|
|
25
|
+
import { LocalSandbox, Workspace } from '@mastra/core/workspace'
|
|
26
26
|
|
|
27
27
|
export const codingAgent = new Agent({
|
|
28
28
|
id: 'coding-agent',
|
|
@@ -33,20 +33,15 @@ export const codingAgent = new Agent({
|
|
|
33
33
|
sandbox: new LocalSandbox({
|
|
34
34
|
workingDirectory: './workspace',
|
|
35
35
|
}),
|
|
36
|
-
filesystem: new LocalFilesystem({
|
|
37
|
-
basePath: './workspace',
|
|
38
|
-
}),
|
|
39
36
|
}),
|
|
40
37
|
})
|
|
41
38
|
|
|
42
39
|
await codingAgent.generate('List the files in the sandbox directory')
|
|
43
40
|
```
|
|
44
41
|
|
|
45
|
-
> **Warning:** `LocalSandbox`
|
|
46
|
-
|
|
47
|
-
To use a different sandbox for each user, tenant, or thread, configure a [sandbox resolver](#multi-tenant-sandboxes) instead.
|
|
42
|
+
> **Warning:** `LocalSandbox` runs commands on the application host by default and isn't isolated or secure. Enable [native isolation](#localsandbox), or use a remote or container sandbox when running untrusted code.
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
A static sandbox is shared across every request and memory thread that uses the agent. Use a [resolver](#sandboxes-per-user-or-thread) when each user or thread needs a separate environment. See [Lifecycle and persistence](#lifecycle-and-persistence) for sharing and cleanup details.
|
|
50
45
|
|
|
51
46
|
## Using the sandbox
|
|
52
47
|
|
|
@@ -74,7 +69,7 @@ const workspace = new Workspace({
|
|
|
74
69
|
})
|
|
75
70
|
```
|
|
76
71
|
|
|
77
|
-
|
|
72
|
+
Set `{ enabled: false }` on one tool to remove it, or set the top-level `enabled: false` to disable generated tools by default. A per-tool `{ enabled: true }` overrides that global setting. The top-level `requireApproval` policy applies to every generated tool unless a per-tool entry overrides it.
|
|
78
73
|
|
|
79
74
|
See the [sandbox tools reference](https://mastra.ai/reference/workspace/workspace-class) for all generated tools and the [tool configuration reference](https://mastra.ai/reference/workspace/workspace-class) for approvals, output limits, and hooks.
|
|
80
75
|
|
|
@@ -109,17 +104,12 @@ export const startServerTool = createTool({
|
|
|
109
104
|
})
|
|
110
105
|
```
|
|
111
106
|
|
|
112
|
-
##
|
|
107
|
+
## Sandboxes
|
|
113
108
|
|
|
114
109
|
### `LocalSandbox`
|
|
115
110
|
|
|
116
111
|
[`LocalSandbox`](https://mastra.ai/reference/workspace/local-sandbox) executes commands on the same machine as your Mastra application. By default, commands run directly on the host with the permissions of the application process.
|
|
117
112
|
|
|
118
|
-
Enable native isolation to restrict filesystem and network access at the operating-system level:
|
|
119
|
-
|
|
120
|
-
- **macOS**: Seatbelt (`sandbox-exec`)
|
|
121
|
-
- **Linux**: Bubblewrap (`bwrap`)
|
|
122
|
-
|
|
123
113
|
```typescript
|
|
124
114
|
const sandbox = new LocalSandbox({
|
|
125
115
|
workingDirectory: './workspace',
|
|
@@ -131,11 +121,13 @@ const sandbox = new LocalSandbox({
|
|
|
131
121
|
})
|
|
132
122
|
```
|
|
133
123
|
|
|
134
|
-
|
|
124
|
+
Enable native isolation to restrict filesystem and network access at the operating-system level. On macOS, native isolation uses Seatbelt (`sandbox-exec`). On Linux, it uses Bubblewrap (`bwrap`). Use `LocalSandbox.detectIsolation()` to check whether Seatbelt or Bubblewrap is available on the current operating system.
|
|
135
125
|
|
|
136
|
-
|
|
126
|
+
The [`nativeSandbox` options](https://mastra.ai/reference/workspace/local-sandbox) control network access, read-only or writable paths, write access to the working directory, and system binaries. You can also provide a custom Seatbelt profile or Bubblewrap arguments. See [`LocalSandbox`](https://mastra.ai/reference/workspace/local-sandbox) for the full configuration.
|
|
137
127
|
|
|
138
|
-
|
|
128
|
+
### Remote sandboxes
|
|
129
|
+
|
|
130
|
+
Use a remote or container sandbox when commands need a stronger boundary from the host application or when workloads need to scale beyond the resources of your application server. Each sandbox has its own isolation, persistence, networking, and mount behavior:
|
|
139
131
|
|
|
140
132
|
- [AgentCore](https://mastra.ai/integrations/sandboxes/agentcore)
|
|
141
133
|
- [Apple Container](https://mastra.ai/integrations/sandboxes/apple-container)
|
|
@@ -149,47 +141,40 @@ Use a remote or container backend when commands need a stronger boundary from th
|
|
|
149
141
|
- [Railway](https://mastra.ai/integrations/sandboxes/railway)
|
|
150
142
|
- [Vercel](https://mastra.ai/integrations/sandboxes/vercel)
|
|
151
143
|
|
|
152
|
-
If Mastra doesn't support your
|
|
144
|
+
If Mastra doesn't support your sandbox provider, implement the [sandbox provider interface](https://mastra.ai/reference/workspace/sandbox) to add it.
|
|
153
145
|
|
|
154
146
|
## Filesystem
|
|
155
147
|
|
|
156
|
-
|
|
148
|
+
Every sandbox has a filesystem for commands. `LocalSandbox` uses the host filesystem, while remote sandboxes have isolated filesystems that are often temporary. For files that need to outlive a sandbox, use external storage.
|
|
149
|
+
|
|
150
|
+
Mastra filesystems connect agents and sandboxes to provider-backed storage such as Amazon S3, Google Cloud Storage, or Google Drive. Configuring one gives the agent tools to read, write, and search files. When a remote sandbox and provider support mounting, Mastra automatically mounts the storage through Filesystem in Userspace (FUSE). Commands use normal file paths while the provider stores changes outside the sandbox.
|
|
157
151
|
|
|
158
|
-
|
|
152
|
+
See [Filesystem](https://mastra.ai/docs/sandbox/filesystem) for providers, file tools, and mounts.
|
|
159
153
|
|
|
160
|
-
##
|
|
154
|
+
## Sandboxes per user or thread
|
|
161
155
|
|
|
162
156
|
Use a **resolver** when each user, tenant, or thread needs a separate sandbox. Set `sandboxCacheKey` to the identity that owns the sandbox so later requests reuse the same live environment.
|
|
163
157
|
|
|
164
158
|
This example creates and caches one Daytona sandbox per user:
|
|
165
159
|
|
|
166
160
|
```typescript
|
|
167
|
-
import type { RequestContext } from '@mastra/core/request-context'
|
|
168
161
|
import { Workspace } from '@mastra/core/workspace'
|
|
169
162
|
import { DaytonaSandbox } from '@mastra/daytona'
|
|
170
163
|
|
|
171
|
-
const getUserId = (requestContext: RequestContext) => {
|
|
172
|
-
const userId = requestContext.get('user-id')
|
|
173
|
-
if (typeof userId !== 'string' || !userId) {
|
|
174
|
-
throw new Error('A user ID is required to resolve this sandbox')
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return userId
|
|
178
|
-
}
|
|
179
|
-
|
|
180
164
|
const workspace = new Workspace({
|
|
181
165
|
sandbox: async ({ requestContext }) => {
|
|
182
|
-
const
|
|
166
|
+
const userId = requestContext.get('user-id') as string
|
|
167
|
+
const sandbox = new DaytonaSandbox({ id: `user-${userId}` })
|
|
183
168
|
await sandbox.start()
|
|
184
169
|
return sandbox
|
|
185
170
|
},
|
|
186
|
-
sandboxCacheKey: ({ requestContext }) =>
|
|
171
|
+
sandboxCacheKey: ({ requestContext }) => requestContext.get('user-id') as string,
|
|
187
172
|
})
|
|
188
173
|
```
|
|
189
174
|
|
|
190
175
|
The first request from a user creates the sandbox. Later requests with the same user ID reuse it.
|
|
191
176
|
|
|
192
|
-
For a sandbox with persistent storage, create
|
|
177
|
+
For a sandbox with persistent storage, create a [filesystem](https://mastra.ai/docs/sandbox/filesystem) and mount it inside the resolver. This example creates one Daytona sandbox and one S3 storage prefix per memory thread, then mounts the storage at `/workspace`:
|
|
193
178
|
|
|
194
179
|
```typescript
|
|
195
180
|
import { MASTRA_THREAD_ID_KEY, type RequestContext } from '@mastra/core/request-context'
|
|
@@ -197,14 +182,8 @@ import { Workspace } from '@mastra/core/workspace'
|
|
|
197
182
|
import { DaytonaSandbox } from '@mastra/daytona'
|
|
198
183
|
import { S3Filesystem } from '@mastra/s3'
|
|
199
184
|
|
|
200
|
-
const getThreadId = (requestContext: RequestContext) =>
|
|
201
|
-
|
|
202
|
-
if (typeof threadId !== 'string' || !threadId) {
|
|
203
|
-
throw new Error('A memory thread is required to resolve this sandbox')
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return threadId
|
|
207
|
-
}
|
|
185
|
+
const getThreadId = (requestContext: RequestContext) =>
|
|
186
|
+
requestContext.get(MASTRA_THREAD_ID_KEY) as string
|
|
208
187
|
|
|
209
188
|
const createThreadFilesystem = (threadId: string) =>
|
|
210
189
|
new S3Filesystem({
|
|
@@ -234,25 +213,13 @@ The first request in a thread runs the resolver and starts the sandbox. Later re
|
|
|
234
213
|
|
|
235
214
|
The example mounts the filesystem inside the resolver because static `mounts` can't be combined with a sandbox resolver. Generated tools resolve the filesystem and sandbox from the request context automatically.
|
|
236
215
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
You are responsible for every sandbox returned by a resolver. It must be ready to use when returned. Keep track of it and destroy it through your application lifecycle code when it's no longer needed. `workspace.destroy()` doesn't destroy resolver-returned sandboxes.
|
|
240
|
-
|
|
241
|
-
Resolvers are incompatible with `mounts` and [`lsp: true`](https://mastra.ai/docs/sandbox/lsp), because both require a static sandbox during configuration. Using a resolver with `mounts` throws an `INVALID_CONFIG` error. With `lsp: true`, Mastra disables LSP and logs a warning.
|
|
216
|
+
> **Warning:** Your application owns sandboxes returned by a resolver. Destroy them and call `workspace.clearSandboxCache(cacheKey)` when the user, thread, or session ends. `workspace.destroy()` doesn't destroy resolver-returned sandboxes.
|
|
242
217
|
|
|
243
218
|
### Tool availability
|
|
244
219
|
|
|
245
|
-
With a static sandbox, Mastra knows which capabilities the backend supports and only gives the agent the corresponding tools. Application code should also check that an optional capability is available before using it
|
|
246
|
-
|
|
247
|
-
```typescript
|
|
248
|
-
const processManager = workspace.sandbox?.processes
|
|
249
|
-
|
|
250
|
-
if (processManager) {
|
|
251
|
-
await processManager.spawn('pnpm dev')
|
|
252
|
-
}
|
|
253
|
-
```
|
|
220
|
+
With a static sandbox, Mastra knows which capabilities the backend supports and only gives the agent the corresponding tools. Application code should also check that an optional capability is available before using it.
|
|
254
221
|
|
|
255
|
-
With a [resolver-backed sandbox](#
|
|
222
|
+
With a [resolver-backed sandbox](#sandboxes-per-user-or-thread), the backend isn't known until a request runs, so Mastra initially makes all sandbox tools available. If the resolved backend doesn't support the tool the agent calls, the call fails with `SandboxFeatureNotSupportedError`.
|
|
256
223
|
|
|
257
224
|
## Background processes
|
|
258
225
|
|
|
@@ -292,7 +259,7 @@ Who shares a sandbox depends on where you configure it and whether you use a res
|
|
|
292
259
|
| Resource-scoped resolver | The resolver caches one sandbox for each resource ID. |
|
|
293
260
|
| Thread-scoped resolver | A memory thread keeps its sandbox across requests in that thread. |
|
|
294
261
|
|
|
295
|
-
A static sandbox isn't automatically scoped to the current resource or memory thread. For resource or thread scope, use a resolver and set `sandboxCacheKey` to the corresponding ID. See [
|
|
262
|
+
A static sandbox isn't automatically scoped to the current resource or memory thread. For resource or thread scope, use a resolver and set `sandboxCacheKey` to the corresponding ID. See [Sandboxes per user or thread](#sandboxes-per-user-or-thread).
|
|
296
263
|
|
|
297
264
|
### Start
|
|
298
265
|
|
|
@@ -6,6 +6,10 @@ Mastra servers can execute custom middleware functions before or after an API ro
|
|
|
6
6
|
|
|
7
7
|
A middleware receives the [Hono](https://hono.dev) `Context` (`c`) and a `next` function. If it returns a `Response` the request is short-circuited. Calling `next()` continues processing the next middleware or route handler.
|
|
8
8
|
|
|
9
|
+
> **Note:** Middleware handlers use Hono's signature, so they run on Hono-based serving paths: `mastra dev` and `mastra build`, the [Hono adapter](https://mastra.ai/reference/server/hono-adapter), and adapters built on it such as `@mastra/next` and `@mastra/tanstack-start`. Adapters for other frameworks (Express, Fastify, Koa) can't run Hono handlers and log a warning at startup when middleware is configured. Register middleware through the framework's own API there instead.
|
|
10
|
+
>
|
|
11
|
+
> User middleware never runs on routes declared public with `requiresAuth: false`, so it can't block endpoints the framework needs to keep reachable, such as the Studio sign-in routes.
|
|
12
|
+
|
|
9
13
|
```typescript
|
|
10
14
|
import { Mastra } from '@mastra/core'
|
|
11
15
|
|
|
@@ -424,11 +424,12 @@ See the [NestJS Adapter](https://mastra.ai/reference/server/nestjs-adapter) docu
|
|
|
424
424
|
|
|
425
425
|
## Initialization flow
|
|
426
426
|
|
|
427
|
-
Calling `init()` runs
|
|
427
|
+
Calling `init()` runs four steps in order. Understanding this flow helps when you need to insert your own middleware at specific points.
|
|
428
428
|
|
|
429
429
|
1. `registerContextMiddleware()`: Attaches the Mastra instance, request context, tools, and abort signal to every request. This makes Mastra available to all subsequent middleware and route handlers.
|
|
430
430
|
2. `registerAuthMiddleware()`: Runs the adapter auth hook during initialization. Official adapters enforce auth inline when Mastra registers built-in routes and `registerApiRoute()` routes, so raw framework routes should use the adapter's exported `createAuthMiddleware()` helper when they need Mastra auth.
|
|
431
|
-
3. `
|
|
431
|
+
3. `registerUserMiddleware()`: Registers [middleware](https://mastra.ai/docs/server/middleware) from the `server.middleware` config and `mastra.setServerMiddleware()`. Middleware handlers use Hono's signature, so Hono-based adapters (`@mastra/hono` and the adapters built on it) mount them; other adapters log a warning instead of silently ignoring the config.
|
|
432
|
+
4. `registerRoutes()`: Registers all Mastra API routes for agents, workflows, and other features. Also registers MCP routes if MCP servers are configured.
|
|
432
433
|
|
|
433
434
|
### Manual initialization
|
|
434
435
|
|
|
@@ -445,6 +446,9 @@ server.registerContextMiddleware();
|
|
|
445
446
|
// Middleware that needs Mastra context
|
|
446
447
|
app.use(customMiddleware);
|
|
447
448
|
|
|
449
|
+
// Registers `server.middleware` and `setServerMiddleware()` middleware
|
|
450
|
+
server.registerUserMiddleware();
|
|
451
|
+
|
|
448
452
|
await server.registerRoutes();
|
|
449
453
|
|
|
450
454
|
// Routes after Mastra
|
|
@@ -566,11 +570,12 @@ When using server adapters, configuration comes from two places: the Mastra `ser
|
|
|
566
570
|
|
|
567
571
|
The adapter reads these settings from `mastra.getServer()`:
|
|
568
572
|
|
|
569
|
-
| Option | Description
|
|
570
|
-
| --------------- |
|
|
571
|
-
| `auth` | Authentication config, used by `registerAuthMiddleware()`.
|
|
572
|
-
| `bodySizeLimit` | Default body size limit in bytes. Can be overridden per-adapter via `bodyLimitOptions`.
|
|
573
|
-
| `onError` | Custom error handler called when an unhandled error occurs in a route handler. See [server.onError](https://mastra.ai/reference/configuration).
|
|
573
|
+
| Option | Description |
|
|
574
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
575
|
+
| `auth` | Authentication config, used by `registerAuthMiddleware()`. |
|
|
576
|
+
| `bodySizeLimit` | Default body size limit in bytes. Can be overridden per-adapter via `bodyLimitOptions`. |
|
|
577
|
+
| `onError` | Custom error handler called when an unhandled error occurs in a route handler. See [server.onError](https://mastra.ai/reference/configuration). |
|
|
578
|
+
| `middleware` | User [middleware](https://mastra.ai/docs/server/middleware), registered by `registerUserMiddleware()`. Hono-based adapters run it; Express, Fastify, and Koa log a warning because Hono handlers can't run there. |
|
|
574
579
|
|
|
575
580
|
### Adapter constructor only
|
|
576
581
|
|
|
@@ -595,7 +600,6 @@ These `server` config options are only used by `mastra build` and have no effect
|
|
|
595
600
|
| `cors` | `mastra build` adds CORS middleware |
|
|
596
601
|
| `timeout` | `mastra build` |
|
|
597
602
|
| `apiRoutes` | `registerApiRoute()` for `mastra build` |
|
|
598
|
-
| `middleware` | Middleware config for `mastra build` |
|
|
599
603
|
|
|
600
604
|
When using adapters, configure these features directly with your framework. For example, add CORS middleware using Hono's or Express's built-in CORS packages, and set the port when calling your framework's listen function.
|
|
601
605
|
|
package/.docs/docs/storage.md
CHANGED
|
@@ -207,6 +207,7 @@ Each provider page includes installation instructions, configuration parameters,
|
|
|
207
207
|
- [OracleDB](https://mastra.ai/integrations/databases/oracledb)
|
|
208
208
|
- [PostgreSQL](https://mastra.ai/integrations/databases/postgresql)
|
|
209
209
|
- [Redis](https://mastra.ai/integrations/databases/redis)
|
|
210
|
+
- [Valkey](https://mastra.ai/integrations/databases/valkey)
|
|
210
211
|
- [Upstash](https://mastra.ai/integrations/databases/upstash)
|
|
211
212
|
|
|
212
213
|
## Next steps
|
|
@@ -32,7 +32,7 @@ bun add @mastra/mongodb@latest
|
|
|
32
32
|
|
|
33
33
|
## Usage
|
|
34
34
|
|
|
35
|
-
Ensure you have a [MongoDB Atlas Local (via Docker)](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/) or [MongoDB Atlas Cloud](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-getting-started/) instance with
|
|
35
|
+
Ensure you have a [MongoDB Atlas Local (via Docker)](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/) or [MongoDB Atlas Cloud](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-getting-started/) instance with MongoDB Search enabled. MongoDB 7.0+ is recommended.
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
38
|
import { MongoDBStore } from '@mastra/mongodb'
|
|
@@ -146,6 +146,8 @@ PostgreSQL supports observability and can handle low trace volumes. Throughput c
|
|
|
146
146
|
- Setting up table partitioning for efficient data retention
|
|
147
147
|
- Migrating observability to [ClickHouse via composite storage](https://mastra.ai/reference/storage/composite) if you need to scale further
|
|
148
148
|
|
|
149
|
+
`PostgresStoreVNext` uses the `event-sourced` [tracing strategy](https://mastra.ai/docs/observability/integrations/exporters/mastra-storage) instead. It writes one row when a span starts and another when it ends, never updating a row in place, and collapses those rows when a trace is read. Writes stay append-only, and traces appear in Studio while the run is still executing.
|
|
150
|
+
|
|
149
151
|
### Initialization
|
|
150
152
|
|
|
151
153
|
When you pass storage to the Mastra class, `init()` is called automatically before any storage operation:
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Valkey
|
|
4
|
+
|
|
5
|
+
The Valkey storage implementation provides persistent storage and server-side caching through the [Valkey GLIDE](https://github.com/valkey-io/valkey-glide) client. Use it when your deployment runs Valkey or needs GLIDE features such as native Valkey configuration and authentication.
|
|
6
|
+
|
|
7
|
+
Use [`@mastra/redis`](https://mastra.ai/integrations/databases/redis) for Redis deployments that use the official `redis` client. The packages are tested independently against their respective servers.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
**npm**:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @mastra/valkey
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**pnpm**:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @mastra/valkey
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Yarn**:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add @mastra/valkey
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Bun**:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bun add @mastra/valkey
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Mastra } from '@mastra/core'
|
|
39
|
+
import { ValkeyStore } from '@mastra/valkey'
|
|
40
|
+
|
|
41
|
+
export const mastra = new Mastra({
|
|
42
|
+
storage: new ValkeyStore({
|
|
43
|
+
id: 'valkey-storage',
|
|
44
|
+
host: 'localhost',
|
|
45
|
+
port: 6379,
|
|
46
|
+
password: process.env.VALKEY_PASSWORD,
|
|
47
|
+
}),
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
You can also provide a native GLIDE configuration:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { ValkeyStore } from '@mastra/valkey'
|
|
55
|
+
|
|
56
|
+
const storage = new ValkeyStore({
|
|
57
|
+
id: 'valkey-storage',
|
|
58
|
+
config: {
|
|
59
|
+
addresses: [{ host: 'localhost', port: 6379 }],
|
|
60
|
+
useTLS: true,
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For an existing `GlideClient`, connect it before passing it to `ValkeyStore`. The caller remains responsible for closing injected clients.
|
|
66
|
+
|
|
67
|
+
## Constructor parameters
|
|
68
|
+
|
|
69
|
+
**id** (`string`): Unique identifier for the storage instance.
|
|
70
|
+
|
|
71
|
+
**host** (`string`): Valkey host address. Use with the direct connection fields.
|
|
72
|
+
|
|
73
|
+
**port** (`number`): Valkey port. (Default: `6379`)
|
|
74
|
+
|
|
75
|
+
**username** (`string`): Valkey authentication username. (Default: `default`)
|
|
76
|
+
|
|
77
|
+
**password** (`string`): Valkey authentication password.
|
|
78
|
+
|
|
79
|
+
**db** (`number`): Valkey database number. (Default: `0`)
|
|
80
|
+
|
|
81
|
+
**useTLS** (`boolean`): Enables TLS for direct connections.
|
|
82
|
+
|
|
83
|
+
**config** (`GlideClientConfiguration`): Native GLIDE standalone client configuration.
|
|
84
|
+
|
|
85
|
+
**client** (`GlideClient`): Preconfigured GLIDE standalone client.
|
|
86
|
+
|
|
87
|
+
**disableInit** (`boolean`): Disables automatic storage initialization.
|
|
88
|
+
|
|
89
|
+
Provide exactly one connection form: `client`, `config`, or `host` with its optional direct connection fields.
|
|
90
|
+
|
|
91
|
+
## Closing connections
|
|
92
|
+
|
|
93
|
+
Close clients created by `ValkeyStore` during graceful shutdown:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
await storage.close()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`close()` doesn't close an injected `GlideClient`.
|
|
@@ -12,7 +12,7 @@ Choose the deployment path that fits your application:
|
|
|
12
12
|
|
|
13
13
|
This guide builds an editorial pipeline that reviews a draft from three perspectives in parallel, then passes the feedback to an editor agent. Use the links above if you want to deploy a Mastra API or execute an entire Mastra workflow as one task.
|
|
14
14
|
|
|
15
|
-
## How Render Workflows
|
|
15
|
+
## How Render Workflows integrate with Mastra
|
|
16
16
|
|
|
17
17
|
Mastra supplies the agents and application logic, while Render Workflows defines the execution boundaries. A typical pipeline has three layers:
|
|
18
18
|
|
|
@@ -93,8 +93,6 @@ yarn add @renderinc/sdk tsx
|
|
|
93
93
|
bun add @renderinc/sdk tsx
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
> **Note:** Render Workflows requires `@renderinc/sdk@^0.5.0` or later.
|
|
97
|
-
|
|
98
96
|
Set the API key for your model provider. This example uses OpenAI:
|
|
99
97
|
|
|
100
98
|
```text
|
|
@@ -103,9 +101,9 @@ OPENAI_API_KEY=your_openai_api_key
|
|
|
103
101
|
|
|
104
102
|
Any supported [Mastra model provider](https://mastra.ai/models) works.
|
|
105
103
|
|
|
106
|
-
##
|
|
104
|
+
## Build a distributed agent pipeline
|
|
107
105
|
|
|
108
|
-
###
|
|
106
|
+
### Create the agents
|
|
109
107
|
|
|
110
108
|
In `src/mastra`, create an `agents` directory with `reviewer-agent.ts` and `editor-agent.ts`. Define both agents:
|
|
111
109
|
|
|
@@ -139,7 +137,7 @@ export const editorAgent = new Agent({
|
|
|
139
137
|
})
|
|
140
138
|
```
|
|
141
139
|
|
|
142
|
-
###
|
|
140
|
+
### Configure the Mastra instance
|
|
143
141
|
|
|
144
142
|
Add both agents to the Mastra instance in `src/mastra/index.ts`:
|
|
145
143
|
|
|
@@ -158,7 +156,7 @@ export const mastra = new Mastra({
|
|
|
158
156
|
|
|
159
157
|
Retrieving agents from the Mastra instance gives them access to shared application services such as logging, storage, and observability.
|
|
160
158
|
|
|
161
|
-
###
|
|
159
|
+
### Create the review task
|
|
162
160
|
|
|
163
161
|
In `src`, create a `tasks` directory. The reviewer agent handles one area of focus. Its compute plan, five-minute timeout, and retry policy apply only to that analysis. A temporary model-provider failure can trigger another attempt without restarting the other reviewers.
|
|
164
162
|
|
|
@@ -199,7 +197,7 @@ export const reviewDraft = task(
|
|
|
199
197
|
)
|
|
200
198
|
```
|
|
201
199
|
|
|
202
|
-
###
|
|
200
|
+
### Create the revision task
|
|
203
201
|
|
|
204
202
|
This task combines the feedback and produces a revised draft. It uses a larger compute plan and a longer timeout than each reviewer.
|
|
205
203
|
|
|
@@ -240,7 +238,7 @@ export const reviseDraft = task(
|
|
|
240
238
|
)
|
|
241
239
|
```
|
|
242
240
|
|
|
243
|
-
###
|
|
241
|
+
### Create the orchestration task
|
|
244
242
|
|
|
245
243
|
The parent dispatches three reviews in parallel with `Promise.all()`, then sends their combined feedback to the revision step. Retries are disabled at this level because each child defines its own policy. If you enable orchestration retries, ensure that another attempt cannot duplicate external side effects or other non-idempotent work.
|
|
246
244
|
|
|
@@ -268,7 +266,7 @@ export const editorialPipeline = task(
|
|
|
268
266
|
)
|
|
269
267
|
```
|
|
270
268
|
|
|
271
|
-
###
|
|
269
|
+
### Register the tasks
|
|
272
270
|
|
|
273
271
|
Create `src/index.ts` and import the editorial task:
|
|
274
272
|
|
|
@@ -278,7 +276,7 @@ import './tasks/editorial-task.js'
|
|
|
278
276
|
|
|
279
277
|
Running the entry point loads the module and registers every task defined with `task()`.
|
|
280
278
|
|
|
281
|
-
|
|
279
|
+
Change your `tsconfig.json`:
|
|
282
280
|
|
|
283
281
|
```json
|
|
284
282
|
{
|
|
@@ -292,7 +290,7 @@ Running the entry point loads the module and registers every task defined with `
|
|
|
292
290
|
}
|
|
293
291
|
```
|
|
294
292
|
|
|
295
|
-
Add these scripts
|
|
293
|
+
Add these scripts to `package.json`:
|
|
296
294
|
|
|
297
295
|
```json
|
|
298
296
|
{
|
|
@@ -304,13 +302,11 @@ Add these scripts next to the ones `create mastra` already added. `create mastra
|
|
|
304
302
|
}
|
|
305
303
|
```
|
|
306
304
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
Those files are the complete pipeline. [render-examples/render-workflows-mastra](https://github.com/render-examples/render-workflows-mastra) mirrors this `src/` layout and adds a web UI that starts the parent task. Its agents use the provider-specific model ID `openai/gpt-5.6-sol`. In this page's source, that value is represented by a documentation token that is replaced during the docs build. Clone it to skip copying the snippets before you run it.
|
|
305
|
+
Those files are the complete pipeline. [render-examples/render-workflows-mastra](https://github.com/render-examples/render-workflows-mastra) mirrors this `src/` layout and adds a web UI that starts the parent task.
|
|
310
306
|
|
|
311
|
-
##
|
|
307
|
+
## Run the pipeline
|
|
312
308
|
|
|
313
|
-
###
|
|
309
|
+
### Local
|
|
314
310
|
|
|
315
311
|
Start the local Render Workflows development server:
|
|
316
312
|
|
|
@@ -334,56 +330,56 @@ render workflows tasks start editorial_pipeline \
|
|
|
334
330
|
|
|
335
331
|
The local server keeps runs and their logs in memory, so you can inspect them after they finish with `render workflows runs list <task-name> --local`.
|
|
336
332
|
|
|
337
|
-
###
|
|
333
|
+
### Production
|
|
338
334
|
|
|
339
335
|
Running the pipeline on Render requires a _workflow service_. This is the Render service that holds your task definitions: it builds your repository, registers every task it finds, and provisions an instance for each run.
|
|
340
336
|
|
|
341
|
-
|
|
337
|
+
1. #### Push the project to a Git repository
|
|
342
338
|
|
|
343
|
-
Render builds workflow services from a repository on GitHub, GitLab, or Bitbucket, so push your project to one of those providers. The first time you use a provider, Render asks for permission to access your repositories.
|
|
339
|
+
Render builds workflow services from a repository on GitHub, GitLab, or Bitbucket, so push your project to one of those providers. The first time you use a provider, Render asks for permission to access your repositories.
|
|
344
340
|
|
|
345
|
-
|
|
341
|
+
2. #### Create the workflow service
|
|
346
342
|
|
|
347
|
-
In the [Render Dashboard](https://dashboard.render.com), click **New > Workflow** and link the repository from the previous step. Then complete the creation form:
|
|
343
|
+
In the [Render Dashboard](https://dashboard.render.com), click **New > Workflow** and link the repository from the previous step. Then complete the creation form:
|
|
348
344
|
|
|
349
|
-
| Field | Value |
|
|
350
|
-
| ----------------- | ------------------------------------------------------------- |
|
|
351
|
-
| **Language** | Node |
|
|
352
|
-
| **Region** | The region of any other Render services your tasks connect to |
|
|
353
|
-
| **Build Command** | `npm install && npm run build` |
|
|
354
|
-
| **Start Command** | `npm run start:workflows` |
|
|
345
|
+
| Field | Value |
|
|
346
|
+
| ----------------- | ------------------------------------------------------------- |
|
|
347
|
+
| **Language** | Node |
|
|
348
|
+
| **Region** | The region of any other Render services your tasks connect to |
|
|
349
|
+
| **Build Command** | `npm install && npm run build` |
|
|
350
|
+
| **Start Command** | `npm run start:workflows` |
|
|
355
351
|
|
|
356
|
-
Click **Deploy Workflow**. Render builds the project and registers `review_draft`, `revise_draft`, and `editorial_pipeline`, which then appear on the workflow's **Tasks** page.
|
|
352
|
+
Click **Deploy Workflow**. Render builds the project and registers `review_draft`, `revise_draft`, and `editorial_pipeline`, which then appear on the workflow's **Tasks** page.
|
|
357
353
|
|
|
358
|
-
The Render CLI creates the same service without leaving your terminal:
|
|
354
|
+
The Render CLI creates the same service without leaving your terminal:
|
|
359
355
|
|
|
360
|
-
```bash
|
|
361
|
-
render workflows create \
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
```
|
|
356
|
+
```bash
|
|
357
|
+
render workflows create \
|
|
358
|
+
--name mastra-workflows \
|
|
359
|
+
--repo . \
|
|
360
|
+
--runtime node \
|
|
361
|
+
--build-command "npm install && npm run build" \
|
|
362
|
+
--run-command "npm run start:workflows"
|
|
363
|
+
```
|
|
368
364
|
|
|
369
|
-
`--repo .` reads the `origin` remote of your local repository, so the project must already be pushed.
|
|
365
|
+
`--repo .` reads the `origin` remote of your local repository, so the project must already be pushed.
|
|
370
366
|
|
|
371
|
-
|
|
367
|
+
3. #### Set the workflow's environment variables
|
|
372
368
|
|
|
373
|
-
Add `OPENAI_API_KEY`, or the key for your chosen model provider, to the workflow service in the Dashboard before the first run.
|
|
369
|
+
Add `OPENAI_API_KEY`, or the key for your chosen model provider, to the workflow service in the Dashboard before the first run.
|
|
374
370
|
|
|
375
|
-
|
|
371
|
+
4. #### Start a run
|
|
376
372
|
|
|
377
|
-
```bash
|
|
378
|
-
render workflows tasks start mastra-workflows/editorial_pipeline \
|
|
379
|
-
|
|
380
|
-
```
|
|
373
|
+
```bash
|
|
374
|
+
render workflows tasks start mastra-workflows/editorial_pipeline \
|
|
375
|
+
--input='["Render Workflows runs long-running tasks outside the request lifecycle."]'
|
|
376
|
+
```
|
|
381
377
|
|
|
382
|
-
The first part of that identifier is your workflow's slug and the second is the task name. Both appear on the task's page in the Render Dashboard, so use the slug shown there if your workflow has a different name.
|
|
378
|
+
The first part of that identifier is your workflow's slug and the second is the task name. Both appear on the task's page in the Render Dashboard, so use the slug shown there if your workflow has a different name.
|
|
383
379
|
|
|
384
|
-
Open the workflow in the Render Dashboard to inspect each task run, attempt, result, and log stream.
|
|
380
|
+
Open the workflow in the Render Dashboard to inspect each task run, attempt, result, and log stream.
|
|
385
381
|
|
|
386
|
-
##
|
|
382
|
+
## Trigger from your application
|
|
387
383
|
|
|
388
384
|
You can trigger the pipeline asynchronously from a Mastra application, web service, or script with the Render SDK.
|
|
389
385
|
|
|
@@ -415,17 +411,6 @@ The task continues running after `startTask()` returns. Call `await run.get()` w
|
|
|
415
411
|
|
|
416
412
|
Returning the task run ID from a request handler lets the application respond without keeping the request open for the full pipeline.
|
|
417
413
|
|
|
418
|
-
## Constraints
|
|
419
|
-
|
|
420
|
-
These limits live in Render's docs and can change. Prefer those pages over this list:
|
|
421
|
-
|
|
422
|
-
- Task arguments and return values must be JSON serializable. Arguments to a single run cannot exceed 4 MB. See [defining tasks](https://render.com/docs/workflows-defining#task-arguments) and [Workflows limits](https://render.com/docs/workflows-limits).
|
|
423
|
-
- A task can run for up to 24 hours. The default timeout is two hours. See [timeouts](https://render.com/docs/workflows-defining#timeout).
|
|
424
|
-
- A workflow service can register up to 500 task definitions. See [Workflows limits](https://render.com/docs/workflows-limits).
|
|
425
|
-
- Render Workflows currently supports TypeScript and Python task definitions. See [defining tasks](https://render.com/docs/workflows-defining).
|
|
426
|
-
|
|
427
|
-
To run the pipeline on a schedule, create a [Render cron job](https://render.com/docs/cronjobs) whose command calls `render workflows tasks start` or `startTask()`.
|
|
428
|
-
|
|
429
414
|
## Related
|
|
430
415
|
|
|
431
416
|
- [Live demo](https://render-workflows-mastra.onrender.com)
|
|
@@ -433,4 +418,5 @@ To run the pipeline on a schedule, create a [Render cron job](https://render.com
|
|
|
433
418
|
- [Defining Render workflow tasks](https://render.com/docs/workflows-defining)
|
|
434
419
|
- [Triggering task runs](https://render.com/docs/workflows-running)
|
|
435
420
|
- [Render Workflows TypeScript SDK](https://render.com/docs/workflows-sdk-typescript)
|
|
436
|
-
- [Render Workflows limits and pricing](https://render.com/docs/workflows-limits)
|
|
421
|
+
- [Render Workflows limits and pricing](https://render.com/docs/workflows-limits)
|
|
422
|
+
- [Render cron jobs](https://render.com/docs/cronjobs)
|