@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.
Files changed (69) hide show
  1. package/.docs/docs/deployment/mastra-server.md +19 -0
  2. package/.docs/docs/deployment/workers.md +2 -2
  3. package/.docs/docs/evals/built-in-scorers.md +1 -0
  4. package/.docs/docs/evals/multi-turn.md +84 -1
  5. package/.docs/docs/evals/overview.md +63 -1
  6. package/.docs/docs/harness/durable-agents.md +1 -1
  7. package/.docs/docs/mastra-platform/deploy.md +101 -0
  8. package/.docs/docs/mastra-platform/server.md +6 -11
  9. package/.docs/docs/mastra-platform/studio.md +8 -10
  10. package/.docs/docs/observability/integrations/exporters/mastra-storage.md +19 -14
  11. package/.docs/docs/sandbox/filesystem.md +8 -8
  12. package/.docs/docs/sandbox/overview.md +33 -66
  13. package/.docs/docs/server/middleware.md +4 -0
  14. package/.docs/docs/server/server-adapters.md +12 -8
  15. package/.docs/docs/storage.md +1 -0
  16. package/.docs/integrations/databases/mongodb.md +1 -1
  17. package/.docs/integrations/databases/postgresql.md +2 -0
  18. package/.docs/integrations/databases/valkey.md +99 -0
  19. package/.docs/integrations/deploy/render.md +47 -61
  20. package/.docs/integrations/sandboxes/e2b.md +2 -0
  21. package/.docs/integrations/tools/parallel.md +240 -0
  22. package/.docs/integrations.md +2 -0
  23. package/.docs/models/environment-variables.md +2 -0
  24. package/.docs/models/gateways/merge-gateway.md +2 -1
  25. package/.docs/models/gateways/netlify.md +9 -5
  26. package/.docs/models/gateways/openrouter.md +8 -9
  27. package/.docs/models/gateways/vercel.md +7 -1
  28. package/.docs/models/index.md +1 -1
  29. package/.docs/models/providers/agentrouter.md +17 -34
  30. package/.docs/models/providers/aki-io.md +14 -13
  31. package/.docs/models/providers/chutes.md +2 -2
  32. package/.docs/models/providers/crof.md +3 -8
  33. package/.docs/models/providers/crossmodel.md +56 -55
  34. package/.docs/models/providers/deepseek.md +8 -7
  35. package/.docs/models/providers/digitalocean.md +8 -8
  36. package/.docs/models/providers/edenai.md +14 -14
  37. package/.docs/models/providers/google.md +3 -3
  38. package/.docs/models/providers/hyper.md +5 -5
  39. package/.docs/models/providers/inceptron.md +1 -1
  40. package/.docs/models/providers/kilo.md +24 -20
  41. package/.docs/models/providers/llmgateway-providers.md +11 -8
  42. package/.docs/models/providers/llmgateway.md +3 -5
  43. package/.docs/models/providers/nano-gpt.md +12 -6
  44. package/.docs/models/providers/nvidia.md +3 -1
  45. package/.docs/models/providers/ofox.md +114 -110
  46. package/.docs/models/providers/opencode-go.md +26 -23
  47. package/.docs/models/providers/opencode.md +1 -1
  48. package/.docs/models/providers/opper.md +112 -0
  49. package/.docs/models/providers/requesty.md +1 -1
  50. package/.docs/models/providers/scaleway.md +2 -1
  51. package/.docs/models/providers.md +2 -0
  52. package/.docs/reference/ai-sdk/handle-chat-stream.md +11 -0
  53. package/.docs/reference/ai-sdk/with-sse-heartbeat.md +47 -0
  54. package/.docs/reference/core/mastra-class.md +1 -1
  55. package/.docs/reference/evals/checks.md +6 -0
  56. package/.docs/reference/evals/multi-turn-judge.md +101 -0
  57. package/.docs/reference/index.md +4 -0
  58. package/.docs/reference/pubsub/valkey-streams.md +84 -0
  59. package/.docs/reference/rag/vector-databases.md +4 -4
  60. package/.docs/reference/server/express-adapter.md +6 -8
  61. package/.docs/reference/server/hono-adapter.md +19 -6
  62. package/.docs/reference/storage/turso.md +88 -0
  63. package/.docs/reference/streaming/ChunkType.md +29 -1
  64. package/.docs/reference/tools/mcp-client.md +41 -9
  65. package/.docs/reference/vectors/mongodb.md +11 -11
  66. package/.docs/reference/vectors/pg.md +2 -0
  67. package/.docs/reference/workspace/workspace-class.md +15 -3
  68. package/CHANGELOG.md +59 -0
  69. 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. Sandboxes can isolate potentially risky agent-run code from your host, and they can also provide a place to run longer-lived or more resource-intensive work outside your application process.
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
- [Filesystems](https://mastra.ai/docs/sandbox/filesystem) give the agent files it can read, write, and [search](https://mastra.ai/docs/sandbox/search). They can provide a knowledge base for your agent, or be shared with a sandbox so commands can work with the same files and keep data beyond the sandbox's lifetime.
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
- Sandboxes work well for:
11
+ Use a sandbox when an agent needs to:
12
12
 
13
- - **Coding agents and software factories**: Clone repositories and run shell, Git, build, or test workflows without giving autonomous agents access to the host system.
14
- - **Deep research and analysis**: Use specialized libraries to process downloaded PDFs or presentations and produce new artifacts.
15
- - **Long-running and parallel tasks**: Run work in separate environments without tying it to one request or sharing files and processes.
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 and filesystem:
21
+ Give an agent a local sandbox:
22
22
 
23
23
  ```typescript
24
24
  import { Agent } from '@mastra/core/agent'
25
- import { LocalFilesystem, LocalSandbox, Workspace } from '@mastra/core/workspace'
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` is the quickest sandbox to set up, but commands run on the host by default. Enable [native isolation](#localsandbox) whenever possible. For applications exposed to untrusted users, use a remote or container backend with a stronger isolation boundary instead.
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
- The `LocalSandbox` above is one static instance. Every request and memory thread that uses `codingAgent` shares its files, processes, and lifecycle state. A memory thread doesn't create an isolated sandbox by itself.
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
- Omitting a tool entry keeps its capability-driven default. 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.
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
- ## Supported backends
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
- Use `LocalSandbox.detectIsolation()` to check whether Seatbelt or Bubblewrap is available on the current operating system. 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.
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
- ### Other backends
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
- Use a remote or container backend when commands need a stronger boundary from the host application or when workloads need to scale beyond the resources of your application server. Each backend has its own isolation, persistence, networking, and mount behavior:
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 execution backend, implement the [sandbox provider interface](https://mastra.ai/reference/workspace/sandbox) to add it.
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
- Each sandbox has a native filesystem that commands can use. Treat it as ephemeral because its contents follow the sandbox's lifecycle.
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
- To seed a sandbox with files or keep files between runs, give the agent a [filesystem](https://mastra.ai/docs/sandbox/filesystem). Use mounts when sandbox commands need access to the same files.
152
+ See [Filesystem](https://mastra.ai/docs/sandbox/filesystem) for providers, file tools, and mounts.
159
153
 
160
- ## Multi-tenant sandboxes
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 sandbox = new DaytonaSandbox({ id: `user-${getUserId(requestContext)}` })
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 }) => getUserId(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 the 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`:
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
- const threadId = requestContext.get(MASTRA_THREAD_ID_KEY)
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
- ### Resolver ownership
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](#multi-tenant-sandboxes), 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`.
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 [Multi-tenant sandboxes](#multi-tenant-sandboxes).
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 three steps in order. Understanding this flow helps when you need to insert your own middleware at specific points.
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. `registerRoutes()`: Registers all Mastra API routes for agents, workflows, and other features. Also registers MCP routes if MCP servers are configured.
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
 
@@ -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 Atlas Search enabled. MongoDB 7.0+ is recommended.
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 works with Mastra
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
- ## Building a distributed agent pipeline
104
+ ## Build a distributed agent pipeline
107
105
 
108
- ### Creating the agents
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
- ### Configuring the Mastra instance
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
- ### Creating the review task
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
- ### Creating the revision task
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
- ### Creating the orchestration task
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
- ### Registering the tasks
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
- `create mastra` already wrote `tsconfig.json` and `package.json`. Keep those files. For the workflow start command, `tsc` must emit JavaScript into `dist`, so set these compiler options (do not leave `noEmit: true`):
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 next to the ones `create mastra` already added. `create mastra` already sets `"type": "module"`:
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
- Relative imports in the examples above end in `.js` because Node resolves the compiled output as ES modules. Keep those extensions so the built entry point resolves its imports.
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
- ## Running the pipeline
307
+ ## Run the pipeline
312
308
 
313
- ### Running locally
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
- ### Running in production
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
- #### 1. Push the project to a Git repository
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
- #### 2. Create the workflow service
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
- --name mastra-workflows \
363
- --repo . \
364
- --runtime node \
365
- --build-command "npm install && npm run build" \
366
- --run-command "npm run start:workflows"
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
- #### 3. Set the workflow's environment variables
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
- #### 4. Start a run
371
+ 4. #### Start a run
376
372
 
377
- ```bash
378
- render workflows tasks start mastra-workflows/editorial_pipeline \
379
- --input='["Render Workflows runs long-running tasks outside the request lifecycle."]'
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
- ## Triggering from your application
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)