@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
|
@@ -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)
|
package/.docs/reference/index.md
CHANGED
|
@@ -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
|
|
30
|
+
### Using MongoDB Vector Search
|
|
31
31
|
|
|
32
|
-
For detailed setup instructions and best practices, see the [official MongoDB
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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.
|