@mastra/mcp-docs-server 1.2.7-alpha.1 → 1.2.7-alpha.10

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 (198) hide show
  1. package/.docs/docs/agent-builder/integrations.md +1 -1
  2. package/.docs/docs/agent-builder/overview.md +4 -3
  3. package/.docs/docs/agent-builder/skill-registries.md +1 -3
  4. package/.docs/docs/agent-controller/modes.md +1 -1
  5. package/.docs/docs/agent-controller/overview.md +4 -3
  6. package/.docs/docs/agent-controller/session.md +3 -5
  7. package/.docs/docs/agents/a2a.md +2 -1
  8. package/.docs/docs/agents/agent-approval.md +2 -2
  9. package/.docs/docs/agents/code-mode.md +1 -1
  10. package/.docs/docs/agents/guardrails.md +10 -9
  11. package/.docs/docs/agents/networks.md +1 -1
  12. package/.docs/docs/agents/overview.md +5 -5
  13. package/.docs/docs/agents/skills.md +3 -5
  14. package/.docs/docs/agents/structured-output.md +1 -1
  15. package/.docs/docs/agents/supervisor-agents.md +3 -4
  16. package/.docs/docs/agents/using-tools.md +2 -4
  17. package/.docs/docs/browser/agent-browser.md +1 -3
  18. package/.docs/docs/browser/browser-viewer.md +1 -3
  19. package/.docs/docs/browser/overview.md +2 -1
  20. package/.docs/docs/browser/recording.md +1 -1
  21. package/.docs/docs/browser/stagehand.md +1 -1
  22. package/.docs/docs/capabilities/channels/discord.md +98 -0
  23. package/.docs/docs/capabilities/channels/other-adapters.md +68 -0
  24. package/.docs/docs/capabilities/channels/overview.md +255 -0
  25. package/.docs/docs/capabilities/channels/slack.md +225 -0
  26. package/.docs/docs/capabilities/channels/teams.md +100 -0
  27. package/.docs/docs/capabilities/channels/telegram.md +98 -0
  28. package/.docs/docs/capabilities/channels/whatsapp.md +99 -0
  29. package/.docs/docs/deployment/mastra-server.md +2 -4
  30. package/.docs/docs/editor/overview.md +2 -6
  31. package/.docs/docs/editor/prompts.md +1 -1
  32. package/.docs/docs/editor/tools.md +1 -3
  33. package/.docs/docs/evals/built-in-scorers.md +2 -2
  34. package/.docs/docs/evals/custom-scorers.md +1 -3
  35. package/.docs/docs/evals/datasets/overview.md +4 -5
  36. package/.docs/docs/evals/datasets/running-experiments.md +10 -8
  37. package/.docs/docs/evals/evals-with-memory.md +1 -3
  38. package/.docs/docs/evals/gates-and-verdicts.md +2 -4
  39. package/.docs/docs/evals/overview.md +4 -1
  40. package/.docs/docs/evals/quick-checks.md +3 -5
  41. package/.docs/docs/getting-started/file-based-agents.md +114 -0
  42. package/.docs/docs/getting-started/manual-install.md +17 -4
  43. package/.docs/docs/index.md +1 -1
  44. package/.docs/docs/long-running-agents/background-tasks.md +3 -3
  45. package/.docs/docs/long-running-agents/durable-agents.md +5 -7
  46. package/.docs/docs/long-running-agents/goals.md +5 -7
  47. package/.docs/docs/long-running-agents/schedules.md +1 -1
  48. package/.docs/docs/long-running-agents/signal-providers.md +1 -3
  49. package/.docs/docs/long-running-agents/signals.md +12 -23
  50. package/.docs/docs/mastra-platform/database.md +2 -2
  51. package/.docs/docs/mastra-platform/github.md +1 -1
  52. package/.docs/docs/mastra-platform/observability.md +5 -1
  53. package/.docs/docs/mcp/mcp-apps.md +3 -3
  54. package/.docs/docs/mcp/overview.md +6 -10
  55. package/.docs/docs/memory/memory-processors.md +67 -0
  56. package/.docs/docs/memory/message-history.md +56 -2
  57. package/.docs/docs/memory/observational-memory.md +5 -4
  58. package/.docs/docs/memory/overview.md +8 -6
  59. package/.docs/docs/memory/semantic-recall.md +36 -2
  60. package/.docs/docs/memory/working-memory.md +3 -3
  61. package/.docs/docs/observability/integrations/exporters/mastra-platform.md +1 -3
  62. package/.docs/docs/observability/integrations/exporters/mastra-storage.md +1 -1
  63. package/.docs/docs/observability/logging.md +1 -1
  64. package/.docs/docs/observability/tracing/overview.md +1 -1
  65. package/.docs/docs/rag/vector-databases.md +7 -2
  66. package/.docs/docs/server/auth/auth0.md +1 -1
  67. package/.docs/docs/server/auth/better-auth.md +2 -2
  68. package/.docs/docs/server/auth/clerk.md +1 -1
  69. package/.docs/docs/server/auth/firebase.md +1 -1
  70. package/.docs/docs/server/auth/google.md +3 -3
  71. package/.docs/docs/server/auth/jwt.md +2 -2
  72. package/.docs/docs/server/auth/okta.md +2 -2
  73. package/.docs/docs/server/auth/workos.md +1 -1
  74. package/.docs/docs/server/mastra-client.md +1 -1
  75. package/.docs/docs/server/mastra-server.md +1 -1
  76. package/.docs/docs/server/pubsub.md +1 -1
  77. package/.docs/docs/server/request-context.md +4 -4
  78. package/.docs/docs/server/server-adapters.md +8 -8
  79. package/.docs/docs/storage/overview.md +214 -0
  80. package/.docs/docs/studio/auth.md +1 -3
  81. package/.docs/docs/studio/overview.md +1 -1
  82. package/.docs/docs/voice/livekit.md +101 -4
  83. package/.docs/docs/workflows/agents-and-tools.md +3 -5
  84. package/.docs/docs/workflows/control-flow.md +1 -3
  85. package/.docs/docs/workflows/overview.md +6 -7
  86. package/.docs/docs/workflows/snapshots.md +1 -1
  87. package/.docs/docs/workspace/overview.md +2 -1
  88. package/.docs/docs/workspace/sandbox.md +2 -0
  89. package/.docs/guides/build-your-ui/assistant-ui.md +1 -1
  90. package/.docs/guides/build-your-ui/copilotkit/channels.md +1 -1
  91. package/.docs/guides/build-your-ui/copilotkit/generative-ui.md +2 -2
  92. package/.docs/guides/build-your-ui/copilotkit/overview.md +1 -1
  93. package/.docs/guides/concepts/streaming.md +3 -3
  94. package/.docs/guides/getting-started/quickstart.md +4 -2
  95. package/.docs/guides/guide/chef-michel.md +0 -2
  96. package/.docs/guides/guide/slack-assistant.md +2 -2
  97. package/.docs/guides/guide/stock-agent.md +0 -2
  98. package/.docs/models/embeddings.md +119 -0
  99. package/.docs/models/environment-variables.md +3 -0
  100. package/.docs/models/gateways/netlify.md +4 -1
  101. package/.docs/models/gateways/openrouter.md +10 -6
  102. package/.docs/models/gateways/vercel.md +7 -1
  103. package/.docs/models/index.md +1 -1
  104. package/.docs/models/providers/crossmodel.md +109 -0
  105. package/.docs/models/providers/google.md +2 -1
  106. package/.docs/models/providers/llmgateway.md +184 -181
  107. package/.docs/models/providers/meta.md +101 -0
  108. package/.docs/models/providers/nano-gpt.md +2 -2
  109. package/.docs/models/providers/neon.md +40 -29
  110. package/.docs/models/providers/openai.md +5 -1
  111. package/.docs/models/providers/opencode.md +2 -1
  112. package/.docs/models/providers/poolside.md +6 -5
  113. package/.docs/models/providers/routing-run.md +20 -34
  114. package/.docs/models/providers/the-grid-ai.md +3 -3
  115. package/.docs/models/providers/wandb.md +21 -14
  116. package/.docs/models/providers/xai.md +2 -1
  117. package/.docs/models/providers/zenifra.md +73 -0
  118. package/.docs/models/providers.md +3 -0
  119. package/.docs/reference/agent-controller/agent-controller-class.md +3 -3
  120. package/.docs/reference/agent-controller/session.md +4 -4
  121. package/.docs/reference/agents/agent.md +1 -1
  122. package/.docs/reference/agents/channels.md +2 -2
  123. package/.docs/reference/agents/inngest-agent.md +1 -1
  124. package/.docs/reference/agents/listSkills.md +1 -1
  125. package/.docs/reference/agents/listSuspendedRuns.md +3 -3
  126. package/.docs/reference/auth/google.md +5 -5
  127. package/.docs/reference/channels/channel-provider.md +1 -1
  128. package/.docs/reference/channels/slack-provider.md +3 -3
  129. package/.docs/reference/cli/mastra.md +119 -12
  130. package/.docs/reference/code-sdk/mount-agent-controller.md +76 -0
  131. package/.docs/reference/coding-agent/create-coding-agent.md +1 -1
  132. package/.docs/reference/configuration.md +1 -1
  133. package/.docs/reference/evals/checks.md +4 -4
  134. package/.docs/reference/evals/create-scorer.md +8 -0
  135. package/.docs/reference/file-based-agents/config.md +97 -0
  136. package/.docs/reference/file-based-agents/instructions.md +54 -0
  137. package/.docs/reference/file-based-agents/memory.md +58 -0
  138. package/.docs/reference/file-based-agents/observability.md +32 -0
  139. package/.docs/reference/file-based-agents/processors.md +56 -0
  140. package/.docs/reference/file-based-agents/server.md +37 -0
  141. package/.docs/reference/file-based-agents/skills.md +56 -0
  142. package/.docs/reference/file-based-agents/storage.md +30 -0
  143. package/.docs/reference/file-based-agents/studio.md +56 -0
  144. package/.docs/reference/file-based-agents/subagents.md +123 -0
  145. package/.docs/reference/file-based-agents/tools.md +63 -0
  146. package/.docs/reference/file-based-agents/workflows.md +52 -0
  147. package/.docs/reference/file-based-agents/workspace.md +74 -0
  148. package/.docs/reference/index.md +16 -0
  149. package/.docs/reference/memory/memory-class.md +1 -1
  150. package/.docs/reference/memory/observational-memory.md +1 -1
  151. package/.docs/reference/memory/serialized-memory-config.md +1 -1
  152. package/.docs/reference/memory/summarizeConversation.md +99 -0
  153. package/.docs/reference/memory/summarizeThread.md +93 -0
  154. package/.docs/{docs/getting-started → reference}/project-structure.md +3 -10
  155. package/.docs/reference/pubsub/lease-provider.md +5 -5
  156. package/.docs/reference/server/express-adapter.md +1 -3
  157. package/.docs/reference/server/fastify-adapter.md +1 -3
  158. package/.docs/reference/server/hono-adapter.md +1 -3
  159. package/.docs/reference/server/koa-adapter.md +1 -3
  160. package/.docs/reference/server/nestjs-adapter.md +1 -3
  161. package/.docs/reference/signals/task-signal-provider.md +1 -1
  162. package/.docs/reference/storage/clickhouse.md +34 -2
  163. package/.docs/reference/storage/cloudflare-d1.md +1 -1
  164. package/.docs/reference/storage/composite.md +64 -6
  165. package/.docs/reference/storage/convex.md +1 -1
  166. package/.docs/reference/storage/dynamodb.md +1 -1
  167. package/.docs/reference/storage/mongodb.md +46 -46
  168. package/.docs/reference/storage/retention.md +74 -6
  169. package/.docs/reference/tools/create-tool.md +2 -2
  170. package/.docs/reference/tools/mcp-client.md +22 -0
  171. package/.docs/reference/tools/mcp-server.md +161 -4
  172. package/.docs/reference/vectors/mongodb.md +93 -4
  173. package/.docs/reference/voice/livekit.md +272 -8
  174. package/.docs/reference/workspace/agentcore-runtime-sandbox.md +1 -3
  175. package/.docs/reference/workspace/agentfs-filesystem.md +1 -3
  176. package/.docs/reference/workspace/apple-container-sandbox.md +6 -8
  177. package/.docs/reference/workspace/archil-filesystem.md +1 -3
  178. package/.docs/reference/workspace/azure-blob-filesystem.md +1 -3
  179. package/.docs/reference/workspace/blaxel-sandbox.md +1 -3
  180. package/.docs/reference/workspace/daytona-sandbox.md +1 -3
  181. package/.docs/reference/workspace/docker-sandbox.md +1 -3
  182. package/.docs/reference/workspace/e2b-sandbox.md +1 -3
  183. package/.docs/reference/workspace/files-sdk-filesystem.md +1 -3
  184. package/.docs/reference/workspace/gcs-filesystem.md +1 -3
  185. package/.docs/reference/workspace/google-drive-filesystem.md +1 -3
  186. package/.docs/reference/workspace/local-filesystem.md +1 -3
  187. package/.docs/reference/workspace/local-sandbox.md +1 -3
  188. package/.docs/reference/workspace/mesa-filesystem.md +4 -4
  189. package/.docs/reference/workspace/modal-sandbox.md +1 -3
  190. package/.docs/reference/workspace/railway-sandbox.md +2 -4
  191. package/.docs/reference/workspace/s3-filesystem.md +1 -3
  192. package/.docs/reference/workspace/vercel-sandbox.md +5 -7
  193. package/.docs/reference/workspace/vercel-serverless.md +2 -4
  194. package/CHANGELOG.md +29 -0
  195. package/package.json +5 -5
  196. package/.docs/docs/agents/channels.md +0 -225
  197. package/.docs/docs/agents/file-based-agents.md +0 -297
  198. package/.docs/docs/memory/storage.md +0 -267
@@ -32,7 +32,7 @@ bun add @mastra/mongodb@latest
32
32
 
33
33
  ## Usage
34
34
 
35
- Ensure you have a MongoDB Atlas Local (via Docker) or MongoDB Atlas Cloud instance with Atlas Search enabled. MongoDB 7.0+ is recommended.
35
+ Ensure you have a [MongoDB Atlas Local (via Docker)](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/) or [MongoDB Atlas Cloud](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-getting-started/) instance with Atlas Search enabled. MongoDB 7.0+ is recommended.
36
36
 
37
37
  ```typescript
38
38
  import { MongoDBStore } from '@mastra/mongodb'
@@ -40,7 +40,7 @@ import { MongoDBStore } from '@mastra/mongodb'
40
40
  const storage = new MongoDBStore({
41
41
  id: 'mongodb-storage',
42
42
  uri: process.env.MONGODB_URI,
43
- dbName: process.env.MONGODB_DATABASE,
43
+ dbName: process.env.MONGODB_DB_NAME,
44
44
  })
45
45
  ```
46
46
 
@@ -54,7 +54,15 @@ const storage = new MongoDBStore({
54
54
 
55
55
  **dbName** (`string`): The name of the database you want the storage to use.
56
56
 
57
- **options** (`MongoClientOptions`): MongoDB client options for advanced configuration (SSL, connection pooling, etc.).
57
+ **options** (`MongoClientOptions`): MongoDB client options for advanced configuration (SSL, connection pooling, etc.). See Connection Options
58
+
59
+ **disableInit** (`boolean`): When true, automatic initialization (collection creation) is disabled. Useful for CI/CD pipelines where you want to run migrations explicitly. You must call storage.init() manually when this is true.
60
+
61
+ **skipDefaultIndexes** (`boolean`): When true, default indexes will not be created during initialization. Useful when managing indexes separately or using only custom indexes.
62
+
63
+ **indexes** (`MongoDBIndexConfig[]`): Custom indexes to create during initialization. Each index must specify a collection, keys, and optional index options. See Indexes
64
+
65
+ **connectorHandler** (`ConnectorHandler`): Custom connection handler for advanced connection management. Alternative to providing uri/dbName directly.
58
66
 
59
67
  > **Deprecation Notice:** The `url` parameter is deprecated but still supported for backward compatibility. Please use `uri` instead in all new code.
60
68
 
@@ -84,6 +92,26 @@ const store2 = new MongoDBStore({
84
92
  socketTimeoutMS: 45000,
85
93
  },
86
94
  })
95
+
96
+ // With custom indexes
97
+ const store3 = new MongoDBStore({
98
+ id: 'mongodb-storage-03',
99
+ uri: 'mongodb+srv://user:password@cluster.mongodb.net',
100
+ dbName: 'mastra_storage',
101
+ indexes: [
102
+ { collection: 'mastra_threads', keys: { 'metadata.type': 1 } },
103
+ { collection: 'mastra_messages', keys: { 'metadata.status': 1 }, options: { sparse: true } },
104
+ ],
105
+ })
106
+
107
+ // For CI/CD with explicit initialization
108
+ const store4 = new MongoDBStore({
109
+ id: 'mongodb-storage-04',
110
+ uri: 'mongodb+srv://user:password@cluster.mongodb.net',
111
+ dbName: 'mastra_storage',
112
+ disableInit: true, // Disable auto-init
113
+ })
114
+ await store4.init() // Call init explicitly
87
115
  ```
88
116
 
89
117
  ## Additional notes
@@ -114,7 +142,7 @@ import { MongoDBStore } from '@mastra/mongodb'
114
142
  const storage = new MongoDBStore({
115
143
  id: 'mongodb-storage',
116
144
  uri: process.env.MONGODB_URI,
117
- dbName: process.env.MONGODB_DATABASE,
145
+ dbName: process.env.MONGODB_DB_NAME,
118
146
  })
119
147
 
120
148
  const mastra = new Mastra({
@@ -130,7 +158,7 @@ import { MongoDBStore } from '@mastra/mongodb'
130
158
  const storage = new MongoDBStore({
131
159
  id: 'mongodb-storage',
132
160
  uri: process.env.MONGODB_URI,
133
- dbName: process.env.MONGODB_DATABASE,
161
+ dbName: process.env.MONGODB_DB_NAME,
134
162
  })
135
163
 
136
164
  // Required when using storage directly
@@ -143,57 +171,28 @@ const thread = await memoryStore?.getThreadById({ threadId: '...' })
143
171
 
144
172
  > **Warning:** If `init()` isn't called, collections won't be created and storage operations will fail silently or throw errors.
145
173
 
146
- ## Vector search capabilities
147
-
148
- MongoDB storage includes built-in vector search capabilities for AI applications:
174
+ ### Connection Management
149
175
 
150
- ### Vector Index Creation
176
+ The `close()` method closes the MongoDB client connection. Call this when shutting down your application:
151
177
 
152
178
  ```typescript
153
- import { MongoDBVector } from '@mastra/mongodb'
179
+ import { MongoDBStore } from '@mastra/mongodb'
154
180
 
155
- const vectorStore = new MongoDBVector({
156
- id: 'mongodb-vector',
181
+ const storage = new MongoDBStore({
182
+ id: 'mongodb-storage',
157
183
  uri: process.env.MONGODB_URI,
158
- dbName: process.env.MONGODB_DATABASE,
184
+ dbName: process.env.MONGODB_DB_NAME,
159
185
  })
160
186
 
161
- // Create a vector index for embeddings
162
- await vectorStore.createIndex({
163
- indexName: 'document_embeddings',
164
- dimension: 1536,
165
- })
187
+ // Use storage...
188
+
189
+ // Clean up on shutdown
190
+ await storage.close()
166
191
  ```
167
192
 
168
- ### Vector Operations
193
+ ## Vector search capabilities
169
194
 
170
- ```typescript
171
- // Store vectors with metadata
172
- await vectorStore.upsert({
173
- indexName: "document_embeddings",
174
- vectors: [
175
- {
176
- id: "doc-1",
177
- values: [0.1, 0.2, 0.3, ...], // 1536-dimensional vector
178
- metadata: {
179
- title: "Document Title",
180
- category: "technical",
181
- source: "api-docs",
182
- },
183
- },
184
- ],
185
- });
186
-
187
- // Similarity search
188
- const results = await vectorStore.query({
189
- indexName: "document_embeddings",
190
- vector: queryEmbedding,
191
- topK: 5,
192
- filter: {
193
- category: "technical",
194
- },
195
- });
196
- ```
195
+ MongoDB storage includes built-in vector search capabilities for AI applications. For detailed vector operations including index creation, upserting embeddings, similarity search, and metadata filtering, see the [MongoDB vector reference](https://mastra.ai/reference/vectors/mongodb).
197
196
 
198
197
  ## Usage example
199
198
 
@@ -214,6 +213,7 @@ export const mongodbAgent = new Agent({
214
213
  model: 'openai/gpt-5.5',
215
214
  memory: new Memory({
216
215
  storage: new MongoDBStore({
216
+ id: 'mongodb-storage',
217
217
  uri: process.env.MONGODB_URI!,
218
218
  dbName: process.env.MONGODB_DB_NAME!,
219
219
  }),
@@ -6,7 +6,7 @@ Storage grows without bound by default. Retention is an opt-in, age-based cleanu
6
6
 
7
7
  `prune()` deletes rows. It caps growth and is safe to run against large tables (batched, bounded, resumable, cancellable). It never reclaims disk — on SQLite/libSQL the freed pages are reused by future writes so the file stops growing, but handing disk back to the OS (for example a `VACUUM`) is left to the underlying database and the operator to manage.
8
8
 
9
- Retention covers **growth tables** only — tables that accumulate rows unbounded as a side effect of normal operation (conversation history, telemetry, job and run records, schedule fire history, event feeds). User-authored artifacts and config (agents, skills, workspaces, prompt blocks, datasets, schedule definitions, channel installations, and so on) grow with user intent and are edited or deleted explicitly, so they are not valid retention keys.
9
+ Retention covers **growth tables** only — tables that accumulate rows unbounded as a side effect of normal operation (conversation history, telemetry, job and run records, schedule fire history, event feeds). User-authored artifacts and config (agents, skills, workspaces, prompt blocks, datasets, schedule definitions, channel installations, and so on) grow with user intent and are edited or deleted explicitly, so they're not valid retention keys.
10
10
 
11
11
  The reference implementations are [libSQL](https://mastra.ai/reference/storage/libsql), [PostgreSQL](https://mastra.ai/reference/storage/postgresql), and [MongoDB](https://mastra.ai/reference/storage/mongodb). Other adapters keep rows forever until they implement retention.
12
12
 
@@ -89,8 +89,8 @@ Each domain declares which of its tables can be age-pruned and which timestamp c
89
89
  > **Note:**
90
90
  >
91
91
  > - The memory `observational_memory` table has no timestamp anchor, so it can't be age-pruned and isn't a valid retention key.
92
- > - Experiments prune as whole units: an aged experiment's result rows are deleted together with it (results cascade with their parent), so a run is never left partially deleted. There is no separate `results` key.
93
- > - For `schedules`, the growth table is the fire history (`schedule_triggers`, one row per fire) — schedule definitions are config and are not pruned.
92
+ > - Experiments prune as whole units: an aged experiment's result rows are deleted together with it (results cascade with their parent), so a run is never left partially deleted. Retention doesn't have a separate `results` key.
93
+ > - For `schedules`, the growth table is the fire history (`schedule_triggers`, one row per fire) — schedule definitions are config and aren't pruned.
94
94
  > - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
95
95
  > - LibSQL supports all domains above; PostgreSQL and MongoDB support all except `threadState` and `harness`, which they don't implement.
96
96
  > - The v-next PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows — effective granularity is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
@@ -105,6 +105,8 @@ Deletes rows older than their configured `maxAge` across every domain that has a
105
105
 
106
106
  `prune()` is designed to be safe on tables with millions of rows. It deletes in bounded, batched chunks — each batch is its own transaction — so it never takes a long lock or bloats the transaction log. It never runs a `VACUUM`.
107
107
 
108
+ Pass `options.retention` to replace the configured policies for that call only — for example to skip a domain (keep chat history) or prune more aggressively than the standing config. The store's configured `retention` is unchanged.
109
+
108
110
  Anchor-column indexes are created lazily on the first `prune()` call for each table with a policy — never at `init()` — so deployments that don't configure retention pay no extra index write or disk overhead. The first prune of an existing large table pays a one-time index build; subsequent prunes reuse the index.
109
111
 
110
112
  ```typescript
@@ -116,6 +118,13 @@ const results = await storage.prune({
116
118
  for (const r of results) {
117
119
  console.log(`${r.domain}.${r.table}: deleted ${r.deleted}, done=${r.done}`)
118
120
  }
121
+
122
+ // One-off pass with different policies (configured retention untouched):
123
+ await storage.prune({
124
+ retention: {
125
+ observability: { spans: { maxAge: '1d' } },
126
+ },
127
+ })
119
128
  ```
120
129
 
121
130
  Returns: `Promise<PruneResult[]>`
@@ -130,6 +139,8 @@ Returns: `Promise<PruneResult[]>`
130
139
 
131
140
  **signal** (`AbortSignal`): Cooperative cancellation. The batch loop checks it between batches and stops cleanly, returning partial results with done: false.
132
141
 
142
+ **retention** (`RetentionConfig`): Replaces the store's configured retention policies for this call only — e.g. to skip a domain or prune more aggressively. The configured retention is unchanged.
143
+
133
144
  ##### PruneResult
134
145
 
135
146
  Each result describes one table's progress:
@@ -145,7 +156,7 @@ interface PruneResult {
145
156
 
146
157
  ## Running prune on a schedule
147
158
 
148
- `prune()` has no built-in scheduler — you decide when it runs. Because it is bounded, a single call may not delete everything. When any result has `done: false`, eligible rows remain and you call again on the next tick. This keeps each invocation short and lets a large backlog drain over several runs.
159
+ `prune()` has no built-in scheduler — you decide when it runs. Because it's bounded, a single call may not delete everything. When any result has `done: false`, eligible rows remain and you call again on the next tick. This keeps each invocation short and lets a large backlog drain over several runs.
149
160
 
150
161
  ```typescript
151
162
  // Runs on your own cron (node-cron, a workflow schedule, an external job, etc.).
@@ -164,11 +175,68 @@ async function retentionTick() {
164
175
 
165
176
  You can also cancel a long-running prune with an `AbortSignal` — the loop stops between batches and returns partial results with `done: false`, so the next run resumes cleanly.
166
177
 
178
+ ## MongoDB TTL indexes (alternative to prune)
179
+
180
+ MongoDB offers native [TTL (Time-To-Live) indexes](https://www.mongodb.com/docs/manual/core/index-ttl/) that automatically delete expired documents without requiring manual `prune()` calls. This is a database-level feature that runs as a background thread.
181
+
182
+ > **When to use TTL vs prune():** **Use MongoDB TTL indexes when:**
183
+ >
184
+ > - You want automated, zero-maintenance deletion
185
+ > - Your retention periods are fixed (e.g., "always 30 days")
186
+ > - You prefer database-native solutions
187
+ >
188
+ > **Use `prune()` when:**
189
+ >
190
+ > - You need fine-grained control over deletion timing
191
+ > - You want to cap deletion rate during business hours
192
+ > - You need resumable, cancellable cleanup operations
193
+ > - You're using composite storage with multiple databases
194
+ >
195
+ > Both approaches are valid. TTL is simpler; `prune()` gives more control.
196
+
197
+ ### Setting up TTL indexes on MongoDB
198
+
199
+ TTL indexes work on date fields. MongoDB checks the index every 60 seconds and deletes documents where the date field + TTL duration < current time.
200
+
201
+ ```typescript
202
+ import { MongoDBStore } from '@mastra/mongodb'
203
+
204
+ const storage = new MongoDBStore({
205
+ id: 'mongodb-storage',
206
+ uri: process.env.MONGODB_URI!,
207
+ dbName: process.env.MONGODB_DB_NAME!,
208
+ indexes: [
209
+ // Messages expire after 30 days
210
+ {
211
+ collection: 'mastra_messages',
212
+ keys: { createdAt: 1 },
213
+ options: { expireAfterSeconds: 30 * 24 * 60 * 60 }, // 30 days
214
+ },
215
+ // Threads expire after 90 days
216
+ {
217
+ collection: 'mastra_threads',
218
+ keys: { createdAt: 1 },
219
+ options: { expireAfterSeconds: 90 * 24 * 60 * 60 }, // 90 days
220
+ },
221
+ // Spans expire after 7 days
222
+ {
223
+ collection: 'mastra_ai_spans',
224
+ keys: { startedAt: 1 },
225
+ options: { expireAfterSeconds: 7 * 24 * 60 * 60 }, // 7 days
226
+ },
227
+ ],
228
+ })
229
+ ```
230
+
231
+ > **Tip:** TTL indexes delete documents shortly after they expire (background thread runs every \~60 seconds), but the exact timing is not guaranteed. For precise, immediate cleanup, use `prune()` instead.
232
+
167
233
  ## Reclaiming disk
168
234
 
169
- `prune()` deletes rows but does not shrink the database file. On SQLite/libSQL the freed pages go on a freelist and are reused by future writes, so the file stops growing — for most users this alone solves the unbounded-growth problem.
235
+ `prune()` deletes rows but doesn't shrink the database file. On SQLite/libSQL the freed pages go on a freelist and are reused by future writes, so the file stops growing — for most users this alone solves the unbounded-growth problem.
236
+
237
+ Handing that free space back to the OS is a separate concern that Mastra doesn't manage. If you specifically need to shrink the file, run the underlying database's compaction (for example `VACUUM` on self-hosted libSQL) yourself, in a maintenance window — a full `VACUUM` locks the file and needs roughly twice the file size in free disk. On PostgreSQL, autovacuum reclaims dead tuples for reuse automatically; a manual `VACUUM FULL` is only needed if you must return disk to the OS.
170
238
 
171
- Handing that free space back to the OS is a separate concern that Mastra does not manage. If you specifically need to shrink the file, run the underlying database's compaction (for example `VACUUM` on self-hosted libSQL) yourself, in a maintenance window — a full `VACUUM` locks the file and needs roughly twice the file size in free disk. On PostgreSQL, autovacuum reclaims dead tuples for reuse automatically; a manual `VACUUM FULL` is only needed if you must return disk to the OS.
239
+ For MongoDB, deleted documents are reused by future insertions. To reclaim disk space, run [`db.runCommand({ compact: "collection_name" })`](https://www.mongodb.com/docs/manual/reference/command/compact/) during a maintenance window.
172
240
 
173
241
  > **LibSQL and Turso:** [Turso Cloud](https://mastra.ai/reference/storage/libsql) manages storage compaction for you, so there's nothing to reclaim manually. This applies only to self-hosted libSQL files.
174
242
 
@@ -87,7 +87,7 @@ export const tool = createTool({
87
87
 
88
88
  **onOutput** (`function`): Optional callback invoked after the tool has successfully executed and returned output. Signature: ({ output, toolName, ...options }: { output: TSchemaOut; toolName: string } & Omit\<ToolCallOptions, 'messages'>) => void | PromiseLike\<void>.
89
89
 
90
- Runtime-populated fields such as `mastra` and `mcpMetadata` appear in source types but are set by Mastra or MCP adapters. You do not need to configure them for ordinary `createTool()` usage.
90
+ Runtime-populated fields such as `mastra` and `mcpMetadata` appear in source types but are set by Mastra or MCP adapters. You don't need to configure them for ordinary `createTool()` usage.
91
91
 
92
92
  ## Returns
93
93
 
@@ -450,7 +450,7 @@ Hook callbacks receive these source-backed parameter shapes:
450
450
  - `onInputStart`: Receives `ToolCallOptions`, including fields such as `toolCallId`, `messages`, and `abortSignal`.
451
451
  - `onInputDelta`: Receives `{ inputTextDelta: string } & ToolCallOptions`.
452
452
  - `onInputAvailable`: Receives `{ input: TSchemaIn } & ToolCallOptions`, where `input` is typed from `inputSchema`.
453
- - `onOutput`: Receives `{ output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>`, where `output` is typed from `outputSchema`. This hook does not receive `messages`.
453
+ - `onOutput`: Receives `{ output: TSchemaOut; toolName: string } & Omit<ToolCallOptions, 'messages'>`, where `output` is typed from `outputSchema`. This hook doesn't receive `messages`.
454
454
 
455
455
  ### Error handling
456
456
 
@@ -601,6 +601,28 @@ mcpClient.prompts.onListChanged('myWeatherServer', () => {
601
601
  })
602
602
  ```
603
603
 
604
+ ### `tools` Property
605
+
606
+ The `MCPClient` instance has a `tools` property for subscribing to tool list change notifications. To fetch tools, use `listTools()` or `listToolsets()`.
607
+
608
+ #### `tools.onListChanged(serverName: string, handler: () => void)`
609
+
610
+ Sets a notification handler that will be called when the list of available tools changes on a specific server (for example, when the server adds or removes tools at runtime).
611
+
612
+ ```typescript
613
+ async onListChanged(serverName: string, handler: () => void): Promise<void>
614
+ ```
615
+
616
+ Example:
617
+
618
+ ```typescript
619
+ await mcpClient.tools.onListChanged('myWeatherServer', async () => {
620
+ console.log('Tool list changed on myWeatherServer.')
621
+ // You should re-fetch the tools
622
+ // const tools = await mcpClient.listTools();
623
+ })
624
+ ```
625
+
604
626
  ### `progress` Property
605
627
 
606
628
  The `MCPClient` instance has a `progress` property for subscribing to progress notifications emitted by MCP servers while tools execute.
@@ -399,12 +399,31 @@ serve(async req => {
399
399
  >
400
400
  > The serverless mode disables session management and creates fresh server instances per request, which is necessary for stateless environments where memory doesn't persist between invocations.
401
401
  >
402
- > **Note:** The following MCP features require session state or persistent connections and **won't work** in serverless mode:
402
+ > By default, serverless mode buffers each request into a single JSON response, so `notifications/progress` sent by a tool never reach the client. Set `serverlessStreaming: true` to handle the request with request-scoped SSE streaming instead, which delivers progress notifications before the final result:
403
+ >
404
+ > ```typescript
405
+ > await server.startHTTP({
406
+ > url,
407
+ > httpPath: '/mcp',
408
+ > req: nodeReq,
409
+ > res: nodeRes,
410
+ > options: {
411
+ > serverless: true,
412
+ > serverlessStreaming: true, // ← Stream request-scoped notifications/progress
413
+ > },
414
+ > })
415
+ > ```
416
+ >
417
+ > This is still stateless: no `mcp-session-id` is required or persisted. It only enables notifications scoped to the current request (such as progress). The session-dependent features below remain unavailable.
418
+ >
419
+ > **Note:** The following MCP features require session state or persistent connections and **won't work** in serverless mode (including with `serverlessStreaming: true`):
403
420
  >
404
421
  > - **Elicitation** - Interactive user input requests during tool execution require session management to route responses back to the correct client
405
422
  > - **Resource subscriptions** - `resources/subscribe` and `resources/unsubscribe` need persistent connections to maintain subscription state
406
423
  > - **Resource update notifications** - `resources.notifyUpdated()` requires active subscriptions and persistent connections to notify clients
407
424
  > - **Prompt list change notifications** - `prompts.notifyListChanged()` requires persistent connections to push updates to clients
425
+ > - **Tool list change notifications** - `toolActions.notifyListChanged()` requires persistent connections to push updates to clients
426
+ > - **Server log notifications** - `sendLoggingMessage()` requires persistent connections to push log messages to clients
408
427
  >
409
428
  > These features work normally in long-lived server environments (Node.js servers, Docker containers, etc.).
410
429
 
@@ -424,6 +443,8 @@ The `StreamableHTTPServerTransportOptions` object allows you to customize the be
424
443
 
425
444
  **serverless** (`boolean`): If true, runs in stateless mode without session management. Each request is handled independently with a fresh server instance. Essential for serverless environments (Cloudflare Workers, Supabase Edge Functions, Vercel Edge, etc.) where sessions cannot persist between invocations. Defaults to false.
426
445
 
446
+ **serverlessStreaming** (`boolean`): If true, serverless requests use request-scoped SSE streaming instead of a buffered JSON response, allowing in-request notifications/progress to reach the client before the final result. Only takes effect together with serverless: true. Defaults to false (buffered JSON responses), which preserves backward-compatible behavior. This enables only request-scoped notifications such as progress; elicitation, subscriptions, and out-of-request notifications still require session state.
447
+
427
448
  **sessionIdGenerator** (`(() => string) | undefined`): A function that generates a unique session ID. This should be a cryptographically secure, globally unique string. Return undefined to disable session management.
428
449
 
429
450
  **onsessioninitialized** (`(sessionId: string) => void`): A callback that is invoked when a new session is initialized. This is useful for tracking active MCP sessions.
@@ -776,6 +797,144 @@ await serverWithPrompts.prompts.notifyListChanged()
776
797
  - Handle errors with informative messages.
777
798
  - Document argument expectations and available versions.
778
799
 
800
+ ## Dynamic tool management
801
+
802
+ Tools are usually provided when constructing the `MCPServer`, but you can also add or remove tools while the server is running. The server exposes these operations through the `toolActions` property. When the tool list changes, connected clients receive a `notifications/tools/list_changed` message prompting them to re-fetch the tool list.
803
+
804
+ The property is named `toolActions` because `tools()` is the method that returns the registered tool registry.
805
+
806
+ ### `toolActions.add(tools)`
807
+
808
+ Registers new tools on the running server and notifies connected clients. Tools are keyed by their record key, the same as tools passed to the constructor. Adding a tool under an existing key replaces it.
809
+
810
+ ```typescript
811
+ async server.toolActions.add(tools: ToolsInput): Promise<void>
812
+ ```
813
+
814
+ Example:
815
+
816
+ ```typescript
817
+ import { createTool } from '@mastra/core/tools'
818
+ import { z } from 'zod'
819
+
820
+ const searchTool = createTool({
821
+ id: 'search',
822
+ description: 'Searches the knowledge base.',
823
+ inputSchema: z.object({ query: z.string() }),
824
+ execute: async ({ query }) => ({ results: [] }),
825
+ })
826
+
827
+ await server.toolActions.add({ searchTool })
828
+ ```
829
+
830
+ ### `toolActions.remove(toolIds)`
831
+
832
+ Removes tools from the running server by tool ID and notifies connected clients. Unknown tool IDs are ignored. If no tools were removed, no notification is sent.
833
+
834
+ ```typescript
835
+ async server.toolActions.remove(toolIds: string[]): Promise<void>
836
+ ```
837
+
838
+ Example:
839
+
840
+ ```typescript
841
+ await server.toolActions.remove(['searchTool'])
842
+ ```
843
+
844
+ ### `toolActions.notifyListChanged()`
845
+
846
+ Sends a `notifications/tools/list_changed` message to connected clients without modifying the tool registry. Call this when tool availability changes through other means (for example, authorization changes).
847
+
848
+ ```typescript
849
+ async server.toolActions.notifyListChanged(): Promise<void>
850
+ ```
851
+
852
+ ### Mastra registry synchronization
853
+
854
+ When the server is registered with a Mastra instance, `toolActions.add()` and `toolActions.remove()` also update the Mastra instance's tool registry, matching the automatic tool registration that happens at startup. Added tools become available through `mastra.listTools()` (keyed by the tool's intrinsic `id` when present), and removed tools are deleted from the registry.
855
+
856
+ ## Logging
857
+
858
+ MCP servers can send structured log messages to clients using `notifications/message`. Clients control verbosity by sending a `logging/setLevel` request; the server drops messages below the requested minimum level (following RFC 5424 severity ordering). The level is tracked per session, so different clients can request different verbosity.
859
+
860
+ ### `sendLoggingMessage()`
861
+
862
+ Sends a log notification to all connected clients, honoring each client's minimum logging level.
863
+
864
+ ```typescript
865
+ async server.sendLoggingMessage(params: {
866
+ level: LoggingLevel;
867
+ data: unknown;
868
+ logger?: string;
869
+ }): Promise<void>
870
+ ```
871
+
872
+ Example:
873
+
874
+ ```typescript
875
+ await server.sendLoggingMessage({
876
+ level: 'info',
877
+ data: { message: 'Sync completed', itemsProcessed: 42 },
878
+ })
879
+ ```
880
+
881
+ ### `context.mcp.log()`
882
+
883
+ Inside a tool's `execute` function, use `context.mcp.log()` to send a log message to the client that called the tool.
884
+
885
+ ```typescript
886
+ async context.mcp.log(
887
+ level: LoggingLevel,
888
+ message: string,
889
+ data?: Record<string, unknown>
890
+ ): Promise<void>
891
+ ```
892
+
893
+ Example:
894
+
895
+ ```typescript
896
+ execute: async ({ location }, context) => {
897
+ await context.mcp.log('debug', 'Fetching weather', { location })
898
+ const weather = await fetchWeather(location)
899
+ await context.mcp.log('info', 'Weather fetched')
900
+ return weather
901
+ }
902
+ ```
903
+
904
+ ## Progress notifications
905
+
906
+ Long-running tools can report progress to the calling client with `notifications/progress`. Progress is only sent when the caller requested progress tracking by including a `progressToken` in the request (the Mastra `MCPClient` does this when `enableProgressTracking` is set). When no token was sent, `context.mcp.progress()` is a no-op.
907
+
908
+ ### `context.mcp.progress()`
909
+
910
+ ```typescript
911
+ async context.mcp.progress(params: {
912
+ progress: number;
913
+ total?: number;
914
+ message?: string;
915
+ }): Promise<void>
916
+ ```
917
+
918
+ Example:
919
+
920
+ ```typescript
921
+ execute: async ({ items }, context) => {
922
+ for (const [index, item] of items.entries()) {
923
+ await processItem(item)
924
+ await context.mcp.progress({
925
+ progress: index + 1,
926
+ total: items.length,
927
+ message: `Processed ${item.name}`,
928
+ })
929
+ }
930
+ return { done: true }
931
+ }
932
+ ```
933
+
934
+ ## Notification delivery
935
+
936
+ Notification methods (`resources.notifyListChanged()`, `prompts.notifyListChanged()`, `toolActions.notifyListChanged()`, and `sendLoggingMessage()`) broadcast to every connected client across all transports: the stdio/SSE connection and each streamable HTTP session. `resources.notifyUpdated()` is the exception: it only notifies clients that subscribed to the resource URI via `resources/subscribe`. Subscriptions are tracked per session for streamable HTTP clients; legacy SSE clients share the main server instance and therefore share one subscription set. Clients using the stateless serverless mode can't receive notifications because each request uses a transient server instance.
937
+
779
938
  ## Examples
780
939
 
781
940
  For practical examples of setting up and deploying an MCPServer, see the [Publishing an MCP Server guide](https://mastra.ai/guides/guide/publishing-mcp-server).
@@ -1402,9 +1561,7 @@ const server = new MCPServer({
1402
1561
  })
1403
1562
  ```
1404
1563
 
1405
- Link a tool to its app resource by setting `_meta.ui.resourceUri` on the tool to the matching `ui://` URI. The server auto-normalizes this metadata when registering tools.
1406
-
1407
- > **Note:** Visit [MCP Apps](https://mastra.ai/docs/mcp/mcp-apps) for the full app bridge API and usage patterns.
1564
+ Link a tool to its app resource by setting `_meta.ui.resourceUri` on the tool to the matching `ui://` URI. The server auto-normalizes this metadata when registering tools. Visit [MCP Apps](https://mastra.ai/docs/mcp/mcp-apps) for the full app bridge API and usage patterns.
1408
1565
 
1409
1566
  ## Related information
1410
1567