@mastra/mcp-docs-server 1.1.6 → 1.1.7-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.docs/course/02-agent-tools-mcp/07-what-is-zapier-mcp.md +10 -1
  2. package/.docs/course/02-agent-tools-mcp/08-getting-zapier-mcp-url.md +14 -9
  3. package/.docs/course/02-agent-tools-mcp/09-updating-mcp-config-zapier.md +13 -1
  4. package/.docs/course/02-agent-tools-mcp/12-troubleshooting-zapier.md +10 -8
  5. package/.docs/course/02-agent-tools-mcp/13-what-is-github-mcp.md +1 -1
  6. package/.docs/course/02-agent-tools-mcp/14-getting-github-mcp-url.md +28 -20
  7. package/.docs/course/02-agent-tools-mcp/15-updating-mcp-config-github.md +18 -2
  8. package/.docs/course/02-agent-tools-mcp/18-troubleshooting-github.md +5 -5
  9. package/.docs/course/02-agent-tools-mcp/20-updating-mcp-config-hackernews.md +11 -1
  10. package/.docs/course/02-agent-tools-mcp/26-updating-mcp-config-filesystem.md +11 -1
  11. package/.docs/course/02-agent-tools-mcp/32-conclusion.md +1 -1
  12. package/.docs/docs/agents/using-tools.md +34 -0
  13. package/.docs/docs/deployment/studio.md +8 -0
  14. package/.docs/docs/memory/observational-memory.md +3 -5
  15. package/.docs/docs/server/auth/better-auth.md +23 -6
  16. package/.docs/docs/workspace/sandbox.md +2 -0
  17. package/.docs/guides/deployment/vercel.md +19 -0
  18. package/.docs/guides/index.md +20 -1
  19. package/.docs/models/gateways/netlify.md +11 -6
  20. package/.docs/models/gateways/openrouter.md +4 -1
  21. package/.docs/models/gateways/vercel.md +13 -3
  22. package/.docs/models/index.md +1 -1
  23. package/.docs/models/providers/aihubmix.md +7 -1
  24. package/.docs/models/providers/anthropic.md +3 -2
  25. package/.docs/models/providers/baseten.md +7 -5
  26. package/.docs/models/providers/chutes.md +2 -1
  27. package/.docs/models/providers/cloudferro-sherlock.md +74 -0
  28. package/.docs/models/providers/evroc.md +83 -0
  29. package/.docs/models/providers/fireworks-ai.md +20 -26
  30. package/.docs/models/providers/firmware.md +2 -1
  31. package/.docs/models/providers/friendli.md +5 -6
  32. package/.docs/models/providers/google.md +3 -1
  33. package/.docs/models/providers/meganova.md +89 -0
  34. package/.docs/models/providers/opencode-go.md +73 -0
  35. package/.docs/models/providers/opencode.md +33 -33
  36. package/.docs/models/providers/perplexity-agent.md +113 -0
  37. package/.docs/models/providers/perplexity.md +2 -1
  38. package/.docs/models/providers/poe.md +2 -1
  39. package/.docs/models/providers/qihang-ai.md +79 -0
  40. package/.docs/models/providers/qiniu-ai.md +146 -0
  41. package/.docs/models/providers/siliconflow-cn.md +5 -1
  42. package/.docs/models/providers/togetherai.md +2 -1
  43. package/.docs/models/providers/zenmux.md +5 -1
  44. package/.docs/models/providers.md +7 -0
  45. package/.docs/reference/agents/network.md +38 -1
  46. package/.docs/reference/ai-sdk/with-mastra.md +5 -1
  47. package/.docs/reference/deployer/vercel.md +28 -3
  48. package/.docs/reference/harness/harness-class.md +58 -6
  49. package/.docs/reference/index.md +1 -1
  50. package/.docs/reference/memory/cloneThread.md +13 -1
  51. package/.docs/reference/memory/observational-memory.md +4 -2
  52. package/.docs/reference/streaming/agents/stream.md +34 -0
  53. package/.docs/reference/tools/create-tool.md +48 -0
  54. package/.docs/reference/workspace/daytona-sandbox.md +580 -0
  55. package/.docs/reference/workspace/s3-filesystem.md +2 -0
  56. package/CHANGELOG.md +8 -0
  57. package/LICENSE.md +15 -0
  58. package/package.json +5 -5
  59. package/.docs/docs/mastra-code/configuration.md +0 -299
  60. package/.docs/docs/mastra-code/customization.md +0 -228
  61. package/.docs/docs/mastra-code/modes.md +0 -104
  62. package/.docs/docs/mastra-code/overview.md +0 -135
  63. package/.docs/docs/mastra-code/tools.md +0 -229
  64. package/.docs/reference/mastra-code/createMastraCode.md +0 -108
@@ -19,9 +19,11 @@ Direct access to individual AI model providers. Each provider offers unique mode
19
19
  - [Berget.AI](https://mastra.ai/models/providers/berget)
20
20
  - [Cerebras](https://mastra.ai/models/providers/cerebras)
21
21
  - [Chutes](https://mastra.ai/models/providers/chutes)
22
+ - [CloudFerro Sherlock](https://mastra.ai/models/providers/cloudferro-sherlock)
22
23
  - [Cloudflare Workers AI](https://mastra.ai/models/providers/cloudflare-workers-ai)
23
24
  - [Cortecs](https://mastra.ai/models/providers/cortecs)
24
25
  - [Deep Infra](https://mastra.ai/models/providers/deepinfra)
26
+ - [evroc](https://mastra.ai/models/providers/evroc)
25
27
  - [FastRouter](https://mastra.ai/models/providers/fastrouter)
26
28
  - [Fireworks AI](https://mastra.ai/models/providers/fireworks-ai)
27
29
  - [Firmware](https://mastra.ai/models/providers/firmware)
@@ -40,6 +42,7 @@ Direct access to individual AI model providers. Each provider offers unique mode
40
42
  - [Llama](https://mastra.ai/models/providers/llama)
41
43
  - [LMStudio](https://mastra.ai/models/providers/lmstudio)
42
44
  - [LucidQuery AI](https://mastra.ai/models/providers/lucidquery)
45
+ - [Meganova](https://mastra.ai/models/providers/meganova)
43
46
  - [MiniMax (minimax.io)](https://mastra.ai/models/providers/minimax)
44
47
  - [MiniMax (minimaxi.com)](https://mastra.ai/models/providers/minimax-cn)
45
48
  - [MiniMax Coding Plan (minimax.io)](https://mastra.ai/models/providers/minimax-coding-plan)
@@ -55,11 +58,15 @@ Direct access to individual AI model providers. Each provider offers unique mode
55
58
  - [NovitaAI](https://mastra.ai/models/providers/novita-ai)
56
59
  - [Nvidia](https://mastra.ai/models/providers/nvidia)
57
60
  - [Ollama Cloud](https://mastra.ai/models/providers/ollama-cloud)
61
+ - [OpenCode Go](https://mastra.ai/models/providers/opencode-go)
58
62
  - [OpenCode Zen](https://mastra.ai/models/providers/opencode)
59
63
  - [OVHcloud AI Endpoints](https://mastra.ai/models/providers/ovhcloud)
60
64
  - [Perplexity](https://mastra.ai/models/providers/perplexity)
65
+ - [Perplexity Agent](https://mastra.ai/models/providers/perplexity-agent)
61
66
  - [Poe](https://mastra.ai/models/providers/poe)
62
67
  - [Privatemode AI](https://mastra.ai/models/providers/privatemode-ai)
68
+ - [QiHang](https://mastra.ai/models/providers/qihang-ai)
69
+ - [Qiniu](https://mastra.ai/models/providers/qiniu-ai)
63
70
  - [Requesty](https://mastra.ai/models/providers/requesty)
64
71
  - [Scaleway](https://mastra.ai/models/providers/scaleway)
65
72
  - [SiliconFlow](https://mastra.ai/models/providers/siliconflow)
@@ -44,6 +44,10 @@ await agent.network(`
44
44
 
45
45
  **maxSteps?:** (`number`): Maximum number of steps to run during execution.
46
46
 
47
+ **abortSignal?:** (`AbortSignal`): Signal to abort the network execution. When aborted, the network stops routing, cancels any in-progress sub-agent, tool, or workflow execution, and skips saving partial results to memory.
48
+
49
+ **onAbort?:** (`(event: { primitiveType: string; primitiveId: string; iteration: number }) => void | Promise<void>`): Callback fired when the network is aborted. Receives an event with the type and ID of the primitive that was executing when the abort occurred.
50
+
47
51
  **memory?:** (`object`): thread:string | { id: string; metadata?: Record\<string, any>, title?: string }The conversation thread, as a string ID or an object with an \`id\` and optional \`metadata\`.resource:stringIdentifier for the user or resource associated with the thread.options?:MemoryConfigConfiguration for memory behavior, like message history and semantic recall.
48
52
 
49
53
  **tracingContext?:** (`TracingContext`): currentSpan?:SpanCurrent span for creating child spans and adding metadata. Use this to create custom child spans or update span attributes during execution.
@@ -62,6 +66,10 @@ await agent.network(`
62
66
 
63
67
  **traceId?:** (`string`): The trace ID associated with this execution when Tracing is enabled. Use this to correlate logs and debug execution flow.
64
68
 
69
+ **onStepFinish?:** (`(event: any) => Promise<void> | void`): Callback fired after each LLM step within a sub-agent execution. Receives step details including finish reason and token usage.
70
+
71
+ **onError?:** (`({ error }: { error: Error | string }) => Promise<void> | void`): Callback fired when an error occurs during sub-agent execution.
72
+
65
73
  ## Returns
66
74
 
67
75
  **stream:** (`MastraAgentNetworkStream<NetworkChunkType>`): A custom stream that extends ReadableStream\<NetworkChunkType> with additional network-specific properties
@@ -130,4 +138,33 @@ const final = await stream.object
130
138
  When using structured output, additional chunk types are emitted:
131
139
 
132
140
  - `network-object`: Emitted with partial objects during streaming
133
- - `network-object-result`: Emitted with the final structured object
141
+ - `network-object-result`: Emitted with the final structured object
142
+
143
+ ## Aborting a Network
144
+
145
+ Use `abortSignal` to cancel a running network. When aborted, the network stops routing, cancels any in-progress sub-agent, tool, or workflow execution, and does not save partial results to memory.
146
+
147
+ ```typescript
148
+ const controller = new AbortController()
149
+
150
+ // Abort after 30 seconds
151
+ setTimeout(() => controller.abort(), 30_000)
152
+
153
+ const stream = await agent.network('Research this topic thoroughly', {
154
+ abortSignal: controller.signal,
155
+ onAbort: ({ primitiveType, primitiveId, iteration }) => {
156
+ console.log(`Aborted ${primitiveType} "${primitiveId}" at iteration ${iteration}`)
157
+ },
158
+ })
159
+
160
+ for await (const chunk of stream) {
161
+ if (
162
+ chunk.type === 'routing-agent-abort' ||
163
+ chunk.type === 'agent-execution-abort' ||
164
+ chunk.type === 'tool-execution-abort' ||
165
+ chunk.type === 'workflow-execution-abort'
166
+ ) {
167
+ console.log('Network was aborted')
168
+ }
169
+ }
170
+ ```
@@ -56,4 +56,8 @@ const { text } = await generateText({
56
56
 
57
57
  ## Returns
58
58
 
59
- A wrapped model compatible with `generateText`, `streamText`, `generateObject`, and `streamObject`.
59
+ A wrapped model compatible with `generateText`, `streamText`, `generateObject`, and `streamObject`.
60
+
61
+ ## Streaming behavior
62
+
63
+ Output processors that implement `processOutputResult` run after the stream finishes. Consume the stream to completion to persist message history and semantic recall.
@@ -45,13 +45,14 @@ export const mastra = new Mastra({
45
45
 
46
46
  ## Constructor options
47
47
 
48
- The deployer accepts overrides that are written to the Vercel Output API function config (`.vc-config.json`):
48
+ The deployer accepts the following options:
49
49
 
50
+ - `studio?: boolean` — Deploy [Studio](https://mastra.ai/docs/getting-started/studio) alongside your API as static assets served from Vercel's Edge CDN. Defaults to `false`.
50
51
  - `maxDuration?: number` — Function execution timeout (in seconds)
51
52
  - `memory?: number` — Function memory (in MB)
52
53
  - `regions?: string[]` — Regions to deploy the function (e.g. `['sfo1','iad1']`)
53
54
 
54
- These options are merged into `.vercel/output/functions/index.func/.vc-config.json` while preserving default fields (`handler`, `launcherType`, `runtime`, `shouldAddHelpers`).
55
+ The `maxDuration`, `memory`, and `regions` options are merged into `.vercel/output/functions/index.func/.vc-config.json` while preserving default fields (`handler`, `launcherType`, `runtime`, `shouldAddHelpers`).
55
56
 
56
57
  ### Example with overrides
57
58
 
@@ -61,6 +62,7 @@ import { VercelDeployer } from '@mastra/deployer-vercel'
61
62
 
62
63
  export const mastra = new Mastra({
63
64
  deployer: new VercelDeployer({
65
+ studio: true,
64
66
  maxDuration: 600,
65
67
  memory: 1536,
66
68
  regions: ['sfo1', 'iad1'],
@@ -74,13 +76,34 @@ After running `mastra build`, the deployer generates a `.vercel/output` director
74
76
 
75
77
  The output contains:
76
78
 
77
- - **config.json** — Routing configuration that directs all requests to your function
79
+ - **config.json** — Routing configuration that directs requests to the appropriate handler
78
80
  - **functions/** — Your Mastra server bundled as a serverless function
81
+ - **static/** — Studio SPA assets (only when `studio: true`)
82
+
83
+ Without studio:
84
+
85
+ ```bash
86
+ .vercel/
87
+ └── output/
88
+ ├── config.json
89
+ └── functions/
90
+ └── index.func/
91
+ ├── .vc-config.json
92
+ ├── index.mjs
93
+ └── node_modules/
94
+ ```
95
+
96
+ With `studio: true`:
79
97
 
80
98
  ```bash
81
99
  .vercel/
82
100
  └── output/
83
101
  ├── config.json
102
+ ├── static/
103
+ │ ├── index.html
104
+ │ └── assets/
105
+ │ ├── *.js
106
+ │ └── *.css
84
107
  └── functions/
85
108
  └── index.func/
86
109
  ├── .vc-config.json
@@ -88,4 +111,6 @@ The output contains:
88
111
  └── node_modules/
89
112
  ```
90
113
 
114
+ When studio is enabled, the routing is configured so that `/api/*` requests are handled by the serverless function, static assets (JS, CSS) are served from Vercel's Edge CDN with no function invocations, and all other paths fall back to `index.html` for client-side routing.
115
+
91
116
  This folder is generated during build and should not be committed to version control.
@@ -2,6 +2,8 @@
2
2
 
3
3
  **Added in:** `@mastra/core@1.5.0`
4
4
 
5
+ > **Warning:** The `Harness` class is in alpha stage and subject to change. It won't follow semantic versioning guarantees until it graduates from experimental status. Use with caution and expect breaking changes in minor versions.
6
+
5
7
  The `Harness` class orchestrates multiple agent modes, shared state, memory, and storage. It provides a control layer that a TUI or other UI can drive to manage threads, switch models and modes, send messages, handle tool approvals, and track events.
6
8
 
7
9
  ## Usage example
@@ -106,6 +108,10 @@ Each entry in the `subagents` array defines a subagent the harness can spawn.
106
108
 
107
109
  **defaultModelId?:** (`string`): Default model ID for this subagent type.
108
110
 
111
+ **maxSteps?:** (`number`): Optional maximum number of steps for the spawned subagent. Defaults to \`50\` when omitted.
112
+
113
+ **stopWhen?:** (`LoopOptions['stopWhen']`): Optional stop condition for the spawned subagent.
114
+
109
115
  ## Properties
110
116
 
111
117
  **id:** (`string`): Harness identifier, set at construction.
@@ -302,6 +308,23 @@ Update the title of the current thread.
302
308
  await harness.renameThread({ title: 'Updated title' })
303
309
  ```
304
310
 
311
+ #### `cloneThread({ sourceThreadId?, title?, resourceId? })`
312
+
313
+ Clone an existing thread and switch to the clone. Copies all messages, acquires a lock on the new thread, releases the lock on the previous thread, and emits a `thread_created` event. If `sourceThreadId` is omitted, the current thread is cloned. When [Observational Memory](https://mastra.ai/docs/memory/observational-memory) is enabled, OM records are cloned with remapped message IDs.
314
+
315
+ ```typescript
316
+ // Clone the current thread
317
+ const cloned = await harness.cloneThread()
318
+
319
+ // Clone a specific thread with a custom title
320
+ const cloned = await harness.cloneThread({
321
+ sourceThreadId: 'thread-abc123',
322
+ title: 'Alternative approach',
323
+ })
324
+ ```
325
+
326
+ See [`Memory.cloneThread()`](https://mastra.ai/reference/memory/cloneThread) for details on what gets cloned.
327
+
305
328
  #### `getResourceId()`
306
329
 
307
330
  Return the current resource ID.
@@ -329,9 +352,9 @@ const session = await harness.getSession()
329
352
 
330
353
  ### Messages
331
354
 
332
- #### `sendMessage({ content, images? })`
355
+ #### `sendMessage({ content, files?, requestContext? })`
333
356
 
334
- Send a message to the current agent. Creates a thread if none exists, builds a `RequestContext` and toolsets, and streams the agent's response. Handles tool calls, approvals, and errors automatically.
357
+ Send a message to the current agent. Creates a thread if none exists, builds a `RequestContext` and toolsets, and streams the agent's response. Handles tool calls, approvals, and errors automatically. If you provide `requestContext`, the harness forwards it to tools and subagents during the run.
335
358
 
336
359
  ```typescript
337
360
  await harness.sendMessage({ content: 'Explain the authentication flow' })
@@ -364,6 +387,34 @@ Retrieve the first user message for a given thread.
364
387
  const firstMsg = await harness.getFirstUserMessageForThread({ threadId: 'thread-abc123' })
365
388
  ```
366
389
 
390
+ ### Memory
391
+
392
+ The `memory` property exposes thread management operations. These are also available as top-level methods on the harness.
393
+
394
+ #### `memory.createThread({ title? })`
395
+
396
+ Create a new thread. Same as `harness.createThread()`.
397
+
398
+ #### `memory.switchThread({ threadId })`
399
+
400
+ Switch to a different thread. Same as `harness.switchThread()`.
401
+
402
+ #### `memory.listThreads(options?)`
403
+
404
+ List threads from storage. Same as `harness.listThreads()`.
405
+
406
+ #### `memory.renameThread({ title })`
407
+
408
+ Update the title of the current thread. Same as `harness.renameThread()`.
409
+
410
+ #### `memory.deleteThread({ threadId })`
411
+
412
+ Delete a thread and all its messages from storage. If the deleted thread is the currently active thread, the thread lock is released and the harness clears its active thread. Emits a `thread_deleted` event.
413
+
414
+ ```typescript
415
+ await harness.memory.deleteThread({ threadId: 'thread-abc123' })
416
+ ```
417
+
367
418
  ### Flow control
368
419
 
369
420
  #### `abort()`
@@ -374,7 +425,7 @@ Abort any in-progress generation.
374
425
  harness.abort()
375
426
  ```
376
427
 
377
- #### `steer({ content })`
428
+ #### `steer({ content, requestContext? })`
378
429
 
379
430
  Steer the agent mid-stream by injecting an instruction into the current generation.
380
431
 
@@ -382,7 +433,7 @@ Steer the agent mid-stream by injecting an instruction into the current generati
382
433
  harness.steer({ content: 'Focus on security implications' })
383
434
  ```
384
435
 
385
- #### `followUp({ content })`
436
+ #### `followUp({ content, requestContext? })`
386
437
 
387
438
  Queue a follow-up message to be sent after the current generation completes. If no operation is running, sends the message immediately.
388
439
 
@@ -392,7 +443,7 @@ harness.followUp({ content: 'Now apply those changes' })
392
443
 
393
444
  ### Tool approvals
394
445
 
395
- #### `respondToToolApproval({ decision })`
446
+ #### `respondToToolApproval({ decision, requestContext? })`
396
447
 
397
448
  Respond to a pending tool approval request. Called when a `tool_approval_required` event is received.
398
449
 
@@ -494,7 +545,7 @@ Return the current workspace instance, or `undefined` if no workspace is configu
494
545
  const workspace = harness.getWorkspace()
495
546
  ```
496
547
 
497
- #### `resolveWorkspace()`
548
+ #### `resolveWorkspace({ requestContext? })`
498
549
 
499
550
  Eagerly resolve and cache the workspace. For dynamic workspaces (factory function), this triggers the factory and caches the result so `getWorkspace()` returns it. Returns the resolved workspace or `undefined` if none is configured.
500
551
 
@@ -659,6 +710,7 @@ The harness emits events through registered listeners. The following table lists
659
710
  | `model_changed` | The active model changed. |
660
711
  | `thread_changed` | The active thread changed. |
661
712
  | `thread_created` | A new thread was created. |
713
+ | `thread_deleted` | A thread was deleted. |
662
714
  | `state_changed` | Harness state was updated. |
663
715
  | `agent_start` | The agent started processing. |
664
716
  | `agent_end` | The agent finished processing. |
@@ -106,7 +106,6 @@ The Reference section provides documentation of Mastra's API, including paramete
106
106
  - [Tool Call Accuracy Scorers](https://mastra.ai/reference/evals/tool-call-accuracy)
107
107
  - [Toxicity](https://mastra.ai/reference/evals/toxicity)
108
108
  - [Harness Class](https://mastra.ai/reference/harness/harness-class)
109
- - [createMastraCode()](https://mastra.ai/reference/mastra-code/createMastraCode)
110
109
  - [Cloned Thread Utilities](https://mastra.ai/reference/memory/clone-utilities)
111
110
  - [Memory Class](https://mastra.ai/reference/memory/memory-class)
112
111
  - [Observational Memory](https://mastra.ai/reference/memory/observational-memory)
@@ -267,6 +266,7 @@ The Reference section provides documentation of Mastra's API, including paramete
267
266
  - [.start()](https://mastra.ai/reference/workflows/run-methods/start)
268
267
  - [.startAsync()](https://mastra.ai/reference/workflows/run-methods/startAsync)
269
268
  - [.timeTravel()](https://mastra.ai/reference/workflows/run-methods/timeTravel)
269
+ - [DaytonaSandbox](https://mastra.ai/reference/workspace/daytona-sandbox)
270
270
  - [E2BSandbox](https://mastra.ai/reference/workspace/e2b-sandbox)
271
271
  - [GCSFilesystem](https://mastra.ai/reference/workspace/gcs-filesystem)
272
272
  - [LocalFilesystem](https://mastra.ai/reference/workspace/local-filesystem)
@@ -44,6 +44,8 @@ const { thread, clonedMessages } = await memory.cloneThread({
44
44
 
45
45
  **clonedMessages:** (`MastraDBMessage[]`): Array of the cloned messages with new IDs assigned to the new thread.
46
46
 
47
+ **messageIdMap?:** (`Record<string, string>`): A mapping from source message IDs to their corresponding cloned message IDs.
48
+
47
49
  ### Clone Metadata
48
50
 
49
51
  The cloned thread's metadata includes a `clone` property with:
@@ -127,4 +129,14 @@ const results = await memory.recall({
127
129
  threadId: thread.id,
128
130
  vectorSearchString: 'search query',
129
131
  })
130
- ```
132
+ ```
133
+
134
+ ## Observational Memory
135
+
136
+ When [Observational Memory](https://mastra.ai/docs/memory/observational-memory) is enabled, `cloneThread()` automatically clones the OM records associated with the source thread. The behavior depends on the OM scope:
137
+
138
+ - **Thread-scoped OM**: The OM record is cloned to the new thread. All internal message ID references are remapped to point to the cloned messages.
139
+ - **Resource-scoped OM (same `resourceId`)**: The OM record is shared between the source and cloned threads since they belong to the same resource. No duplication occurs.
140
+ - **Resource-scoped OM (different `resourceId`)**: The OM record is cloned to the new resource. Message IDs are remapped and any thread-identifying tags within observations are updated to reference the cloned thread.
141
+
142
+ Only the current (most recent) OM generation is cloned — older history generations are not copied. Transient processing state (observation/reflection in-progress flags) is reset on the cloned record.
@@ -107,6 +107,8 @@ export const agent = new Agent({
107
107
 
108
108
  ### Shared token budget
109
109
 
110
+ When `shareTokenBudget` is enabled, the total budget is `observation.messageTokens + reflection.observationTokens` (100k in this example). If observations only use 30k tokens, messages can expand to use up to 70k. If messages are short, observations have more room before triggering reflection.
111
+
110
112
  ```typescript
111
113
  import { Memory } from '@mastra/memory'
112
114
  import { Agent } from '@mastra/core/agent'
@@ -132,10 +134,10 @@ export const agent = new Agent({
132
134
  })
133
135
  ```
134
136
 
135
- When `shareTokenBudget` is enabled, the total budget is `observation.messageTokens + reflection.observationTokens` (100k in this example). If observations only use 30k tokens, messages can expand to use up to 70k. If messages are short, observations have more room before triggering reflection.
136
-
137
137
  ### Custom model
138
138
 
139
+ By passing a `model` in the config, you can use any model from Mastra's model router.
140
+
139
141
  ```typescript
140
142
  import { Memory } from '@mastra/memory'
141
143
  import { Agent } from '@mastra/core/agent'
@@ -211,6 +211,40 @@ await agent.stream('message for agent', {
211
211
  })
212
212
  ```
213
213
 
214
+ ## OpenAI WebSocket Transport
215
+
216
+ Opt into OpenAI Responses WebSocket streaming via `providerOptions.openai.transport`. This only applies to streaming calls and is currently supported for direct OpenAI models (for example, `openai/gpt-4o`). If WebSocket streaming is unavailable, Mastra falls back to HTTP streaming. By default, Mastra closes the WebSocket when the stream finishes.
217
+
218
+ ```ts
219
+ const stream = await agent.stream('Hello', {
220
+ providerOptions: {
221
+ openai: {
222
+ transport: 'websocket', // 'websocket' | 'fetch' | 'auto'
223
+ websocket: {
224
+ url: 'wss://api.openai.com/v1/responses',
225
+ closeOnFinish: true, // default
226
+ },
227
+ },
228
+ },
229
+ })
230
+ ```
231
+
232
+ To keep the connection open after the stream finishes, set `closeOnFinish: false` and close it manually.
233
+
234
+ ```ts
235
+ const stream = await agent.stream('Hello', {
236
+ providerOptions: {
237
+ openai: {
238
+ transport: 'websocket',
239
+ websocket: { closeOnFinish: false },
240
+ },
241
+ },
242
+ })
243
+
244
+ // Later, when you're done with the connection:
245
+ stream.transport?.close()
246
+ ```
247
+
214
248
  ## Related
215
249
 
216
250
  - [Generating responses](https://mastra.ai/docs/agents/overview)
@@ -27,6 +27,52 @@ export const tool = createTool({
27
27
  })
28
28
  ```
29
29
 
30
+ ## Example with `toModelOutput`
31
+
32
+ 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.
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
+ inputSchema: z.object({
42
+ city: z.string(),
43
+ }),
44
+ outputSchema: z.object({
45
+ city: z.string(),
46
+ temperature: z.number(),
47
+ condition: z.string(),
48
+ radarImageUrl: z.string().url(),
49
+ }),
50
+ execute: async ({ city }) => ({
51
+ city,
52
+ temperature: 72,
53
+ condition: 'sunny',
54
+ radarImageUrl: 'https://example.com/radar/seattle.png',
55
+ }),
56
+ toModelOutput: output => {
57
+ return {
58
+ type: 'content',
59
+ value: [
60
+ { type: 'text', text: `${output.city}: ${output.temperature}F and ${output.condition}` },
61
+ { type: 'image-url', url: output.radarImageUrl },
62
+ ],
63
+ }
64
+ },
65
+ })
66
+ ```
67
+
68
+ The tool still returns the full `execute` result to your application, while the model receives the transformed `toModelOutput` value.
69
+
70
+ `toModelOutput` can return:
71
+
72
+ - `type: 'text'`
73
+ - `type: 'json'`
74
+ - `type: 'content'` with parts like `text`, `image-url`, `image-data`, `file-url`, `file-data`, `file-id`, `image-file-id`, or `custom`
75
+
30
76
  ## Example with MCP Annotations
31
77
 
32
78
  When exposing tools via MCP (Model Context Protocol), you can add annotations to describe tool behavior and customize how clients display the tool. These MCP-specific properties are grouped under the `mcp` property:
@@ -74,6 +120,8 @@ export const weatherTool = createTool({
74
120
 
75
121
  **outputSchema?:** (`Zod schema`): A Zod schema defining the expected output structure of the tool's \`execute\` function.
76
122
 
123
+ **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
+
77
125
  **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.
78
126
 
79
127
  **resumeSchema?:** (`Zod schema`): A Zod schema defining the expected structure of \`resumeData\` when the tool is resumed. Used by the agent to extract data from user messages when \`autoResumeSuspendedTools\` is enabled.