@mastra/mcp-docs-server 1.1.25-alpha.7 → 1.1.25-alpha.9

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.
@@ -11,6 +11,8 @@ You can use individual [`Processor`](https://mastra.ai/reference/processors/proc
11
11
 
12
12
  Some processors implement both input and output logic and can be used in either array depending on where the transformation should occur.
13
13
 
14
+ Some built-in processors also persist hidden system reminder messages using `<system-reminder>...</system-reminder>` text plus `metadata.systemReminder`. These reminders stay available in raw memory history and retry/prompt reconstruction paths, but standard UI-facing message conversions and default memory recall hide them unless you explicitly opt in.
15
+
14
16
  ## When to use processors
15
17
 
16
18
  Use processors to:
@@ -536,6 +538,37 @@ The retry mechanism:
536
538
  - Tracks retry count via the `retryCount` parameter
537
539
  - Respects `maxProcessorRetries` limit on the agent
538
540
 
541
+ ## API error handling
542
+
543
+ The `processAPIError` method handles LLM API rejections — errors where the API rejects the request (such as 400 or 422 status codes) rather than network or server failures. This lets you modify the request and retry when the API rejects the message format.
544
+
545
+ ```typescript
546
+ import { APICallError } from '@ai-sdk/provider'
547
+ import type { Processor, ProcessAPIErrorArgs, ProcessAPIErrorResult } from '@mastra/core/processors'
548
+
549
+ export class ContextLengthHandler implements Processor {
550
+ id = 'context-length-handler'
551
+
552
+ processAPIError({
553
+ error,
554
+ messageList,
555
+ retryCount,
556
+ }: ProcessAPIErrorArgs): ProcessAPIErrorResult | void {
557
+ if (retryCount > 0) return
558
+
559
+ if (APICallError.isInstance(error) && error.message.includes('context length exceeded')) {
560
+ const messages = messageList.get.all.db()
561
+ if (messages.length > 4) {
562
+ messageList.removeByIds([messages[1]!.id, messages[2]!.id])
563
+ return { retry: true }
564
+ }
565
+ }
566
+ }
567
+ }
568
+ ```
569
+
570
+ Mastra includes a built-in [`PrefillErrorHandler`](https://mastra.ai/reference/processors/prefill-error-handler) that automatically handles the Anthropic "assistant message prefill" error. This processor is auto-injected and requires no configuration.
571
+
539
572
  ## Related documentation
540
573
 
541
574
  - [Guardrails](https://mastra.ai/docs/agents/guardrails): Security and validation processors
@@ -89,6 +89,23 @@ export const testAgent = new Agent({
89
89
 
90
90
  > **Info:** Visit [Agent Class](https://mastra.ai/reference/agents/agent) for a full list of configuration options.
91
91
 
92
+ ## Tool approval
93
+
94
+ You can require human approval before MCP tools are executed by setting `requireToolApproval` on a server definition. This integrates with the existing [human-in-the-loop](https://mastra.ai/docs/workflows/human-in-the-loop) approval flow.
95
+
96
+ ```typescript
97
+ export const mcp = new MCPClient({
98
+ servers: {
99
+ github: {
100
+ url: new URL('http://localhost:3000/mcp'),
101
+ requireToolApproval: true,
102
+ },
103
+ },
104
+ })
105
+ ```
106
+
107
+ You can also pass a function to decide dynamically per-call. See the [MCPClient reference](https://mastra.ai/reference/tools/mcp-client) for the full API.
108
+
92
109
  ## Configuring `MCPServer`
93
110
 
94
111
  To expose agents, tools, and workflows from your Mastra application to external systems over HTTP(S) use the `MCPServer` class. This makes them accessible to any system or agent that supports the protocol.
@@ -6,6 +6,12 @@ You can also retrieve message history to display past conversations in your UI.
6
6
 
7
7
  > **Info:** Each message belongs to a thread (the conversation) and a resource (the user or entity it's associated with). See [Threads and resources](https://mastra.ai/docs/memory/storage) for more detail.
8
8
 
9
+ > **Warning:** When you use memory with a client application, send **only the new message** from the client instead of the full conversation history.
10
+ >
11
+ > Sending the full history is redundant because Mastra loads messages from storage, and it can cause message ordering bugs when client-side timestamps conflict with stored timestamps.
12
+ >
13
+ > For an AI SDK example, see [Using Mastra Memory](https://mastra.ai/guides/build-your-ui/ai-sdk-ui).
14
+
9
15
  ## Getting started
10
16
 
11
17
  Install the Mastra memory module along with a [storage adapter](https://mastra.ai/docs/memory/storage) for your database. The examples below use `@mastra/libsql`, which stores data locally in a `mastra.db` file.
@@ -38,6 +38,12 @@ const memory = new Memory({
38
38
 
39
39
  See [configuration options](https://mastra.ai/reference/memory/observational-memory) for full API details.
40
40
 
41
+ > **Warning:** When you use OM with a client application, send **only the new message** from the client instead of the full conversation history.
42
+ >
43
+ > Observational memory still relies on stored conversation history. Sending the full history is redundant and can cause message ordering bugs when client-side timestamps conflict with stored timestamps.
44
+ >
45
+ > For an AI SDK example, see [Using Mastra Memory](https://mastra.ai/guides/build-your-ui/ai-sdk-ui).
46
+
41
47
  > **Note:** OM currently only supports `@mastra/pg`, `@mastra/libsql`, and `@mastra/mongodb` storage adapters. It uses background agents for managing memory. When using `observationalMemory: true`, the default model is `google/gemini-2.5-flash`. When passing a config object, a `model` must be explicitly set.
42
48
 
43
49
  ## Benefits
@@ -265,7 +265,7 @@ const { text } = await voiceAgent.generate('What color is the sky?')
265
265
 
266
266
  // Convert text to speech to an Audio Stream
267
267
  const audioStream = await voiceAgent.voice.speak(text, {
268
- speaker: 'default', // Optional: specify a speaker
268
+ speaker: 'shubh', // Optional: specify a bulbul:v3 speaker
269
269
  })
270
270
 
271
271
  playAudio(audioStream)
@@ -760,12 +760,15 @@ Visit the [Speechify Voice Reference](https://mastra.ai/reference/voice/speechif
760
760
  // Sarvam Voice Configuration
761
761
  const voice = new SarvamVoice({
762
762
  speechModel: {
763
- name: 'sarvam-voice', // Example model name
763
+ model: 'bulbul:v3', // TTS model (bulbul:v2 or bulbul:v3)
764
+ apiKey: process.env.SARVAM_API_KEY,
765
+ language: 'en-IN', // BCP-47 language code
766
+ },
767
+ listeningModel: {
768
+ model: 'saarika:v2.5', // STT model (saarika:v2.5 or saaras:v3)
764
769
  apiKey: process.env.SARVAM_API_KEY,
765
- language: 'en-IN', // Language code
766
- style: 'conversational', // Style setting
767
770
  },
768
- // Sarvam may not have a separate listening model
771
+ speaker: 'shubh', // Default bulbul:v3 speaker
769
772
  })
770
773
  ```
771
774
 
@@ -238,6 +238,38 @@ export default function Chat() {
238
238
 
239
239
  Use [`prepareSendMessagesRequest`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#transport.default-chat-transport.prepare-send-messages-request) to customize the request sent to the chat route, for example to pass additional configuration to the agent.
240
240
 
241
+ ## Using Mastra Memory
242
+
243
+ When your agent has [memory](https://mastra.ai/docs/memory/overview) configured, Mastra loads conversation history from storage on the server. Send only the new message from the client instead of the full conversation history.
244
+
245
+ Sending the full history is redundant and can cause message ordering bugs because client-side timestamps can conflict with the timestamps stored in your database.
246
+
247
+ ```typescript
248
+ import { useChat } from '@ai-sdk/react'
249
+ import { DefaultChatTransport } from 'ai'
250
+
251
+ const { messages, sendMessage } = useChat({
252
+ transport: new DefaultChatTransport({
253
+ api: 'http://localhost:4111/chat/weatherAgent',
254
+ prepareSendMessagesRequest({ messages }) {
255
+ return {
256
+ body: {
257
+ messages: [messages[messages.length - 1]],
258
+ threadId: 'user-thread-123',
259
+ resourceId: 'user-123',
260
+ },
261
+ }
262
+ },
263
+ }),
264
+ })
265
+ ```
266
+
267
+ Set `threadId` and `resourceId` from your app's own state, such as URL params, auth context, or your database.
268
+
269
+ See [Message history](https://mastra.ai/docs/memory/message-history) for more on how Mastra memory loads and stores messages.
270
+
271
+ [`chatRoute()`](https://mastra.ai/reference/ai-sdk/chat-route) and [`handleChatStream()`](https://mastra.ai/reference/ai-sdk/handle-chat-stream) already work with memory. Configure the client to send only the new message and include the thread and resource identifiers.
272
+
241
273
  ### `useCompletion()`
242
274
 
243
275
  The `useCompletion()` hook handles single-turn completions between your frontend and a Mastra agent, allowing you to send a prompt and receive a streamed response over HTTP.
@@ -182,6 +182,8 @@ The CLI reads `organizationId` and `projectId` from `.mastra-project.json` by de
182
182
  ## Related
183
183
 
184
184
  - [CLI reference: `mastra server deploy`](https://mastra.ai/reference/cli/mastra)
185
+ - [CLI reference: `mastra server pause`](https://mastra.ai/reference/cli/mastra)
186
+ - [CLI reference: `mastra server restart`](https://mastra.ai/reference/cli/mastra)
185
187
  - [CLI reference: `mastra studio deploy`](https://mastra.ai/reference/cli/mastra)
186
188
  - [CLI reference: `mastra auth tokens`](https://mastra.ai/reference/cli/mastra)
187
189
  - [Mastra platform overview](https://mastra.ai/docs/mastra-platform/overview)
@@ -1,6 +1,6 @@
1
1
  # ![OpenRouter logo](https://models.dev/logos/openrouter.svg)OpenRouter
2
2
 
3
- OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 176 models through Mastra's model router.
3
+ OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 171 models through Mastra's model router.
4
4
 
5
5
  Learn more in the [OpenRouter documentation](https://openrouter.ai/models).
6
6
 
@@ -46,7 +46,6 @@ ANTHROPIC_API_KEY=ant-...
46
46
  | `anthropic/claude-sonnet-4.6` |
47
47
  | `arcee-ai/trinity-large-preview:free` |
48
48
  | `arcee-ai/trinity-large-thinking` |
49
- | `arcee-ai/trinity-mini:free` |
50
49
  | `black-forest-labs/flux.2-flex` |
51
50
  | `black-forest-labs/flux.2-klein-4b` |
52
51
  | `black-forest-labs/flux.2-max` |
@@ -117,7 +116,6 @@ ANTHROPIC_API_KEY=ant-...
117
116
  | `moonshotai/kimi-k2-0905` |
118
117
  | `moonshotai/kimi-k2-0905:exacto` |
119
118
  | `moonshotai/kimi-k2-thinking` |
120
- | `moonshotai/kimi-k2:free` |
121
119
  | `moonshotai/kimi-k2.5` |
122
120
  | `nousresearch/hermes-3-llama-3.1-405b:free` |
123
121
  | `nousresearch/hermes-4-405b` |
@@ -168,15 +166,12 @@ ANTHROPIC_API_KEY=ant-...
168
166
  | `qwen/qwen3-235b-a22b-thinking-2507` |
169
167
  | `qwen/qwen3-30b-a3b-instruct-2507` |
170
168
  | `qwen/qwen3-30b-a3b-thinking-2507` |
171
- | `qwen/qwen3-4b:free` |
172
169
  | `qwen/qwen3-coder` |
173
170
  | `qwen/qwen3-coder-30b-a3b-instruct` |
174
171
  | `qwen/qwen3-coder-flash` |
175
172
  | `qwen/qwen3-coder:exacto` |
176
- | `qwen/qwen3-coder:free` |
177
173
  | `qwen/qwen3-max` |
178
174
  | `qwen/qwen3-next-80b-a3b-instruct` |
179
- | `qwen/qwen3-next-80b-a3b-instruct:free` |
180
175
  | `qwen/qwen3-next-80b-a3b-thinking` |
181
176
  | `qwen/qwen3.5-397b-a17b` |
182
177
  | `qwen/qwen3.5-flash-02-23` |
@@ -1,6 +1,6 @@
1
1
  # Model Providers
2
2
 
3
- Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 3610 models from 99 providers through a single API.
3
+ Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 3596 models from 99 providers through a single API.
4
4
 
5
5
  ## Features
6
6
 
@@ -114,13 +114,23 @@ const response = await agent.generate("Hello!", {
114
114
 
115
115
  **cacheControl** (`{ type: "ephemeral"; ttl?: "5m" | "1h" | undefined; } | undefined`)
116
116
 
117
+ **metadata** (`{ userId?: string | undefined; } | undefined`)
118
+
119
+ **mcpServers** (`{ type: "url"; name: string; url: string; authorizationToken?: string | null | undefined; toolConfiguration?: { enabled?: boolean | null | undefined; allowedTools?: string[] | null | undefined; } | null | undefined; }[] | undefined`)
120
+
117
121
  **container** (`{ id?: string | undefined; skills?: { type: "anthropic" | "custom"; skillId: string; version?: string | undefined; }[] | undefined; } | undefined`)
118
122
 
123
+ **toolStreaming** (`boolean | undefined`)
124
+
119
125
  **effort** (`"low" | "medium" | "high" | "max" | undefined`)
120
126
 
121
- **speed** (`"fast" | undefined`)
127
+ **speed** (`"fast" | "standard" | undefined`)
128
+
129
+ **inferenceGeo** (`"us" | "global" | undefined`)
130
+
131
+ **anthropicBeta** (`string[] | undefined`)
122
132
 
123
- **contextManagement** (`{ edits: ({ type: "clear_01"; trigger?: { type: "input_tokens"; value: number; } | undefined; keep?: "all" | { type: "thinking_turns"; value: number; } | undefined; } | { type: "compact_20260112"; trigger?: { ...; } | undefined; pauseAfterCompaction?: boolean | undefined; instructions?: string | undefined; })[]; } |...`)
133
+ **contextManagement** (`{ edits: ({ type: "clear_tool_uses_20250919"; trigger?: { type: "input_tokens"; value: number; } | { type: "tool_uses"; value: number; } | undefined; keep?: { type: "tool_uses"; value: number; } | undefined; clearAtLeast?: { ...; } | undefined; clearToolInputs?: boolean | undefined; excludeTools?: string[] | undefin...`)
124
134
 
125
135
  ## Direct provider installation
126
136
 
@@ -1,6 +1,6 @@
1
1
  # ![Fireworks AI logo](https://models.dev/logos/fireworks-ai.svg)Fireworks AI
2
2
 
3
- Access 16 Fireworks AI models through Mastra's model router. Authentication is handled automatically using the `FIREWORKS_API_KEY` environment variable.
3
+ Access 17 Fireworks AI models through Mastra's model router. Authentication is handled automatically using the `FIREWORKS_API_KEY` environment variable.
4
4
 
5
5
  Learn more in the [Fireworks AI documentation](https://fireworks.ai/docs/).
6
6
 
@@ -48,6 +48,7 @@ for await (const chunk of stream) {
48
48
  | `fireworks-ai/accounts/fireworks/models/kimi-k2p5` | 256K | | | | | | $0.60 | $3 |
49
49
  | `fireworks-ai/accounts/fireworks/models/minimax-m2p1` | 200K | | | | | | $0.30 | $1 |
50
50
  | `fireworks-ai/accounts/fireworks/models/minimax-m2p5` | 197K | | | | | | $0.30 | $1 |
51
+ | `fireworks-ai/accounts/fireworks/models/minimax-m2p7` | 197K | | | | | | $0.30 | $1 |
51
52
  | `fireworks-ai/accounts/fireworks/models/qwen3p6-plus` | 128K | | | | | | $0.50 | $3 |
52
53
  | `fireworks-ai/accounts/fireworks/routers/kimi-k2p5-turbo` | 256K | | | | | | — | — |
53
54
 
@@ -137,10 +137,14 @@ const response = await agent.generate("Hello!", {
137
137
 
138
138
  **mediaResolution** (`"MEDIA_RESOLUTION_UNSPECIFIED" | "MEDIA_RESOLUTION_LOW" | "MEDIA_RESOLUTION_MEDIUM" | "MEDIA_RESOLUTION_HIGH" | undefined`)
139
139
 
140
- **imageConfig** (`{ aspectRatio?: "1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9" | undefined; imageSize?: "1K" | "2K" | "4K" | undefined; } | undefined`)
140
+ **imageConfig** (`{ aspectRatio?: "1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9" | "1:8" | "8:1" | "1:4" | "4:1" | undefined; imageSize?: "1K" | "2K" | "4K" | "512" | undefined; } | undefined`)
141
141
 
142
142
  **retrievalConfig** (`{ latLng?: { latitude: number; longitude: number; } | undefined; } | undefined`)
143
143
 
144
+ **streamFunctionCallArguments** (`boolean | undefined`)
145
+
146
+ **serviceTier** (`"standard" | "flex" | "priority" | undefined`)
147
+
144
148
  ## Direct provider installation
145
149
 
146
150
  This provider can also be installed directly as a standalone package, which can be used instead of the Mastra model router string. View the [package documentation](https://www.npmjs.com/package/@ai-sdk/google) for more details.
@@ -1,6 +1,6 @@
1
1
  # ![Kilo Gateway logo](https://models.dev/logos/kilo.svg)Kilo Gateway
2
2
 
3
- Access 334 Kilo Gateway models through Mastra's model router. Authentication is handled automatically using the `KILO_API_KEY` environment variable.
3
+ Access 335 Kilo Gateway models through Mastra's model router. Authentication is handled automatically using the `KILO_API_KEY` environment variable.
4
4
 
5
5
  Learn more in the [Kilo Gateway documentation](https://kilo.ai).
6
6
 
@@ -268,6 +268,7 @@ for await (const chunk of stream) {
268
268
  | `kilo/openai/o4-mini-high` | 200K | | | | | | $1 | $4 |
269
269
  | `kilo/openrouter/auto` | 2.0M | | | | | | — | — |
270
270
  | `kilo/openrouter/bodybuilder` | 128K | | | | | | — | — |
271
+ | `kilo/openrouter/elephant-alpha` | 262K | | | | | | — | — |
271
272
  | `kilo/openrouter/free` | 200K | | | | | | — | — |
272
273
  | `kilo/perplexity/sonar` | 127K | | | | | | $1 | $1 |
273
274
  | `kilo/perplexity/sonar-deep-research` | 128K | | | | | | $2 | $8 |
@@ -171,6 +171,10 @@ const response = await agent.generate("Hello!", {
171
171
 
172
172
  **user** (`string | null | undefined`)
173
173
 
174
+ **systemMessageMode** (`"remove" | "system" | "developer" | undefined`)
175
+
176
+ **forceReasoning** (`boolean | undefined`)
177
+
174
178
  ## Direct provider installation
175
179
 
176
180
  This provider can also be installed directly as a standalone package, which can be used instead of the Mastra model router string. View the [package documentation](https://www.npmjs.com/package/@ai-sdk/openai) for more details.
@@ -1,6 +1,6 @@
1
1
  # ![Poe logo](https://models.dev/logos/poe.svg)Poe
2
2
 
3
- Access 128 Poe models through Mastra's model router. Authentication is handled automatically using the `POE_API_KEY` environment variable.
3
+ Access 117 Poe models through Mastra's model router. Authentication is handled automatically using the `POE_API_KEY` environment variable.
4
4
 
5
5
  Learn more in the [Poe documentation](https://creator.poe.com/docs/external-applications/openai-compatible-api).
6
6
 
@@ -41,17 +41,12 @@ for await (const chunk of stream) {
41
41
  | `poe/anthropic/claude-opus-4.1` | 197K | | | | | | $13 | $64 |
42
42
  | `poe/anthropic/claude-opus-4.5` | 197K | | | | | | $4 | $21 |
43
43
  | `poe/anthropic/claude-opus-4.6` | 983K | | | | | | $4 | $21 |
44
- | `poe/anthropic/claude-sonnet-3.5` | 189K | | | | | | $3 | $13 |
45
- | `poe/anthropic/claude-sonnet-3.5-june` | 189K | | | | | | $3 | $13 |
46
44
  | `poe/anthropic/claude-sonnet-3.7` | 197K | | | | | | $3 | $13 |
47
45
  | `poe/anthropic/claude-sonnet-4` | 983K | | | | | | $3 | $13 |
48
46
  | `poe/anthropic/claude-sonnet-4.5` | 983K | | | | | | $3 | $13 |
49
47
  | `poe/anthropic/claude-sonnet-4.6` | 983K | | | | | | $3 | $13 |
50
- | `poe/cerebras/gpt-oss-120b-cs` | | | | | | | | |
51
- | `poe/cerebras/llama-3.1-8b-cs` | | | | | | | | |
52
- | `poe/cerebras/llama-3.3-70b-cs` | — | | | | | | — | — |
53
- | `poe/cerebras/qwen3-235b-2507-cs` | — | | | | | | — | — |
54
- | `poe/cerebras/qwen3-32b-cs` | — | | | | | | — | — |
48
+ | `poe/cerebras/gpt-oss-120b-cs` | 128K | | | | | | $0.35 | $0.75 |
49
+ | `poe/cerebras/llama-3.1-8b-cs` | 128K | | | | | | $0.10 | $0.10 |
55
50
  | `poe/elevenlabs/elevenlabs-music` | 2K | | | | | | — | — |
56
51
  | `poe/elevenlabs/elevenlabs-v2.5-turbo` | 128K | | | | | | — | — |
57
52
  | `poe/elevenlabs/elevenlabs-v3` | 128K | | | | | | — | — |
@@ -62,10 +57,8 @@ for await (const chunk of stream) {
62
57
  | `poe/google/gemini-2.5-flash-lite` | 1.0M | | | | | | $0.07 | $0.28 |
63
58
  | `poe/google/gemini-2.5-pro` | 1.1M | | | | | | $0.87 | $7 |
64
59
  | `poe/google/gemini-3-flash` | 1.0M | | | | | | $0.40 | $2 |
65
- | `poe/google/gemini-3-pro` | 1.0M | | | | | | $2 | $10 |
66
60
  | `poe/google/gemini-3.1-flash-lite` | 1.0M | | | | | | $0.25 | $2 |
67
61
  | `poe/google/gemini-3.1-pro` | 1.0M | | | | | | $2 | $12 |
68
- | `poe/google/gemini-deep-research` | 1.0M | | | | | | $2 | $10 |
69
62
  | `poe/google/gemma-4-31b` | 262K | | | | | | — | — |
70
63
  | `poe/google/imagen-3` | 480 | | | | | | — | — |
71
64
  | `poe/google/imagen-3-fast` | 480 | | | | | | — | — |
@@ -88,20 +81,16 @@ for await (const chunk of stream) {
88
81
  | `poe/novita/deepseek-v3.2` | 128K | | | | | | $0.27 | $0.40 |
89
82
  | `poe/novita/glm-4.6` | — | | | | | | — | — |
90
83
  | `poe/novita/glm-4.6v` | 131K | | | | | | — | — |
91
- | `poe/novita/glm-4.7` | 205K | | | | | | — | — |
92
84
  | `poe/novita/glm-4.7-flash` | 200K | | | | | | — | — |
93
85
  | `poe/novita/glm-4.7-n` | 205K | | | | | | — | — |
94
- | `poe/novita/glm-5` | 205K | | | | | | | |
86
+ | `poe/novita/glm-5` | 205K | | | | | | $1 | $3 |
95
87
  | `poe/novita/kimi-k2-thinking` | 256K | | | | | | — | — |
96
- | `poe/novita/kimi-k2.5` | 256K | | | | | | | |
88
+ | `poe/novita/kimi-k2.5` | 128K | | | | | | $0.60 | $3 |
97
89
  | `poe/novita/minimax-m2.1` | 205K | | | | | | — | — |
98
- | `poe/openai/chatgpt-4o-latest` | 128K | | | | | | $5 | $14 |
99
90
  | `poe/openai/dall-e-3` | 800 | | | | | | — | — |
100
91
  | `poe/openai/gpt-3.5-turbo` | 16K | | | | | | $0.45 | $1 |
101
92
  | `poe/openai/gpt-3.5-turbo-instruct` | 4K | | | | | | $1 | $2 |
102
93
  | `poe/openai/gpt-3.5-turbo-raw` | 5K | | | | | | $0.45 | $1 |
103
- | `poe/openai/gpt-4-classic` | 8K | | | | | | $27 | $54 |
104
- | `poe/openai/gpt-4-classic-0314` | 8K | | | | | | $27 | $54 |
105
94
  | `poe/openai/gpt-4-turbo` | 128K | | | | | | $9 | $27 |
106
95
  | `poe/openai/gpt-4.1` | 1.0M | | | | | | $2 | $7 |
107
96
  | `poe/openai/gpt-4.1-mini` | 1.0M | | | | | | $0.36 | $1 |
@@ -109,6 +109,10 @@ const response = await agent.generate("Hello!", {
109
109
 
110
110
  **reasoningEffort** (`"low" | "high" | undefined`)
111
111
 
112
+ **logprobs** (`boolean | undefined`)
113
+
114
+ **topLogprobs** (`number | undefined`)
115
+
112
116
  **parallel\_function\_calling** (`boolean | undefined`)
113
117
 
114
118
  **searchParameters** (`{ mode: "off" | "auto" | "on"; returnCitations?: boolean | undefined; fromDate?: string | undefined; toDate?: string | undefined; maxSearchResults?: number | undefined; sources?: ({ ...; } | ... 2 more ... | { ...; })[] | undefined; } | undefined`)
@@ -8,6 +8,23 @@ Framework-agnostic handler for streaming agent chat in AI SDK-compatible format.
8
8
 
9
9
  Use [`chatRoute()`](https://mastra.ai/reference/ai-sdk/chat-route) if you want to create a chat route inside a Mastra server.
10
10
 
11
+ ## Structured output in UI streams
12
+
13
+ When you pass `structuredOutput` to the underlying agent execution, the final structured output object is emitted in the AI SDK-compatible UI stream as a custom data part:
14
+
15
+ ```json
16
+ {
17
+ "type": "data-structured-output",
18
+ "data": {
19
+ "object": {}
20
+ }
21
+ }
22
+ ```
23
+
24
+ The `object` field contains your full structured output value. Mastra emits this event for the final structured output object only. Partial structured output chunks are not exposed in the UI stream.
25
+
26
+ Read this event with AI SDK UI's custom data handling, such as `onData`, or render it from message data parts.
27
+
11
28
  ## Usage example
12
29
 
13
30
  Next.js App Router example:
@@ -6,6 +6,21 @@ This is useful when building custom streaming endpoints outside Mastra's provide
6
6
 
7
7
  `toAISdkStream()` keeps the existing AI SDK v5/default behavior. If your app is typed against AI SDK v6, pass `version: 'v6'` in the options object.
8
8
 
9
+ ## Structured output in UI streams
10
+
11
+ When the source agent stream includes a final structured output object, `toAISdkStream()` emits it as a custom AI SDK UI data part:
12
+
13
+ ```json
14
+ {
15
+ "type": "data-structured-output",
16
+ "data": {
17
+ "object": {}
18
+ }
19
+ }
20
+ ```
21
+
22
+ The `object` field contains your full structured output value. This maps Mastra's final structured output chunk into the AI SDK UI stream. Partial structured output chunks are not emitted.
23
+
9
24
  ## Usage example
10
25
 
11
26
  Next.js App Router example:
@@ -217,7 +217,7 @@ Organization ID. Can also be set via the `MASTRA_ORG_ID` environment variable.
217
217
 
218
218
  #### `--project`
219
219
 
220
- Project ID. Can also be set via the `MASTRA_PROJECT_ID` environment variable.
220
+ Project ID or slug. Can also be set via the `MASTRA_PROJECT_ID` environment variable.
221
221
 
222
222
  #### `-y, --yes`
223
223
 
@@ -231,6 +231,10 @@ Path to the project config file. Defaults to `.mastra-project.json`.
231
231
 
232
232
  Skip the build step and deploy the existing `.mastra/output` directory.
233
233
 
234
+ #### `--debug`
235
+
236
+ Enable debug logs during the build step.
237
+
234
238
  ### CI/CD usage
235
239
 
236
240
  Set `MASTRA_API_TOKEN`, `MASTRA_ORG_ID`, and `MASTRA_PROJECT_ID` as environment variables for headless deploys. Interactive prompts are skipped automatically when `MASTRA_API_TOKEN` is set.
@@ -283,6 +287,101 @@ Builds and deploys your project to Server on Mastra platform. Works the same as
283
287
  mastra server deploy [dir]
284
288
  ```
285
289
 
290
+ ## `mastra server pause`
291
+
292
+ Pauses the running server instance for the linked project. Organization and project resolution work the same as [`mastra server deploy`](#mastra-server-deploy).
293
+
294
+ ```bash
295
+ mastra server pause
296
+ ```
297
+
298
+ ### Flags
299
+
300
+ #### `--org`
301
+
302
+ Organization ID. Can also be set via the `MASTRA_ORG_ID` environment variable.
303
+
304
+ #### `--project`
305
+
306
+ Project ID or slug when `MASTRA_PROJECT_ID` is not set. Slugs are resolved against projects in the current organization.
307
+
308
+ #### `-c, --config`
309
+
310
+ Path to the project config file. Defaults to `.mastra-project.json`.
311
+
312
+ Fails if the instance is not running.
313
+
314
+ ## `mastra server restart`
315
+
316
+ Restarts a paused or stopped server instance for the linked project. After the platform accepts the restart, the CLI resolves the deploy id (from the API response or by polling project and deploy metadata when the response omits an id), then streams build and deploy logs the same way as [`mastra server deploy`](#mastra-server-deploy) until the deploy reaches a terminal state.
317
+
318
+ ### Flags
319
+
320
+ Same flags as [`mastra server pause`](#mastra-server-pause): **`--org`**, **`--project`**, and **`-c` / `--config`**, with the same defaults and behavior.
321
+
322
+ ```bash
323
+ mastra server restart
324
+ ```
325
+
326
+ Fails if a deployment is still active for this project (running, building, deploying, etc.); that is a platform restriction so you cannot restart while another deploy is in progress.
327
+
328
+ ## `mastra server env`
329
+
330
+ Manages environment variables for the linked server deployment. Organization and project resolution work the same as [`mastra server deploy`](#mastra-server-deploy).
331
+
332
+ Every subcommand accepts `-c` / `--config` for the project config file path (defaults to `.mastra-project.json`).
333
+
334
+ ### `mastra server env list`
335
+
336
+ Lists all environment variables for the linked project. Values are partially masked in the output.
337
+
338
+ ### `mastra server env set`
339
+
340
+ Sets an environment variable. The CLI reads the current map, applies the change, and uploads the result.
341
+
342
+ ```bash
343
+ mastra server env set <key> <value>
344
+ ```
345
+
346
+ ### `mastra server env unset`
347
+
348
+ Removes an environment variable.
349
+
350
+ ```bash
351
+ mastra server env unset <key>
352
+ ```
353
+
354
+ ### `mastra server env import`
355
+
356
+ Imports variables from a file (for example a `.env` file) and merges them into the existing map. New values override keys that already exist on the server.
357
+
358
+ ```bash
359
+ mastra server env import <file>
360
+ ```
361
+
362
+ ### `mastra server env pull`
363
+
364
+ Downloads environment variables from the linked project and writes them to a local file. This is the inverse of [`mastra server env import`](#mastra-server-env-import).
365
+
366
+ ```bash
367
+ mastra server env pull [file]
368
+ ```
369
+
370
+ The file defaults to `.env` when no argument is given. All values are double-quoted and escaped for safe shell sourcing. Keys that aren't valid shell identifiers are skipped. The output file is created with restrictive permissions (`0600`) since it contains secrets.
371
+
372
+ #### `--project`
373
+
374
+ Project ID or slug. Overrides the linked project when `MASTRA_PROJECT_ID` isn't set.
375
+
376
+ #### CI usage
377
+
378
+ In a continuous-integration pipeline, authenticate with `MASTRA_API_TOKEN` and pull the environment before running your app:
379
+
380
+ ```bash
381
+ export MASTRA_API_TOKEN="..."
382
+ mastra server env pull .env.production --project my-project
383
+ ```
384
+
286
385
  ## `mastra auth`
287
386
 
288
387
  Manages authentication for Mastra platform. Credentials are stored in `~/.mastra/credentials.json`. You can also set the `MASTRA_API_TOKEN` environment variable as an alternative to interactive login.
@@ -162,6 +162,7 @@ The Reference section provides documentation of Mastra's API, including paramete
162
162
  - [MessageHistory](https://mastra.ai/reference/processors/message-history-processor)
163
163
  - [ModerationProcessor](https://mastra.ai/reference/processors/moderation-processor)
164
164
  - [PIIDetector](https://mastra.ai/reference/processors/pii-detector)
165
+ - [PrefillErrorHandler](https://mastra.ai/reference/processors/prefill-error-handler)
165
166
  - [Processor Interface](https://mastra.ai/reference/processors/processor-interface)
166
167
  - [PromptInjectionDetector](https://mastra.ai/reference/processors/prompt-injection-detector)
167
168
  - [SemanticRecall](https://mastra.ai/reference/processors/semantic-recall-processor)
@@ -0,0 +1,70 @@
1
+ # PrefillErrorHandler
2
+
3
+ The `PrefillErrorHandler` is an **error processor** that handles the Anthropic "assistant message prefill" error. This error occurs when a conversation ends with an assistant message and the model doesn't support prefilling assistant responses.
4
+
5
+ When the error is detected, the processor appends a hidden `<system-reminder>continue</system-reminder>` user message to the conversation and signals a retry. The reminder is persisted with `metadata.systemReminder = { type: 'anthropic-prefill-processor-retry' }`, which keeps it available for retry reconstruction and raw history while standard UI-facing message conversions hide it.
6
+
7
+ Add this processor to `errorProcessors` when you want Mastra to recover from Anthropic assistant message prefill errors.
8
+
9
+ ## How it works
10
+
11
+ 1. The LLM API call fails with a message containing "assistant message prefill"
12
+ 2. `PrefillErrorHandler` checks that this is the first retry attempt
13
+ 3. It appends a hidden `<system-reminder>continue</system-reminder>` user message to the `messageList`
14
+ 4. It returns `{ retry: true }` to signal the LLM call should be retried with the modified messages
15
+
16
+ The processor now reacts to the API rejection itself instead of re-checking whether the conversation currently ends with an assistant message. This makes it resilient to cases where the provider rejects the request for prefill semantics even if the trailing message shape has already been transformed upstream.
17
+
18
+ ## Usage example
19
+
20
+ Add `PrefillErrorHandler` to `errorProcessors` for any agent that should retry Anthropic prefill failures:
21
+
22
+ ```typescript
23
+ import { Agent } from '@mastra/core/agent'
24
+ import { PrefillErrorHandler } from '@mastra/core/processors'
25
+
26
+ export const agent = new Agent({
27
+ name: 'my-agent',
28
+ instructions: 'You are a helpful assistant.',
29
+ model: 'anthropic/claude-opus-4-6',
30
+ errorProcessors: [new PrefillErrorHandler()],
31
+ })
32
+ ```
33
+
34
+ If you want custom recovery behavior, provide your own error processor with a `processAPIError` method:
35
+
36
+ ```typescript
37
+ import { Agent } from '@mastra/core/agent'
38
+ import type { Processor } from '@mastra/core/processors'
39
+
40
+ const customErrorHandler: Processor = {
41
+ id: 'custom-prefill-error-handler',
42
+ processAPIError({ error, messageList, retryCount }) {
43
+ // Your custom logic here
44
+ },
45
+ }
46
+
47
+ export const agent = new Agent({
48
+ name: 'my-agent',
49
+ instructions: 'You are a helpful assistant.',
50
+ model: 'anthropic/claude-opus-4-6',
51
+ errorProcessors: [customErrorHandler],
52
+ })
53
+ ```
54
+
55
+ ## Constructor parameters
56
+
57
+ The `PrefillErrorHandler` takes no constructor parameters.
58
+
59
+ ## Properties
60
+
61
+ **id** (`'prefill-error-handler'`): Processor identifier.
62
+
63
+ **name** (`'Prefill Error Handler'`): Processor display name.
64
+
65
+ **processAPIError** (`(args: ProcessAPIErrorArgs) => ProcessAPIErrorResult | void`): Handles the Anthropic prefill error by appending a hidden system reminder continue message and signaling retry. Only triggers on the first retry attempt.
66
+
67
+ ## Related
68
+
69
+ - [Processor interface](https://mastra.ai/reference/processors/processor-interface)
70
+ - [Guardrails](https://mastra.ai/docs/agents/guardrails)
@@ -4,7 +4,7 @@ The `Processor` interface defines the contract for all processors in Mastra. Pro
4
4
 
5
5
  ## When processor methods run
6
6
 
7
- The five processor methods run at different points in the agent execution lifecycle:
7
+ The six processor methods run at different points in the agent execution lifecycle:
8
8
 
9
9
  ```text
10
10
  ┌─────────────────────────────────────────────────────────────────┐
@@ -26,10 +26,14 @@ The five processor methods run at different points in the agent execution lifecy
26
26
  │ │ └──────────┬──────────┘ │ │
27
27
  │ │ │ │ │
28
28
  │ │ ▼ │ │
29
- │ │ LLM Execution │ │
30
- │ │ │ │ │
31
- │ │ │ │
32
- │ │ ┌──────────────────────┐ │ │
29
+ │ │ LLM Execution ──── API Error? ──┐ │ │
30
+ │ │ │
31
+ │ │ │ ┌───────────────────┐ │
32
+ │ │ │ │ processAPIError
33
+ │ │ │ └─────────┬─────────┘ │ │
34
+ │ │ │ retry? └── Loop back ──┐ │ │
35
+ │ │ ▼ │ │ │
36
+ │ │ ┌──────────────────────┐ │ │ │
33
37
  │ │ │ processOutputStream │ ← Runs on EACH stream chunk │ │
34
38
  │ │ └──────────┬───────────┘ │ │
35
39
  │ │ │ │ │
@@ -55,13 +59,14 @@ The five processor methods run at different points in the agent execution lifecy
55
59
  └─────────────────────────────────────────────────────────────────┘
56
60
  ```
57
61
 
58
- | Method | When it runs | Use case |
59
- | --------------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
60
- | `processInput` | Once at the start, before the agentic loop | Validate/transform initial user input, add context |
61
- | `processInputStep` | At each step of the agentic loop, before each LLM call | Transform messages between steps, handle tool results |
62
- | `processOutputStream` | On each streaming chunk during LLM response | Filter/modify streaming content, detect patterns in real-time |
63
- | `processOutputStep` | After each LLM response, before tool execution | Validate output quality, implement guardrails with retry |
64
- | `processOutputResult` | Once after generation completes | Post-process final response, log results |
62
+ | Method | When it runs | Use case |
63
+ | --------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------- |
64
+ | `processInput` | Once at the start, before the agentic loop | Validate/transform initial user input, add context |
65
+ | `processInputStep` | At each step of the agentic loop, before each LLM call | Transform messages between steps, handle tool results |
66
+ | `processAPIError` | When an LLM API call fails | Inspect API rejections, optionally mutate state/messages, and request a retry |
67
+ | `processOutputStream` | On each streaming chunk during LLM response | Filter/modify streaming content, detect patterns in real-time |
68
+ | `processOutputStep` | After each LLM response, before tool execution | Validate output quality, implement guardrails with retry |
69
+ | `processOutputResult` | Once after generation completes | Post-process final response, log results |
65
70
 
66
71
  ## Interface definition
67
72
 
@@ -72,6 +77,9 @@ interface Processor<TId extends string = string> {
72
77
 
73
78
  processInput?(args: ProcessInputArgs): Promise<ProcessInputResult> | ProcessInputResult
74
79
  processInputStep?(args: ProcessInputStepArgs): ProcessorMessageResult
80
+ processAPIError?(
81
+ args: ProcessAPIErrorArgs,
82
+ ): Promise<ProcessAPIErrorResult | void> | ProcessAPIErrorResult | void
75
83
  processOutputStream?(args: ProcessOutputStreamArgs): Promise<ChunkType | null | undefined>
76
84
  processOutputStep?(args: ProcessOutputStepArgs): ProcessorMessageResult
77
85
  processOutputResult?(args: ProcessOutputResultArgs): ProcessorMessageResult
@@ -224,6 +232,84 @@ System messages are **reset to their original values** at the start of each step
224
232
 
225
233
  ***
226
234
 
235
+ ### `processAPIError`
236
+
237
+ Handles LLM API rejection errors before they surface as final errors. This runs when the API call fails with a non-retryable error (such as a 400 or 422 status code). Unlike `processOutputStep` which runs after successful responses, this runs when the API rejects the request.
238
+
239
+ Add processors that implement `processAPIError` to an agent's `errorProcessors` array.
240
+
241
+ Processors can inspect the error, modify the request (for example, by appending messages to the `messageList`), and return `{ retry: true }` to signal a retry with the modified state.
242
+
243
+ ```typescript
244
+ processAPIError?(args: ProcessAPIErrorArgs): Promise<ProcessAPIErrorResult | void> | ProcessAPIErrorResult | void;
245
+ ```
246
+
247
+ #### `ProcessAPIErrorArgs`
248
+
249
+ **error** (`unknown`): The error that occurred during the LLM API call.
250
+
251
+ **messages** (`MastraDBMessage[]`): All messages at the time of the error.
252
+
253
+ **messageList** (`MessageList`): MessageList instance for managing messages. Modify this to change the request before retry.
254
+
255
+ **stepNumber** (`number`): Current step number (0-indexed).
256
+
257
+ **steps** (`StepResult[]`): All completed steps so far.
258
+
259
+ **state** (`Record<string, unknown>`): Per-processor state that persists across all method calls within this request.
260
+
261
+ **retryCount** (`number`): The current retry count for error handlers. Use this to limit retry attempts.
262
+
263
+ **abort** (`(reason?: string, options?: { retry?: boolean; metadata?: unknown }) => never`): Function to abort processing.
264
+
265
+ **writer** (`ProcessorStreamWriter`): Stream writer for emitting custom data chunks during streaming. Use \`writer.custom()\` to send transient UI signals.
266
+
267
+ **requestContext** (`RequestContext`): Request context passed through from the agent call.
268
+
269
+ **abortSignal** (`AbortSignal`): Signal for cancelling the operation.
270
+
271
+ #### `ProcessAPIErrorResult`
272
+
273
+ **retry** (`boolean`): Whether to retry the LLM call after applying modifications.
274
+
275
+ #### Use cases
276
+
277
+ - Handling API-specific rejections by modifying the request and retrying
278
+ - Converting non-retryable errors into retryable ones with request modifications
279
+ - Implementing model-specific error recovery strategies
280
+
281
+ #### Example: Custom error recovery
282
+
283
+ ```typescript
284
+ import { APICallError } from '@ai-sdk/provider'
285
+ import type { Processor, ProcessAPIErrorArgs, ProcessAPIErrorResult } from '@mastra/core/processors'
286
+
287
+ export class ErrorRecoveryProcessor implements Processor {
288
+ id = 'error-recovery'
289
+
290
+ processAPIError({
291
+ error,
292
+ messageList,
293
+ retryCount,
294
+ }: ProcessAPIErrorArgs): ProcessAPIErrorResult | void {
295
+ // Only retry once
296
+ if (retryCount > 0) return
297
+
298
+ // Check for a specific API error
299
+ if (APICallError.isInstance(error) && error.message.includes('context length exceeded')) {
300
+ // Trim older messages to fit within context
301
+ const messages = messageList.get.all.db()
302
+ if (messages.length > 4) {
303
+ messageList.removeByIds([messages[1]!.id, messages[2]!.id])
304
+ return { retry: true }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ ```
310
+
311
+ ***
312
+
227
313
  ### `processOutputStream`
228
314
 
229
315
  Processes streaming output chunks with built-in state management. Allows processors to accumulate chunks and make decisions based on larger context.
@@ -368,6 +454,18 @@ type OutputProcessor = Processor &
368
454
  | { processOutputStep: required }
369
455
  | { processOutputResult: required }
370
456
  )
457
+
458
+ // Must implement processAPIError
459
+ type ErrorProcessor = Processor & { processAPIError: required }
460
+ ```
461
+
462
+ Configure processors that implement `processAPIError` in `errorProcessors`:
463
+
464
+ ```typescript
465
+ const agent = new Agent({
466
+ // ...
467
+ errorProcessors: [new PrefillErrorHandler()],
468
+ })
371
469
  ```
372
470
 
373
471
  ## Usage examples
@@ -27,6 +27,34 @@ export const tool = createTool({
27
27
  })
28
28
  ```
29
29
 
30
+ ## Example with strict tool inputs
31
+
32
+ Set `strict: true` when you want Mastra to ask supported model providers to generate tool arguments that exactly match the tool schema.
33
+
34
+ ```typescript
35
+ import { createTool } from '@mastra/core/tools'
36
+ import { z } from 'zod'
37
+
38
+ export const weatherTool = createTool({
39
+ id: 'get-weather',
40
+ description: 'Get weather for a city',
41
+ strict: true,
42
+ inputSchema: z.object({
43
+ city: z.string(),
44
+ units: z.enum(['metric', 'imperial']),
45
+ }),
46
+ execute: async ({ city, units }) => {
47
+ return {
48
+ city,
49
+ units,
50
+ forecast: 'sunny',
51
+ }
52
+ },
53
+ })
54
+ ```
55
+
56
+ Mastra forwards `strict: true` to model adapters that support strict tool calling. On adapters that do not support strict tool calling, Mastra ignores this option.
57
+
30
58
  ## Example with `toModelOutput`
31
59
 
32
60
  Use `toModelOutput` when your tool should return rich internal data to your app, but the model should receive either a simplified value or multimodal content.
@@ -120,6 +148,8 @@ export const weatherTool = createTool({
120
148
 
121
149
  **outputSchema** (`Zod schema`): A Zod schema defining the expected output structure of the tool's \`execute\` function.
122
150
 
151
+ **strict** (`boolean`): When true, Mastra enables strict tool input generation on model adapters that support it. This helps supported providers return arguments that match the tool schema more closely.
152
+
123
153
  **toModelOutput** (`(output: TSchemaOut) => unknown`): Optional function that transforms the tool's \`execute\` output before it is sent back to the model. Use this to return \`text\`, \`json\`, or \`content\`-shaped outputs (including multimodal parts like images/files) to the model while still keeping the full raw output in your application code.
124
154
 
125
155
  **suspendSchema** (`Zod schema`): A Zod schema defining the structure of the payload passed to \`suspend()\`. This payload is returned to the client when the tool suspends execution.
@@ -53,6 +53,51 @@ Each server in the `servers` map is configured using the `MastraMCPServerDefinit
53
53
 
54
54
  **enableServerLogs** (`boolean`): Whether to enable logging for this server. (Default: `true`)
55
55
 
56
+ **requireToolApproval** (`boolean | (params: RequireToolApprovalContext) => boolean | Promise<boolean>`): Require human approval before executing tools from this server. When set to \`true\`, all tools require approval. When set to a function, the function is called with the tool name, arguments, and request context to dynamically decide whether approval is needed.
57
+
58
+ ## Tool approval
59
+
60
+ Use `requireToolApproval` on a server definition to require human approval before any tool from that server is executed. This works with the existing [human-in-the-loop](https://mastra.ai/docs/workflows/human-in-the-loop) approval flow.
61
+
62
+ ### Require approval for all tools
63
+
64
+ Set `requireToolApproval` to `true` to require approval for every tool on the server:
65
+
66
+ ```typescript
67
+ const mcp = new MCPClient({
68
+ servers: {
69
+ github: {
70
+ url: new URL('http://localhost:3000/mcp'),
71
+ requireToolApproval: true,
72
+ },
73
+ },
74
+ })
75
+ ```
76
+
77
+ ### Dynamic approval with a function
78
+
79
+ Pass a function to decide per-call whether approval is needed. The function receives the tool name, the arguments the model passed, and any request context from the incoming request:
80
+
81
+ ```typescript
82
+ const mcp = new MCPClient({
83
+ servers: {
84
+ github: {
85
+ url: new URL('http://localhost:3000/mcp'),
86
+ requireToolApproval: ({ toolName, args, requestContext }) => {
87
+ // Read-only tools don't need approval
88
+ if (toolName === 'list_repos') return false
89
+ // Destructive tools with force flag always need approval
90
+ if (toolName === 'delete_repo') return args.force === true
91
+ // Non-admin users need approval for everything else
92
+ return requestContext?.userRole !== 'admin'
93
+ },
94
+ },
95
+ },
96
+ })
97
+ ```
98
+
99
+ The function can also be async. It receives `requestContext` from the incoming request, which you can use for auth checks or other per-request logic.
100
+
56
101
  ## Methods
57
102
 
58
103
  ### `listTools()`
@@ -13,25 +13,23 @@ const voice = new SarvamVoice()
13
13
  // Or initialize with specific configuration
14
14
  const voiceWithConfig = new SarvamVoice({
15
15
  speechModel: {
16
- model: 'bulbul:v1',
16
+ model: 'bulbul:v3',
17
17
  apiKey: process.env.SARVAM_API_KEY!,
18
18
  language: 'en-IN',
19
19
  properties: {
20
- pitch: 0,
21
- pace: 1.65,
22
- loudness: 1.5,
23
- speech_sample_rate: 8000,
24
- enable_preprocessing: false,
25
- eng_interpolation_wt: 123,
20
+ pace: 1.0,
21
+ temperature: 0.6,
22
+ speech_sample_rate: 24000,
23
+ output_audio_codec: 'wav',
26
24
  },
27
25
  },
28
26
  listeningModel: {
29
- model: 'saarika:v2',
27
+ model: 'saarika:v2.5',
30
28
  apiKey: process.env.SARVAM_API_KEY!,
31
29
  languageCode: 'en-IN',
32
30
  filetype: 'wav',
33
31
  },
34
- speaker: 'meera', // Default voice
32
+ speaker: 'shubh', // Default voice for bulbul:v3
35
33
  })
36
34
 
37
35
  // Convert text to speech
@@ -45,46 +43,52 @@ const text = await voice.listen(audioStream, {
45
43
 
46
44
  ### Sarvam API Docs -
47
45
 
48
- <https://docs.sarvam.ai/api-reference-docs/endpoints/text-to-speech>
46
+ <https://docs.sarvam.ai/api-reference-docs/text-to-speech/convert>
49
47
 
50
48
  ## Configuration
51
49
 
52
50
  ### Constructor options
53
51
 
54
- **speechModel** (`SarvamVoiceConfig`): Configuration for text-to-speech synthesis. (Default: `{ model: 'bulbul:v1', language: 'en-IN' }`)
52
+ **speechModel** (`SarvamVoiceConfig`): Configuration for text-to-speech synthesis. (Default: `{ model: 'bulbul:v3', language: 'en-IN' }`)
55
53
 
56
54
  **speechModel.apiKey** (`string`): Sarvam API key. Falls back to SARVAM\_API\_KEY environment variable.
57
55
 
58
- **speechModel.model** (`SarvamTTSModel`): Specifies the model to use for text-to-speech conversion.
56
+ **speechModel.model** (`SarvamTTSModel`): Specifies the model to use for text-to-speech conversion. Available options: bulbul:v2, bulbul:v3, bulbul:v3-beta. bulbul:v3-beta is a beta variant of bulbul:v3 that shares the same speaker catalog. Note: bulbul:v1 has been deprecated by Sarvam and is no longer supported.
59
57
 
60
58
  **speechModel.language** (`SarvamTTSLanguage`): Target language for speech synthesis. Available options: hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, od-IN, pa-IN, ta-IN, te-IN, en-IN, gu-IN
61
59
 
62
60
  **speechModel.properties** (`object`): Additional voice properties for customization.
63
61
 
64
- **speechModel.properties.pitch** (`number`): Controls the pitch of the audio. Lower values result in a deeper voice, while higher values make it sharper. The suitable range is between -0.75 and 0.75.
62
+ **speechModel.properties.pace** (`number`): Controls the speed of the audio. Supported by both bulbul:v2 (range 0.3–3.0) and bulbul:v3 (range 0.5–2.0).
65
63
 
66
- **speechModel.properties.pace** (`number`): Controls the speed of the audio. Lower values result in slower speech, while higher values make it faster. The suitable range is between 0.5 and 2.0. Default is 1.0. Required range: 0.3 <= x <= 3
64
+ **speechModel.properties.temperature** (`number`): Sampling temperature that controls the randomness of the generated voice. bulbul:v3 only. Range: 0.01–2.0. Default: 0.6.
67
65
 
68
- **speechModel.properties.loudness** (`number`): Controls the loudness of the audio. Lower values result in quieter audio, while higher values make it louder. The suitable range is between 0.3 and 3.0. Required range: 0 <= x <= 3
66
+ **speechModel.properties.dict\_id** (`string`): Pronunciation dictionary ID. bulbul:v3 only.
69
67
 
70
- **speechModel.properties.speech\_sample\_rate** (`8000 | 16000 | 22050`): Audio sample rate in Hz.
68
+ **speechModel.properties.pitch** (`number`): Controls the pitch of the audio. Lower values result in a deeper voice, while higher values make it sharper. bulbul:v2 only. Range: -0.75 to 0.75.
71
69
 
72
- **speechModel.properties.enable\_preprocessing** (`boolean`): Controls whether normalization of English words and numeric entities (e.g., numbers, dates) is performed. Set to true for better handling of mixed-language text. Default is false.
70
+ **speechModel.properties.loudness** (`number`): Controls the loudness of the audio. bulbul:v2 only. Range: 0.3 to 3.0.
73
71
 
74
- **speechModel.properties.eng\_interpolation\_wt** (`number`): Weight for interpolating with English speaker at encoder.
72
+ **speechModel.properties.enable\_preprocessing** (`boolean`): Enables normalization of English words and numeric entities (numbers, dates, etc.). bulbul:v2 only. Default is false.
75
73
 
76
- **speaker** (`SarvamVoiceId`): The speaker to be used for the output audio. If not provided, Meera will be used as default. AvailableOptions - meera, pavithra, maitreyi, arvind, amol, amartya, diya, neel, misha, vian, arjun, maya (Default: `'meera'`)
74
+ **speechModel.properties.speech\_sample\_rate** (`8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000`): Audio sample rate in Hz.
77
75
 
78
- **listeningModel** (`SarvamListenOptions`): Configuration for speech-to-text recognition. (Default: `{ model: 'saarika:v2', language_code: 'unknown' }`)
76
+ **speechModel.properties.output\_audio\_codec** (`'mp3' | 'wav' | 'linear16' | 'mulaw' | 'alaw' | 'opus' | 'flac' | 'aac'`): Output audio codec.
77
+
78
+ **speaker** (`SarvamVoiceId`): The speaker to be used for the output audio. Defaults to 'shubh'. bulbul:v3 supports 39 voices (shubh, aditya, ritu, priya, neha, rahul, pooja, rohan, simran, kavya, amit, dev, ishita, shreya, ratan, varun, manan, sumit, roopa, kabir, aayan, ashutosh, advait, amelia, sophia, anand, tanya, tarun, sunny, mani, gokul, vijay, shruti, suhani, mohit, kavitha, rehan, soham, rupali). bulbul:v2 supports 7 voices (anushka, manisha, vidya, arya, abhilash, karun, hitesh). Speakers are not interchangeable between model versions. (Default: `'shubh'`)
79
+
80
+ **listeningModel** (`SarvamListenOptions`): Configuration for speech-to-text recognition. (Default: `{ model: 'saarika:v2.5', languageCode: 'unknown' }`)
79
81
 
80
82
  **listeningModel.apiKey** (`string`): Sarvam API key. Falls back to SARVAM\_API\_KEY environment variable.
81
83
 
82
- **listeningModel.model** (`SarvamSTTModel`): Specifies the model to use for speech-to-text conversion. Note:- Default model is saarika:v2 . Available options: saarika:v1, saarika:v2, saarika:flash
84
+ **listeningModel.model** (`SarvamSTTModel`): Specifies the model to use for speech-to-text conversion. Available options: saarika:v2.5 (transcription), saaras:v3 (multi-mode: transcribe/translate/verbatim/translit/codemix). Note: saarika:v1, saarika:v2, and saarika:flash have been deprecated by Sarvam.
83
85
 
84
- **listeningModel.languageCode** (`SarvamSTTLanguage`): Specifies the language of the input audio. This parameter is required to ensure accurate transcription. For the saarika:v1 model, this parameter is mandatory. For the saarika:v2 model, it is optional. unknown: Use this when the language is not known; the API will detect it automatically. Note:- that the saarika:v1 model does not support unknown language code. Available options: unknown, hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, od-IN, pa-IN, ta-IN, te-IN, en-IN, gu-IN
86
+ **listeningModel.languageCode** (`SarvamSTTLanguage`): BCP-47 language code of the input audio. Optional for saarika:v2.5 and saaras:v3 (the API will detect the language automatically when 'unknown' is passed). Available options: unknown, hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, od-IN, pa-IN, ta-IN, te-IN, en-IN, gu-IN.
85
87
 
86
88
  **listeningModel.filetype** (`'mp3' | 'wav'`): Audio format of the input stream.
87
89
 
90
+ **listeningModel.mode** (`SarvamSTTMode`): Operation mode. Only valid when using the saaras:v3 model; ignored by saarika:v2.5. Available options: 'transcribe', 'translate', 'verbatim', 'translit', 'codemix'.
91
+
88
92
  ## Methods
89
93
 
90
94
  ### `speak()`
@@ -121,4 +125,6 @@ Returns: `Promise<Array<{voiceId: SarvamVoiceId}>>`
121
125
  - If no API key is provided, the constructor will throw an error
122
126
  - The service communicates with the Sarvam AI API at `https://api.sarvam.ai`
123
127
  - Audio is returned as a stream containing binary audio data
124
- - Speech recognition supports mp3 and wav audio formats
128
+ - Speech recognition supports mp3 and wav audio formats
129
+ - `bulbul:v1`, `saarika:v1`, `saarika:v2`, and `saarika:flash` have been deprecated by Sarvam and are no longer supported. Use `bulbul:v3` (or `bulbul:v2`) for TTS and `saarika:v2.5` (or `saaras:v3`) for STT.
130
+ - Speaker names are not interchangeable between `bulbul:v2` and `bulbul:v3` — each model version has its own speaker catalog.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @mastra/mcp-docs-server
2
2
 
3
+ ## 1.1.25-alpha.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`cbdf3e1`](https://github.com/mastra-ai/mastra/commit/cbdf3e12b3d0c30a6e5347be658e2009648c130a), [`8fe46d3`](https://github.com/mastra-ai/mastra/commit/8fe46d354027f3f0f0846e64219772348de106dd), [`18c67db`](https://github.com/mastra-ai/mastra/commit/18c67dbb9c9ebc26f26f65f7d3ff836e5691ef46), [`8dcc77e`](https://github.com/mastra-ai/mastra/commit/8dcc77e78a5340f5848f74b9e9f1b3da3513c1f5), [`aa67fc5`](https://github.com/mastra-ai/mastra/commit/aa67fc59ee8a5eeff1f23eb05970b8d7a536c8ff), [`fa8140b`](https://github.com/mastra-ai/mastra/commit/fa8140bcd4251d2e3ac85fdc5547dfc4f372b5be), [`190f452`](https://github.com/mastra-ai/mastra/commit/190f45258b0640e2adfc8219fa3258cdc5b8f071), [`7e7bf60`](https://github.com/mastra-ai/mastra/commit/7e7bf606886bf374a6f9d4ca9b09dd83d0533372), [`184907d`](https://github.com/mastra-ai/mastra/commit/184907d775d8609c03c26e78ccaf37315f3aa287), [`5f3d4dd`](https://github.com/mastra-ai/mastra/commit/5f3d4ddf237241f4b238ac062ac61eadabed0770), [`0c4cd13`](https://github.com/mastra-ai/mastra/commit/0c4cd131931c04ac5405373c932a242dbe88edd6), [`b16a753`](https://github.com/mastra-ai/mastra/commit/b16a753d5748440248d7df82e29bb987a9c8386c)]:
8
+ - @mastra/core@1.25.0-alpha.3
9
+ - @mastra/mcp@1.5.0-alpha.0
10
+
3
11
  ## 1.1.25-alpha.5
4
12
 
5
13
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp-docs-server",
3
- "version": "1.1.25-alpha.7",
3
+ "version": "1.1.25-alpha.9",
4
4
  "description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -29,8 +29,8 @@
29
29
  "jsdom": "^26.1.0",
30
30
  "local-pkg": "^1.1.2",
31
31
  "zod": "^4.3.6",
32
- "@mastra/core": "1.25.0-alpha.2",
33
- "@mastra/mcp": "^1.4.2"
32
+ "@mastra/core": "1.25.0-alpha.3",
33
+ "@mastra/mcp": "^1.5.0-alpha.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@hono/node-server": "^1.19.11",
@@ -48,7 +48,7 @@
48
48
  "vitest": "4.0.18",
49
49
  "@internal/lint": "0.0.82",
50
50
  "@internal/types-builder": "0.0.57",
51
- "@mastra/core": "1.25.0-alpha.2"
51
+ "@mastra/core": "1.25.0-alpha.3"
52
52
  },
53
53
  "homepage": "https://mastra.ai",
54
54
  "repository": {