@mastra/mcp-docs-server 1.2.14 → 1.2.15-alpha.3
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.
- package/.docs/docs/agents/a2a.md +36 -2
- package/.docs/docs/agents/processors.md +2 -0
- package/.docs/docs/capabilities/subagents.md +23 -5
- package/.docs/docs/connections/overview.md +94 -0
- package/.docs/docs/datasets/running-experiments.md +18 -0
- package/.docs/docs/harness/agent-controller.md +6 -0
- package/.docs/docs/harness/overview.md +26 -0
- package/.docs/docs/mcp/overview.md +10 -0
- package/.docs/guides/build-your-ui/ai-sdk-ui.md +25 -14
- package/.docs/models/gateways/neon.md +17 -14
- package/.docs/models/gateways/openrouter.md +3 -1
- package/.docs/models/gateways/vercel.md +3 -2
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/anthropic.md +2 -2
- package/.docs/models/providers/deepinfra.md +4 -1
- package/.docs/models/providers/digitalocean.md +1 -1
- package/.docs/models/providers/friendli.md +8 -9
- package/.docs/models/providers/huggingface.md +4 -1
- package/.docs/models/providers/hyper.md +7 -7
- package/.docs/models/providers/kilo.md +7 -5
- package/.docs/models/providers/llmgateway.md +1 -1
- package/.docs/models/providers/meta.md +7 -5
- package/.docs/models/providers/minimax.md +25 -23
- package/.docs/models/providers/nano-gpt.md +5 -3
- package/.docs/models/providers/openai.md +28 -26
- package/.docs/models/providers/opencode.md +0 -1
- package/.docs/models/providers/perplexity-agent.md +24 -24
- package/.docs/models/providers/pioneer.md +27 -1
- package/.docs/models/providers/upstage.md +3 -2
- package/.docs/reference/agents/generate.md +1 -1
- package/.docs/reference/ai-sdk/chat-route.md +2 -0
- package/.docs/reference/client-js/observability.md +22 -0
- package/.docs/reference/file-based-agents/schedules.md +232 -0
- package/.docs/reference/index.md +1 -0
- package/.docs/reference/streaming/agents/stream.md +1 -1
- package/.docs/reference/tools/mcp-client.md +54 -0
- package/.docs/reference/workspace/workspace-class.md +2 -0
- package/CHANGELOG.md +15 -0
- 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
|
+
```
|
package/.docs/reference/index.md
CHANGED
|
@@ -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)
|
|
@@ -66,7 +66,7 @@ const stream = await agent.stream('message for agent')
|
|
|
66
66
|
|
|
67
67
|
**options.delegation** (`DelegationConfig`): Configuration for subagent delegation. Use this to control and monitor when the agent delegates tasks to other agents, including the ability to modify, reject delegations, and provide feedback to guide the supervisor.
|
|
68
68
|
|
|
69
|
-
**options.delegation.onDelegationStart** (`(context: DelegationStartContext) => DelegationStartResult | void | Promise<DelegationStartResult | void>`): Called before delegating to a subagent. Use this to modify the delegation parameters
|
|
69
|
+
**options.delegation.onDelegationStart** (`(context: DelegationStartContext) => DelegationStartResult | void | Promise<DelegationStartResult | void>`): Called before delegating to a subagent. Use this to modify the delegation parameters, reject the delegation entirely, or mutate context.requestContext to add entries to the subagent run's request context.
|
|
70
70
|
|
|
71
71
|
**options.delegation.onDelegationComplete** (`(context: DelegationCompleteContext) => { feedback?: string } | void | Promise<{ feedback?: string } | void>`): Called after a subagent delegation completes. The context includes a bail() method to stop further execution, and you can return { feedback } to guide the supervisor's next action. Feedback is saved to supervisor memory as an assistant message.
|
|
72
72
|
|
|
@@ -37,6 +37,8 @@ Each server in the `servers` map is configured using the `MastraMCPServerDefinit
|
|
|
37
37
|
|
|
38
38
|
**env** (`Record<string, string>`): For Stdio servers: Environment variables to set for the command.
|
|
39
39
|
|
|
40
|
+
**inheritDefaultEnv** (`boolean`): For Stdio servers: Whether the subprocess environment starts from the MCP SDK's default inherited environment. The default is a curated whitelist, not the full process environment: on POSIX it inherits HOME, LOGNAME, PATH, SHELL, TERM, and USER; on Windows it inherits APPDATA, HOMEDRIVE, HOMEPATH, LOCALAPPDATA, PATH, PROCESSOR\_ARCHITECTURE, SYSTEMDRIVE, SYSTEMROOT, TEMP, USERNAME, and USERPROFILE. When set to false, only the variables explicitly listed in env are passed to the subprocess. Note that a subprocess without PATH may fail to spawn commands that are not absolute paths. (Default: `true`)
|
|
41
|
+
|
|
40
42
|
**url** (`URL`): For HTTP servers (Streamable HTTP or SSE): The URL of the server.
|
|
41
43
|
|
|
42
44
|
**requestInit** (`RequestInit`): For HTTP servers: Request configuration for the fetch API.
|
|
@@ -45,6 +47,8 @@ Each server in the `servers` map is configured using the `MastraMCPServerDefinit
|
|
|
45
47
|
|
|
46
48
|
**fetch** (`MastraFetchLike`): For HTTP servers: Custom fetch implementation used for all network requests. Receives an optional third requestContext parameter containing request-scoped data (e.g., authentication cookies, bearer tokens) from the incoming request. When provided, this function will be used for all HTTP requests, allowing you to add dynamic authentication headers, forward request-scoped credentials to the MCP server, customize request behavior per-request, or intercept and modify requests/responses. When fetch is provided, requestInit, eventSourceInit, and authProvider become optional, as you can handle these concerns within your custom fetch function.
|
|
47
49
|
|
|
50
|
+
**allowedHosts** (`string[]`): For HTTP servers: Opt-in allowlist of hosts the client may contact on behalf of this server. Each entry is matched against the URL host (hostname plus port when the URL carries a non-default port), for example "api.example.com" or "localhost:8080". Matching is exact and case-insensitive on the hostname; wildcards are not supported and the URL scheme is not checked. An empty array denies all requests. When unset, no restriction is applied. See the Security section below for enforcement details.
|
|
51
|
+
|
|
48
52
|
**logger** (`LogHandler`): Optional additional handler for logging.
|
|
49
53
|
|
|
50
54
|
**timeout** (`number`): Server-specific timeout in milliseconds.
|
|
@@ -159,6 +163,56 @@ When `forwardInstructions` is omitted (the default), instructions are still cach
|
|
|
159
163
|
|
|
160
164
|
> **Security note:** server instructions are forwarded verbatim (subject only to length truncation) into the agent's system prompt. A malicious or compromised MCP server can use them to inject instructions the agent will treat as trusted system guidance. Only enable `forwardInstructions` for servers you trust, and prefer reviewing instructions with `getServerInstructions()` before forwarding instructions from third-party servers.
|
|
161
165
|
|
|
166
|
+
## Security
|
|
167
|
+
|
|
168
|
+
### Subprocess environment for Stdio servers
|
|
169
|
+
|
|
170
|
+
Stdio subprocesses don't inherit the full parent process environment. By default the subprocess environment starts from the MCP SDK's curated whitelist (POSIX: `HOME`, `LOGNAME`, `PATH`, `SHELL`, `TERM`, `USER`; Windows: `APPDATA`, `HOMEDRIVE`, `HOMEPATH`, `LOCALAPPDATA`, `PATH`, `PROCESSOR_ARCHITECTURE`, `SYSTEMDRIVE`, `SYSTEMROOT`, `TEMP`, `USERNAME`, `USERPROFILE`), merged with any variables you set in `env`. Sensitive variables such as API keys aren't inherited unless you pass them explicitly.
|
|
171
|
+
|
|
172
|
+
For stricter isolation, set `inheritDefaultEnv: false` so only your configured `env` entries reach the subprocess:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const mcp = new MCPClient({
|
|
176
|
+
servers: {
|
|
177
|
+
myTool: {
|
|
178
|
+
command: '/usr/local/bin/my-mcp-server',
|
|
179
|
+
inheritDefaultEnv: false,
|
|
180
|
+
env: { MY_TOOL_API_KEY: process.env.MY_TOOL_API_KEY! },
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Variables you place in `env` are forwarded verbatim, so treat server configurations that come from untrusted sources (for example, user-supplied config files) as untrusted input.
|
|
187
|
+
|
|
188
|
+
### Restricting outbound hosts with `allowedHosts`
|
|
189
|
+
|
|
190
|
+
When HTTP server URLs come from untrusted configuration, an attacker-controlled URL can point the client at internal services (server-side request forgery). Set `allowedHosts` on such servers to restrict which hosts the client will contact:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const mcp = new MCPClient({
|
|
194
|
+
servers: {
|
|
195
|
+
remote: {
|
|
196
|
+
url: new URL(untrustedConfig.serverUrl),
|
|
197
|
+
allowedHosts: ['api.example.com'],
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
})
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Enforcement details:
|
|
204
|
+
|
|
205
|
+
- On the default fetch path, requests to disallowed hosts, including every redirect hop, are blocked **before** they're sent. Redirects are followed manually (up to 5 hops) so each hop is validated, and the `Authorization` header isn't carried across hops to a different origin (any scheme, host, or port change drops it, matching standard fetch behavior).
|
|
206
|
+
- When you supply a custom `fetch` (or a custom `eventSourceInit.fetch`), the initial URL is still checked before the request, but redirect hops are validated **after the fact** using `response.url`: the outbound hop may occur, and the response is discarded when its final URL points at a disallowed host. A hand-built `Response` with an empty `response.url` skips this post-hoc check.
|
|
207
|
+
- OAuth requests made through `authProvider` (authorization server metadata discovery, token exchange, refresh) are also validated. If your authorization server runs on a different host than the MCP server, add that host to `allowedHosts` too.
|
|
208
|
+
- A blocked host fails the connection with a clear error and is never retried by the reconnect logic.
|
|
209
|
+
|
|
210
|
+
`allowedHosts` is intentionally minimal: it matches exact hosts and doesn't support wildcards or scheme checks. If you need richer policy (scheme checks, IP-range rules), supply a custom `fetch` implementation, which is invoked for every request the client makes.
|
|
211
|
+
|
|
212
|
+
### Treat tool responses as untrusted input
|
|
213
|
+
|
|
214
|
+
Tool results returned by MCP servers flow into your agent's context as model input. A malicious or compromised server can use tool output for prompt injection. The transport client doesn't sanitize tool responses: sanitization policy belongs at the agent layer, where Mastra's [input and output processors](https://mastra.ai/docs/agents/processors) let you inspect, transform, or block content before and after it reaches the model. Combine this with `requireToolApproval` and the `forwardInstructions` security note above when working with third-party servers.
|
|
215
|
+
|
|
162
216
|
## Methods
|
|
163
217
|
|
|
164
218
|
### `listTools()`
|
|
@@ -67,6 +67,8 @@ const workspace = new Workspace({
|
|
|
67
67
|
|
|
68
68
|
**tools.maxOutputTokens** (`number`): Maximum tokens for tool output. Output exceeding this limit is truncated using tiktoken.
|
|
69
69
|
|
|
70
|
+
**tools.writeLockTimeoutMs** (`number`): Maximum time in milliseconds a write tool waits to acquire the per-file write lock before failing. Raise this for slow or cold-starting filesystems (e.g. remote sandboxes).
|
|
71
|
+
|
|
70
72
|
**tools.hooks** (`WorkspaceToolHooks`): Hooks that run before and after every enabled workspace tool call. See Tool hooks below.
|
|
71
73
|
|
|
72
74
|
**operationTimeout** (`number`): Timeout for operations in milliseconds
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @mastra/mcp-docs-server
|
|
2
2
|
|
|
3
|
+
## 1.2.15-alpha.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`e7109ee`](https://github.com/mastra-ai/mastra/commit/e7109ee6f731bacc79c885906f3c7dca8d8f013a), [`772c0c8`](https://github.com/mastra-ai/mastra/commit/772c0c897cec383258de2e6178147f8014767c7b), [`578bf2e`](https://github.com/mastra-ai/mastra/commit/578bf2e6a88e9d5b8bf502204e15a95dfbb679ae), [`06b2d87`](https://github.com/mastra-ai/mastra/commit/06b2d87e63bcdd0ed59215c6789692b9b12de376), [`ac01d63`](https://github.com/mastra-ai/mastra/commit/ac01d6355974aec73fdb8781449ed12bac582094), [`a810a05`](https://github.com/mastra-ai/mastra/commit/a810a058f62ad407cfc1701e0be36ae91145d7cf), [`f8da216`](https://github.com/mastra-ai/mastra/commit/f8da21633e7eb0e31c9ce0fc30567870d19416d3), [`e7a5da4`](https://github.com/mastra-ai/mastra/commit/e7a5da4ef8e4dd452d2f232961b4e682a85ffe43), [`c71e307`](https://github.com/mastra-ai/mastra/commit/c71e3077e69eae3f25aa628e3778f153a9d6ab36), [`e7a5da4`](https://github.com/mastra-ai/mastra/commit/e7a5da4ef8e4dd452d2f232961b4e682a85ffe43), [`6104347`](https://github.com/mastra-ai/mastra/commit/61043473ba6bfd0a25156824e853e13165562e6c), [`45bfb88`](https://github.com/mastra-ai/mastra/commit/45bfb88fd52f1dd3be20e2a38905777c96499c90), [`e3b9307`](https://github.com/mastra-ai/mastra/commit/e3b9307098daefbfae2a52ae2ef51bc9fc701190), [`d6834c5`](https://github.com/mastra-ai/mastra/commit/d6834c5a7866b16734d23900163c2414ed70d791), [`c52d346`](https://github.com/mastra-ai/mastra/commit/c52d3462ec831a5d95926ecd3d3373f5928ad2e5), [`0023e79`](https://github.com/mastra-ai/mastra/commit/0023e7919431078280abd11c89d1edeae35fcc69), [`c2ad51e`](https://github.com/mastra-ai/mastra/commit/c2ad51e2467f901eecba8c9f4a45e22a50bd7c18), [`3dc97ea`](https://github.com/mastra-ai/mastra/commit/3dc97ea415fad353b48a13095fad1835933cc12a), [`3d01cd3`](https://github.com/mastra-ai/mastra/commit/3d01cd387321b6f9c5cac31d487c84bf51b19c78), [`7bf3086`](https://github.com/mastra-ai/mastra/commit/7bf308663f0115ca74ad20554ade740f06640859), [`a8dd139`](https://github.com/mastra-ai/mastra/commit/a8dd1391a9fe9a6632c25809ef236980afa9a020), [`e5786be`](https://github.com/mastra-ai/mastra/commit/e5786be02bb903073082bd9d6da880ebaacc343f), [`2093fbd`](https://github.com/mastra-ai/mastra/commit/2093fbd53bb744bae19ec89f6d73db9a66fbe8a7), [`e7a5da4`](https://github.com/mastra-ai/mastra/commit/e7a5da4ef8e4dd452d2f232961b4e682a85ffe43), [`7b4393d`](https://github.com/mastra-ai/mastra/commit/7b4393d557411fdcf07b0e30e5acaf7cc85154ae)]:
|
|
8
|
+
- @mastra/core@1.58.0-alpha.1
|
|
9
|
+
- @mastra/mcp@1.16.0-alpha.0
|
|
10
|
+
|
|
11
|
+
## 1.2.15-alpha.0
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`45a9147`](https://github.com/mastra-ai/mastra/commit/45a914741f578754d79d8b7de7b4e4f304d8e14a), [`990611b`](https://github.com/mastra-ai/mastra/commit/990611ba76eb876d86c9c594371ae5f02f94b432), [`ed5d606`](https://github.com/mastra-ai/mastra/commit/ed5d606739c5e3fbdfa9f272df7809aa5ab43b1d)]:
|
|
16
|
+
- @mastra/core@1.58.0-alpha.0
|
|
17
|
+
|
|
3
18
|
## 1.2.14
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/mcp-docs-server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15-alpha.3",
|
|
4
4
|
"description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"jsdom": "^26.1.0",
|
|
29
29
|
"local-pkg": "^1.1.2",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@mastra/
|
|
32
|
-
"@mastra/
|
|
31
|
+
"@mastra/mcp": "^1.16.0-alpha.0",
|
|
32
|
+
"@mastra/core": "1.58.0-alpha.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@hono/node-server": "^
|
|
35
|
+
"@hono/node-server": "^2.0.0",
|
|
36
36
|
"@types/jsdom": "^21.1.7",
|
|
37
37
|
"@types/node": "22.20.1",
|
|
38
38
|
"@vitest/coverage-v8": "4.1.10",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"tsx": "^4.23.1",
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
47
|
"vitest": "4.1.10",
|
|
48
|
+
"@internal/types-builder": "0.0.96",
|
|
48
49
|
"@internal/lint": "0.0.121",
|
|
49
|
-
"@mastra/core": "1.
|
|
50
|
-
"@internal/types-builder": "0.0.96"
|
|
50
|
+
"@mastra/core": "1.58.0-alpha.1"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://mastra.ai",
|
|
53
53
|
"repository": {
|