@mastra/mcp-docs-server 1.2.15-alpha.11 → 1.2.15-alpha.15

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.
@@ -90,6 +90,20 @@ for await (const chunk of stream.fullStream) {
90
90
  }
91
91
  ```
92
92
 
93
+ #### Explaining a decline
94
+
95
+ `declineToolCall()`, `declineToolCallGenerate()`, and `declineNetworkToolCall()` accept an optional `reason`. The reason is returned to the model in place of the tool result, so the model can adjust instead of retrying blindly. It's also stored on the tool call's `approval` metadata, so it's still there when the conversation is recalled.
96
+
97
+ ```typescript
98
+ const declined = await agent.declineToolCall({
99
+ runId: stream.runId,
100
+ toolCallId,
101
+ reason: 'Reading other users PII is not allowed, ask the user for their own email instead',
102
+ })
103
+ ```
104
+
105
+ Without a `reason`, the model receives the default message `Tool call was not approved by the user`.
106
+
93
107
  #### Conditional approval with a function
94
108
 
95
109
  Instead of a boolean, `requireToolApproval` accepts a function that decides per tool call. It receives the `toolName`, the `args` the model passed, the `requestContext`, and the `workspace`. Return `true` to require approval for that call, or `false` to allow it. This lets you gate approval at runtime, for example, only for tools whose name matches a pattern:
@@ -113,7 +113,7 @@ The `context` object includes:
113
113
 
114
114
  ### Request context at the delegation boundary
115
115
 
116
- Each delegation receives a request context whose entries are shallowly copied from the parent run, excluding run-scoped identity keys. Setting or deleting entries during the subagent run does not affect the parent's context. Set entries on `context.requestContext` in `onDelegationStart` to pass values to the delegated run:
116
+ Each delegation receives a request context whose entries are shallowly copied from the parent run, excluding run-scoped identity keys. Setting or deleting entries during the subagent run doesn't affect the parent's context. Set entries on `context.requestContext` in `onDelegationStart` to pass values to the delegated run:
117
117
 
118
118
  ```typescript
119
119
  const stream = await parentAgent.stream('Research AI trends', {
@@ -134,6 +134,9 @@ Called after a delegation finishes. Use it to inspect results or provide feedbac
134
134
 
135
135
  - `context.bail()`: Stop the parent agent's loop immediately
136
136
  - Return `{ feedback: '...' }`: Add feedback that gets saved to the parent agent's memory and is visible to subsequent iterations
137
+ - Return `{ resultText: '...' }`: Replace the tool result text the parent model sees for this delegation, within the current run
138
+
139
+ Use `resultText` when the subagent's own result would mislead the parent immediately. For example, a subagent that stops on a tool-calls step returns empty text, which the parent model reads as a successful but empty delegation. Unlike `feedback`, which only reaches the model on the next turn, `resultText` changes what the parent reasons on right away.
137
140
 
138
141
  ```typescript
139
142
  const stream = await parentAgent.stream('Research AI trends', {
@@ -206,6 +206,55 @@ The `experiment.run.finished` event is awaited before Mastra persists the final
206
206
 
207
207
  The exported event types are `ExperimentEvent`, `ExperimentRunStartedEvent`, `ExperimentItemCompletedEvent`, and `ExperimentRunFinishedEvent`. Use the discriminated `type` field to narrow an event before reading event-specific properties.
208
208
 
209
+ ## Lifecycle hooks
210
+
211
+ Use lifecycle hooks to prepare state before a target runs and clean it up afterwards. This is useful when an item can't be evaluated against an empty environment. A run might need a fixture file copied into the agent's workspace, or a sandbox provisioned before the agent can touch it.
212
+
213
+ Hooks run at two levels. `beforeAll` and `afterAll` run once per experiment, and `beforeEach` and `afterEach` run once per item:
214
+
215
+ ```typescript
216
+ const summary = await dataset.startExperiment({
217
+ targetType: 'agent',
218
+ targetId: 'document-agent',
219
+ scorers: ['accuracy'],
220
+ beforeAll: async ({ experimentId }) => {
221
+ await createWorkspace(experimentId)
222
+ },
223
+ beforeEach: async ({ item }) => {
224
+ await copyFixture(item.metadata?.fixture)
225
+ },
226
+ afterEach: async ({ item, result }) => {
227
+ await clearWorkspaceFiles(item.id)
228
+ },
229
+ afterAll: async ({ summary }) => {
230
+ await deleteWorkspace(summary.experimentId)
231
+ },
232
+ })
233
+ ```
234
+
235
+ Every hook can be async. Each one receives the `experimentId`, the `mastra` instance, and the run-level `signal`, so long-running setup can be cancelled along with the experiment. The per-item hooks also receive `item`. The teardown hooks receive the result they follow: `afterEach` receives the item's `result` including scores, and `afterAll` receives the `summary` that's about to be returned.
236
+
237
+ The item passed to hooks exposes `id`, `input`, `groundTruth`, and `metadata`. Fields that control execution, such as tool mocks and scorer selection, aren't exposed, so a hook can't change how the item runs.
238
+
239
+ ### Hook failures
240
+
241
+ Each hook has a different consequence when it throws, based on how much of the run depends on it:
242
+
243
+ | Hook | On failure |
244
+ | ------------ | -------------------------------------------------------------------------------- |
245
+ | `beforeAll` | Fails the experiment. No items run. |
246
+ | `beforeEach` | Fails that item with `EXPERIMENT_ITEM_BEFORE_EACH_FAILED`. Other items continue. |
247
+ | `afterEach` | Logged. The item's recorded outcome doesn't change. |
248
+ | `afterAll` | Logged. The returned summary doesn't change. |
249
+
250
+ When `beforeAll` fails, the experiment is marked failed and the `experiment.run.finished` event is still emitted before the error propagates.
251
+
252
+ When `beforeEach` fails, the target and its scorers are skipped for that item, since the item's preconditions were never met. `afterEach` is also skipped for that item, on the basis that setup which didn't finish owns its own cleanup.
253
+
254
+ Teardown failures are logged rather than propagated. By the time `afterEach` runs, the target has already produced a real result, and discarding it because cleanup was untidy would lose the data the experiment was run to collect.
255
+
256
+ `afterAll` runs on every exit path, including when the experiment fails, when `beforeAll` fails, and when an [event observer](#observe-experiment-events) fails, so teardown isn't skipped when something goes wrong. It runs at most once per experiment.
257
+
209
258
  ## Tool mocks
210
259
 
211
260
  When an experiment runs an agent that calls side-effecting tools, attach static tool mocks to individual dataset items to make the run deterministic. During the experiment, a mocked tool returns its declared output instead of executing. Tools without a mock on the item run live by default.
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ![Vercel logo](https://models.dev/logos/vercel.svg)Vercel
4
4
 
5
- Vercel aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 323 models through Mastra's model router.
5
+ Vercel aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 322 models through Mastra's model router.
6
6
 
7
7
  Learn more in the [Vercel documentation](https://ai-sdk.dev/providers/ai-sdk-providers).
8
8
 
@@ -247,7 +247,6 @@ ANTHROPIC_API_KEY=ant-...
247
247
  | `openai/gpt-5.1-codex` |
248
248
  | `openai/gpt-5.1-codex-max` |
249
249
  | `openai/gpt-5.1-codex-mini` |
250
- | `openai/gpt-5.1-instant` |
251
250
  | `openai/gpt-5.1-thinking` |
252
251
  | `openai/gpt-5.2` |
253
252
  | `openai/gpt-5.2-codex` |
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Model Providers
4
4
 
5
- Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 5458 models from 168 providers through a single API.
5
+ Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 5460 models from 168 providers through a single API.
6
6
 
7
7
  ## Features
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ![Alibaba logo](https://models.dev/logos/alibaba.svg)Alibaba
4
4
 
5
- Access 52 Alibaba models through Mastra's model router. Authentication is handled automatically using the `DASHSCOPE_API_KEY` environment variable.
5
+ Access 54 Alibaba models through Mastra's model router. Authentication is handled automatically using the `DASHSCOPE_API_KEY` environment variable.
6
6
 
7
7
  Learn more in the [Alibaba documentation](https://www.alibabacloud.com/help/en/model-studio/models).
8
8
 
@@ -17,7 +17,7 @@ const agent = new Agent({
17
17
  id: "my-agent",
18
18
  name: "My Agent",
19
19
  instructions: "You are a helpful assistant",
20
- model: "alibaba/qvq-max"
20
+ model: "alibaba/deepseek-v4-flash-0731"
21
21
  });
22
22
 
23
23
  // Generate a response
@@ -36,6 +36,8 @@ for await (const chunk of stream) {
36
36
 
37
37
  | Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
38
38
  | -------------------------------------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
39
+ | `alibaba/deepseek-v4-flash-0731` | 1.0M | | | | | | $0.20 | $0.40 |
40
+ | `alibaba/glm-5.2` | 1.0M | | | | | | $1 | $4 |
39
41
  | `alibaba/qvq-max` | 131K | | | | | | $1 | $5 |
40
42
  | `alibaba/qwen-flash` | 1.0M | | | | | | $0.05 | $0.40 |
41
43
  | `alibaba/qwen-max` | 33K | | | | | | $2 | $6 |
@@ -99,7 +101,7 @@ const agent = new Agent({
99
101
  name: "custom-agent",
100
102
  model: {
101
103
  url: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
102
- id: "alibaba/qvq-max",
104
+ id: "alibaba/deepseek-v4-flash-0731",
103
105
  apiKey: process.env.DASHSCOPE_API_KEY,
104
106
  headers: {
105
107
  "X-Custom-Header": "value"
@@ -118,7 +120,7 @@ const agent = new Agent({
118
120
  const useAdvanced = requestContext.task === "complex";
119
121
  return useAdvanced
120
122
  ? "alibaba/qwq-plus"
121
- : "alibaba/qvq-max";
123
+ : "alibaba/deepseek-v4-flash-0731";
122
124
  }
123
125
  });
124
126
  ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ![Cortecs logo](https://models.dev/logos/cortecs.svg)Cortecs
4
4
 
5
- Access 106 Cortecs models through Mastra's model router. Authentication is handled automatically using the `CORTECS_API_KEY` environment variable.
5
+ Access 105 Cortecs models through Mastra's model router. Authentication is handled automatically using the `CORTECS_API_KEY` environment variable.
6
6
 
7
7
  Learn more in the [Cortecs documentation](https://cortecs.ai).
8
8
 
@@ -51,7 +51,6 @@ for await (const chunk of stream) {
51
51
  | `cortecs/cosmos3-super-reasoner` | 256K | | | | | | $0.10 | $0.30 |
52
52
  | `cortecs/deepseek-r1-0528` | 164K | | | | | | $0.65 | $3 |
53
53
  | `cortecs/deepseek-v3.2` | 164K | | | | | | $0.30 | $0.49 |
54
- | `cortecs/deepseek-v4-flash` | 1.0M | | | | | | $0.15 | $0.30 |
55
54
  | `cortecs/deepseek-v4-flash-0731` | 1.0M | | | | | | $0.25 | $0.30 |
56
55
  | `cortecs/deepseek-v4-pro` | 1.0M | | | | | | $2 | $3 |
57
56
  | `cortecs/devstral-2512` | 262K | | | | | | $0.45 | $2 |
@@ -59,7 +59,7 @@ for await (const chunk of stream) {
59
59
  | `digitalocean/deepseek-4-flash` | 1.0M | | | | | | $0.08 | $0.17 |
60
60
  | `digitalocean/deepseek-r1-distill-llama-70b` | 33K | | | | | | $0.99 | $0.99 |
61
61
  | `digitalocean/deepseek-v3` | 164K | | | | | | — | — |
62
- | `digitalocean/deepseek-v4-flash-0731` | 1.0M | | | | | | $0.13 | $0.25 |
62
+ | `digitalocean/deepseek-v4-flash-0731` | 1.0M | | | | | | $0.08 | $0.25 |
63
63
  | `digitalocean/deepseek-v4-pro` | 1.0M | | | | | | $0.87 | $2 |
64
64
  | `digitalocean/e5-large-v2` | 512 | | | | | | $0.02 | — |
65
65
  | `digitalocean/fal-ai/elevenlabs/tts/multilingual-v2` | — | | | | | | — | — |
@@ -40,7 +40,7 @@ for await (const chunk of stream) {
40
40
  | `kilo/~anthropic/claude-haiku-latest` | 200K | | | | | | $1 | $5 |
41
41
  | `kilo/~anthropic/claude-opus-latest` | 1.0M | | | | | | $5 | $25 |
42
42
  | `kilo/~anthropic/claude-sonnet-latest` | 1.0M | | | | | | $2 | $10 |
43
- | `kilo/~deepseek/deepseek-v4-flash-latest` | 1.0M | | | | | | $0.09 | $0.18 |
43
+ | `kilo/~deepseek/deepseek-v4-flash-latest` | 1.0M | | | | | | $0.08 | $0.25 |
44
44
  | `kilo/~google/gemini-flash-latest` | 1.0M | | | | | | $2 | $8 |
45
45
  | `kilo/~google/gemini-pro-latest` | 1.0M | | | | | | $2 | $12 |
46
46
  | `kilo/~moonshotai/kimi-latest` | 1.0M | | | | | | $3 | $14 |
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ![Nebius Token Factory logo](https://models.dev/logos/nebius.svg)Nebius Token Factory
4
4
 
5
- Access 33 Nebius Token Factory models through Mastra's model router. Authentication is handled automatically using the `NEBIUS_API_KEY` environment variable.
5
+ Access 34 Nebius Token Factory models through Mastra's model router. Authentication is handled automatically using the `NEBIUS_API_KEY` environment variable.
6
6
 
7
7
  Learn more in the [Nebius Token Factory documentation](https://docs.tokenfactory.nebius.com/).
8
8
 
@@ -36,6 +36,7 @@ for await (const chunk of stream) {
36
36
 
37
37
  | Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
38
38
  | ------------------------------------------------ | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
39
+ | `nebius/deepseek-ai/DeepSeek-V4-Flash` | 131K | | | | | | $0.14 | $0.28 |
39
40
  | `nebius/deepseek-ai/DeepSeek-V4-Pro` | 1.0M | | | | | | $2 | $4 |
40
41
  | `nebius/google/gemma-3-27b-it` | 110K | | | | | | $0.10 | $0.30 |
41
42
  | `nebius/meta-llama/Llama-3.3-70B-Instruct` | 128K | | | | | | $0.13 | $0.40 |
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ![Tinfoil logo](https://models.dev/logos/tinfoil.svg)Tinfoil
4
4
 
5
- Access 7 Tinfoil models through Mastra's model router. Authentication is handled automatically using the `TINFOIL_API_KEY` environment variable.
5
+ Access 8 Tinfoil models through Mastra's model router. Authentication is handled automatically using the `TINFOIL_API_KEY` environment variable.
6
6
 
7
7
  Learn more in the [Tinfoil documentation](https://docs.tinfoil.sh).
8
8
 
@@ -41,6 +41,7 @@ for await (const chunk of stream) {
41
41
  | `tinfoil/gpt-oss-120b` | 131K | | | | | | $0.15 | $0.60 |
42
42
  | `tinfoil/gpt-oss-safeguard-120b` | 131K | | | | | | $0.15 | $0.60 |
43
43
  | `tinfoil/kimi-k2-6` | 256K | | | | | | $2 | $5 |
44
+ | `tinfoil/kimi-k3` | 256K | | | | | | $2 | $6 |
44
45
  | `tinfoil/llama3-3-70b` | 128K | | | | | | $2 | $3 |
45
46
  | `tinfoil/nomic-embed-text` | 8K | | | | | | $0.05 | — |
46
47
 
@@ -17,7 +17,7 @@ const agent = new Agent({
17
17
  id: "my-agent",
18
18
  name: "My Agent",
19
19
  instructions: "You are a helpful assistant",
20
- model: "zeldoc/z-code"
20
+ model: "zeldoc/zdev"
21
21
  });
22
22
 
23
23
  // Generate a response
@@ -34,9 +34,9 @@ for await (const chunk of stream) {
34
34
 
35
35
  ## Models
36
36
 
37
- | Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
38
- | --------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
39
- | `zeldoc/z-code` | 1.0M | | | | | | — | — |
37
+ | Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
38
+ | ------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
39
+ | `zeldoc/zdev` | 1.0M | | | | | | — | — |
40
40
 
41
41
  ## Advanced configuration
42
42
 
@@ -48,7 +48,7 @@ const agent = new Agent({
48
48
  name: "custom-agent",
49
49
  model: {
50
50
  url: "https://api.zeldoc.ai/v1",
51
- id: "zeldoc/z-code",
51
+ id: "zeldoc/zdev",
52
52
  apiKey: process.env.ZELDOC_API_KEY,
53
53
  headers: {
54
54
  "X-Custom-Header": "value"
@@ -66,8 +66,8 @@ const agent = new Agent({
66
66
  model: ({ requestContext }) => {
67
67
  const useAdvanced = requestContext.task === "complex";
68
68
  return useAdvanced
69
- ? "zeldoc/z-code"
70
- : "zeldoc/z-code";
69
+ ? "zeldoc/zdev"
70
+ : "zeldoc/zdev";
71
71
  }
72
72
  });
73
73
  ```
@@ -143,12 +143,14 @@ session.abort()
143
143
 
144
144
  Return the workspace resolved for this session. This preserves session-level overrides and workspaces selected from the session scope.
145
145
 
146
+ A workspace is optional. When neither the session nor the `AgentController` configures one, the session still runs without filesystem or sandbox access, and this returns `undefined`. Check the result before using it.
147
+
146
148
  ```typescript
147
149
  const workspace = session.getWorkspace()
148
- const skill = await workspace.skills?.get('code-review')
150
+ const skill = await workspace?.skills?.get('code-review')
149
151
  ```
150
152
 
151
- Returns: `Workspace`
153
+ Returns: `Workspace | undefined`
152
154
 
153
155
  ### Session grants
154
156
 
@@ -421,12 +421,13 @@ Returns `{ accepted: true, runId: string, toolCallId?: string }`.
421
421
 
422
422
  ### `declineToolCall()`
423
423
 
424
- Decline a pending tool call and return a continuation stream. Use this when you are rendering the resumed chunks from the decline response.
424
+ Decline a pending tool call and return a continuation stream. Use this when you are rendering the resumed chunks from the decline response. Pass an optional `reason` to tell the model why the call was rejected. The default is `Tool call was not approved by the user`.
425
425
 
426
426
  ```typescript
427
427
  const response = await agent.declineToolCall({
428
428
  runId: 'run-123',
429
429
  toolCallId: 'tool-call-456',
430
+ reason: 'This file is outside the allowed directory', // optional
430
431
  })
431
432
 
432
433
  response.processDataStream({
@@ -567,6 +567,25 @@ export const mastra = new Mastra({
567
567
  })
568
568
  ```
569
569
 
570
+ ### bundler.minify
571
+
572
+ **Type:** `boolean`\
573
+ **Default:** `false`
574
+
575
+ Minifies the bundled output, stripping comments and whitespace and shortening local identifiers. Exported names are preserved.
576
+
577
+ Off by default so build output stays readable and stack traces stay usable. Enable it when bundle size matters, such as packaging a container image for an on-prem deployment. `mastra dev` is never minified.
578
+
579
+ ```typescript
580
+ import { Mastra } from '@mastra/core'
581
+
582
+ export const mastra = new Mastra({
583
+ bundler: {
584
+ minify: true,
585
+ },
586
+ })
587
+ ```
588
+
570
589
  ### bundler.transpilePackages
571
590
 
572
591
  **Type:** `string[]`\
@@ -79,6 +79,14 @@ console.log(`Status: ${summary2.status}`)
79
79
 
80
80
  **unmockedToolPolicy** (`'allow' | 'deny'`): Controls undeclared agent tool calls. allow executes them live. deny fails the item with TOOL\_MOCK\_NOT\_DECLARED before execution. An item-level value overrides this experiment default. (Default: `'allow'`)
81
81
 
82
+ **beforeAll** (`(args: ExperimentHookArgs) => void | Promise<void>`): Runs once before any item executes. Receives experimentId, mastra, and signal. A failure fails the experiment and no items run.
83
+
84
+ **beforeEach** (`(args: ExperimentItemHookArgs) => void | Promise<void>`): Runs before each item executes. Also receives the item (id, input, groundTruth, metadata). A failure fails that item with EXPERIMENT\_ITEM\_BEFORE\_EACH\_FAILED and skips its target, scorers, and afterEach.
85
+
86
+ **afterEach** (`(args: ExperimentItemResultHookArgs) => void | Promise<void>`): Runs after each item completes. Also receives the item's result with its scores. Skipped when beforeEach failed. A failure is logged and doesn't change the item's outcome.
87
+
88
+ **afterAll** (`(args: ExperimentRunResultHookArgs) => void | Promise<void>`): Runs once after the experiment finishes, on every exit path including failure. Also receives the summary. A failure is logged and doesn't change the summary.
89
+
82
90
  **persistence** (`ExperimentPersistencePolicy`): Controls whether this run writes experiment records and score records. Targets and scorers still execute, and results remain available in the returned summary.
83
91
 
84
92
  **persistence.experiments** (`'default' | 'none'`): Set to none to skip experiment creation, item results, progress, and terminal status writes.
@@ -43,6 +43,24 @@ const filter = new RegexFilterProcessor({
43
43
  })
44
44
  ```
45
45
 
46
+ Raise the streaming carryover window for long custom matches (e.g. a fixed-length secret or a value that only matches once its closing delimiter arrives):
47
+
48
+ ```typescript
49
+ import { RegexFilterProcessor } from '@mastra/core/processors'
50
+
51
+ const filter = new RegexFilterProcessor({
52
+ rules: [
53
+ {
54
+ name: 'armored-key',
55
+ pattern: /-----BEGIN KEY-----[A-Z]+-----END KEY-----/g,
56
+ replacement: '[KEY]',
57
+ },
58
+ ],
59
+ strategy: 'redact',
60
+ streamCarryoverSize: 256,
61
+ })
62
+ ```
63
+
46
64
  Attach to an agent:
47
65
 
48
66
  ```typescript
@@ -80,6 +98,8 @@ const agent = new Agent({
80
98
 
81
99
  **includeRedactedValues** (`boolean`): Include the text that was redacted in each report entry. Off by default, because the values are the data the processor removes. (Default: `false`)
82
100
 
101
+ **streamCarryoverSize** (`number`): Trailing characters the streaming redact path holds back between chunks, so a match split across a chunk boundary is redacted whole. The default covers every built-in preset with a wide margin. Raise it for custom rules whose matches stay invisible to the rule until they complete, such as a fixed-length secret or a value with a closing delimiter, when such a match can be longer than the window. (Default: `128`)
102
+
83
103
  ## Returns
84
104
 
85
105
  **id** (`'regex-filter'`): Processor identifier.
@@ -29,6 +29,8 @@ const toolSearch = new ToolSearchProcessor({
29
29
 
30
30
  **options.tools** (`Record<string, Tool>`): All tools that can be searched and loaded dynamically. These tools are not immediately available to the agent — they must be discovered via search and loaded on demand.
31
31
 
32
+ **options.includeResolvedTools** (`boolean`): Also make the tools the agent resolved for this request (MCP tools requiring the caller's credentials, or anything returned by a dynamic tools function) searchable, and withhold them from the prompt until the agent loads them. The meta-tools are never withheld. Request-resolved tools are indexed per request, so each request searches and loads its own tool instances.
33
+
32
34
  **options.search** (`{ topK?: number; minScore?: number; autoLoad?: boolean }`): Configuration for the search behavior.
33
35
 
34
36
  **options.search.topK** (`number`): Maximum number of tools to return in search results.
@@ -120,7 +122,37 @@ The `phase` value describes where the filter is being applied:
120
122
  - `load`: Blocks `load_tool` from loading disallowed tools.
121
123
  - `active`: Hides already-loaded tools from the current request if they're no longer allowed.
122
124
 
123
- If the hook throws or rejects, `ToolSearchProcessor` treats the tool as disallowed for that request. The hook may run for every matching search candidate, so keep async policy checks cheap or cached. The `search_tools` meta-tool is always available. `load_tool` is available unless `search.autoLoad` is enabled. Tools passed directly through the agent or `processInputStep` remain available unless you filter them outside `ToolSearchProcessor`.
125
+ If the hook throws or rejects, `ToolSearchProcessor` treats the tool as disallowed for that request. The hook may run for every matching search candidate, so keep async policy checks cheap or cached. The `search_tools` meta-tool is always available. `load_tool` is available unless `search.autoLoad` is enabled. Tools passed directly through the agent or `processInputStep` remain available unless you filter them outside `ToolSearchProcessor`, or enable `includeResolvedTools`.
126
+
127
+ ## Searching request-resolved tools
128
+
129
+ The `tools` option is fixed at construction, so you can't list tools that only exist per request (MCP tools that need the caller's credentials, or anything returned by a dynamic `tools` function). By default those tools bypass search and occupy prompt space on every turn.
130
+
131
+ Set `includeResolvedTools: true` to index them for the request and withhold them from the prompt until the agent loads them:
132
+
133
+ ```typescript
134
+ import { Agent } from '@mastra/core/agent'
135
+ import { ToolSearchProcessor } from '@mastra/core/processors'
136
+
137
+ const toolSearch = new ToolSearchProcessor({
138
+ tools: staticTools,
139
+ includeResolvedTools: true,
140
+ })
141
+
142
+ const agent = new Agent({
143
+ id: 'mcp-agent',
144
+ name: 'mcp-agent',
145
+ instructions: 'Search for a tool when you need a capability you do not have.',
146
+ model: 'openai/gpt-5.6-sol',
147
+ // Resolved per request, then searchable alongside staticTools
148
+ tools: async ({ requestContext }) => mcpClient.getTools(requestContext.get('userToken')),
149
+ inputProcessors: [toolSearch],
150
+ })
151
+ ```
152
+
153
+ Each request is indexed on its own, so a tool loaded by one caller never resolves to another caller's instance of the same tool name.
154
+
155
+ This option applies to every tool resolved for the request, including memory, workspace, skill, and browser tools. Only the `search_tools` and `load_tool` meta-tools stay in the prompt, so any tool the agent relies on implicitly must be found through search before it can be called.
124
156
 
125
157
  ## Extended usage example
126
158
 
@@ -127,6 +127,24 @@ export const testWorkflow = createWorkflow({
127
127
 
128
128
  **options.pruneSnapshot** (`(params: { snapshot: WorkflowRunState; workflowStatus: WorkflowRunStatus }) => WorkflowRunState`): Optional hook to transform the workflow snapshot immediately before it is persisted. Must return JSON-serializable data and preserve everything the workflow needs to resume (suspended step suspendPayloads, suspendedPaths, executionPath, etc.). Used internally by agent runs to keep snapshots minimal; user workflows persist full snapshots by default.
129
129
 
130
+ **options.onStart** (`(info: WorkflowStartCallbackInfo) => void | Promise<void>`): Callback awaited before a run starts executing, and before any step runs. Fires only on initial start, not on resume, restart, or time travel. Unlike onFinish and onError, errors thrown here are propagated: they reject the start() or stream() call and the run never executes, so this can be used as a pre-flight gate such as a quota check. The run record created by createRun() stays at status pending.
131
+
132
+ **options.onStart.runId** (`string`): The workflow run ID
133
+
134
+ **options.onStart.workflowId** (`string`): The workflow identifier
135
+
136
+ **options.onStart.resourceId** (`string`): Resource or user identifier for multi-tenant scenarios
137
+
138
+ **options.onStart.getInitData** (`() => any`): Returns the initial workflow input data
139
+
140
+ **options.onStart.state** (`Record<string, any>`): The initial workflow state
141
+
142
+ **options.onStart.requestContext** (`RequestContext`): The request context for the run
143
+
144
+ **options.onStart.mastra** (`Mastra`): The Mastra instance, when the workflow is registered
145
+
146
+ **options.onStart.logger** (`IMastraLogger`): The Mastra logger
147
+
130
148
  **options.onFinish** (`(result: WorkflowFinishCallbackResult) => void | Promise<void>`): Callback invoked when workflow completes with any status (success, failed, suspended, tripwire). Receives the workflow result including status, output, error, and step results. Errors thrown in this callback are caught and logged, not propagated.
131
149
 
132
150
  **options.onFinish.status** (`WorkflowRunStatus`): The workflow status: 'success', 'failed', 'suspended', or 'tripwire'
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @mastra/mcp-docs-server
2
2
 
3
+ ## 1.2.15-alpha.14
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`86b7b77`](https://github.com/mastra-ai/mastra/commit/86b7b777980d30f66e1fd134a37d2af4c22e54cc), [`80a3324`](https://github.com/mastra-ai/mastra/commit/80a33245d3110204de6f56d61211523ffe338692), [`d9d2881`](https://github.com/mastra-ai/mastra/commit/d9d2881ede6dd6c023d144215fc812062aed0890), [`82e3365`](https://github.com/mastra-ai/mastra/commit/82e3365ef7c9bf7bee2e7a7029035ea262d68895), [`1b482c2`](https://github.com/mastra-ai/mastra/commit/1b482c2d89244dd758c41e5f927a2b44041388d2), [`e6a2860`](https://github.com/mastra-ai/mastra/commit/e6a2860649cc51f87d32d78b766ae2126446ba07), [`7bd85ea`](https://github.com/mastra-ai/mastra/commit/7bd85ea7588b71c25ce9f4019c88f8539be5dcbc)]:
8
+ - @mastra/core@1.58.0-alpha.9
9
+
10
+ ## 1.2.15-alpha.12
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [[`1c75e32`](https://github.com/mastra-ai/mastra/commit/1c75e32f7fc0b9fb6f548b4407feaec8a1440212), [`c47165c`](https://github.com/mastra-ai/mastra/commit/c47165c983c87594c6952f1fd2fa51a90205034c), [`e08e789`](https://github.com/mastra-ai/mastra/commit/e08e789c1bf4cd2fe46363f7a4728536ceccc9bd), [`35cc901`](https://github.com/mastra-ai/mastra/commit/35cc90102cf834a84827acaf9eee0b6d6d1e2a3b), [`a8b4cf0`](https://github.com/mastra-ai/mastra/commit/a8b4cf02823cffebc4751a53337dfacf097c1ae1), [`f33264f`](https://github.com/mastra-ai/mastra/commit/f33264f517ae603279afd5c4251e2b40f6dd3618), [`689f2c4`](https://github.com/mastra-ai/mastra/commit/689f2c4b6c0835fe455702b01d21daa8abcd9331), [`eeae63e`](https://github.com/mastra-ai/mastra/commit/eeae63e7fbe8e1f237adc69bca6e2ac13c5ca907), [`4c186a0`](https://github.com/mastra-ai/mastra/commit/4c186a017275f45e6ed4c09de0f89550e2d09e8c), [`b0fa077`](https://github.com/mastra-ai/mastra/commit/b0fa077bcbc9b08551846fe372a0d3d15b71ed72)]:
15
+ - @mastra/core@1.58.0-alpha.8
16
+
3
17
  ## 1.2.15-alpha.11
4
18
 
5
19
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp-docs-server",
3
- "version": "1.2.15-alpha.11",
3
+ "version": "1.2.15-alpha.15",
4
4
  "description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "jsdom": "^26.1.0",
29
29
  "local-pkg": "^1.1.2",
30
30
  "zod": "^4.4.3",
31
- "@mastra/core": "1.58.0-alpha.7",
32
- "@mastra/mcp": "^1.16.0-alpha.1"
31
+ "@mastra/mcp": "^1.16.0-alpha.1",
32
+ "@mastra/core": "1.58.0-alpha.9"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@hono/node-server": "^2.0.0",
@@ -45,9 +45,9 @@
45
45
  "tsx": "^4.23.1",
46
46
  "typescript": "^6.0.3",
47
47
  "vitest": "4.1.10",
48
- "@internal/lint": "0.0.121",
49
48
  "@internal/types-builder": "0.0.96",
50
- "@mastra/core": "1.58.0-alpha.7"
49
+ "@internal/lint": "0.0.121",
50
+ "@mastra/core": "1.58.0-alpha.9"
51
51
  },
52
52
  "homepage": "https://mastra.ai",
53
53
  "repository": {