@mastra/mcp-docs-server 1.2.15-alpha.1 → 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 (91) 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 +15 -9
  32. package/.docs/models/gateways/netlify.md +1 -2
  33. package/.docs/models/gateways/openrouter.md +3 -2
  34. package/.docs/models/gateways/vercel.md +10 -3
  35. package/.docs/models/index.md +1 -1
  36. package/.docs/models/providers/cortecs.md +2 -1
  37. package/.docs/models/providers/deepinfra.md +6 -3
  38. package/.docs/models/providers/digitalocean.md +6 -5
  39. package/.docs/models/providers/empiriolabs.md +6 -4
  40. package/.docs/models/providers/friendli.md +8 -9
  41. package/.docs/models/providers/huggingface.md +4 -1
  42. package/.docs/models/providers/hyper.md +5 -6
  43. package/.docs/models/providers/kilo.md +11 -9
  44. package/.docs/models/providers/llmgateway.md +3 -3
  45. package/.docs/models/providers/meta.md +7 -5
  46. package/.docs/models/providers/nano-gpt.md +7 -4
  47. package/.docs/models/providers/neuralwatt.md +2 -1
  48. package/.docs/models/providers/ofox.md +74 -16
  49. package/.docs/models/providers/opencode-go.md +1 -1
  50. package/.docs/models/providers/opencode.md +2 -3
  51. package/.docs/models/providers/regolo-ai.md +25 -20
  52. package/.docs/models/providers/upstage.md +3 -2
  53. package/.docs/models/providers/vivgrid.md +4 -2
  54. package/.docs/models/providers/wandb.md +1 -1
  55. package/.docs/reference/agents/channels.md +22 -1
  56. package/.docs/reference/agents/generate.md +1 -1
  57. package/.docs/reference/ai-sdk/chat-route.md +2 -0
  58. package/.docs/reference/browser/agent-browser.md +1 -1
  59. package/.docs/reference/browser/mastra-browser.md +1 -1
  60. package/.docs/reference/browser/stagehand-browser.md +1 -1
  61. package/.docs/reference/channels/slack-provider.md +2 -0
  62. package/.docs/reference/client-js/observability.md +22 -0
  63. package/.docs/reference/client-js/workflows.md +32 -19
  64. package/.docs/reference/configuration.md +26 -1
  65. package/.docs/reference/core/{addStoredWorkflow.md → addDynamicWorkflow.md} +10 -10
  66. package/.docs/reference/core/{addStoredWorkflows.md → addDynamicWorkflows.md} +9 -9
  67. package/.docs/reference/editor/tool-provider.md +26 -1
  68. package/.docs/reference/file-based-agents/config.md +22 -21
  69. package/.docs/reference/file-based-agents/instructions.md +42 -17
  70. package/.docs/reference/index.md +6 -3
  71. package/.docs/reference/observability/metrics/automatic-metrics.md +10 -8
  72. package/.docs/reference/rag/metadata-filters.md +13 -4
  73. package/.docs/reference/server/register-api-route.md +2 -0
  74. package/.docs/reference/server/routes.md +38 -24
  75. package/.docs/reference/storage/composite.md +58 -0
  76. package/.docs/reference/storage/oracledb.md +239 -0
  77. package/.docs/reference/storage/overview.md +9 -9
  78. package/.docs/reference/storage/retention.md +1 -1
  79. package/.docs/reference/streaming/agents/stream.md +1 -1
  80. package/.docs/reference/tools/bedrock-kb-tool.md +117 -0
  81. package/.docs/reference/tools/mcp-client.md +54 -0
  82. package/.docs/reference/vectors/oracledb.md +347 -0
  83. package/.docs/reference/voice/google.md +19 -3
  84. package/.docs/reference/workflows/{stored-workflow-definition.md → dynamic-workflow-definition.md} +7 -7
  85. package/.docs/reference/workflows/step.md +40 -0
  86. package/.docs/reference/workflows/workflow-methods/agent.md +3 -3
  87. package/.docs/reference/workflows/workflow-methods/tool.md +3 -3
  88. package/.docs/reference/workspace/daytona-sandbox.md +21 -0
  89. package/.docs/reference/workspace/workspace-class.md +2 -0
  90. package/CHANGELOG.md +44 -0
  91. package/package.json +6 -6
@@ -2,9 +2,11 @@
2
2
 
3
3
  # Instructions
4
4
 
5
- An agent's `instructions.md` holds its always-on system prompt: the model reads it on every turn. Use it to define the agent's identity, tone, role, and standing rules.
5
+ An agent's instructions hold its always-on system prompt: the model reads it on every turn. Use them to define the agent's identity, tone, role, and standing rules.
6
6
 
7
- Instructions are always in context, so keep them for stable behavior that applies to every request. Move anything conditional, large, or action-oriented out of `instructions.md` and into [`tools/`](https://mastra.ai/reference/file-based-agents/tools) or [`skills/`](https://mastra.ai/reference/file-based-agents/skills), which the model uses only when relevant.
7
+ Write them in one of two files at the agent root. Use `instructions.md` when the prompt is fixed text. Use `instructions.ts` when the prompt needs code, for example when it's built from shared constants or resolved per request.
8
+
9
+ Instructions are always in context, so keep them for stable behavior that applies to every request. Move anything conditional, large, or action-oriented into [`tools/`](https://mastra.ai/reference/file-based-agents/tools) or [`skills/`](https://mastra.ai/reference/file-based-agents/skills), which the model uses only when relevant.
8
10
 
9
11
  ## Quickstart
10
12
 
@@ -25,30 +27,53 @@ Effective instructions cover the parts of an agent's behavior that don't change
25
27
 
26
28
  Move conditional, large, or action-oriented guidance into [`tools/`](https://mastra.ai/reference/file-based-agents/tools) or [`skills/`](https://mastra.ai/reference/file-based-agents/skills), which the model uses only when relevant.
27
29
 
28
- ## Dynamic instructions
30
+ ## Instructions in TypeScript
31
+
32
+ Use `instructions.ts` when markdown can't express the prompt. The file default-exports a string, a system message, or a function returning one, and `agentInstructions()` types the export without changing it.
33
+
34
+ Export a string when the prompt is assembled in code, for example from constants shared with the rest of your app:
35
+
36
+ ```typescript
37
+ import { agentInstructions } from '@mastra/core/agent'
38
+ import { SUPPORTED_UNITS } from '../../constants'
39
+
40
+ export default agentInstructions(`
41
+ You are a helpful weather assistant.
42
+ Report conditions using one of these units: ${SUPPORTED_UNITS.join(', ')}.
43
+ `)
44
+ ```
29
45
 
30
- When the prompt needs to change per request, for example based on the current user or runtime context, set a runtime-defined `instructions` function in [`config.ts`](https://mastra.ai/reference/file-based-agents/config) instead of using `instructions.md`. A function `instructions` wins over `instructions.md`, so the static file is ignored when both are present.
46
+ Export a function when the prompt depends on the request. Mastra calls it on every turn and passes the request context:
31
47
 
32
48
  ```typescript
33
- import { agentConfig } from '@mastra/core/agent'
34
-
35
- export default agentConfig({
36
- model: 'openai/gpt-5.6-sol',
37
- instructions: ({ runtimeContext }) => {
38
- const tier = runtimeContext.get('tier') ?? 'standard'
39
- return `You are a support agent. Treat this as a ${tier}-tier customer.`
40
- },
49
+ import { agentInstructions } from '@mastra/core/agent'
50
+
51
+ export default agentInstructions(({ requestContext }) => {
52
+ const tier = requestContext.get('tier') ?? 'standard'
53
+ return `You are a support agent. Treat this as a ${tier}-tier customer.`
41
54
  })
42
55
  ```
43
56
 
57
+ The function can be `async` and receives `mastra` alongside `requestContext`, so it can read from storage or another registered primitive before returning the prompt.
58
+
59
+ Both files can also live in a [subagent](https://mastra.ai/reference/file-based-agents/subagents) directory, which follows the same rules.
60
+
44
61
  ## Build-time behavior
45
62
 
46
- Mastra reads `instructions.md` and inlines its contents into the generated code when the bundler builds your project. The deployed agent doesn't read the file at runtime, so changes to `instructions.md` take effect only after the next build.
63
+ `instructions.md` and `instructions.ts` reach the deployed agent differently:
64
+
65
+ - `instructions.md`: Mastra reads the file and inlines its contents into the generated code at build time.
66
+ - `instructions.ts`: The generated code imports the module, so it's bundled like any other TypeScript file and can import from the rest of your project.
67
+
68
+ Under `mastra dev`, editing either file triggers a rebuild. In a deployed app neither file is read from disk at runtime, so changes take effect after the next build.
47
69
 
48
70
  ## Precedence with config
49
71
 
50
- Instructions can come from `instructions.md` or from the `instructions` field in [`config.ts`](https://mastra.ai/reference/file-based-agents/config):
72
+ Instructions can come from `instructions.ts`, `instructions.md`, or the `instructions` field in [`config.ts`](https://mastra.ai/reference/file-based-agents/config):
73
+
74
+ - A runtime-defined (function) `instructions` in `config.ts` wins over both files.
75
+ - Otherwise `instructions.ts` wins over `instructions.md`.
76
+ - `instructions.md` wins over a static `instructions` string in `config.ts`.
77
+ - If none is present, the build fails and names the agent directory.
51
78
 
52
- - A runtime-defined (function) `instructions` in `config.ts` wins over `instructions.md`.
53
- - Otherwise `instructions.md` wins over a static `instructions` string.
54
- - If neither is present, the build fails and names the agent directory.
79
+ Defining instructions in more than one place logs a warning that names both sources and which one wins. Keep one source per agent.
@@ -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)
@@ -285,6 +285,7 @@ The Reference section provides documentation of Mastra's API, including paramete
285
285
  - [libSQL Storage](https://mastra.ai/reference/storage/libsql)
286
286
  - [MongoDB Storage](https://mastra.ai/reference/storage/mongodb)
287
287
  - [MSSQL Storage](https://mastra.ai/reference/storage/mssql)
288
+ - [OracleDB Storage](https://mastra.ai/reference/storage/oracledb)
288
289
  - [PostgreSQL Storage](https://mastra.ai/reference/storage/postgresql)
289
290
  - [Redis Storage](https://mastra.ai/reference/storage/redis)
290
291
  - [Retention (prune)](https://mastra.ai/reference/storage/retention)
@@ -302,6 +303,7 @@ The Reference section provides documentation of Mastra's API, including paramete
302
303
  - [Overview](https://mastra.ai/reference/templates/overview)
303
304
  - [askUserTool](https://mastra.ai/reference/tools/ask-user-tool)
304
305
  - [Bright Data Tools](https://mastra.ai/reference/tools/brightdata)
306
+ - [createBedrockKBTool()](https://mastra.ai/reference/tools/bedrock-kb-tool)
305
307
  - [createCodeMode()](https://mastra.ai/reference/tools/create-code-mode)
306
308
  - [createDocumentChunkerTool()](https://mastra.ai/reference/tools/document-chunker-tool)
307
309
  - [createGraphRAGTool()](https://mastra.ai/reference/tools/graph-rag-tool)
@@ -326,6 +328,7 @@ The Reference section provides documentation of Mastra's API, including paramete
326
328
  - [libSQL Vector Store](https://mastra.ai/reference/vectors/libsql)
327
329
  - [MongoDB Vector Store](https://mastra.ai/reference/vectors/mongodb)
328
330
  - [OpenSearch Vector Store](https://mastra.ai/reference/vectors/opensearch)
331
+ - [OracleDB Vector Store](https://mastra.ai/reference/vectors/oracledb)
329
332
  - [PG Vector Store](https://mastra.ai/reference/vectors/pg)
330
333
  - [Pinecone Vector Store](https://mastra.ai/reference/vectors/pinecone)
331
334
  - [Qdrant Vector Store](https://mastra.ai/reference/vectors/qdrant)
@@ -365,9 +368,9 @@ The Reference section provides documentation of Mastra's API, including paramete
365
368
  - [.speak()](https://mastra.ai/reference/voice/voice.speak)
366
369
  - [.updateConfig()](https://mastra.ai/reference/voice/voice.updateConfig)
367
370
  - [Overview](https://mastra.ai/reference/workers/overview)
371
+ - [Dynamic Workflow Definition](https://mastra.ai/reference/workflows/dynamic-workflow-definition)
368
372
  - [Run Class](https://mastra.ai/reference/workflows/run)
369
373
  - [Step Class](https://mastra.ai/reference/workflows/step)
370
- - [Stored Workflow Definition](https://mastra.ai/reference/workflows/stored-workflow-definition)
371
374
  - [Workflow Class](https://mastra.ai/reference/workflows/workflow)
372
375
  - [Workflow State Reader](https://mastra.ai/reference/workflows/workflow-state-reader)
373
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
@@ -0,0 +1,239 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # OracleDB storage
4
+
5
+ The OracleDB storage provider stores Mastra application state in Oracle Database. It implements Mastra's composite storage interface, so one `OracleStore` instance can back memory, workflow snapshots, observability, scores, scorer definitions, MCP client metadata, and agent registry data.
6
+
7
+ ## Installation
8
+
9
+ **npm**:
10
+
11
+ ```bash
12
+ npm install @mastra/oracledb@latest
13
+ ```
14
+
15
+ **pnpm**:
16
+
17
+ ```bash
18
+ pnpm add @mastra/oracledb@latest
19
+ ```
20
+
21
+ **Yarn**:
22
+
23
+ ```bash
24
+ yarn add @mastra/oracledb@latest
25
+ ```
26
+
27
+ **Bun**:
28
+
29
+ ```bash
30
+ bun add @mastra/oracledb@latest
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```ts
36
+ import { OracleStore } from '@mastra/oracledb'
37
+
38
+ const storage = new OracleStore({
39
+ id: 'oracle-storage',
40
+ user: process.env.ORACLE_DATABASE_USER,
41
+ password: process.env.ORACLE_DATABASE_PASSWORD,
42
+ connectString: process.env.ORACLE_DATABASE_CONNECT_STRING,
43
+ })
44
+ ```
45
+
46
+ Use it with Mastra:
47
+
48
+ ```ts
49
+ import { Mastra } from '@mastra/core/mastra'
50
+
51
+ export const mastra = new Mastra({
52
+ storage,
53
+ })
54
+ ```
55
+
56
+ ## Parameters
57
+
58
+ **id** (`string`): Unique identifier for this storage instance.
59
+
60
+ **user** (`string`): Oracle Database user. Required unless using pool or externalAuth.
61
+
62
+ **password** (`string`): Password for the Oracle Database user. Required unless using pool or externalAuth.
63
+
64
+ **connectString** (`string`): Oracle connect string, service name, TNS alias, or Autonomous Database connect descriptor. Required unless using pool.
65
+
66
+ **pool** (`oracledb.Pool`): Existing Oracle connection pool. When provided, Mastra uses the pool but doesn't close it when store.close() is called.
67
+
68
+ **poolManager** (`OraclePoolManager`): Shared Oracle pool manager. Use this to share one Oracle pool between OracleStore and OracleVector.
69
+
70
+ **schemaName** (`string`): Oracle schema name used to qualify storage tables.
71
+
72
+ **poolMin** (`number`): Minimum number of Oracle pool connections. (Default: `0`)
73
+
74
+ **poolMax** (`number`): Maximum number of Oracle pool connections. (Default: `4`)
75
+
76
+ **poolIncrement** (`number`): Number of connections to add when the pool grows. (Default: `1`)
77
+
78
+ **configDir** (`string`): Directory containing Oracle Network configuration files such as tnsnames.ora.
79
+
80
+ **walletLocation** (`string`): Oracle wallet directory for mTLS connections such as Autonomous Database.
81
+
82
+ **walletPassword** (`string`): Password for the Oracle wallet, when required by the wallet configuration.
83
+
84
+ **externalAuth** (`boolean`): Use Oracle external authentication instead of username/password authentication.
85
+
86
+ **disableInit** (`boolean`): When true, automatic schema initialization is disabled. Use this when schema changes are applied separately before the app starts. (Default: `false`)
87
+
88
+ **messageBatchSize** (`number`): Number of messages sent per Oracle executeMany call when saving messages. The operation still commits once at the transaction boundary. (Default: `200`)
89
+
90
+ **skipDefaultIndexes** (`boolean`): When true, default storage indexes aren't created during initialization.
91
+
92
+ **indexes** (`OracleCreateIndexOptions[]`): Custom Oracle index definitions to create during initialization. Indexes are routed to the storage domain that owns the target table.
93
+
94
+ **migrationTableName** (`string`): Oracle table used to track storage schema migrations. (Default: `'MASTRA_ORACLE_MIGRATIONS'`)
95
+
96
+ **vectorRegistryTableName** (`string`): OracleVector registry table used to discover semantic-recall vector tables when threads or messages are deleted. Set this to match OracleVector's registryTableName when that option is customized.
97
+
98
+ ## Connection examples
99
+
100
+ The basic username/password constructor is shown above. For Autonomous Database, add wallet options to the same constructor:
101
+
102
+ ```ts
103
+ const storage = new OracleStore({
104
+ id: 'oracle-storage',
105
+ user: process.env.ORACLE_DATABASE_USER,
106
+ password: process.env.ORACLE_DATABASE_PASSWORD,
107
+ connectString: process.env.ORACLE_DATABASE_CONNECT_STRING,
108
+ walletLocation: process.env.ORACLE_DATABASE_WALLET_DIR,
109
+ walletPassword: process.env.ORACLE_DATABASE_WALLET_PASSWORD,
110
+ configDir: process.env.ORACLE_DATABASE_CONFIG_DIR,
111
+ })
112
+ ```
113
+
114
+ For external authentication, set `externalAuth: true` and omit `password`. To reuse an existing `oracledb.Pool`, pass it as `pool`. Mastra uses it but doesn't close it.
115
+
116
+ `OracleStore` backs memory, workflow snapshots, observability, scores, scorer definitions, MCP client metadata, and agent registry data. When using the store outside a `Mastra` instance, call `await storage.init()` and access a domain with `await storage.getStore('memory')`.
117
+
118
+ ## Initialization
119
+
120
+ When you pass `OracleStore` to `Mastra`, `init()` is called automatically before storage operations run. If you use `OracleStore` directly, call `init()` before reading or writing:
121
+
122
+ ```ts
123
+ await storage.init()
124
+ ```
125
+
126
+ > **Warning:** If initialization is disabled or skipped, storage operations require the Oracle tables and indexes to already exist.
127
+
128
+ `OracleStore.init()` runs repeatable migrations and records the result in the migration ledger table. The default ledger table is `MASTRA_ORACLE_MIGRATIONS`.
129
+
130
+ ```ts
131
+ await storage.migrate()
132
+ const history = await storage.listMigrations()
133
+ ```
134
+
135
+ Repeatable migrations are idempotent. They reconcile the tables and indexes owned by each storage domain on startup, which lets new domain indexes or compatible schema additions apply without changing application code.
136
+
137
+ Initialization also creates the provider's default indexes for common Mastra query paths. Use `skipDefaultIndexes` when indexes are managed separately, or pass `indexes` for custom Oracle indexes. Custom definitions support Oracle options such as `bitmap`, `online`, `invisible`, `parallel`, `compress`, `noLogging`, and `reverse`, as well as function-based expressions like `JSON_VALUE(...)`.
138
+
139
+ Custom indexes are useful when your app repeatedly filters on JSON metadata or when database administrators (DBAs) want to test an index before the optimizer uses it:
140
+
141
+ ```ts
142
+ const storage = new OracleStore({
143
+ id: 'oracle-storage',
144
+ user,
145
+ password,
146
+ connectString,
147
+ indexes: [
148
+ {
149
+ name: 'idx_messages_status',
150
+ table: 'mastra_messages',
151
+ columns: [
152
+ "JSON_VALUE(metadata, '$.status' RETURNING VARCHAR2(32) NULL ON ERROR)",
153
+ 'thread_id',
154
+ ],
155
+ online: true,
156
+ invisible: true,
157
+ },
158
+ ],
159
+ })
160
+ ```
161
+
162
+ Use `invisible` for staged rollout, then remove it after validating query plans. Use `skipDefaultIndexes: true` only when a DBA-managed indexing strategy replaces the defaults.
163
+
164
+ Use `disableInit: true` when schema changes are applied by a separate deployment step or by a database administrator.
165
+
166
+ ## Schema export
167
+
168
+ Use `exportSchemas()` to generate Oracle DDL without connecting to a database. This is useful when schema changes are reviewed or applied outside application startup.
169
+
170
+ ```ts
171
+ import { exportSchemas } from '@mastra/oracledb'
172
+
173
+ const ddl = exportSchemas({
174
+ schemaName: 'MASTRA_APP',
175
+ domains: [
176
+ 'memory',
177
+ 'workflows',
178
+ 'observability',
179
+ 'scores',
180
+ 'scorerDefinitions',
181
+ 'mcpClients',
182
+ 'agents',
183
+ ],
184
+ })
185
+
186
+ console.log(ddl)
187
+ ```
188
+
189
+ `domains` defaults to every supported domain, including `vector`, when omitted.
190
+
191
+ ## Operational notes
192
+
193
+ Use the same `OraclePoolManager` when `OracleStore` and `OracleVector` should share one Oracle connection lifecycle:
194
+
195
+ ```ts
196
+ import { OracleStore, OracleVector } from '@mastra/oracledb'
197
+
198
+ const storage = new OracleStore({ id: 'oracle-storage', user, password, connectString })
199
+ const vector = new OracleVector({
200
+ id: 'oracle-vector',
201
+ poolManager: storage.getPoolManager(),
202
+ })
203
+ ```
204
+
205
+ `OracleStore` exposes `storage.db` and `await storage.getPool()` for advanced use cases. When using these APIs directly, you're responsible for transaction boundaries and connection lifecycle.
206
+
207
+ JSON metadata, payloads, and snapshots are stored in native Oracle JSON columns and encoded server-side, so the rows are readable directly with standard Oracle JDBC tools such as DBeaver and SQL Developer.
208
+
209
+ ## Usage example
210
+
211
+ ### Adding OracleDB memory to an agent
212
+
213
+ ```ts
214
+ import { Agent } from '@mastra/core/agent'
215
+ import { Memory } from '@mastra/memory'
216
+ import { OracleStore } from '@mastra/oracledb'
217
+
218
+ const storage = new OracleStore({
219
+ id: 'oracle-storage',
220
+ user: process.env.ORACLE_DATABASE_USER,
221
+ password: process.env.ORACLE_DATABASE_PASSWORD,
222
+ connectString: process.env.ORACLE_DATABASE_CONNECT_STRING,
223
+ })
224
+
225
+ export const oracleAgent = new Agent({
226
+ id: 'oracle-agent',
227
+ name: 'Oracle Agent',
228
+ instructions: 'You are an assistant with persistent OracleDB-backed memory.',
229
+ model: 'openai/gpt-5.6-sol',
230
+ memory: new Memory({ storage }),
231
+ })
232
+ ```
233
+
234
+ ## Related
235
+
236
+ - [OracleDB vector store](https://mastra.ai/reference/vectors/oracledb)
237
+ - [Storage overview](https://mastra.ai/reference/storage/overview)
238
+ - [Working memory](https://mastra.ai/docs/memory/working-memory)
239
+ - [Workflow snapshots](https://mastra.ai/docs/workflows/snapshots)
@@ -10,15 +10,15 @@ Mastra storage is organized into domains. Each domain owns a set of tables or co
10
10
 
11
11
  Not every storage adapter implements every domain. Composite storage lets you mix adapters per domain when the adapter packages export the corresponding domain classes.
12
12
 
13
- | Domain | Description |
14
- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
15
- | `memory` | Conversation persistence: messages, threads, and resources (including working memory). |
16
- | `workflows` | Workflow run snapshots used for suspend and resume. |
17
- | `workflowDefinitions` | Persisted [stored workflow](https://mastra.ai/docs/workflows/stored-workflows) definitions (beta). Loaded and live-registered on boot. |
18
- | `scores` | Evaluation score records from eval runs. |
19
- | `observability` | Traces and spans used by observability exporters and Studio. |
20
- | `datasets` | Dataset records, versioned items, and dataset versions used by experiments. |
21
- | `experiments` | Experiment runs and per-item experiment results. |
13
+ | Domain | Description |
14
+ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
15
+ | `memory` | Conversation persistence: messages, threads, and resources (including working memory). |
16
+ | `workflows` | Workflow run snapshots used for suspend and resume. |
17
+ | `workflowDefinitions` | Persisted [dynamic workflow](https://mastra.ai/docs/workflows/dynamic-workflows) definitions (beta). Loaded and live-registered on boot. |
18
+ | `scores` | Evaluation score records from eval runs. |
19
+ | `observability` | Traces and spans used by observability exporters and Studio. |
20
+ | `datasets` | Dataset records, versioned items, and dataset versions used by experiments. |
21
+ | `experiments` | Experiment runs and per-item experiment results. |
22
22
 
23
23
  The schema definitions below cover the built-in database-backed tables documented for `memory`, `workflows`, `scores`, and `observability`. Other domains, and non-database adapters, use implementation-specific storage structures.
24
24