@mastra/mcp-docs-server 1.2.14 → 1.2.15-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 (97) hide show
  1. package/.docs/docs/agents/a2a.md +75 -2
  2. package/.docs/docs/agents/processors.md +2 -0
  3. package/.docs/docs/agents/skills.md +15 -1
  4. package/.docs/docs/capabilities/channels/overview.md +19 -0
  5. package/.docs/docs/capabilities/subagents.md +23 -5
  6. package/.docs/docs/connections/overview.md +94 -0
  7. package/.docs/docs/datasets/running-experiments.md +18 -0
  8. package/.docs/docs/evals/overview.md +16 -4
  9. package/.docs/docs/harness/agent-controller.md +6 -0
  10. package/.docs/docs/harness/overview.md +26 -0
  11. package/.docs/docs/index.md +1 -1
  12. package/.docs/docs/mcp/overview.md +10 -0
  13. package/.docs/docs/memory/multi-user-threads.md +1 -1
  14. package/.docs/docs/memory/observational-memory.md +1 -1
  15. package/.docs/docs/memory/semantic-recall.md +2 -1
  16. package/.docs/docs/memory/working-memory.md +1 -0
  17. package/.docs/docs/observability/feedback.md +16 -0
  18. package/.docs/docs/observability/integrations/exporters/mastra-storage.md +1 -0
  19. package/.docs/docs/server/auth.md +2 -0
  20. package/.docs/docs/server/mastra-client.md +11 -11
  21. package/.docs/docs/storage/overview.md +1 -0
  22. package/.docs/docs/workflows/agents-and-tools.md +2 -2
  23. package/.docs/docs/workflows/{stored-workflows.md → dynamic-workflows.md} +23 -23
  24. package/.docs/docs/workflows/snapshots.md +3 -1
  25. package/.docs/guides/build-your-ui/ai-sdk-ui.md +25 -14
  26. package/.docs/guides/getting-started/quickstart.md +1 -1
  27. package/.docs/guides/rag/overview.md +1 -1
  28. package/.docs/guides/rag/retrieval.md +17 -0
  29. package/.docs/guides/rag/vector-databases.md +41 -0
  30. package/.docs/guides/voice/realtime-voice.md +28 -2
  31. package/.docs/models/gateways/neon.md +20 -14
  32. package/.docs/models/gateways/netlify.md +1 -2
  33. package/.docs/models/gateways/openrouter.md +4 -2
  34. package/.docs/models/gateways/vercel.md +10 -3
  35. package/.docs/models/index.md +1 -1
  36. package/.docs/models/providers/anthropic.md +2 -2
  37. package/.docs/models/providers/cortecs.md +2 -1
  38. package/.docs/models/providers/deepinfra.md +6 -3
  39. package/.docs/models/providers/digitalocean.md +6 -5
  40. package/.docs/models/providers/empiriolabs.md +6 -4
  41. package/.docs/models/providers/friendli.md +8 -9
  42. package/.docs/models/providers/huggingface.md +4 -1
  43. package/.docs/models/providers/hyper.md +5 -6
  44. package/.docs/models/providers/kilo.md +11 -9
  45. package/.docs/models/providers/llmgateway.md +3 -3
  46. package/.docs/models/providers/meta.md +7 -5
  47. package/.docs/models/providers/minimax.md +25 -23
  48. package/.docs/models/providers/nano-gpt.md +7 -4
  49. package/.docs/models/providers/neuralwatt.md +2 -1
  50. package/.docs/models/providers/ofox.md +74 -16
  51. package/.docs/models/providers/openai.md +28 -26
  52. package/.docs/models/providers/opencode-go.md +1 -1
  53. package/.docs/models/providers/opencode.md +2 -3
  54. package/.docs/models/providers/perplexity-agent.md +24 -24
  55. package/.docs/models/providers/pioneer.md +27 -1
  56. package/.docs/models/providers/regolo-ai.md +25 -20
  57. package/.docs/models/providers/upstage.md +3 -2
  58. package/.docs/models/providers/vivgrid.md +4 -2
  59. package/.docs/models/providers/wandb.md +1 -1
  60. package/.docs/reference/agents/channels.md +22 -1
  61. package/.docs/reference/agents/generate.md +1 -1
  62. package/.docs/reference/ai-sdk/chat-route.md +2 -0
  63. package/.docs/reference/browser/agent-browser.md +1 -1
  64. package/.docs/reference/browser/mastra-browser.md +1 -1
  65. package/.docs/reference/browser/stagehand-browser.md +1 -1
  66. package/.docs/reference/channels/slack-provider.md +2 -0
  67. package/.docs/reference/client-js/observability.md +22 -0
  68. package/.docs/reference/client-js/workflows.md +32 -19
  69. package/.docs/reference/configuration.md +26 -1
  70. package/.docs/reference/core/{addStoredWorkflow.md → addDynamicWorkflow.md} +10 -10
  71. package/.docs/reference/core/{addStoredWorkflows.md → addDynamicWorkflows.md} +9 -9
  72. package/.docs/reference/editor/tool-provider.md +26 -1
  73. package/.docs/reference/file-based-agents/config.md +22 -21
  74. package/.docs/reference/file-based-agents/instructions.md +42 -17
  75. package/.docs/reference/file-based-agents/schedules.md +232 -0
  76. package/.docs/reference/index.md +7 -3
  77. package/.docs/reference/observability/metrics/automatic-metrics.md +10 -8
  78. package/.docs/reference/rag/metadata-filters.md +13 -4
  79. package/.docs/reference/server/register-api-route.md +2 -0
  80. package/.docs/reference/server/routes.md +38 -24
  81. package/.docs/reference/storage/composite.md +58 -0
  82. package/.docs/reference/storage/oracledb.md +239 -0
  83. package/.docs/reference/storage/overview.md +9 -9
  84. package/.docs/reference/storage/retention.md +1 -1
  85. package/.docs/reference/streaming/agents/stream.md +1 -1
  86. package/.docs/reference/tools/bedrock-kb-tool.md +117 -0
  87. package/.docs/reference/tools/mcp-client.md +54 -0
  88. package/.docs/reference/vectors/oracledb.md +347 -0
  89. package/.docs/reference/voice/google.md +19 -3
  90. package/.docs/reference/workflows/{stored-workflow-definition.md → dynamic-workflow-definition.md} +7 -7
  91. package/.docs/reference/workflows/step.md +40 -0
  92. package/.docs/reference/workflows/workflow-methods/agent.md +3 -3
  93. package/.docs/reference/workflows/workflow-methods/tool.md +3 -3
  94. package/.docs/reference/workspace/daytona-sandbox.md +21 -0
  95. package/.docs/reference/workspace/workspace-class.md +2 -0
  96. package/CHANGELOG.md +51 -0
  97. package/package.json +6 -6
@@ -0,0 +1,232 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # Schedules
4
+
5
+ A file-based agent discovers **schedules** from its `schedules/` directory. Each file declares one recurring task: a cron expression plus what the agent should do when it fires. Mastra registers them into schedule storage at startup, so a scheduled agent needs no runtime registration code.
6
+
7
+ Use this page for the file-based convention. To create schedules at runtime instead, see [Schedules](https://mastra.ai/reference/schedules/overview).
8
+
9
+ `defineSchedule` is re-exported from `@mastra/core/agent` so file-based agents need one import path. `@mastra/core/schedules` exports it too.
10
+
11
+ ## Quickstart
12
+
13
+ Add a file under the agent's `schedules/` directory:
14
+
15
+ ```typescript
16
+ import { defineSchedule } from '@mastra/core/agent'
17
+
18
+ export default defineSchedule({
19
+ cron: '*/5 * * * *',
20
+ prompt: 'Check system health and report any failures.',
21
+ })
22
+ ```
23
+
24
+ Every five minutes, Mastra runs the `support` agent with that prompt.
25
+
26
+ ## Schedule identity
27
+
28
+ A schedule's id is its path relative to `schedules/` with the extension stripped, so nested directories are a way to group related schedules:
29
+
30
+ ```text
31
+ src/mastra/agents/
32
+ └── support/
33
+ ├── config.ts
34
+ ├── instructions.md
35
+ └── schedules/
36
+ ├── heartbeat.ts # id: heartbeat
37
+ ├── cleanup.md # id: cleanup
38
+ └── billing/
39
+ └── sweep.ts # id: billing/sweep
40
+ ```
41
+
42
+ That id is stable across builds, which is what lets Mastra tell an edited schedule from a new one. Renaming or moving a file is treated as deleting one schedule and creating another.
43
+
44
+ `heartbeat.ts` and `heartbeat.md` resolve to the same id, so declaring both is a build error.
45
+
46
+ ## Execution modes
47
+
48
+ A schedule sets exactly one execution mode. Setting both, or neither, fails the build.
49
+
50
+ ### Prompt mode
51
+
52
+ `prompt` runs the owning agent with a fixed message. This is fire-and-forget: nothing waits for the result.
53
+
54
+ ```typescript
55
+ import { defineSchedule } from '@mastra/core/agent'
56
+
57
+ export default defineSchedule({
58
+ cron: '0 9 * * 1',
59
+ timezone: 'America/New_York',
60
+ prompt: 'Summarize last week and post the digest.',
61
+ })
62
+ ```
63
+
64
+ ### Handler mode
65
+
66
+ `handler` computes the fire's parameters when the schedule triggers. Use it when the prompt depends on current state, when some fires should be skipped, or when the run needs channel delivery context.
67
+
68
+ ```typescript
69
+ import { defineSchedule } from '@mastra/core/agent'
70
+
71
+ export default defineSchedule({
72
+ cron: '0 3 * * *',
73
+ handler: async ({ mastra, agentId }) => {
74
+ const overdue = await findOverdueInvoices()
75
+
76
+ // Returning null skips this fire; nothing runs and the trigger is
77
+ // recorded with outcome 'skipped'.
78
+ if (overdue.length === 0) return null
79
+
80
+ return {
81
+ prompt: `Chase these overdue invoices: ${overdue.join(', ')}`,
82
+ threadId: 'billing-ops',
83
+ resourceId: agentId,
84
+ }
85
+ },
86
+ })
87
+ ```
88
+
89
+ The handler's return value is merged over the schedule's stored fields. Returning `undefined` applies no overrides, so the fire falls back to those stored fields. Since a handler-mode schedule can't declare a `prompt`, that fire then fails for a missing prompt. Return a `prompt` to run, or `null` to skip.
90
+
91
+ Handlers are functions, so they can't be persisted on the stored schedule row. Mastra resolves them in-process when the schedule fires. A handler-mode schedule that supplies no prompt (and declares none) fails that fire with a reason rather than sending the agent an empty message.
92
+
93
+ That in-process lookup means the process running the scheduler must have the owning agent registered. A normal deployment boots a single entry and gets that for free. Standalone workers need the same entry as your server. Boot one from a trimmed entry and it has no handler to call, so its fires fail rather than run.
94
+
95
+ ### Markdown schedules
96
+
97
+ A `.md` schedule uses frontmatter for the cron and the document body as the prompt. This is prompt mode with more room to write:
98
+
99
+ ```markdown
100
+ ---
101
+ cron: '0 3 * * *'
102
+ timezone: 'UTC'
103
+ name: 'nightly cleanup'
104
+ ---
105
+
106
+ Review tickets untouched for 30 days.
107
+
108
+ Close the ones that are clearly resolved and summarize the rest.
109
+ ```
110
+
111
+ Always quote the cron. A leading `*` is a YAML alias, so `cron: */5 * * * *` is a parse error while `cron: "*/5 * * * *"` is fine.
112
+
113
+ Frontmatter accepts every option below except `handler`, which needs a function and so needs a `.ts` or `.js` schedule module. `prompt` isn't settable either, because the body is the prompt. Unknown frontmatter fields fail the build rather than being silently ignored, so a typo like `ifIdel` is caught at build time.
114
+
115
+ ## Options
116
+
117
+ **cron** (`string`): Standard five-field cron expression. Required. The scheduler evaluates schedules on a tick loop, so the effective granularity is one minute. Sub-minute fields are not supported.
118
+
119
+ **prompt** (`string`): Message the agent runs on each fire. Set this or handler, not both.
120
+
121
+ **handler** (`(ctx) => ScheduleOverrides | null | undefined`): Computes the fire at trigger time. Return overrides to apply, or null to skip this fire. Returning nothing applies no overrides, which fails the fire because handler mode has no stored prompt. Set this or prompt, not both.
122
+
123
+ **timezone** (`string`): IANA timezone the cron is evaluated in (e.g. America/New\_York). Defaults to the host process timezone, which varies by deployment, so set this explicitly for anything time-of-day sensitive. DST transitions are handled by the timezone rules, so 0 9 \* \* \* stays 9am local across the shift.
124
+
125
+ **name** (`string`): Free-form label shown in Studio and filterable via mastra.schedules.list({ name }).
126
+
127
+ **threadId** (`string`): Sends the fire as a signal into an existing thread instead of starting a fresh run. Requires resourceId.
128
+
129
+ **resourceId** (`string`): Owner of the target thread. Required when threadId is set.
130
+
131
+ **signalType** (`'user' | 'state' | 'reactive' | 'notification' | 'user-message' | 'system-reminder'`): Signal category for the fire. Threaded schedules only. (Default: `'notification'`)
132
+
133
+ **tagName** (`string`): XML tag the signal renders as, so a fire reaches the agent as \<schedule>…\</schedule>. (Default: `'schedule'`)
134
+
135
+ **attributes** (`Record<string, string | number | boolean | null>`): Attributes rendered onto the signal XML tag.
136
+
137
+ **providerOptions** (`Record<string, unknown>`): Provider options merged into the schedule signal payload on every fire. Must be JSON-safe.
138
+
139
+ **ifActive** (`ScheduleIfActive`): What to do when the target thread is already streaming: deliver, persist, or discard. Threaded schedules only.
140
+
141
+ **ifIdle** (`ScheduleIfIdle`): What to do when the target thread is idle: wake, persist, or discard. Threaded schedules only.
142
+
143
+ **status** (`'active' | 'paused'`): Status the row is created with. Applies on first create only, because the sync never patches status so that pausing through the API survives a redeploy. Changing this value in code later has no effect on an existing schedule. (Default: `'active'`)
144
+
145
+ **metadata** (`Record<string, unknown>`): Arbitrary JSON-safe data stored alongside the schedule row.
146
+
147
+ ## Testing a schedule in development
148
+
149
+ Schedules fire on their cron cadence, which is impractical while iterating. Fire one on demand by id instead:
150
+
151
+ ```bash
152
+ # List schedules to find the id
153
+ curl http://localhost:4111/api/schedules
154
+
155
+ # Fire one now, out-of-band from its cron
156
+ curl -X POST http://localhost:4111/api/schedules/<scheduleId>/run
157
+ ```
158
+
159
+ This records a trigger with `triggerKind: "manual"` and doesn't advance `nextFireAt`, so the regular cadence is unaffected. Studio lists the same schedules and their trigger history.
160
+
161
+ Stored ids are namespaced and URL-encoded. `billing/sweep` on the `support` agent becomes `fsa_support__billing%2Fsweep`, so copy the id from the list response rather than assembling it by hand.
162
+
163
+ ## Registration and lifecycle
164
+
165
+ Mastra syncs declared schedules into schedule storage when it starts, and again whenever an agent is registered afterward. Declaring a schedule is enough to start the scheduler, with no `scheduler: { enabled: true }` needed.
166
+
167
+ The sync compares each declared schedule against its stored row and writes only what changed:
168
+
169
+ - A new schedule file creates a row.
170
+ - Editing `cron` or `timezone` patches the row and recomputes the next fire time, so an edited schedule never fires on its old cadence.
171
+ - Deleting or renaming a schedule file deletes its row.
172
+ - Pausing a schedule through the API survives a redeploy. The sync deliberately leaves `status` alone.
173
+
174
+ The sync only removes rows belonging to agents registered in the current process, so a process holding a subset of your agents never deletes the others' schedules. When an agent is removed from the project entirely, its leftover rows are cleaned up on their next fire, when the scheduler finds no agent to run.
175
+
176
+ Schedules created at runtime through `mastra.schedules.create(...)` live in a separate namespace and are never touched by this sync.
177
+
178
+ ## Limits
179
+
180
+ **Root agents only.** Schedules must be declared on a top-level agent. A `schedules/` directory under `subagents/` is a build error, because subagents are wired into their parent rather than registered on the Mastra instance, so the scheduler could never resolve one as a target. Give the parent the schedule and let it delegate.
181
+
182
+ **Storage required.** Schedules are persisted rows, so the instance needs [storage](https://mastra.ai/reference/file-based-agents/storage) configured. Rows in an in-memory store don't survive a restart.
183
+
184
+ **Hosting.** The scheduler runs as a background worker inside the Mastra process, so it needs a host that keeps that process alive. Long-running Node servers and containers work. Environments that freeze or recycle the process between requests, which includes most serverless function platforms, will miss fires. Use the platform's own cron to call the run endpoint there instead.
185
+
186
+ **Code-defined agents.** An agent directory whose `config.ts` exports `new Agent({...})` is used verbatim, so its `schedules/` directory is ignored with a warning. Use `mastra.schedules.create(...)` for those.
187
+
188
+ ## Example
189
+
190
+ A support agent with two schedules: a fixed weekly digest, and a nightly sweep that only runs when there's something to do.
191
+
192
+ ```text
193
+ src/mastra/agents/
194
+ └── support/
195
+ ├── config.ts
196
+ ├── instructions.md
197
+ └── schedules/
198
+ ├── weekly-digest.md
199
+ └── billing/
200
+ └── sweep.ts
201
+ ```
202
+
203
+ ```typescript
204
+ import { agentConfig } from '@mastra/core/agent'
205
+
206
+ export default agentConfig({
207
+ model: 'openai/gpt-5.6-sol',
208
+ })
209
+ ```
210
+
211
+ ```markdown
212
+ ---
213
+ cron: '0 9 * * 1'
214
+ timezone: 'America/New_York'
215
+ ---
216
+
217
+ Summarize the past week's tickets and post the digest to the team channel.
218
+ ```
219
+
220
+ ```typescript
221
+ import { defineSchedule } from '@mastra/core/agent'
222
+
223
+ export default defineSchedule({
224
+ cron: '0 3 * * *',
225
+ timezone: 'America/New_York',
226
+ handler: async () => {
227
+ const overdue = await findOverdueInvoices()
228
+ if (overdue.length === 0) return null
229
+ return { prompt: `Draft reminders for ${overdue.length} overdue invoices.` }
230
+ },
231
+ })
232
+ ```
@@ -82,9 +82,9 @@ The Reference section provides documentation of Mastra's API, including paramete
82
82
  - [createCodingAgent()](https://mastra.ai/reference/coding-agent/create-coding-agent)
83
83
  - [Mastra Class](https://mastra.ai/reference/core/mastra-class)
84
84
  - [MastraModelGateway](https://mastra.ai/reference/core/mastra-model-gateway)
85
+ - [.addDynamicWorkflow()](https://mastra.ai/reference/core/addDynamicWorkflow)
86
+ - [.addDynamicWorkflows()](https://mastra.ai/reference/core/addDynamicWorkflows)
85
87
  - [.addGateway()](https://mastra.ai/reference/core/addGateway)
86
- - [.addStoredWorkflow()](https://mastra.ai/reference/core/addStoredWorkflow)
87
- - [.addStoredWorkflows()](https://mastra.ai/reference/core/addStoredWorkflows)
88
88
  - [.getAgent()](https://mastra.ai/reference/core/getAgent)
89
89
  - [.getAgentById()](https://mastra.ai/reference/core/getAgentById)
90
90
  - [.getDeployer()](https://mastra.ai/reference/core/getDeployer)
@@ -189,6 +189,7 @@ The Reference section provides documentation of Mastra's API, including paramete
189
189
  - [Memory](https://mastra.ai/reference/file-based-agents/memory)
190
190
  - [Observability](https://mastra.ai/reference/file-based-agents/observability)
191
191
  - [Processors](https://mastra.ai/reference/file-based-agents/processors)
192
+ - [Schedules](https://mastra.ai/reference/file-based-agents/schedules)
192
193
  - [Scorers](https://mastra.ai/reference/file-based-agents/scorers)
193
194
  - [Server](https://mastra.ai/reference/file-based-agents/server)
194
195
  - [Skills](https://mastra.ai/reference/file-based-agents/skills)
@@ -284,6 +285,7 @@ The Reference section provides documentation of Mastra's API, including paramete
284
285
  - [libSQL Storage](https://mastra.ai/reference/storage/libsql)
285
286
  - [MongoDB Storage](https://mastra.ai/reference/storage/mongodb)
286
287
  - [MSSQL Storage](https://mastra.ai/reference/storage/mssql)
288
+ - [OracleDB Storage](https://mastra.ai/reference/storage/oracledb)
287
289
  - [PostgreSQL Storage](https://mastra.ai/reference/storage/postgresql)
288
290
  - [Redis Storage](https://mastra.ai/reference/storage/redis)
289
291
  - [Retention (prune)](https://mastra.ai/reference/storage/retention)
@@ -301,6 +303,7 @@ The Reference section provides documentation of Mastra's API, including paramete
301
303
  - [Overview](https://mastra.ai/reference/templates/overview)
302
304
  - [askUserTool](https://mastra.ai/reference/tools/ask-user-tool)
303
305
  - [Bright Data Tools](https://mastra.ai/reference/tools/brightdata)
306
+ - [createBedrockKBTool()](https://mastra.ai/reference/tools/bedrock-kb-tool)
304
307
  - [createCodeMode()](https://mastra.ai/reference/tools/create-code-mode)
305
308
  - [createDocumentChunkerTool()](https://mastra.ai/reference/tools/document-chunker-tool)
306
309
  - [createGraphRAGTool()](https://mastra.ai/reference/tools/graph-rag-tool)
@@ -325,6 +328,7 @@ The Reference section provides documentation of Mastra's API, including paramete
325
328
  - [libSQL Vector Store](https://mastra.ai/reference/vectors/libsql)
326
329
  - [MongoDB Vector Store](https://mastra.ai/reference/vectors/mongodb)
327
330
  - [OpenSearch Vector Store](https://mastra.ai/reference/vectors/opensearch)
331
+ - [OracleDB Vector Store](https://mastra.ai/reference/vectors/oracledb)
328
332
  - [PG Vector Store](https://mastra.ai/reference/vectors/pg)
329
333
  - [Pinecone Vector Store](https://mastra.ai/reference/vectors/pinecone)
330
334
  - [Qdrant Vector Store](https://mastra.ai/reference/vectors/qdrant)
@@ -364,9 +368,9 @@ The Reference section provides documentation of Mastra's API, including paramete
364
368
  - [.speak()](https://mastra.ai/reference/voice/voice.speak)
365
369
  - [.updateConfig()](https://mastra.ai/reference/voice/voice.updateConfig)
366
370
  - [Overview](https://mastra.ai/reference/workers/overview)
371
+ - [Dynamic Workflow Definition](https://mastra.ai/reference/workflows/dynamic-workflow-definition)
367
372
  - [Run Class](https://mastra.ai/reference/workflows/run)
368
373
  - [Step Class](https://mastra.ai/reference/workflows/step)
369
- - [Stored Workflow Definition](https://mastra.ai/reference/workflows/stored-workflow-definition)
370
374
  - [Workflow Class](https://mastra.ai/reference/workflows/workflow)
371
375
  - [Workflow State Reader](https://mastra.ai/reference/workflows/workflow-state-reader)
372
376
  - [.agent()](https://mastra.ai/reference/workflows/workflow-methods/agent)
@@ -64,17 +64,19 @@ The detailed breakdown metrics (everything except `total_input` and `total_outpu
64
64
 
65
65
  ### When cost context is attached
66
66
 
67
- Cost context is attached to token metrics when the embedded pricing registry has a matching entry for the provider and model. Mastra includes the registry and covers common providers and models. If no match is found, token metrics are still emitted but without cost fields.
67
+ Cost context is attached to token metrics when the provider reports a valid cost for every completed model step or when the embedded pricing registry has a matching entry for the provider and model. Mastra sums the per-step provider costs into one query total. If any completed step lacks a valid reported cost, Mastra uses the pricing registry instead of reporting a partial total. If neither source is available, token metrics are still emitted without cost fields.
68
+
69
+ A caller-supplied `costContext` takes precedence over provider-reported costs and pricing registry estimates. Provider-reported totals use `costMetadata.source: 'provider_reported'`, `costMetadata.scope: 'query_total'`, and `costMetadata.reportedStepCount` to identify the source, scope, and number of completed steps included in the total.
68
70
 
69
71
  ### What cost fields may be included
70
72
 
71
- | Field | Description |
72
- | --------------- | ---------------------------------------------------------------------------- |
73
- | `provider` | Provider name (e.g. `openai`, `anthropic`) |
74
- | `model` | Model identifier (e.g. `gpt-4o`, `claude-sonnet-4-20250514`) |
75
- | `estimatedCost` | Estimated cost for this metric, calculated from token count and pricing tier |
76
- | `costUnit` | Currency unit (e.g. `USD`) |
77
- | `costMetadata` | Additional pricing context (tier information, error details) |
73
+ | Field | Description |
74
+ | --------------- | ------------------------------------------------------------------------------------------------------------------ |
75
+ | `provider` | Provider name (e.g. `openai`, `anthropic`) |
76
+ | `model` | Model identifier (e.g. `gpt-4o`, `claude-sonnet-4-20250514`) |
77
+ | `estimatedCost` | Estimated cost from token count and pricing tier, or a total reported by the provider |
78
+ | `costUnit` | Currency unit (e.g. `USD`) |
79
+ | `costMetadata` | Additional pricing context, including tier information, error details, and provider-reported cost source and scope |
78
80
 
79
81
  ## Correlation with traces
80
82
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Metadata filters
4
4
 
5
- Mastra provides a unified metadata filtering syntax across all vector stores, based on MongoDB/Sift query syntax. Each vector store translates these filters into their native format.
5
+ Mastra provides a unified metadata filtering syntax across all vector stores, based on MongoDB/Sift query syntax. Each vector store translates these filters into its native query format. For example, PgVector uses PostgreSQL JSONB predicates, while OracleDB stores metadata as Oracle JSON and compiles filters to `JSON_VALUE`, `JSON_EXISTS`, `REGEXP_LIKE`, and `LIKE` predicates with bound values.
6
6
 
7
7
  ## Basic example
8
8
 
@@ -34,11 +34,11 @@ const results = await store.query({
34
34
 
35
35
  ### Array Operators
36
36
 
37
- `$in`Matches any value in array{ category: { $in: \["A", "B"] } }Supported by: All except Couchbase`$nin`Matches none of the values{ status: { $nin: \["deleted", "archived"] } }Supported by: All except Couchbase`$all`Matches arrays containing all elements{ tags: { $all: \["urgent", "high"] } }Supported by: Astra, Pinecone, Upstash, MongoDB`$elemMatch`Matches array elements meeting criteria{ scores: { $elemMatch: { $gt: 80 } } }Supported by: libSQL, PgVector, MongoDB
37
+ `$in`Matches any value in array{ category: { $in: \["A", "B"] } }Supported by: All except Couchbase`$nin`Matches none of the values{ status: { $nin: \["deleted", "archived"] } }Supported by: All except Couchbase`$all`Matches arrays containing all elements{ tags: { $all: \["urgent", "high"] } }Supported by: Astra, Pinecone, Upstash, MongoDB, OracleDB`$elemMatch`Matches array elements meeting criteria{ scores: { $elemMatch: { $gt: 80 } } }Supported by: libSQL, PgVector, MongoDB, OracleDB
38
38
 
39
39
  ### Logical Operators
40
40
 
41
- `$and`Logical AND{ $and: \[{ price: { $gt: 100 } }, { stock: { $gt: 0 } }] }Supported by: All except Vectorize, Couchbase`$or`Logical OR{ $or: \[{ status: "active" }, { priority: "high" }] }Supported by: All except Vectorize, Couchbase`$not`Logical NOT{ price: { $not: { $lt: 100 } } }Supported by: Astra, Qdrant, Upstash, PgVector, libSQL, MongoDB`$nor`Logical NOR{ $nor: \[{ status: "deleted" }, { archived: true }] }Supported by: Qdrant, Upstash, PgVector, libSQL, MongoDB
41
+ `$and`Logical AND{ $and: \[{ price: { $gt: 100 } }, { stock: { $gt: 0 } }] }Supported by: All except Vectorize, Couchbase`$or`Logical OR{ $or: \[{ status: "active" }, { priority: "high" }] }Supported by: All except Vectorize, Couchbase`$not`Logical NOT{ price: { $not: { $lt: 100 } } }Supported by: Astra, Qdrant, Upstash, PgVector, libSQL, MongoDB, OracleDB`$nor`Logical NOR{ $nor: \[{ status: "deleted" }, { archived: true }] }Supported by: Qdrant, Upstash, PgVector, libSQL, MongoDB, OracleDB
42
42
 
43
43
  ### Element Operators
44
44
 
@@ -46,7 +46,7 @@ const results = await store.query({
46
46
 
47
47
  ### Custom Operators
48
48
 
49
- `$contains`Text contains substring{ description: { $contains: "sale" } }Supported by: Upstash, libSQL, PgVector`$regex`Regular expression match{ name: { $regex: "^test" } }Supported by: Qdrant, PgVector, Upstash, MongoDB`$size`Array length check{ tags: { $size: { $gt: 2 } } }Supported by: Astra, libSQL, PgVector, MongoDB`$geo`Geospatial query{ location: { $geo: { type: "radius", ... } } }Supported by: Qdrant`$datetime`Datetime range query{ created: { $datetime: { range: { gt: "2024-01-01" } } } }Supported by: Qdrant`$hasId`Vector ID existence check{ $hasId: \["id1", "id2"] }Supported by: Qdrant`$hasVector`Vector existence check{ $hasVector: true }Supported by: Qdrant
49
+ `$contains`Text contains substring{ description: { $contains: "sale" } }Supported by: Upstash, libSQL, PgVector, OracleDB`$regex`Regular expression match{ name: { $regex: "^test" } }Supported by: Qdrant, PgVector, Upstash, MongoDB, OracleDB`$size`Array length check{ tags: { $size: 3 } }Supported by: Astra, libSQL, PgVector, MongoDB, OracleDB`$geo`Geospatial query{ location: { $geo: { type: "radius", ... } } }Supported by: Qdrant`$datetime`Datetime range query{ created: { $datetime: { range: { gt: "2024-01-01" } } } }Supported by: Qdrant`$hasId`Vector ID existence check{ $hasId: \["id1", "id2"] }Supported by: Qdrant`$hasVector`Vector existence check{ $hasVector: true }Supported by: Qdrant
50
50
 
51
51
  ## Common rules and restrictions
52
52
 
@@ -124,6 +124,14 @@ const results = await store.query({
124
124
  - Empty arrays in conditions are handled gracefully
125
125
  - Metadata is stored in a JSONB column for efficient querying
126
126
 
127
+ ### OracleDB
128
+
129
+ - Metadata is stored as Oracle JSON alongside each `VECTOR` row
130
+ - Scalar comparisons use `JSON_VALUE`, while array, existence, and element-match checks use `JSON_EXISTS`
131
+ - `$regex` uses Oracle `REGEXP_LIKE`; string `$contains` uses case-insensitive `LIKE`
132
+ - Nested fields are supported with dot notation and are converted to quoted Oracle JSON paths
133
+ - User-provided metadata values are bound as parameters instead of interpolated into SQL
134
+
127
135
  ### PgVector
128
136
 
129
137
  - Full support for PostgreSQL's native JSON querying capabilities
@@ -211,6 +219,7 @@ const results = await store.query({
211
219
  - [Cloudflare Vectorize](https://mastra.ai/reference/vectors/vectorize)
212
220
  - [libSQL](https://mastra.ai/reference/vectors/libsql)
213
221
  - [MongoDB](https://mastra.ai/reference/vectors/mongodb)
222
+ - [OracleDB](https://mastra.ai/reference/vectors/oracledb)
214
223
  - [PgStore](https://mastra.ai/reference/vectors/pg)
215
224
  - [Pinecone](https://mastra.ai/reference/vectors/pinecone)
216
225
  - [Qdrant](https://mastra.ai/reference/vectors/qdrant)
@@ -22,6 +22,8 @@ registerApiRoute("/items/:itemId", { ... })
22
22
 
23
23
  Custom route paths can't start with the server's configured `apiPrefix` (default: `/api`), as that prefix is reserved for built-in Mastra routes. If you set a custom `apiPrefix`, only that prefix is reserved. For example, with `apiPrefix: '/mastra/api'`, paths like `/api/my-endpoint` are allowed.
24
24
 
25
+ > **Warning:** The default auth configuration protects `/api/*` and treats `/api`, `/api/auth/*` as public. When you change `apiPrefix`, those defaults no longer match and built-in routes fall outside the protected pattern. Update `server.auth.protected` and `server.auth.public` to reference the new prefix, and update any client code (including `MastraClient` `apiPrefix`) that hits `/api/*`.
26
+
25
27
  ### options
26
28
 
27
29
  **method** (`'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'ALL'`): HTTP method for the route
@@ -171,30 +171,44 @@ The route returns:
171
171
 
172
172
  ## Workflows
173
173
 
174
- | Method | Path | Description |
175
- | ------ | ----------------------------------------- | ------------------------------- |
176
- | `GET` | `/api/workflows` | List all workflows |
177
- | `GET` | `/api/workflows/:workflowId` | Get workflow by ID |
178
- | `POST` | `/api/workflows/:workflowId/create-run` | Create a new workflow run |
179
- | `POST` | `/api/workflows/:workflowId/start-async` | Start workflow and await result |
180
- | `POST` | `/api/workflows/:workflowId/stream` | Stream workflow execution |
181
- | `POST` | `/api/workflows/:workflowId/resume` | Resume suspended workflow |
182
- | `POST` | `/api/workflows/:workflowId/resume-async` | Resume asynchronously |
183
- | `GET` | `/api/workflows/:workflowId/runs` | List workflow runs |
184
- | `GET` | `/api/workflows/:workflowId/runs/:runId` | Get specific run |
185
-
186
- ### Stored workflows
187
-
188
- Stored workflow definitions (beta) are workflows expressed as JSON, persisted through the `workflowDefinitions` storage domain, and live-registered on the running instance. See [Stored workflows](https://mastra.ai/docs/workflows/stored-workflows).
189
-
190
- | Method | Path | Description |
191
- | -------- | ----------------------------------------- | ------------------------------------------------------------------------------ |
192
- | `GET` | `/api/stored/workflows` | List stored workflow definitions, filterable by `status` and `authorId` |
193
- | `GET` | `/api/stored/workflows/:storedWorkflowId` | Get a stored workflow definition by ID |
194
- | `POST` | `/api/stored/workflows` | Upsert a definition (plus optional helper `dependencies`) and live-register it |
195
- | `DELETE` | `/api/stored/workflows/:storedWorkflowId` | Delete a stored definition and unregister the live workflow |
196
-
197
- On authenticated servers, the read routes require the `stored-workflows:read` permission and the write routes require `stored-workflows:write`. Registered stored workflows are executed through the ordinary `/api/workflows/:workflowId` routes above.
174
+ | Method | Path | Description |
175
+ | ------ | ----------------------------------------- | ----------------------------------------------------- |
176
+ | `GET` | `/api/workflows` | List all workflows |
177
+ | `GET` | `/api/workflows/run-counts` | Get per-workflow counts of running and suspended runs |
178
+ | `GET` | `/api/workflows/:workflowId` | Get workflow by ID |
179
+ | `POST` | `/api/workflows/:workflowId/create-run` | Create a new workflow run |
180
+ | `POST` | `/api/workflows/:workflowId/start-async` | Start workflow and await result |
181
+ | `POST` | `/api/workflows/:workflowId/stream` | Stream workflow execution |
182
+ | `POST` | `/api/workflows/:workflowId/resume` | Resume suspended workflow |
183
+ | `POST` | `/api/workflows/:workflowId/resume-async` | Resume asynchronously |
184
+ | `GET` | `/api/workflows/:workflowId/runs` | List workflow runs |
185
+ | `GET` | `/api/workflows/:workflowId/runs/:runId` | Get specific run |
186
+
187
+ ### Run counts response
188
+
189
+ The `/api/workflows/run-counts` endpoint returns counts of `running` and [`suspended`](https://mastra.ai/docs/workflows/suspend-and-resume) runs for every registered workflow. The record is keyed by the workflow's registry key from the Mastra config, and the server may cache the response for a few seconds:
190
+
191
+ ```typescript
192
+ {
193
+ [workflowRegistryKey: string]: {
194
+ running: number;
195
+ suspended: number;
196
+ };
197
+ }
198
+ ```
199
+
200
+ ### Dynamic workflows
201
+
202
+ Dynamic workflow definitions (beta) are workflows expressed as JSON, persisted through the `workflowDefinitions` storage domain, and live-registered on the running instance. See [Dynamic workflows](https://mastra.ai/docs/workflows/dynamic-workflows).
203
+
204
+ | Method | Path | Description |
205
+ | -------- | ------------------------------------------ | ------------------------------------------------------------------------------ |
206
+ | `GET` | `/api/stored/workflows` | List dynamic workflow definitions, filterable by `status` and `authorId` |
207
+ | `GET` | `/api/stored/workflows/:dynamicWorkflowId` | Get a dynamic workflow definition by ID |
208
+ | `POST` | `/api/stored/workflows` | Upsert a definition (plus optional helper `dependencies`) and live-register it |
209
+ | `DELETE` | `/api/stored/workflows/:dynamicWorkflowId` | Delete a dynamic workflow definition and unregister the live workflow |
210
+
211
+ On authenticated servers, the read routes require the `stored-workflows:read` permission and the write routes require `stored-workflows:write`. Registered dynamic workflows are executed through the ordinary `/api/workflows/:workflowId` routes above.
198
212
 
199
213
  ### Create run request body
200
214
 
@@ -251,6 +251,64 @@ const memoryStore = await storage.getStore('memory')
251
251
  const thread = await memoryStore?.getThreadById({ threadId: '...' })
252
252
  ```
253
253
 
254
+ ## Closing connections
255
+
256
+ `close()` releases the connections of the stores a composite was built from: the `default` and `editor` stores, plus any domain that owns its own client. Each store is closed once, even when it backs several domains. When passed to the Mastra class, `close()` is called by `shutdown()`:
257
+
258
+ ```typescript
259
+ import { MastraCompositeStore } from '@mastra/core/storage'
260
+ import { PostgresStore } from '@mastra/pg'
261
+ import { Mastra } from '@mastra/core'
262
+
263
+ const pgStore = new PostgresStore({
264
+ id: 'pg-storage',
265
+ connectionString: process.env.DATABASE_URL,
266
+ })
267
+
268
+ export const mastra = new Mastra({
269
+ storage: new MastraCompositeStore({ id: 'composite', default: pgStore }),
270
+ })
271
+
272
+ process.on('SIGTERM', async () => {
273
+ // Releases the Postgres pool, so the process can exit
274
+ await mastra.shutdown()
275
+ })
276
+ ```
277
+
278
+ A store you construct only to supply a domain isn't reachable through the composite. Keep a reference to it and close it yourself:
279
+
280
+ ```typescript
281
+ import { MastraCompositeStore } from '@mastra/core/storage'
282
+ import { ClickhouseStore } from '@mastra/clickhouse'
283
+ import { PostgresStore } from '@mastra/pg'
284
+ import { Mastra } from '@mastra/core'
285
+
286
+ const pgStore = new PostgresStore({
287
+ id: 'pg-storage',
288
+ connectionString: process.env.DATABASE_URL,
289
+ })
290
+
291
+ const clickhouseStore = new ClickhouseStore({
292
+ id: 'clickhouse-storage',
293
+ url: process.env.CLICKHOUSE_URL,
294
+ username: process.env.CLICKHOUSE_USERNAME,
295
+ password: process.env.CLICKHOUSE_PASSWORD,
296
+ })
297
+
298
+ export const mastra = new Mastra({
299
+ storage: new MastraCompositeStore({
300
+ id: 'composite',
301
+ default: pgStore,
302
+ domains: { observability: clickhouseStore.stores?.observability },
303
+ }),
304
+ })
305
+
306
+ process.on('SIGTERM', async () => {
307
+ await mastra.shutdown()
308
+ await clickhouseStore.close()
309
+ })
310
+ ```
311
+
254
312
  ## Use cases
255
313
 
256
314
  ### Separate databases for different workloads