@mastra/mcp-docs-server 1.1.46-alpha.3 → 1.1.46

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 (145) hide show
  1. package/.docs/docs/agent-builder/browser.md +1 -1
  2. package/.docs/docs/agent-builder/channels.md +1 -1
  3. package/.docs/docs/agent-builder/integrations.md +73 -0
  4. package/.docs/docs/agent-builder/overview.md +1 -0
  5. package/.docs/docs/agents/adding-voice.md +1 -1
  6. package/.docs/docs/agents/agent-approval.md +2 -2
  7. package/.docs/docs/agents/background-tasks.md +1 -1
  8. package/.docs/docs/agents/channels.md +2 -2
  9. package/.docs/docs/agents/code-mode.md +20 -56
  10. package/.docs/docs/agents/overview.md +1 -0
  11. package/.docs/docs/agents/sdk-agents.md +165 -1
  12. package/.docs/docs/agents/supervisor-agents.md +40 -2
  13. package/.docs/docs/agents/using-tools.md +59 -1
  14. package/.docs/docs/browser/agent-browser.md +1 -1
  15. package/.docs/docs/browser/browser-viewer.md +22 -15
  16. package/.docs/docs/browser/overview.md +1 -1
  17. package/.docs/docs/browser/stagehand.md +1 -1
  18. package/.docs/docs/editor/overview.md +6 -6
  19. package/.docs/docs/editor/prompts.md +3 -3
  20. package/.docs/docs/editor/tools.md +2 -2
  21. package/.docs/docs/evals/evals-with-memory.md +8 -8
  22. package/.docs/docs/mastra-platform/observability.md +1 -1
  23. package/.docs/docs/mastra-platform/server.md +1 -1
  24. package/.docs/docs/mcp/mcp-apps.md +4 -4
  25. package/.docs/docs/memory/observational-memory.md +1 -1
  26. package/.docs/docs/memory/working-memory.md +2 -2
  27. package/.docs/docs/observability/integrations/bridges/datadog.md +1 -1
  28. package/.docs/docs/observability/integrations/bridges/otel.md +1 -1
  29. package/.docs/docs/observability/integrations/exporters/laminar.md +1 -1
  30. package/.docs/docs/observability/integrations/exporters/langfuse.md +26 -1
  31. package/.docs/docs/observability/integrations/exporters/mastra-platform.md +1 -1
  32. package/.docs/docs/observability/integrations/exporters/mastra-storage.md +4 -4
  33. package/.docs/docs/observability/integrations/exporters/otel.md +1 -1
  34. package/.docs/docs/observability/integrations/overview.md +1 -1
  35. package/.docs/docs/observability/logging.md +1 -1
  36. package/.docs/docs/observability/metrics/overview.md +3 -3
  37. package/.docs/docs/observability/metrics/querying.md +2 -2
  38. package/.docs/docs/observability/storage.md +2 -2
  39. package/.docs/docs/observability/tracing/overview.md +1 -1
  40. package/.docs/docs/server/auth/fga.md +15 -15
  41. package/.docs/docs/server/auth/okta.md +2 -2
  42. package/.docs/docs/server/auth/workos.md +1 -1
  43. package/.docs/docs/server/custom-api-routes.md +1 -1
  44. package/.docs/docs/server/pubsub.md +4 -4
  45. package/.docs/docs/studio/auth.md +1 -1
  46. package/.docs/docs/studio/observability.md +3 -1
  47. package/.docs/docs/workflows/scheduled-workflows.md +13 -13
  48. package/.docs/docs/workspace/filesystem.md +1 -1
  49. package/.docs/docs/workspace/lsp.md +1 -1
  50. package/.docs/docs/workspace/overview.md +35 -1
  51. package/.docs/docs/workspace/sandbox.md +4 -3
  52. package/.docs/guides/build-your-ui/ai-sdk-ui.md +2 -2
  53. package/.docs/guides/deployment/aws-bedrock-agentcore.md +3 -3
  54. package/.docs/guides/deployment/inngest.md +5 -5
  55. package/.docs/guides/deployment/temporal.md +3 -3
  56. package/.docs/guides/getting-started/nestjs.md +1 -1
  57. package/.docs/guides/migrations/mastra-cloud.md +3 -3
  58. package/.docs/guides/migrations/upgrade-to-v1/overview.md +1 -1
  59. package/.docs/guides/migrations/upgrade-to-v1/tracing.md +1 -1
  60. package/.docs/reference/acp/acp-agent.md +2 -2
  61. package/.docs/reference/agents/agent.md +44 -0
  62. package/.docs/reference/agents/channels.md +1 -1
  63. package/.docs/reference/agents/durable-agent.md +2 -2
  64. package/.docs/reference/agents/generate.md +2 -0
  65. package/.docs/reference/agents/generateLegacy.md +2 -0
  66. package/.docs/reference/ai-sdk/handle-chat-stream.md +1 -1
  67. package/.docs/reference/ai-sdk/to-ai-sdk-stream.md +1 -1
  68. package/.docs/reference/auth/okta.md +1 -1
  69. package/.docs/reference/auth/workos.md +1 -1
  70. package/.docs/reference/browser/agent-browser.md +1 -1
  71. package/.docs/reference/browser/browser-viewer.md +11 -9
  72. package/.docs/reference/browser/stagehand-browser.md +1 -1
  73. package/.docs/reference/cli/mastra.md +3 -1
  74. package/.docs/reference/client-js/responses.md +2 -2
  75. package/.docs/reference/client-js/workflows.md +1 -1
  76. package/.docs/reference/configuration.md +1 -1
  77. package/.docs/reference/core/removeWorkspace.md +26 -0
  78. package/.docs/reference/editor/browser-provider.md +1 -1
  79. package/.docs/reference/editor/storage-browser-ref.md +3 -3
  80. package/.docs/reference/editor/storage-workspace-ref.md +1 -1
  81. package/.docs/reference/evals/rubric.md +113 -0
  82. package/.docs/reference/evals/trajectory-accuracy.md +3 -3
  83. package/.docs/reference/harness/harness-class.md +81 -62
  84. package/.docs/reference/index.md +5 -0
  85. package/.docs/reference/memory/serialized-memory-config.md +1 -1
  86. package/.docs/reference/observability/metrics/automatic-metrics.md +3 -3
  87. package/.docs/reference/observability/tracing/bridges/datadog.md +1 -1
  88. package/.docs/reference/observability/tracing/exporters/cloud-exporter.md +3 -3
  89. package/.docs/reference/observability/tracing/exporters/default-exporter.md +1 -1
  90. package/.docs/reference/observability/tracing/exporters/mastra-platform-exporter.md +5 -5
  91. package/.docs/reference/observability/tracing/exporters/mastra-storage-exporter.md +1 -1
  92. package/.docs/reference/observability/tracing/exporters/otel.md +1 -1
  93. package/.docs/reference/observability/tracing/processors/sensitive-data-filter.md +2 -2
  94. package/.docs/reference/processors/cost-guard-processor.md +2 -2
  95. package/.docs/reference/processors/processor-interface.md +4 -4
  96. package/.docs/reference/processors/response-cache.md +2 -2
  97. package/.docs/reference/processors/skill-search-processor.md +3 -3
  98. package/.docs/reference/processors/tool-search-processor.md +108 -4
  99. package/.docs/reference/pubsub/base.md +1 -1
  100. package/.docs/reference/pubsub/caching-pubsub.md +2 -2
  101. package/.docs/reference/pubsub/event-emitter.md +3 -3
  102. package/.docs/reference/pubsub/google-cloud-pubsub.md +1 -1
  103. package/.docs/reference/pubsub/redis-streams.md +1 -1
  104. package/.docs/reference/pubsub/unix-socket-pubsub.md +1 -1
  105. package/.docs/reference/server/nestjs-adapter.md +2 -2
  106. package/.docs/reference/signals/task-signal-provider.md +62 -0
  107. package/.docs/reference/storage/clickhouse.md +49 -4
  108. package/.docs/reference/storage/composite.md +33 -1
  109. package/.docs/reference/storage/convex.md +2 -2
  110. package/.docs/reference/storage/dsql.md +7 -7
  111. package/.docs/reference/storage/duckdb.md +3 -3
  112. package/.docs/reference/storage/redis.md +3 -3
  113. package/.docs/reference/storage/spanner.md +7 -7
  114. package/.docs/reference/streaming/agents/stream.md +2 -0
  115. package/.docs/reference/streaming/agents/streamLegacy.md +2 -0
  116. package/.docs/reference/streaming/agents/streamUntilIdle.md +1 -1
  117. package/.docs/reference/tools/brightdata.md +3 -3
  118. package/.docs/reference/tools/create-code-mode.md +124 -0
  119. package/.docs/reference/tools/create-tool.md +1 -1
  120. package/.docs/reference/tools/mcp-client.md +5 -5
  121. package/.docs/reference/tools/mcp-server.md +45 -0
  122. package/.docs/reference/tools/perplexity.md +4 -4
  123. package/.docs/reference/tools/tavily.md +3 -3
  124. package/.docs/reference/voice/aws-nova-sonic.md +1 -1
  125. package/.docs/reference/voice/google-gemini-live.md +1 -1
  126. package/.docs/reference/voice/inworld-realtime.md +5 -5
  127. package/.docs/reference/voice/inworld.md +1 -1
  128. package/.docs/reference/voice/sarvam.md +1 -1
  129. package/.docs/reference/workspace/agentcore-runtime-sandbox.md +7 -7
  130. package/.docs/reference/workspace/azure-blob-filesystem.md +2 -2
  131. package/.docs/reference/workspace/files-sdk-filesystem.md +3 -3
  132. package/.docs/reference/workspace/google-drive-filesystem.md +7 -7
  133. package/.docs/reference/workspace/modal-sandbox.md +1 -1
  134. package/.docs/reference/workspace/railway-sandbox.md +230 -0
  135. package/.docs/reference/workspace/vercel-microvm-sandbox.md +1 -1
  136. package/.docs/reference/workspace/vercel.md +2 -2
  137. package/.docs/reference/workspace/workspace-class.md +39 -3
  138. package/CHANGELOG.md +20 -0
  139. package/dist/chunk-GLPCVXXO.js +2075 -0
  140. package/dist/chunk-GLPCVXXO.js.map +1 -0
  141. package/dist/index.js +3 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/stdio.js +1 -2070
  144. package/dist/stdio.js.map +1 -1
  145. package/package.json +6 -6
@@ -22,7 +22,7 @@ OKTA_COOKIE_PASSWORD=a-random-string-at-least-32-characters-long
22
22
  OKTA_API_TOKEN=your-api-token
23
23
  ```
24
24
 
25
- > **Note:** `OKTA_COOKIE_PASSWORD` encrypts session cookies. If omitted, an auto-generated value is used that does not survive server restarts. Set it explicitly for production.
25
+ > **Note:** `OKTA_COOKIE_PASSWORD` encrypts session cookies. If omitted, an auto-generated value is used that doesn't survive server restarts. Set it explicitly for production.
26
26
  >
27
27
  > `OKTA_API_TOKEN` is only required when using `MastraRBACOkta` to map Okta groups to permissions.
28
28
 
@@ -142,7 +142,7 @@ const rbac = new MastraRBACOkta({
142
142
  })
143
143
  ```
144
144
 
145
- The `_default` key assigns permissions to users whose Okta groups do not match any other key.
145
+ The `_default` key assigns permissions to users whose Okta groups don't match any other key.
146
146
 
147
147
  ## Client-side setup
148
148
 
@@ -125,7 +125,7 @@ const workosAuth = new MastraAuthWorkos({
125
125
  })
126
126
  ```
127
127
 
128
- This is useful when your JWT template already includes the exact FGA context Mastra needs, such as `organizationMembershipId`, tenant IDs, or service-principal identifiers. When `trustJwtClaims` is enabled, Mastra can fall back to those verified claims if a bearer token is not meant to round-trip through `workos.userManagement.getUser()`.
128
+ This is useful when your JWT template already includes the exact FGA context Mastra needs, such as `organizationMembershipId`, tenant IDs, or service-principal identifiers. When `trustJwtClaims` is enabled, Mastra can fall back to those verified claims if a bearer token isn't meant to round-trip through `workos.userManagement.getUser()`.
129
129
 
130
130
  ### Custom authorization
131
131
 
@@ -264,7 +264,7 @@ For more information about authentication providers, see the [Auth documentation
264
264
 
265
265
  Built-in streaming helpers such as [`chatRoute()`](https://mastra.ai/reference/ai-sdk/chat-route) forward the incoming request's `AbortSignal` to `agent.stream()`. That's the right default when a browser disconnect should cancel the model call.
266
266
 
267
- For custom streaming routes that should stop when the client disconnects, pass `c.req.raw.signal` to long-running work such as `agent.stream()`. Mastra's Node-based adapters also stop reading streamed `Response` bodies from custom routes when the client connection closes. Streamed response body errors that are not caused by client disconnects still propagate through the adapter's normal error handling. In Hono, disconnect behavior depends on the host runtime forwarding connection closes to `request.signal`.
267
+ For custom streaming routes that should stop when the client disconnects, pass `c.req.raw.signal` to long-running work such as `agent.stream()`. Mastra's Node-based adapters also stop reading streamed `Response` bodies from custom routes when the client connection closes. Streamed response body errors that aren't caused by client disconnects still propagate through the adapter's normal error handling. In Hono, disconnect behavior depends on the host runtime forwarding connection closes to `request.signal`.
268
268
 
269
269
  ```typescript
270
270
  registerApiRoute('/stream', {
@@ -27,7 +27,7 @@ Subscribers can also opt into work distribution. A group of subscribers that sha
27
27
 
28
28
  ## Default backend
29
29
 
30
- When you do not set the `pubsub` option, Mastra uses [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). It delivers events in process using a Node.js [`EventEmitter`](https://nodejs.org/api/events.html#class-eventemitter), so it works without any external service.
30
+ When you don't set the `pubsub` option, Mastra uses [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). It delivers events in process using a Node.js [`EventEmitter`](https://nodejs.org/api/events.html#class-eventemitter), so it works without any external service.
31
31
 
32
32
  ```typescript
33
33
  import { Mastra } from '@mastra/core'
@@ -36,11 +36,11 @@ import { Mastra } from '@mastra/core'
36
36
  export const mastra = new Mastra({})
37
37
  ```
38
38
 
39
- Because it runs in process, events are not persisted and do not reach other processes. The default suits a single instance, which covers most applications.
39
+ Because it runs in process, events aren't persisted and don't reach other processes. The default suits a single instance, which covers most applications.
40
40
 
41
41
  ## Choosing a backend
42
42
 
43
- Set the `pubsub` option on the `Mastra` instance to choose a backend. Each backend implements the same [`PubSub`](https://mastra.ai/reference/pubsub/base) contract, so the rest of your application does not change.
43
+ Set the `pubsub` option on the `Mastra` instance to choose a backend. Each backend implements the same [`PubSub`](https://mastra.ai/reference/pubsub/base) contract, so the rest of your application doesn't change.
44
44
 
45
45
  The deciding question is where the subscriber runs.
46
46
 
@@ -100,7 +100,7 @@ export const mastra = new Mastra({
100
100
 
101
101
  Resumable streams let a client reconnect and replay events it missed, which requires the backend to keep recent history. Distributed backends such as [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) persist events, so they support replay on their own.
102
102
 
103
- In-process delivery does not keep history. To add replay on top of [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter), wrap it in [`CachingPubSub`](https://mastra.ai/reference/pubsub/caching-pubsub), which records published events per topic so a late or reconnecting subscriber can catch up before continuing with live events.
103
+ In-process delivery doesn't keep history. To add replay on top of [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter), wrap it in [`CachingPubSub`](https://mastra.ai/reference/pubsub/caching-pubsub), which records published events per topic so a late or reconnecting subscriber can catch up before continuing with live events.
104
104
 
105
105
  ```typescript
106
106
  import { Mastra } from '@mastra/core'
@@ -62,7 +62,7 @@ Studio handles the token as follows:
62
62
 
63
63
  - It reads `auth_header` once on load and sends the value as the `Authorization` header on every API request in that session.
64
64
  - It removes `auth_header` from the address bar while preserving other query parameters and the hash.
65
- - It keeps the token in memory only and never writes it to local storage, so the token stays transient and does not persist across page reloads.
65
+ - It keeps the token in memory only and never writes it to local storage, so the token stays transient and doesn't persist across page reloads.
66
66
 
67
67
  The token rides in a URL parameter, so the host application is responsible for how that URL is generated and transmitted. URL parameters can be exposed through browser history, referrer headers, and server access logs.
68
68
 
@@ -84,7 +84,7 @@ For hosted traces, logs, and metrics across projects and deploys, see [Observabi
84
84
 
85
85
  ## Metrics
86
86
 
87
- A dashboard that summarizes agent, workflow, and tool performance over a configurable time range (last 24 hours to 30 days). The top row shows total agent runs, model cost, token consumption, and average scorer performance. Below that, detailed cards break down model usage and cost per model, token usage per agent, trace volume with completed and error counts, latency percentiles (p50 and p95), and scorer trends over time.
87
+ A dashboard that summarizes agent, workflow, and tool performance over a configurable time range (last 24 hours to 30 days). The top row shows total agent runs, model cost, token consumption, and average scorer performance. Below that, detailed cards break down model usage and cost per model, token usage per agent, token usage over time with estimated cost, trace volume with completed and error counts, latency percentiles (p50 and p95), and scorer trends over time.
88
88
 
89
89
  Visit the [metrics overview](https://mastra.ai/docs/observability/metrics/overview) for more details.
90
90
 
@@ -96,6 +96,8 @@ When you run an agent or workflow, the Observability tab displays traces that hi
96
96
 
97
97
  Tracing filters out low-level framework details so your traces stay focused and readable. Visit the [tracing overview](https://mastra.ai/docs/observability/tracing/overview) for more details.
98
98
 
99
+ To export a trace, select **Download trace JSON** in the trace panel header. This saves the entire trace as a `trace-<id>.json` file, with every span and its full input, output, metadata, and attributes. Use it to share a trace, attach it to a bug report, or build an evaluation dataset offline.
100
+
99
101
  ## Logs
100
102
 
101
103
  Browse internal Mastra logs forwarded to your observability storage. Logs provide full-text search (across message content, entity names, and trace IDs), date presets (last 24 hours to 30 days), and multi-select filters for level, entity type, and entity name. Selecting a log opens a detail panel showing the full message, structured data, and metadata. If the log is correlated with a trace, you can navigate directly to the trace and span timeline.
@@ -34,13 +34,13 @@ export const dailyReport = createWorkflow({
34
34
  .commit()
35
35
  ```
36
36
 
37
- There is no separate "register schedule" call. The scheduler reads `schedule` straight off the workflow when `Mastra` boots.
37
+ A separate "register schedule" call won't happen. The scheduler reads `schedule` straight off the workflow when `Mastra` boots.
38
38
 
39
39
  ## What `schedule` changes
40
40
 
41
41
  A workflow that declares `schedule` is auto-promoted to the **evented execution engine**. The public API (`workflow.start()`, `workflow.startAsync()`, `streamLegacy()`, `resume()`) is unchanged — `EventedWorkflow extends Workflow` and overrides each method with matching signatures. From your code, scheduled fires and manual runs are indistinguishable.
42
42
 
43
- The promotion has one practical implication: evented runs require a storage adapter that supports concurrent updates, for example `@mastra/libsql`. If your adapter does not, `createRun()` throws a clear error pointing at the `schedule` field. Switch adapters or remove the schedule.
43
+ The promotion has one practical implication: evented runs require a storage adapter that supports concurrent updates, for example `@mastra/libsql`. If your adapter doesn't, `createRun()` throws a clear error pointing at the `schedule` field. Switch adapters or remove the schedule.
44
44
 
45
45
  ## Single schedule
46
46
 
@@ -61,7 +61,7 @@ const dailyReport = createWorkflow({
61
61
  Fields:
62
62
 
63
63
  - `cron` (required): a 5-, 6-, or 7-part cron expression. Validated at workflow construction time.
64
- - `timezone` (optional): IANA timezone, for example `America/New_York`. Defaults to the host's local timezone. Set this explicitly in production so fire times do not depend on server locale.
64
+ - `timezone` (optional): IANA timezone, for example `America/New_York`. Defaults to the host's local timezone. Set this explicitly in production so fire times don't depend on server locale.
65
65
  - `inputData` (optional): payload passed as the workflow's input on every fire.
66
66
  - `initialState` (optional): initial state for the run.
67
67
  - `requestContext` (optional): request context attached to the run.
@@ -105,14 +105,14 @@ Every fire records a trigger row with the run id, scheduled time, actual fire ti
105
105
  - The run's status (`running`, `success`, `failed`, `suspended`, `canceled`) as a badge.
106
106
  - The run's start time and duration.
107
107
  - A link to the run's full graph view at `/workflows/:workflowId/graph/:runId`.
108
- - A `pending` badge for triggers whose run record has not been written yet, due to a race between trigger publish and run snapshot.
109
- - A `publish failed` badge with the publish error when the scheduler could not enqueue the run at all.
108
+ - A `pending` badge for triggers whose run record hasn't been written yet, due to a race between trigger publish and run snapshot.
109
+ - A `publish failed` badge with the publish error when the scheduler couldn't enqueue the run at all.
110
110
 
111
- Triggers in a non-terminal state cause the panel to poll every five seconds until they reach a terminal state. The list paginates, so long-running schedules do not load thousands of rows up front.
111
+ Triggers in a non-terminal state cause the panel to poll every five seconds until they reach a terminal state. The list paginates, so long-running schedules don't load thousands of rows up front.
112
112
 
113
113
  ## Pausing a schedule at runtime
114
114
 
115
- When a scheduled workflow misfires in production, you do not have to redeploy or hand-edit the database. Pause it from the SDK:
115
+ When a scheduled workflow misfires in production, you don't have to redeploy or hand-edit the database. Pause it from the SDK:
116
116
 
117
117
  ```typescript
118
118
  import { MastraClient } from '@mastra/client-js'
@@ -132,8 +132,8 @@ In Studio, open the schedule detail page and select **Pause** or **Resume** in t
132
132
  A few rules worth knowing:
133
133
 
134
134
  - Pause is durable. The status is written to the schedules table and survives process restarts and redeploys. The declarative-config upsert never overwrites a user-set status, even when you change `cron`, `timezone`, or other fields.
135
- - Resume recomputes `nextFireAt` from now. A schedule paused for a week does not fire seven backlogged runs the moment you resume it. It fires on the next regular cron tick.
136
- - The only way to unpause is `resumeSchedule` (or the **Resume** button in Studio). Editing the workflow's `schedule` config does not unpause a paused row.
135
+ - Resume recomputes `nextFireAt` from now. A schedule paused for a week doesn't fire seven backlogged runs the moment you resume it. It fires on the next regular cron tick.
136
+ - The only way to unpause is `resumeSchedule` (or the **Resume** button in Studio). Editing the workflow's `schedule` config doesn't unpause a paused row.
137
137
  - Pause and resume are idempotent. Calling pause on an already-paused schedule is a no-op.
138
138
  - This is an operational override, not a way to author schedules. Creating, deleting, and editing schedules still happens in code via the `schedule` field on `createWorkflow`.
139
139
 
@@ -159,7 +159,7 @@ Deploy targets such as Fly Machines, Railway, Render, AWS ECS, GKE, or your own
159
159
 
160
160
  ### Serverless platforms
161
161
 
162
- Functions-as-a-service platforms such as Vercel, Netlify, AWS Lambda, and Cloudflare Workers shut the process down after each request. The tick loop never gets a second tick. Schedules declared in code do not fire on these platforms with the built-in scheduler today.
162
+ Functions-as-a-service platforms such as Vercel, Netlify, AWS Lambda, and Cloudflare Workers shut the process down after each request. The tick loop never gets a second tick. Schedules declared in code don't fire on these platforms with the built-in scheduler today.
163
163
 
164
164
  On these platforms, use [`@mastra/inngest`](#inngest-workflows) instead. Inngest is serverless-native and holds the cron state for you.
165
165
 
@@ -169,9 +169,9 @@ The `schedule` field documented on this page drives Mastra's built-in scheduler.
169
169
 
170
170
  Practical implications:
171
171
 
172
- - Inngest schedules do not appear in Studio's `/workflows/schedules` view.
173
- - The workflow header **Schedules** action does not show for Inngest workflows.
174
- - `client.pauseSchedule` and `client.resumeSchedule` do not control Inngest schedules.
172
+ - Inngest schedules don't appear in Studio's `/workflows/schedules` view.
173
+ - The workflow header **Schedules** action doesn't show for Inngest workflows.
174
+ - `client.pauseSchedule` and `client.resumeSchedule` don't control Inngest schedules.
175
175
 
176
176
  Manage Inngest schedules from the [Inngest dashboard](https://www.inngest.com/docs/guides/scheduled-functions). Use Mastra schedules when you want Mastra to own scheduling end to end.
177
177
 
@@ -148,7 +148,7 @@ const workspace = new Workspace({
148
148
  })
149
149
  ```
150
150
 
151
- > **Note:** `filesystem` and `mounts` are mutually exclusive. You cannot use a resolver function together with `mounts` in the same workspace.
151
+ > **Note:** `filesystem` and `mounts` are mutually exclusive. You can't use a resolver function together with `mounts` in the same workspace.
152
152
 
153
153
  ## Read-only mode
154
154
 
@@ -177,7 +177,7 @@ const workspace = new Workspace({
177
177
  - LSP inspection only works for file types with a matching built-in or custom language server
178
178
  - The `path` you inspect must resolve inside the workspace filesystem or allowed paths
179
179
  - External package inspection may resolve to declaration files such as `.d.ts` instead of runtime source files
180
- - `lsp_inspect` complements `view` and `search_content`, but does not replace reading implementation code when you need full context
180
+ - `lsp_inspect` complements `view` and `search_content`, but doesn't replace reading implementation code when you need full context
181
181
 
182
182
  ## Related
183
183
 
@@ -80,6 +80,14 @@ export const myAgent = new Agent({
80
80
  })
81
81
  ```
82
82
 
83
+ ## Lifecycle and cleanup
84
+
85
+ Mastra registers global and agent workspaces so they can be listed and retrieved at runtime. When you call `mastra.shutdown()`, Mastra destroys registered workspaces that it owns. This closes workspace resources such as language servers, browsers, sandbox processes, and filesystem provider handles.
86
+
87
+ For manual cleanup, use [`mastra.removeWorkspace()`](https://mastra.ai/reference/core/removeWorkspace). Pass `{ destroy: true }` when the workspace should be destroyed before it's removed from the registry.
88
+
89
+ Static providers are owned by the workspace. Resolver-backed providers are owned by your application because the workspace creates them at request time. See [dynamic sandbox lifecycle ownership](https://mastra.ai/docs/workspace/sandbox) for the resolver cleanup model.
90
+
83
91
  ## Configuration patterns
84
92
 
85
93
  Workspaces support several configuration patterns depending on what capabilities your agent needs. The two main building blocks are `filesystem` (file tools) and `sandbox` (command execution), with `mounts` as the way to bridge cloud storage into sandboxes.
@@ -266,7 +274,7 @@ const workspace = new Workspace({
266
274
  })
267
275
  ```
268
276
 
269
- Functions for `enabled` receive `{ requestContext, workspace }`. Functions for `requireApproval` and `requireReadBeforeWrite` also receive `args` since they are evaluated when the tool is called.
277
+ Functions for `enabled` receive `{ requestContext, workspace }`. Functions for `requireApproval` and `requireReadBeforeWrite` also receive `args` since they're evaluated when the tool is called.
270
278
 
271
279
  ### Tool name remapping
272
280
 
@@ -291,6 +299,32 @@ const workspace = new Workspace({
291
299
 
292
300
  The agent sees `view`, `search_content`, `find_files`, `execute_command`, and `lsp_inspect` instead of the default `mastra_workspace_*` names. Tool names must be unique — duplicate names or conflicts with other default names throw an error.
293
301
 
302
+ ### Tool hooks
303
+
304
+ Set `tools.hooks` to run logic before and after every enabled workspace tool call. Hooks run after name remapping, so the hook context includes both the exposed `toolName` and the original `workspaceToolName`:
305
+
306
+ ```typescript
307
+ import { Workspace, LocalFilesystem } from '@mastra/core/workspace'
308
+
309
+ const workspace = new Workspace({
310
+ filesystem: new LocalFilesystem({ basePath: './workspace' }),
311
+ tools: {
312
+ hooks: {
313
+ beforeToolCall: ({ toolName, workspaceToolName, input }) => {
314
+ console.log(`Running ${toolName} (${workspaceToolName})`, input)
315
+ },
316
+ afterToolCall: ({ toolName, output, error }) => {
317
+ console.log(`Finished ${toolName}`, { output, error })
318
+ },
319
+ },
320
+ },
321
+ })
322
+ ```
323
+
324
+ Return `{ proceed: false, output }` from `beforeToolCall` to skip the tool call and use `output` as its result.
325
+
326
+ If the owning agent also defines [tool hooks](https://mastra.ai/docs/agents/using-tools), workspace hooks run inside the agent hook wrapper: agent `beforeToolCall` first, then workspace `beforeToolCall`, then the tool, then workspace `afterToolCall`, then agent `afterToolCall`.
327
+
294
328
  ## LSP inspection
295
329
 
296
330
  Enable `lsp` on a workspace to add semantic code inspection through language servers. This adds the `mastra_workspace_lsp_inspect` tool by default, which can return hover information, definition locations, and implementations for a symbol at a specific cursor position.
@@ -21,6 +21,7 @@ A sandbox provider executes commands in a controlled environment:
21
21
  - [`DaytonaSandbox`](https://mastra.ai/reference/workspace/daytona-sandbox): Executes commands in isolated Daytona cloud sandboxes
22
22
  - [`E2BSandbox`](https://mastra.ai/reference/workspace/e2b-sandbox): Executes commands in isolated E2B cloud sandboxes
23
23
  - [`ModalSandbox`](https://mastra.ai/reference/workspace/modal-sandbox): Executes commands in isolated Modal cloud sandboxes
24
+ - [`RailwaySandbox`](https://mastra.ai/reference/workspace/railway-sandbox): Executes commands in ephemeral, isolated Railway cloud sandboxes
24
25
 
25
26
  ## Basic usage
26
27
 
@@ -107,13 +108,13 @@ const workspace = new Workspace({
107
108
 
108
109
  When the sandbox is a static instance, `workspace.init()` calls its `start()` method and `workspace.destroy()` calls its `destroy()` method. With a resolver, the workspace has no instance to manage at construction time — the caller owns the returned sandbox's lifecycle.
109
110
 
110
- The resolver must return a sandbox that is ready to use, either already started or able to handle calls without explicit startup. The caller also owns cleanup timing for returned sandboxes. Cleanup might happen per request, per tenant, per user, or as part of a long-lived sandbox pool; `workspace.destroy()` does not destroy resolver-returned sandboxes.
111
+ The resolver must return a sandbox that's ready to use, either already started or able to handle calls without explicit startup. The caller also owns cleanup timing for returned sandboxes. Cleanup might happen per request, per tenant, per user, or as part of a long-lived sandbox pool; `workspace.destroy()` doesn't destroy resolver-returned sandboxes.
111
112
 
112
113
  > **Note:** `sandbox` resolvers are incompatible with `mounts` and `lsp: true`. Both require a concrete sandbox instance at construction time, so combining them with a resolver throws an `INVALID_CONFIG` error (for `mounts`) or disables LSP with a warning (for `lsp: true`).
113
114
 
114
115
  ### Tool registration
115
116
 
116
- With a static sandbox, the workspace inspects the instance to decide which tools to register. With a resolver, the workspace assumes full capabilities and registers `execute_command` (with `background` support), `get_process_output`, and `kill_process`. If the resolved sandbox does not implement a capability, the runtime throws a clear `SandboxFeatureNotSupportedError`.
117
+ With a static sandbox, the workspace inspects the instance to decide which tools to register. With a resolver, the workspace assumes full capabilities and registers `execute_command` (with `background` support), `get_process_output`, and `kill_process`. If the resolved sandbox doesn't implement a capability, the runtime throws a clear `SandboxFeatureNotSupportedError`.
117
118
 
118
119
  ### Background process continuity
119
120
 
@@ -132,7 +133,7 @@ When a cached sandbox is no longer needed, destroy the sandbox in your own lifec
132
133
 
133
134
  ### Workspace instructions
134
135
 
135
- Workspace instructions describe the environment in the agent's system message. With a sandbox resolver, the workspace does not call the resolver to build these instructions. It emits stable placeholder text, so constructing the prompt never provisions a caller-owned sandbox and the system message stays consistent across requests, which keeps prompt caching effective.
136
+ Workspace instructions describe the environment in the agent's system message. With a sandbox resolver, the workspace doesn't call the resolver to build these instructions. It emits stable placeholder text, so constructing the prompt never provisions a caller-owned sandbox and the system message stays consistent across requests, which keeps prompt caching effective.
136
137
 
137
138
  To include concrete per-request sandbox details, set `instructions.dynamicSandbox` to `'resolve'`:
138
139
 
@@ -395,7 +395,7 @@ Mastra streams data to the frontend as "parts" within messages. Each part has a
395
395
  | -------------------- | ----------------------- | ---------------------------------------------------------------------------------- |
396
396
  | `tool-{toolKey}` | AI SDK built-in | Tool invocation with states: `input-available`, `output-available`, `output-error` |
397
397
  | `data-workflow` | `workflowRoute()` | Workflow execution state snapshots with step status and final outputs |
398
- | `data-workflow-step` | `workflowRoute()` | Workflow step delta with the full payload for the step that just changed |
398
+ | `data-workflow-step` | `workflowRoute()` | Workflow step delta with the full payload for the changed step |
399
399
  | `data-network` | `networkRoute()` | Agent network execution with ordered steps and outputs |
400
400
  | `data-tool-agent` | Nested agent in tool | Agent output streamed from within a tool's `execute()` |
401
401
  | `data-tool-workflow` | Nested workflow in tool | Workflow output streamed from within a tool's `execute()` |
@@ -508,7 +508,7 @@ export function Chat() {
508
508
 
509
509
  ### Rendering workflow data
510
510
 
511
- When using `workflowRoute()` or `handleWorkflowStream()`, Mastra emits `data-workflow` parts for workflow state snapshots and `data-workflow-step` parts for the full payload of the step that just changed. This keeps long-running workflows from repeating every completed step output in every intermediate snapshot.
511
+ When using `workflowRoute()` or `handleWorkflowStream()`, Mastra emits `data-workflow` parts for workflow state snapshots and `data-workflow-step` parts for the full payload of the changed step. This keeps long-running workflows from repeating every completed step output in every intermediate snapshot.
512
512
 
513
513
  **Backend**:
514
514
 
@@ -1,6 +1,6 @@
1
1
  # Deploy Mastra to Amazon Bedrock AgentCore
2
2
 
3
- Deploy your Mastra application to [Amazon Bedrock AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/) using the [AgentCore CLI](https://github.com/aws/agentcore-cli). The CLI scaffolds a bring-your-own-code (BYO) TypeScript project, builds the container with AWS CodeBuild, and provisions the runtime. A local Docker daemon is not required for deployment.
3
+ Deploy your Mastra application to [Amazon Bedrock AgentCore Runtime](https://docs.aws.amazon.com/bedrock-agentcore/) using the [AgentCore CLI](https://github.com/aws/agentcore-cli). The CLI scaffolds a bring-your-own-code (BYO) TypeScript project, builds the container with AWS CodeBuild, and provisions the runtime. A local Docker daemon isn't required for deployment.
4
4
 
5
5
  This guide follows the [official AgentCore TypeScript walkthrough](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-cli-typescript.html) and adapts it to call a Mastra agent from the invocation handler.
6
6
 
@@ -190,7 +190,7 @@ export const weatherAgent = new Agent({
190
190
 
191
191
  > **Note:** `fromNodeProviderChain()` lets the agent pick up AWS credentials through the standard SDK resolution chain (environment variables, shared config files, SSO, and container or EC2 roles) instead of environment variables only.
192
192
 
193
- Replace the generated `src/mastra/index.ts` to remove the default file-based storage and observability config. AgentCore Runtime containers run as a non-root user with a read-only application directory, so the default `LibSQLStore` cannot open `./mastra.db` and the runtime fails at startup:
193
+ Replace the generated `src/mastra/index.ts` to remove the default file-based storage and observability config. AgentCore Runtime containers run as a non-root user with a read-only application directory, so the default `LibSQLStore` can't open `./mastra.db` and the runtime fails at startup:
194
194
 
195
195
  ```ts
196
196
  import { Mastra } from '@mastra/core/mastra'
@@ -420,7 +420,7 @@ Run `agentcore status` to view the runtime ARN, endpoint, and recent invocations
420
420
  npx @aws/agentcore invoke "What is the weather in Tokyo?"
421
421
  ```
422
422
 
423
- To stream tokens as they are generated, use `--stream`:
423
+ To stream tokens as they're generated, use `--stream`:
424
424
 
425
425
  ```bash
426
426
  npx @aws/agentcore invoke --stream "Plan a 3-day trip to Tokyo"
@@ -93,7 +93,7 @@ export const inngest = new Inngest({
93
93
  })
94
94
  ```
95
95
 
96
- > **Warning:** Do not set `INNGEST_DEV` in production. It disables signature verification, which is required to securely receive events from Inngest Cloud.
96
+ > **Warning:** Don't set `INNGEST_DEV` in production. It disables signature verification, which is required to securely receive events from Inngest Cloud.
97
97
 
98
98
  The `isDev` option on `new Inngest()` overrides `INNGEST_DEV` when both are set.
99
99
 
@@ -252,7 +252,7 @@ Before you begin, make sure you have:
252
252
 
253
253
  5. Sync with the [Inngest dashboard](https://app.inngest.com/env/production/apps) by selecting **Sync new app with Vercel** and following the instructions
254
254
 
255
- > **Warning:** Inngest's auto-discover convention assumes `/api/inngest`. Because this guide uses `/inngest/api`, set the **URL** field on the Inngest app to your deployed origin plus `/inngest/api` (for example `https://your-app.vercel.app/inngest/api`). If you leave it on the default, the Inngest dashboard will not find your app's functions.
255
+ > **Warning:** Inngest's auto-discover convention assumes `/api/inngest`. Because this guide uses `/inngest/api`, set the **URL** field on the Inngest app to your deployed origin plus `/inngest/api` (for example `https://your-app.vercel.app/inngest/api`). If you leave it on the default, the Inngest dashboard won't find your app's functions.
256
256
 
257
257
  6. Invoke the workflow by going to **Functions**, selecting `workflow.increment-workflow`, selecting **All actions** > **Invoke**, and providing the following input:
258
258
 
@@ -433,9 +433,9 @@ The `createServe` function works with any Inngest adapter. See the [Inngest serv
433
433
 
434
434
  ## Running as a Connect worker
435
435
 
436
- `serve()` exposes an HTTP endpoint that Inngest calls into. As an alternative, `connect()` opens a long-lived outbound connection from your worker to Inngest, so the worker does not need a publicly reachable endpoint. Use this for long-running worker processes on runtimes such as Kubernetes, Docker, ECS, Fly.io, or Render.
436
+ `serve()` exposes an HTTP endpoint that Inngest calls into. As an alternative, `connect()` opens a long-lived outbound connection from your worker to Inngest, so the worker doesn't need a publicly reachable endpoint. Use this for long-running worker processes on runtimes such as Kubernetes, Docker, ECS, Fly.io, or Render.
437
437
 
438
- > **Note:** Inngest Connect is in public beta. Serverless runtimes such as Vercel and AWS Lambda are not supported for Connect workers.
438
+ > **Note:** Inngest Connect is in public beta. Serverless runtimes such as Vercel and AWS Lambda aren't supported for Connect workers.
439
439
 
440
440
  ### When to use `connect()` instead of `serve()`
441
441
 
@@ -453,7 +453,7 @@ Use the same Mastra workflow definitions with either `serve()` or `connect()`. T
453
453
 
454
454
  ### Setup
455
455
 
456
- Run the Mastra server and the Connect worker as two processes. The Mastra server in this setup does not need to expose `/inngest/api`:
456
+ Run the Mastra server and the Connect worker as two processes. The Mastra server in this setup doesn't need to expose `/inngest/api`:
457
457
 
458
458
  ```ts
459
459
  import { Mastra } from '@mastra/core'
@@ -155,7 +155,7 @@ const worker = await Worker.create({
155
155
  await worker.run()
156
156
  ```
157
157
 
158
- `MastraPlugin` rewrites the entry file into a workflow-only bundle and wires step handlers in as Temporal activities. You do not need to pass `activities` or `workflowsPath` to `Worker.create()` manually.
158
+ `MastraPlugin` rewrites the entry file into a workflow-only bundle and wires step handlers in as Temporal activities. You don't need to pass `activities` or `workflowsPath` to `Worker.create()` manually.
159
159
 
160
160
  ## Running workflows
161
161
 
@@ -200,7 +200,7 @@ TEMPORAL_API_KEY=your-api-key
200
200
 
201
201
  See the [Temporal Cloud connection docs](https://docs.temporal.io/cloud/get-started) for mTLS and API key options.
202
202
 
203
- > **Warning:** The Temporal worker must run as a long-lived process. Do not deploy it to serverless platforms with short execution limits, such as AWS Lambda or Vercel functions. Use a container, VM, or worker-friendly platform such as Fly.io, Railway, or Kubernetes.
203
+ > **Warning:** The Temporal worker must run as a long-lived process. Don't deploy it to serverless platforms with short execution limits, such as AWS Lambda or Vercel functions. Use a container, VM, or worker-friendly platform such as Fly.io, Railway, or Kubernetes.
204
204
 
205
205
  ## Configuration options
206
206
 
@@ -223,7 +223,7 @@ export const { createWorkflow, createStep } = init({
223
223
  ## Constraints and notes
224
224
 
225
225
  - Workflow ids must be static string literals. The build-time transformer reads the literal value to derive Temporal workflow export names.
226
- - Activities are generated automatically from `createStep()` handlers. Do not pass them in `Worker.create({ activities })`.
226
+ - Activities are generated automatically from `createStep()` handlers. Don't pass them in `Worker.create({ activities })`.
227
227
 
228
228
  ## Related
229
229
 
@@ -127,7 +127,7 @@ import { mastra } from './mastra'
127
127
  export class AppModule {}
128
128
  ```
129
129
 
130
- > **Note:** `MastraModule` registers a catch-all controller (`@All('*')`). If it is imported before your app modules, it can intercept unrelated routes and return 404s. To avoid conflicts, import `MastraModule` last or mount it under a dedicated prefix (e.g., `/api/v1/mastra`).
130
+ > **Note:** `MastraModule` registers a catch-all controller (`@All('*')`). If it's imported before your app modules, it can intercept unrelated routes and return 404s. To avoid conflicts, import `MastraModule` last or mount it under a dedicated prefix (e.g., `/api/v1/mastra`).
131
131
 
132
132
  ## Test your agent
133
133
 
@@ -56,7 +56,7 @@ The Mastra platform replaces Mastra Cloud with separate Studio and Server produc
56
56
 
57
57
  ## Replace Mastra Cloud Store with a hosted database
58
58
 
59
- Mastra Cloud provided a managed libSQL database, backed by [Turso](https://turso.tech). The Mastra platform does not host a database for you, so you need to point your storage at an externally hosted instance.
59
+ Mastra Cloud provided a managed libSQL database, backed by [Turso](https://turso.tech). The Mastra platform doesn't host a database for you, so you need to point your storage at an externally hosted instance.
60
60
 
61
61
  If you were already using a hosted database ("bring your own"), no changes are needed. Ensure the connection string is set as an environment variable in the dashboard rather than hardcoded.
62
62
 
@@ -64,7 +64,7 @@ If you were using Cloud Store, follow the steps below to export your data and lo
64
64
 
65
65
  ### Export your Cloud Store data
66
66
 
67
- There are two ways to export your Cloud Store data: a one-click download from the dashboard, or a manual dump via the Turso CLI.
67
+ You can export your Cloud Store data in two ways: download it from the dashboard, or create a manual dump with the Turso CLI.
68
68
 
69
69
  #### Option A — Export from the dashboard (recommended)
70
70
 
@@ -281,7 +281,7 @@ See [Studio deployment](https://mastra.ai/docs/studio/deployment) for details.
281
281
 
282
282
  ### Multiple environments
283
283
 
284
- Mastra platform projects do not have a built-in concept of named environments (for example `staging` vs `production`). To deploy the same codebase to multiple environments, create one project per environment and pair each deploy with the matching env file using `--env-file`.
284
+ Mastra platform projects don't have a built-in concept of named environments (for example `staging` vs `production`). To deploy the same codebase to multiple environments, create one project per environment and pair each deploy with the matching env file using `--env-file`.
285
285
 
286
286
  The pattern below uses one `.env.<env>` file per environment, deploys to a project named `my-app-<env>`, and overrides `.mastra-project.json` per deploy with `MASTRA_ORG_ID` and `MASTRA_PROJECT_ID`:
287
287
 
@@ -8,7 +8,7 @@ This guide provides a comprehensive overview of breaking changes when upgrading
8
8
 
9
9
  > **Need help?:** Need help with the migration? Join our [Discord community](https://discord.gg/BTYqqHKUrf) to ask questions.
10
10
 
11
- > **Coming from Mastra Cloud?:** The legacy Mastra Cloud product has been replaced by the [Mastra platform](https://mastra.ai/docs/mastra-platform/overview), which splits hosting into two separate products: **Studio** (visual environment, observability) and **Server** (production API). Old Mastra Cloud access tokens do not work with Mastra platform — you must create new ones with `mastra auth tokens create`.
11
+ > **Coming from Mastra Cloud?:** The legacy Mastra Cloud product has been replaced by the [Mastra platform](https://mastra.ai/docs/mastra-platform/overview), which splits hosting into two separate products: **Studio** (visual environment, observability) and **Server** (production API). Old Mastra Cloud access tokens don't work with Mastra platform — you must create new ones with `mastra auth tokens create`.
12
12
  >
13
13
  > If you upgrade to v1 packages without also migrating your `telemetry:` config to `observability:` and creating a Studio project, observability data will stop flowing. Follow the [Mastra Cloud migration guide](https://mastra.ai/guides/migrations/mastra-cloud) end to end.
14
14
 
@@ -6,7 +6,7 @@ The observability system has been restructured in v1 with a dedicated `@mastra/o
6
6
  >
7
7
  > Complete this migration in the same change that bumps your Mastra packages, and verify traces appear in [Mastra Studio](https://mastra.ai/docs/studio/observability) before considering the upgrade complete. If you previously hosted on Mastra Cloud, also follow the [Mastra Cloud migration guide](https://mastra.ai/guides/migrations/mastra-cloud) — the new platform requires a new access token and a Studio project before `MastraPlatformExporter` can route data to it.
8
8
 
9
- > **Exporter rename:** `MastraPlatformExporter` (sends data to Mastra platform) replaces the previous `CloudExporter`, and `MastraStorageExporter` (persists data to Mastra Storage) replaces the previous `DefaultExporter`. The original classes still ship from `@mastra/observability` and behave identically, but they are deprecated. New code should use `MastraPlatformExporter` and `MastraStorageExporter`; existing imports of `CloudExporter`/`DefaultExporter` continue to work until they are removed in a future major version.
9
+ > **Exporter rename:** `MastraPlatformExporter` (sends data to Mastra platform) replaces the previous `CloudExporter`, and `MastraStorageExporter` (persists data to Mastra Storage) replaces the previous `DefaultExporter`. The original classes still ship from `@mastra/observability` and behave identically, but they're deprecated. New code should use `MastraPlatformExporter` and `MastraStorageExporter`; existing imports of `CloudExporter`/`DefaultExporter` continue to work until they're removed in a future major version.
10
10
 
11
11
  ## Migration paths
12
12
 
@@ -116,7 +116,7 @@ for await (const chunk of result.fullStream) {
116
116
  }
117
117
  ```
118
118
 
119
- `resumeGenerate()` and `resumeStream()` are not supported and throw an error when called.
119
+ `resumeGenerate()` and `resumeStream()` aren't supported and throw an error when called.
120
120
 
121
121
  ### Model management
122
122
 
@@ -160,7 +160,7 @@ With `persistSession: false`, `@mastra/acp` stops the ACP process after each pro
160
160
 
161
161
  ## Workspace integration
162
162
 
163
- ACP file operations go through Mastra's `Workspace` abstraction. If you do not pass `workspace`, `@mastra/acp` creates a `Workspace` backed by `LocalFilesystem` and uses `cwd` or `process.cwd()` as the filesystem base path.
163
+ ACP file operations go through Mastra's `Workspace` abstraction. If you don't pass `workspace`, `@mastra/acp` creates a `Workspace` backed by `LocalFilesystem` and uses `cwd` or `process.cwd()` as the filesystem base path.
164
164
 
165
165
  Pass a custom `Workspace` when the ACP agent should read and write through a specific filesystem implementation:
166
166
 
@@ -426,6 +426,12 @@ Returns an `AgentThreadSubscription` object with these members:
426
426
 
427
427
  **tools** (`ToolsInput | ({ requestContext: RequestContext }) => ToolsInput | Promise<ToolsInput>`): Tools that the agent can access. Can be provided statically or resolved dynamically.
428
428
 
429
+ **hooks** (`ToolHooks`): Hooks that run before and after every tool call made by this agent. Per-execution hooks passed to \`generate()\` or \`stream()\` override matching hooks set here. See Tool hooks below.
430
+
431
+ **hooks.beforeToolCall** (`(context: ToolHookContext) => void | ToolBeforeHookResult | Promise<void | ToolBeforeHookResult>`): Runs before a tool executes. Receives \`{ toolName, input, context, metadata }\`. Return \`{ proceed: false, output }\` to skip the tool call and use \`output\` as its result.
432
+
433
+ **hooks.afterToolCall** (`(context: ToolAfterHookContext) => void | Promise<void>`): Runs after a tool executes. Receives \`{ toolName, input, context, metadata, output, error }\`. \`output\` is undefined when the tool throws, and \`error\` is set instead.
434
+
429
435
  **transform** (`ToolPayloadTransformPolicy`): Shared policy for transforming tool payloads before display streams or user-visible transcript messages receive them. Use per-tool \`transform\` on \`createTool()\` for tool-local rules.
430
436
 
431
437
  **workflows** (`Record<string, Workflow> | ({ requestContext: RequestContext }) => Record<string, Workflow> | Promise<Record<string, Workflow>>`): Workflows that the agent can execute. Can be static or dynamically resolved.
@@ -458,6 +464,44 @@ Returns an `AgentThreadSubscription` object with these members:
458
464
 
459
465
  **editor** (`false | { instructions?: boolean; tools?: boolean | { description?: boolean } }`): Controls which fields the editor can override for this code-defined agent. Omit to allow editing instructions and tools. See Editor overrides below.
460
466
 
467
+ ## Tool hooks
468
+
469
+ Use `hooks` to run logic around every tool call the agent makes, including assigned tools, memory tools, toolsets, client tools, and workspace tools.
470
+
471
+ ```typescript
472
+ import { Agent } from '@mastra/core/agent'
473
+
474
+ export const agent = new Agent({
475
+ name: 'support-agent',
476
+ instructions: 'Help users with their questions.',
477
+ model: 'openai/gpt-5.5',
478
+ hooks: {
479
+ beforeToolCall: ({ toolName, input }) => {
480
+ console.log(`Running ${toolName}`, input)
481
+ },
482
+ afterToolCall: ({ toolName, output, error }) => {
483
+ console.log(`Finished ${toolName}`, { output, error })
484
+ },
485
+ },
486
+ })
487
+ ```
488
+
489
+ `beforeToolCall` can short-circuit the tool call by returning `{ proceed: false, output }`. The agent skips execution and uses `output` as the tool result:
490
+
491
+ ```typescript
492
+ const result = await agent.generate('Clean up old records', {
493
+ hooks: {
494
+ beforeToolCall: ({ toolName }) => {
495
+ if (toolName === 'deleteRecord') {
496
+ return { proceed: false, output: { blocked: true } }
497
+ }
498
+ },
499
+ },
500
+ })
501
+ ```
502
+
503
+ The hook context `metadata` includes `agentId` and `agentName`. Per-execution hooks passed to `generate()` or `stream()` override matching agent-level hooks. When a [workspace](https://mastra.ai/reference/workspace/workspace-class) also defines `tools.hooks`, workspace hooks run inside the agent hook wrapper.
504
+
461
505
  ## Editor overrides
462
506
 
463
507
  When you register the [`MastraEditor`](https://mastra.ai/reference/editor/mastra-editor), the `editor` field controls which parts of a code-defined agent can be changed through the editor. Fields owned by code are read-only in Studio and are stripped from saved overrides.
@@ -247,7 +247,7 @@ The `ResolveResourceIdContext` passed to the function:
247
247
 
248
248
  ## Inline media
249
249
 
250
- Controls which attachment types (images, video, PDFs, etc.) are sent as file parts to the model. Types that do not match are described as text summaries so the agent knows about the file without crashing models that reject unsupported types.
250
+ Controls which attachment types (images, video, PDFs, etc.) are sent as file parts to the model. Types that don't match are described as text summaries so the agent knows about the file without crashing models that reject unsupported types.
251
251
 
252
252
  The default (`['image/png', 'image/jpeg', 'image/webp', 'application/pdf']`) matches the formats supported by major vision models. Override `inlineMedia` to expand the list (e.g. `['image/*', 'audio/*']`) or replace it entirely with a predicate function.
253
253
 
@@ -63,7 +63,7 @@ Returns: `DurableAgent`
63
63
 
64
64
  ## `createEventedAgent(options)`
65
65
 
66
- Wraps an `Agent` with fire-and-forget durable execution on the built-in workflow engine. Like `createDurableAgent`, it returns a result you stream from, but the underlying workflow runs non-blocking (via `startAsync`) instead of running to completion before the stream is wired up. Use it when you want the run to progress independently of the caller. It does not accept `id` or `name` overrides.
66
+ Wraps an `Agent` with fire-and-forget durable execution on the built-in workflow engine. Like `createDurableAgent`, it returns a result you stream from, but the underlying workflow runs non-blocking (via `startAsync`) instead of running to completion before the stream is wired up. Use it when you want the run to progress independently of the caller. It doesn't accept `id` or `name` overrides.
67
67
 
68
68
  ```typescript
69
69
  import { createEventedAgent } from '@mastra/core/agent/durable'
@@ -151,7 +151,7 @@ await output.text
151
151
 
152
152
  Returns: `Promise<DurableAgentStreamResult>`
153
153
 
154
- > **Warning:** The `cleanup()` returned by `observe()` destroys the run's registry entries and cached events. Only call it when you are done with the run. If the run is suspended and you intend to resume later, do not call `cleanup()` — let the auto-cleanup timer handle it after the run finishes or errors. Auto-cleanup does not fire on suspended events.
154
+ > **Warning:** The `cleanup()` returned by `observe()` destroys the run's registry entries and cached events. Only call it when you are done with the run. If the run is suspended and you intend to resume later, don't call `cleanup()` — let the auto-cleanup timer handle it after the run finishes or errors. Auto-cleanup doesn't fire on suspended events.
155
155
 
156
156
  ## Stream options
157
157
 
@@ -266,6 +266,8 @@ const response = await agent.generate('Help me organize my day', {
266
266
 
267
267
  **options.clientTools** (`ToolsInput`): Client-side tools available during execution.
268
268
 
269
+ **options.hooks** (`ToolHooks`): Per-execution hooks that run before and after tool calls. Overrides matching agent-level hooks for this execution. \`beforeToolCall\` can return \`{ proceed: false, output }\` to skip the tool call.
270
+
269
271
  **options.savePerStep** (`boolean`): Save messages incrementally after each generation step completes (default: false). Disabled internally when observational memory is enabled.
270
272
 
271
273
  **options.providerOptions** (`Record<string, Record<string, JSONValue>>`): Provider-specific options passed to the language model.
@@ -84,6 +84,8 @@ await agent.generateLegacy('message for agent')
84
84
 
85
85
  **options.clientTools** (`ToolsInput`): Tools that are executed on the 'client' side of the request. These tools do not have execute functions in the definition.
86
86
 
87
+ **options.hooks** (`ToolHooks`): Per-execution hooks that run before and after tool calls. Overrides matching agent-level hooks for this execution. \`beforeToolCall\` can return \`{ proceed: false, output }\` to skip the tool call.
88
+
87
89
  **options.savePerStep** (`boolean`): Save messages incrementally after each generation step completes (default: false). Disabled internally when observational memory is enabled.
88
90
 
89
91
  **options.providerOptions** (`Record<string, Record<string, JSONValue>>`): Additional provider-specific options that are passed through to the underlying LLM provider. The structure is \`{ providerName: { optionKey: value } }\`. Since Mastra extends AI SDK, see the \[AI SDK documentation]\(https\://sdk.vercel.ai/docs/providers/ai-sdk-providers) for complete provider options.
@@ -21,7 +21,7 @@ When you pass `structuredOutput` to the underlying agent execution, the final st
21
21
  }
22
22
  ```
23
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.
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 aren't exposed in the UI stream.
25
25
 
26
26
  Read this event with AI SDK UI's custom data handling, such as `onData`, or render it from message data parts.
27
27