@mastra/mcp-docs-server 1.2.19-alpha.0 → 1.2.19-alpha.14

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 (76) hide show
  1. package/.docs/docs/channels.md +1 -0
  2. package/.docs/docs/deployment/mastra-server.md +19 -0
  3. package/.docs/docs/deployment/workers.md +2 -2
  4. package/.docs/docs/evals/built-in-scorers.md +1 -0
  5. package/.docs/docs/evals/multi-turn.md +84 -1
  6. package/.docs/docs/evals/overview.md +63 -1
  7. package/.docs/docs/harness/durable-agents.md +1 -1
  8. package/.docs/docs/mastra-platform/deploy.md +101 -0
  9. package/.docs/docs/mastra-platform/server.md +6 -11
  10. package/.docs/docs/mastra-platform/studio.md +8 -10
  11. package/.docs/docs/observability/integrations/exporters/mastra-storage.md +19 -14
  12. package/.docs/docs/sandbox/filesystem.md +8 -8
  13. package/.docs/docs/sandbox/overview.md +33 -66
  14. package/.docs/docs/server/middleware.md +4 -0
  15. package/.docs/docs/server/server-adapters.md +12 -8
  16. package/.docs/docs/storage.md +2 -0
  17. package/.docs/integrations/channels/imessage.md +150 -8
  18. package/.docs/integrations/databases/elasticsearch.md +156 -0
  19. package/.docs/integrations/databases/libsql.md +16 -0
  20. package/.docs/integrations/databases/mongodb.md +1 -1
  21. package/.docs/integrations/databases/postgresql.md +26 -0
  22. package/.docs/integrations/databases/valkey.md +99 -0
  23. package/.docs/integrations/deploy/render.md +47 -61
  24. package/.docs/integrations/sandboxes/e2b.md +2 -0
  25. package/.docs/integrations/tools/parallel.md +240 -0
  26. package/.docs/integrations.md +3 -0
  27. package/.docs/models/environment-variables.md +2 -0
  28. package/.docs/models/gateways/merge-gateway.md +2 -1
  29. package/.docs/models/gateways/netlify.md +10 -5
  30. package/.docs/models/gateways/openrouter.md +8 -9
  31. package/.docs/models/gateways/vercel.md +7 -6
  32. package/.docs/models/index.md +1 -1
  33. package/.docs/models/providers/agentrouter.md +17 -34
  34. package/.docs/models/providers/aki-io.md +14 -13
  35. package/.docs/models/providers/chutes.md +2 -2
  36. package/.docs/models/providers/crof.md +3 -8
  37. package/.docs/models/providers/crossmodel.md +56 -55
  38. package/.docs/models/providers/deepseek.md +8 -7
  39. package/.docs/models/providers/digitalocean.md +11 -11
  40. package/.docs/models/providers/edenai.md +14 -14
  41. package/.docs/models/providers/google.md +3 -3
  42. package/.docs/models/providers/hyper.md +7 -7
  43. package/.docs/models/providers/inceptron.md +1 -1
  44. package/.docs/models/providers/kilo.md +24 -20
  45. package/.docs/models/providers/llmgateway-providers.md +17 -8
  46. package/.docs/models/providers/llmgateway.md +3 -5
  47. package/.docs/models/providers/nano-gpt.md +24 -13
  48. package/.docs/models/providers/nvidia.md +3 -1
  49. package/.docs/models/providers/ofox.md +114 -110
  50. package/.docs/models/providers/opencode-go.md +26 -23
  51. package/.docs/models/providers/opencode.md +1 -1
  52. package/.docs/models/providers/opper.md +112 -0
  53. package/.docs/models/providers/requesty.md +1 -1
  54. package/.docs/models/providers/scaleway.md +2 -1
  55. package/.docs/models/providers.md +2 -0
  56. package/.docs/reference/agents/channels.md +1 -1
  57. package/.docs/reference/ai-sdk/handle-chat-stream.md +11 -0
  58. package/.docs/reference/ai-sdk/with-sse-heartbeat.md +47 -0
  59. package/.docs/reference/core/mastra-class.md +1 -1
  60. package/.docs/reference/evals/checks.md +6 -0
  61. package/.docs/reference/evals/multi-turn-judge.md +101 -0
  62. package/.docs/reference/index.md +4 -0
  63. package/.docs/reference/pubsub/valkey-streams.md +84 -0
  64. package/.docs/reference/rag/vector-databases.md +4 -4
  65. package/.docs/reference/server/express-adapter.md +6 -8
  66. package/.docs/reference/server/hono-adapter.md +19 -6
  67. package/.docs/reference/storage/turso.md +88 -0
  68. package/.docs/reference/streaming/ChunkType.md +29 -1
  69. package/.docs/reference/streaming/agents/stream.md +1 -3
  70. package/.docs/reference/tools/mcp-client.md +41 -9
  71. package/.docs/reference/vectors/mongodb.md +11 -11
  72. package/.docs/reference/vectors/pg.md +2 -0
  73. package/.docs/reference/workspace/sandbox.md +29 -1
  74. package/.docs/reference/workspace/workspace-class.md +15 -3
  75. package/CHANGELOG.md +66 -0
  76. package/package.json +5 -5
@@ -79,7 +79,7 @@ Visit the [Configuration reference](https://mastra.ai/reference/configuration) f
79
79
 
80
80
  **bundler** (`BundlerConfig`): Configuration for the asset bundler with options for externals, sourcemap, transpilePackages, and dynamicPackages. (Default: `{ externals: [], sourcemap: false, transpilePackages: [], dynamicPackages: [] }`)
81
81
 
82
- **scorers** (`Record<string, Scorer>`): Scorers for evaluating agent responses and workflow outputs (Default: `{}`)
82
+ **scorers** (`Record<string, Scorer>`): Scorers for evaluating agent responses and workflow outputs. Registration also makes a scorer resolvable by ID, which is required to persist its scores. See Score persistence (Default: `{}`)
83
83
 
84
84
  **processors** (`Record<string, Processor>`): Input/output processors for transforming agent inputs and outputs (Default: `{}`)
85
85
 
@@ -6,6 +6,8 @@ Quick Checks are zero-LLM, composable micro-scorers for common assertions. They
6
6
 
7
7
  Internally they're standard `createScorer()` instances, so they have the same observability, storage, and pipeline integration as any other scorer.
8
8
 
9
+ > **Register checks to persist their scores:** A check's score is only written to the scores store when the check is registered on the Mastra instance, alongside `storage`. Each check has a fixed id (`checks.includes()` is `check-includes`, `checks.calledTool()` is `check-called-tool`, and so on), so one registered instance covers every use of that check regardless of its arguments. See [Score persistence](https://mastra.ai/docs/evals/overview).
10
+
9
11
  ## Usage example
10
12
 
11
13
  ```typescript
@@ -203,6 +205,10 @@ const result = await runEvals({
203
205
  })
204
206
  ```
205
207
 
208
+ ## Multi-turn behavior
209
+
210
+ Checks read the accumulated `run.output`, so in a [multi-turn eval](https://mastra.ai/docs/evals/multi-turn) they see every turn. `checks.calledTool('get_weather', { times: 2 })` counts calls across the whole conversation, and `checks.includes()` searches all assistant text. Use per-turn `turns[].scorers` when a specific turn has to satisfy the check.
211
+
206
212
  ## Related
207
213
 
208
214
  - [Quick Checks overview](https://mastra.ai/docs/evals/quick-checks)
@@ -0,0 +1,101 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # Multi-turn Judge scorer
4
+
5
+ **Added in:** `@mastra/evals@1.9.0`
6
+
7
+ The `createMultiTurnJudgeScorer()` function creates an LLM-as-judge scorer that grades a whole conversation against a single plain-English criterion. It returns a **binary** score: `1` when the criterion is satisfied, otherwise `0`, and the `reason` echoes the criterion with the judge's explanation.
8
+
9
+ Unlike the other prebuilt LLM judges, which read a single assistant message, this scorer reads every assistant turn accumulated in `run.output`, so it works with the [multi-turn `inputs`](https://mastra.ai/docs/evals/multi-turn) form of [`runEvals()`](https://mastra.ai/reference/evals/run-evals).
10
+
11
+ ## Parameters
12
+
13
+ **model** (`MastraModelConfig`): The language model used to grade the conversation. A smaller, cheaper model is usually sufficient for grading.
14
+
15
+ **criterion** (`string`): What the conversation must satisfy, in plain English, e.g. "The agent gave forecasts for London and Paris, and weather-appropriate packing advice".
16
+
17
+ **options** (`MultiTurnJudgeScorerOptions`): Configuration options for the scorer
18
+
19
+ ## `.run()` returns
20
+
21
+ **score** (`number`): 1 when the judge considers the criterion satisfied, otherwise 0 (multiplied by scale).
22
+
23
+ **reason** (`string`): The verdict, the criterion it graded, and the judge's explanation of why the criterion is or is not satisfied.
24
+
25
+ ## Usage with multi-turn evals
26
+
27
+ Pass the scorer to `runEvals` alongside an `inputs` array. Every assistant turn is included in the prompt sent to the judge:
28
+
29
+ ```typescript
30
+ import { runEvals } from '@mastra/core/evals'
31
+ import { createMultiTurnJudgeScorer } from '@mastra/evals/scorers/prebuilt'
32
+ import { weatherAgent } from '../agents'
33
+
34
+ const result = await runEvals({
35
+ data: [
36
+ {
37
+ inputs: [
38
+ "I'm planning a trip to London, Paris, and Tokyo next week.",
39
+ "How's the weather looking in London?",
40
+ 'And Paris?',
41
+ 'Tokyo too?',
42
+ 'Should I pack an umbrella for the London leg?',
43
+ ],
44
+ },
45
+ ],
46
+ target: weatherAgent,
47
+ scorers: [
48
+ {
49
+ scorer: createMultiTurnJudgeScorer({
50
+ model: 'anthropic/claude-haiku-4-5',
51
+ criterion:
52
+ 'The agent provided weather forecasts for London, Paris, and Tokyo, and gave weather-appropriate packing or clothing advice.',
53
+ }),
54
+ threshold: 1,
55
+ },
56
+ ],
57
+ })
58
+ ```
59
+
60
+ Use `threshold: 1` to turn the verdict into a pass or fail: the score is binary, so any lower threshold always passes.
61
+
62
+ ## Persisting scores
63
+
64
+ Scores are only written to the scores store when a scorer with the same ID is registered on the Mastra instance, because persistence resolves scorer metadata through `Mastra.getScorerById()`. Only the ID is looked up, so the registered instance's `criterion` can be a placeholder:
65
+
66
+ ```typescript
67
+ import { Mastra } from '@mastra/core'
68
+ import { LibSQLStore } from '@mastra/libsql'
69
+ import { createMultiTurnJudgeScorer } from '@mastra/evals/scorers/prebuilt'
70
+
71
+ export const mastra = new Mastra({
72
+ agents: { weatherAgent },
73
+ storage: new LibSQLStore({ url: 'file:./mastra.db' }),
74
+ scorers: {
75
+ 'multi-turn-judge-scorer': createMultiTurnJudgeScorer({
76
+ model: 'anthropic/claude-haiku-4-5',
77
+ criterion: 'placeholder',
78
+ }),
79
+ },
80
+ })
81
+ ```
82
+
83
+ See [Score persistence](https://mastra.ai/docs/evals/overview) for the full requirement and the warning you get when a scorer isn't registered.
84
+
85
+ ## Scoring details
86
+
87
+ The scorer runs in two phases:
88
+
89
+ 1. **Grade**: Every assistant message in `run.output` is collected in order and rendered as a numbered transcript, then the judge decides whether the conversation as a whole satisfies the criterion. Assistant messages with no text (a turn that only carried tool calls, for example) are skipped.
90
+ 2. **Score**: A `satisfied` verdict scores `1` and anything else scores `0`, multiplied by `scale`.
91
+
92
+ The judge only sees what the assistant said. The user's turns and any tool results aren't included, so write criteria in terms of the agent's responses. This keeps the graded text limited to the agent's own output, but it also means a reply that only makes sense next to the question that prompted it ("Yes, bring one.") can't be judged on its own. For criteria that depend on the user's turns, grade each turn with `turns[].scorers` or write a [custom scorer](https://mastra.ai/docs/evals/multi-turn) that renders both roles.
93
+
94
+ The transcript is passed to the judge as untrusted data, fenced with explicit delimiters and an instruction to ignore anything inside it that reads as an instruction, so an agent response can't talk its way into a passing verdict.
95
+
96
+ ## Related
97
+
98
+ - [Multi-turn evals](https://mastra.ai/docs/evals/multi-turn)
99
+ - [`runEvals()`](https://mastra.ai/reference/evals/run-evals)
100
+ - [Rubric scorer](https://mastra.ai/reference/evals/rubric)
101
+ - [createScorer](https://mastra.ai/reference/evals/create-scorer)
@@ -45,6 +45,7 @@ The Reference section provides documentation of Mastra's API, including paramete
45
45
  - [toAISdkV4Messages()](https://mastra.ai/reference/ai-sdk/to-ai-sdk-v4-messages)
46
46
  - [toAISdkV5Messages()](https://mastra.ai/reference/ai-sdk/to-ai-sdk-v5-messages)
47
47
  - [withMastra()](https://mastra.ai/reference/ai-sdk/with-mastra)
48
+ - [withSseHeartbeat()](https://mastra.ai/reference/ai-sdk/with-sse-heartbeat)
48
49
  - [workflowRoute()](https://mastra.ai/reference/ai-sdk/workflow-route)
49
50
  - [workflowSnapshotToStream()](https://mastra.ai/reference/ai-sdk/workflow-snapshot-to-stream)
50
51
  - [Auth0](https://mastra.ai/reference/auth/auth0)
@@ -152,6 +153,7 @@ The Reference section provides documentation of Mastra's API, including paramete
152
153
  - [Faithfulness](https://mastra.ai/reference/evals/faithfulness)
153
154
  - [Hallucination](https://mastra.ai/reference/evals/hallucination)
154
155
  - [Keyword Coverage Scorer](https://mastra.ai/reference/evals/keyword-coverage)
156
+ - [Multi-turn Judge Scorer](https://mastra.ai/reference/evals/multi-turn-judge)
155
157
  - [Noise Sensitivity Scorer](https://mastra.ai/reference/evals/noise-sensitivity)
156
158
  - [Prompt Alignment Scorer](https://mastra.ai/reference/evals/prompt-alignment)
157
159
  - [Rubric Scorer](https://mastra.ai/reference/evals/rubric)
@@ -276,6 +278,7 @@ The Reference section provides documentation of Mastra's API, including paramete
276
278
  - [PubSub](https://mastra.ai/reference/pubsub/base)
277
279
  - [RedisStreamsPubSub](https://mastra.ai/reference/pubsub/redis-streams)
278
280
  - [UnixSocketPubSub](https://mastra.ai/reference/pubsub/unix-socket-pubsub)
281
+ - [ValkeyStreamsPubSub](https://mastra.ai/reference/pubsub/valkey-streams)
279
282
  - [Overview](https://mastra.ai/reference/rag/overview)
280
283
  - [Chunking and Embedding](https://mastra.ai/reference/rag/chunking-and-embedding)
281
284
  - [DatabaseConfig](https://mastra.ai/reference/rag/database-config)
@@ -307,6 +310,7 @@ The Reference section provides documentation of Mastra's API, including paramete
307
310
  - [Overview](https://mastra.ai/reference/storage/overview)
308
311
  - [Composite Storage](https://mastra.ai/reference/storage/composite)
309
312
  - [Retention (prune)](https://mastra.ai/reference/storage/retention)
313
+ - [Turso Storage](https://mastra.ai/reference/storage/turso)
310
314
  - [ChunkType](https://mastra.ai/reference/streaming/ChunkType)
311
315
  - [smoothStream()](https://mastra.ai/reference/streaming/smoothStream)
312
316
  - [MastraModelOutput](https://mastra.ai/reference/streaming/agents/MastraModelOutput)
@@ -0,0 +1,84 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # ValkeyStreamsPubSub
4
+
5
+ `ValkeyStreamsPubSub` is a [`PubSub`](https://mastra.ai/reference/pubsub/base) and [`LeaseProvider`](https://mastra.ai/reference/pubsub/lease-provider) implementation backed by Valkey Streams through [Valkey GLIDE](https://github.com/valkey-io/valkey-glide). It provides persistent cross-process delivery, consumer groups, redelivery, topic cleanup, and distributed leasing.
6
+
7
+ Use it for Valkey deployments. Use [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) for Redis deployments that use the official `redis` client. Both integrations implement the same Mastra behavior, with independent tests running against Valkey and Redis.
8
+
9
+ ## Installation
10
+
11
+ **npm**:
12
+
13
+ ```bash
14
+ npm install @mastra/valkey-streams
15
+ ```
16
+
17
+ **pnpm**:
18
+
19
+ ```bash
20
+ pnpm add @mastra/valkey-streams
21
+ ```
22
+
23
+ **Yarn**:
24
+
25
+ ```bash
26
+ yarn add @mastra/valkey-streams
27
+ ```
28
+
29
+ **Bun**:
30
+
31
+ ```bash
32
+ bun add @mastra/valkey-streams
33
+ ```
34
+
35
+ ## Usage example
36
+
37
+ ```typescript
38
+ import { Mastra } from '@mastra/core'
39
+ import { ValkeyStreamsPubSub } from '@mastra/valkey-streams'
40
+
41
+ export const mastra = new Mastra({
42
+ pubsub: new ValkeyStreamsPubSub({
43
+ url: 'valkey://localhost:6379',
44
+ }),
45
+ })
46
+ ```
47
+
48
+ ## Constructor parameters
49
+
50
+ **url** (`string`): Valkey connection URL. Falls back to valkeyOptions.url. (Default: `valkey://localhost:6379`)
51
+
52
+ **valkeyOptions** (`ValkeyClientOptions`): GLIDE connection options, including native client configuration.
53
+
54
+ **keyPrefix** (`string`): Prefix for stream keys. (Default: `mastra:topic`)
55
+
56
+ **blockMs** (`number`): How long each read blocks while waiting for events. (Default: `1000`)
57
+
58
+ **maxStreamLength** (`number`): Approximate maximum entries retained per stream. Set to 0 to disable trimming. (Default: `10000`)
59
+
60
+ **streamIdleTtlMs** (`number`): Sliding idle expiry refreshed on stream writes. Set to 0 to disable. (Default: `0`)
61
+
62
+ **reclaimIntervalMs** (`number`): Interval for reclaiming unacknowledged events. Set to 0 to disable. (Default: `30000`)
63
+
64
+ **reclaimIdleMs** (`number`): Minimum idle time before an event can be reclaimed. (Default: `60000`)
65
+
66
+ **maxDeliveryAttempts** (`number`): Maximum nack redeliveries. Pass Infinity to disable the cap. (Default: `5`)
67
+
68
+ **logger** (`{ debug?: Function; warn?: Function }`): Optional diagnostic logger.
69
+
70
+ ## Delivery behavior
71
+
72
+ `ValkeyStreamsPubSub` supports pull delivery and doesn't support numeric replay offsets. Grouped subscribers compete for events through a shared consumer group. Subscribers without a group receive fan-out delivery through private consumer groups.
73
+
74
+ Use `startFrom: "latest"` to skip retained entries when a group is first created. The default, `"earliest"`, reads retained entries first.
75
+
76
+ ## Cleanup and shutdown
77
+
78
+ `clearTopic(topic)` deletes a topic stream and its consumer groups. `flush()` waits for in-flight publishes, and `close()` stops subscriptions and closes GLIDE connections.
79
+
80
+ ```typescript
81
+ await pubsub.clearTopic('workflow.events.run-123')
82
+ await pubsub.flush()
83
+ await pubsub.close()
84
+ ```
@@ -27,9 +27,9 @@ await store.upsert({
27
27
  })
28
28
  ```
29
29
 
30
- ### Using MongoDB Atlas Vector Search
30
+ ### Using MongoDB Vector Search
31
31
 
32
- For detailed setup instructions and best practices, see the [official MongoDB Atlas Vector Search documentation](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-overview/?utm_campaign=devrel\&utm_source=third-party-content\&utm_medium=cta\&utm_content=mastra-docs).
32
+ MongoDB Vector Search is a good solution for teams who want to consolidate vector search, full-text search, and operational data in a single database to minimize infrastructure complexity and maintain production-grade performance. For detailed setup instructions and best practices, see the [official MongoDB Vector Search documentation](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-overview/?utm_campaign=devrel\&utm_source=third-party-content\&utm_medium=cta\&utm_content=mastra-docs).
33
33
 
34
34
  ### Using VoyageAI with MongoDB
35
35
 
@@ -37,7 +37,7 @@ MongoDB works seamlessly with VoyageAI's embedding models, which are optimized f
37
37
 
38
38
  ### Hybrid Search (Vector + Full-Text)
39
39
 
40
- MongoDB supports hybrid search that fuses vector similarity with BM25 full-text search using server-side `$rankFusion` (requires MongoDB >= 8.0; generally available from 8.1, and enabled on Atlas 8.0.x). This is useful when you want to combine semantic and keyword-based retrieval:
40
+ MongoDB supports hybrid search that fuses vector similarity with BM25 full-text search using server-side `$rankFusion` (requires MongoDB >= 8.0; generally available from 8.1, and enabled on MongoDB Atlas 8.0.x). This is useful when you want to combine semantic and keyword-based retrieval:
41
41
 
42
42
  ```ts
43
43
  await store.createSearchIndex({ indexName: 'myCollection', fields: ['text'] })
@@ -420,7 +420,7 @@ Each vector database enforces specific naming conventions for indexes and collec
420
420
 
421
421
  **MongoDB**:
422
422
 
423
- Collection (index) names must:
423
+ Collection and index names must:
424
424
 
425
425
  - Start with a letter or underscore
426
426
  - Be up to 120 bytes long
@@ -162,13 +162,13 @@ Available properties on `res.locals`:
162
162
 
163
163
  ## Adding middleware
164
164
 
165
- Add Express middleware before or after `init()`:
165
+ Add Express middleware before `init()` to run it on every request. Mastra context isn't available at that point:
166
166
 
167
167
  ```typescript
168
168
  const app = express()
169
169
  app.use(express.json())
170
170
 
171
- // Middleware before init
171
+ // Runs on every request, before Mastra context exists
172
172
  app.use((req, res, next) => {
173
173
  console.log(`${req.method} ${req.url}`)
174
174
  next()
@@ -176,14 +176,12 @@ app.use((req, res, next) => {
176
176
 
177
177
  const server = new MastraServer({ app, mastra })
178
178
  await server.init()
179
-
180
- // Middleware after init has access to Mastra context
181
- app.use((req, res, next) => {
182
- const mastra = res.locals.mastra
183
- next()
184
- })
185
179
  ```
186
180
 
181
+ Middleware added after `init()` never runs for Mastra's routes. Express dispatches handlers in registration order, so middleware registered after the routes only applies to routes added later.
182
+
183
+ This adapter can't run [`server.middleware`](https://mastra.ai/docs/server/middleware) handlers because they use Hono's signature, and it logs a warning when that option is set. If you need Express middleware between Mastra's context step and its routes, use the manual initialization flow below.
184
+
187
185
  ## Manual initialization
188
186
 
189
187
  For custom middleware ordering, call each method separately instead of `init()`. See [manual initialization](https://mastra.ai/docs/server/server-adapters) for details.
@@ -145,7 +145,7 @@ Available context keys:
145
145
 
146
146
  ## Adding middleware
147
147
 
148
- Add Hono middleware before or after `init()`:
148
+ Add Hono middleware with `app.use()` before `init()` to run it on every request. Mastra context isn't available at that point:
149
149
 
150
150
  ```typescript
151
151
  import { Hono } from 'hono'
@@ -153,7 +153,7 @@ import { HonoBindings, HonoVariables, MastraServer } from '@mastra/hono'
153
153
 
154
154
  const app = new Hono<{ Bindings: HonoBindings; Variables: HonoVariables }>()
155
155
 
156
- // Middleware before init
156
+ // Runs on every request, before Mastra context exists
157
157
  app.use('*', async (c, next) => {
158
158
  console.log(`${c.req.method} ${c.req.url}`)
159
159
  await next()
@@ -161,11 +161,24 @@ app.use('*', async (c, next) => {
161
161
 
162
162
  const server = new MastraServer({ app, mastra })
163
163
  await server.init()
164
+ ```
164
165
 
165
- // Middleware after init has access to Mastra context
166
- app.use('*', async (c, next) => {
167
- const mastra = c.get('mastra')
168
- await next()
166
+ Middleware added after `init()` never runs for Mastra's routes. Hono dispatches handlers in registration order, so middleware registered after the routes only applies to routes added later.
167
+
168
+ To run middleware with Mastra context on Mastra's routes, use [`server.middleware`](https://mastra.ai/docs/server/middleware) in the Mastra config. The adapter registers it during `init()`, after the context step and before any route. These handlers are skipped for routes declared public with `requiresAuth: false`, so they can't block endpoints such as the Studio sign-in routes:
169
+
170
+ ```typescript
171
+ import { Mastra } from '@mastra/core'
172
+
173
+ export const mastra = new Mastra({
174
+ server: {
175
+ middleware: [
176
+ async (c, next) => {
177
+ c.get('requestContext').set('locale', c.req.header('accept-language') ?? 'en')
178
+ await next()
179
+ },
180
+ ],
181
+ },
169
182
  })
170
183
  ```
171
184
 
@@ -0,0 +1,88 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # Turso Storage
4
+
5
+ Use `@mastra/turso` to store Mastra agents, workflows, memory, and other storage domains in a local [Turso Database](https://github.com/tursodatabase/turso) file.
6
+
7
+ ## Installation
8
+
9
+ **npm**:
10
+
11
+ ```bash
12
+ npm install @mastra/turso
13
+ ```
14
+
15
+ **pnpm**:
16
+
17
+ ```bash
18
+ pnpm add @mastra/turso
19
+ ```
20
+
21
+ **Yarn**:
22
+
23
+ ```bash
24
+ yarn add @mastra/turso
25
+ ```
26
+
27
+ **Bun**:
28
+
29
+ ```bash
30
+ bun add @mastra/turso
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```typescript
36
+ import { Mastra } from '@mastra/core/mastra'
37
+ import { TursoStore } from '@mastra/turso'
38
+
39
+ export const mastra = new Mastra({
40
+ storage: new TursoStore({
41
+ id: 'local-storage',
42
+ path: './mastra.db',
43
+ }),
44
+ })
45
+ ```
46
+
47
+ ## Constructor options
48
+
49
+ - `id` (required): Unique identifier for the storage instance.
50
+ - `path` (required unless `client` is provided): Path to the local database file.
51
+ - `client`: A compatible SQLite client to use instead of creating a native Turso client.
52
+ - `readonly`: Opens the database in read-only mode.
53
+ - `fileMustExist`: Requires the database file to exist before opening it.
54
+ - `timeout`: Connection timeout in milliseconds.
55
+ - `defaultQueryTimeout`: Default query timeout in milliseconds.
56
+ - `tracing`: Native driver tracing level: `info`, `debug`, or `trace`.
57
+ - `experimental`: Native Turso Database experimental features to enable.
58
+ - `maxRetries`: Maximum number of retries for retryable writes.
59
+ - `initialBackoffMs`: Initial retry delay in milliseconds.
60
+ - `disableInit`: Disables automatic storage initialization.
61
+ - `retention`: Retention policies for supported storage domains.
62
+
63
+ ## Platform support
64
+
65
+ The native driver supports macOS on arm64, Windows on x64, and glibc-based Linux on x64 and arm64. Use `getTursoDatabaseSupport()` when your application needs to choose a fallback on unsupported systems.
66
+
67
+ ```typescript
68
+ import { getTursoDatabaseSupport } from '@mastra/turso'
69
+
70
+ const support = getTursoDatabaseSupport()
71
+ if (!support.supported) {
72
+ console.warn(support.reason)
73
+ }
74
+ ```
75
+
76
+ ## Experimental features
77
+
78
+ Experimental Turso Database features are disabled by default. Enable only the features your application requires.
79
+
80
+ ```typescript
81
+ const storage = new TursoStore({
82
+ id: 'multiprocess-storage',
83
+ path: './mastra.db',
84
+ experimental: ['multiprocess_wal'],
85
+ })
86
+ ```
87
+
88
+ `@mastra/turso` provides local-file Mastra storage. It doesn't connect to remote libSQL databases and doesn't include a vector store.
@@ -272,8 +272,36 @@ Contains file data.
272
272
 
273
273
  **payload.providerMetadata** (`SharedV2ProviderMetadata`): Provider-specific metadata
274
274
 
275
+ ### reasoning-file
276
+
277
+ Contains a file generated by the model as part of its reasoning. Emitted by providers on the AI SDK v7 specification.
278
+
279
+ **type** (`"reasoning-file"`): Chunk type identifier
280
+
281
+ **payload** (`ReasoningFilePayload`): Reasoning file data
282
+
283
+ **payload.data** (`string | Uint8Array`): The file data
284
+
285
+ **payload.base64** (`string`): Base64 encoded data if applicable
286
+
287
+ **payload.mimeType** (`string`): MIME type of the file
288
+
289
+ **payload.providerMetadata** (`SharedV2ProviderMetadata`): Provider-specific metadata
290
+
275
291
  ## Control chunks
276
292
 
293
+ ### custom
294
+
295
+ Contains a provider-specific content block that doesn't map to any other standardized chunk type. Emitted by providers on the AI SDK v7 specification.
296
+
297
+ **type** (`"custom"`): Chunk type identifier
298
+
299
+ **payload** (`CustomPayload`): Custom provider content
300
+
301
+ **payload.kind** (`string`): The kind of custom content, in the format {provider}.{provider-type}
302
+
303
+ **payload.providerMetadata** (`SharedV2ProviderMetadata`): Provider-specific metadata
304
+
277
305
  ### start
278
306
 
279
307
  Signals the start of streaming.
@@ -324,7 +352,7 @@ Signals the completion of a processing step.
324
352
 
325
353
  ### raw
326
354
 
327
- Contains raw data from the provider.
355
+ Contains raw data from the provider. Content types Mastra doesn't recognize are also emitted as `raw` chunks rather than being discarded. Raw chunks only appear when `includeRawChunks` is enabled.
328
356
 
329
357
  **type** (`"raw"`): Chunk type identifier
330
358
 
@@ -82,7 +82,7 @@ const stream = await agent.stream('message for agent')
82
82
 
83
83
  **options.onAbort** (`(event: { steps: any[]; text?: string }) => Promise<void> | void`): Callback function called when the stream is aborted. steps contains the steps that completed before the abort, and text contains the assistant text streamed so far for the step that was in flight.
84
84
 
85
- **options.abortSignal** (`AbortSignal`): Signal object that allows you to abort the agent's execution. When the signal is aborted, all ongoing operations will be terminated, including any in-flight subagent runs the agent delegated to.
85
+ **options.abortSignal** (`AbortSignal`): Signal object that allows you to abort the agent's execution, including in-flight subagent runs. Canceled runs continue through output processors. When writable memory is configured, built-in memory processors persist submitted messages, completed tool results, and assistant output available when terminal processing runs. Output that doesn't reach terminal processing isn't persisted. Custom output processors can transform or interrupt this behavior before memory processors run.
86
86
 
87
87
  **options.activeTools** (`Array<keyof ToolSet> | undefined`): Array of active tool names that can be used during execution.
88
88
 
@@ -180,8 +180,6 @@ const stream = await agent.stream('message for agent')
180
180
 
181
181
  **options.savePerStep** (`boolean`): Save messages incrementally after each stream step completes (default: false).
182
182
 
183
- **options.persistPartialOnAbort** (`boolean`): Save the assistant text that was streamed before an abort to memory (default: false). Only text emitted before the abort is persisted; output a provider keeps producing after cancellation is discarded, and nothing is saved when no text was streamed.
184
-
185
183
  **options.requireToolApproval** (`boolean`): When true, all tool calls require explicit approval before execution. The stream will emit tool-call-approval chunks and pause until approveToolCall() or declineToolCall() is called.
186
184
 
187
185
  **options.autoResumeSuspendedTools** (`boolean`): When true, automatically resumes suspended tools when the user sends a new message on the same thread. The agent extracts resumeData from the user's message based on the tool's resumeSchema. Requires memory to be configured.
@@ -232,15 +232,17 @@ Retrieves all tools from all configured servers, with tool names namespaced by t
232
232
  Set `perServerTimeoutMs` to limit how long discovery waits for each server. Servers that finish within the limit remain in `tools`. Timed-out servers appear in `errors`, and `durations` reports each server's discovery time in milliseconds.
233
233
 
234
234
  ```typescript
235
- const { tools, errors, durations } = await mcp.listToolsWithErrors({
235
+ const { tools, errors, errorDetails, durations } = await mcp.listToolsWithErrors({
236
236
  perServerTimeoutMs: 3_000,
237
237
  })
238
238
 
239
239
  new Agent({ id: 'agent', tools })
240
- console.log(errors, durations)
240
+ console.log(errors, errorDetails, durations)
241
241
  ```
242
242
 
243
- When called without options, the method returns only `tools` and `errors`.
243
+ `errors` remains a string map for backward compatibility. `errorDetails` provides the same message plus machine-readable `httpStatus` and transport `code` fields when the underlying error exposes them. When an HTTP status is available, the legacy message also includes an `(HTTP nnn)` suffix.
244
+
245
+ When called without options, the method omits only `durations`; `tools`, `errors`, and `errorDetails` are always returned.
244
246
 
245
247
  ### `listToolsets()`
246
248
 
@@ -257,15 +259,15 @@ const res = await agent.stream(prompt, {
257
259
  Returns toolsets grouped by server name, along with per-server discovery errors. Set `perServerTimeoutMs` to limit each server independently and include per-server `durations` in milliseconds.
258
260
 
259
261
  ```typescript
260
- const { toolsets, errors, durations } = await mcp.listToolsetsWithErrors({
262
+ const { toolsets, errors, errorDetails, durations } = await mcp.listToolsetsWithErrors({
261
263
  perServerTimeoutMs: 3_000,
262
264
  })
263
265
 
264
266
  const res = await agent.stream(prompt, { toolsets })
265
- console.log(errors, durations)
267
+ console.log(errors, errorDetails, durations)
266
268
  ```
267
269
 
268
- When called without options, the method returns only `toolsets` and `errors`.
270
+ When called without options, the method omits only `durations`; `toolsets`, `errors`, and `errorDetails` are always returned.
269
271
 
270
272
  ### `listToolDefinitions()`
271
273
 
@@ -286,7 +288,7 @@ Like `listToolDefinitions()`, but also returns per-server errors for servers tha
286
288
  Set `perServerTimeoutMs` to limit each server independently. When options are provided, `durations` reports each server's discovery time in milliseconds.
287
289
 
288
290
  ```typescript
289
- const { definitions, errors, durations } = await mcp.listToolDefinitionsWithErrors({
291
+ const { definitions, errors, errorDetails, durations } = await mcp.listToolDefinitionsWithErrors({
290
292
  perServerTimeoutMs: 3_000,
291
293
  })
292
294
 
@@ -294,10 +296,10 @@ if (Object.keys(errors).length === 0) {
294
296
  await cache.set('mcp-tools', JSON.stringify(definitions))
295
297
  }
296
298
 
297
- console.log(durations)
299
+ console.log(errorDetails, durations)
298
300
  ```
299
301
 
300
- When called without options, the method returns only `definitions` and `errors`.
302
+ When called without options, the method omits only `durations`; `definitions`, `errors`, and `errorDetails` are always returned.
301
303
 
302
304
  ### `toolFromDefinition()`
303
305
 
@@ -441,6 +443,18 @@ for (const serverName in resourcesByServer) {
441
443
  }
442
444
  ```
443
445
 
446
+ #### `resources.listWithErrors(options?)`
447
+
448
+ Preserves successful resources while reporting failed servers through legacy string `errors` and structured `errorDetails`. Pass `perServerTimeoutMs` to bound each server independently and include `durations`.
449
+
450
+ ```typescript
451
+ const { resources, errors, errorDetails, durations } = await mcpClient.resources.listWithErrors({
452
+ perServerTimeoutMs: 3_000,
453
+ })
454
+
455
+ console.log(resources, errors, errorDetails, durations)
456
+ ```
457
+
444
458
  #### `resources.templates()`
445
459
 
446
460
  Retrieves all available resource templates from all connected MCP servers, grouped by server name.
@@ -458,6 +472,15 @@ for (const serverName in templatesByServer) {
458
472
  }
459
473
  ```
460
474
 
475
+ #### `resources.templatesWithErrors(options?)`
476
+
477
+ Returns successful resource templates together with per-server string `errors`, structured `errorDetails`, and optional `durations`.
478
+
479
+ ```typescript
480
+ const { templates, errors, errorDetails } = await mcpClient.resources.templatesWithErrors()
481
+ console.log(templates, errors, errorDetails)
482
+ ```
483
+
461
484
  #### `resources.read(serverName: string, uri: string)`
462
485
 
463
486
  Reads the content of a specific resource from a server.
@@ -711,6 +734,15 @@ for (const serverName in promptsByServer) {
711
734
  }
712
735
  ```
713
736
 
737
+ #### `prompts.listWithErrors(options?)`
738
+
739
+ Returns successful prompts together with per-server string `errors`, structured `errorDetails`, and optional `durations`.
740
+
741
+ ```typescript
742
+ const { prompts, errors, errorDetails } = await mcpClient.prompts.listWithErrors()
743
+ console.log(prompts, errors, errorDetails)
744
+ ```
745
+
714
746
  #### `prompts.get({ serverName, name, args?, version? })`
715
747
 
716
748
  Retrieves a specific prompt and its messages from a server.