@mastra/mcp-docs-server 1.1.36 → 1.1.37-alpha.4
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/processors.md +10 -0
- package/.docs/docs/deployment/cloud-providers.md +1 -0
- package/.docs/docs/mastra-platform/observability.md +31 -1
- package/.docs/docs/memory/observational-memory.md +34 -0
- package/.docs/docs/voice/overview.md +76 -0
- package/.docs/guides/deployment/aws-bedrock-agentcore.md +432 -0
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/ambient.md +72 -0
- package/.docs/models/providers/xpersona.md +71 -0
- package/.docs/models/providers.md +2 -0
- package/.docs/reference/cli/mastra.md +114 -3
- package/.docs/reference/index.md +1 -0
- package/.docs/reference/processors/processor-interface.md +148 -71
- package/.docs/reference/voice/xai-realtime.md +267 -0
- package/.docs/reference/workspace/docker-sandbox.md +60 -0
- package/.docs/reference/workspace/workspace-class.md +30 -10
- package/CHANGELOG.md +21 -0
- package/dist/stdio.js +5 -5
- package/dist/stdio.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# xAI Realtime voice
|
|
2
|
+
|
|
3
|
+
The `XAIRealtimeVoice` class provides realtime voice interaction capabilities using the xAI Grok Voice Agent API. It implements Mastra's `MastraVoice` realtime contract and supports bidirectional audio streaming, text turns, server VAD, xAI voices, function tools, and xAI server-side tools.
|
|
4
|
+
|
|
5
|
+
## Usage example
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Agent } from '@mastra/core/agent'
|
|
9
|
+
import { getMicrophoneStream, playAudio } from '@mastra/node-audio'
|
|
10
|
+
import { XAIRealtimeVoice } from '@mastra/voice-xai-realtime'
|
|
11
|
+
|
|
12
|
+
const voice = new XAIRealtimeVoice({
|
|
13
|
+
apiKey: process.env.XAI_API_KEY,
|
|
14
|
+
model: 'grok-voice-think-fast-1.0',
|
|
15
|
+
speaker: 'eve',
|
|
16
|
+
instructions: 'You are a concise voice assistant.',
|
|
17
|
+
turnDetection: { type: 'server_vad' },
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const agent = new Agent({
|
|
21
|
+
id: 'voice-agent',
|
|
22
|
+
name: 'Voice Agent',
|
|
23
|
+
instructions: 'You are a helpful voice assistant.',
|
|
24
|
+
model: 'xai/grok-4.3',
|
|
25
|
+
voice,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
await agent.voice.connect()
|
|
29
|
+
|
|
30
|
+
agent.voice.on('speaker', audioStream => {
|
|
31
|
+
playAudio(audioStream)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
agent.voice.on('writing', ({ text, role }) => {
|
|
35
|
+
console.log(`${role}: ${text}`)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
await agent.voice.speak('How can I help you today?')
|
|
39
|
+
|
|
40
|
+
const microphoneStream = getMicrophoneStream()
|
|
41
|
+
await agent.voice.send(microphoneStream)
|
|
42
|
+
|
|
43
|
+
agent.voice.close()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
### Constructor options
|
|
49
|
+
|
|
50
|
+
**apiKey** (`string`): xAI API key. Falls back to the XAI\_API\_KEY environment variable.
|
|
51
|
+
|
|
52
|
+
**ephemeralToken** (`string`): Short-lived xAI token sent with the WebSocket protocol instead of an authorization header.
|
|
53
|
+
|
|
54
|
+
**model** (`XAIRealtimeModel`): The Grok voice model to use. (Default: `'grok-voice-think-fast-1.0'`)
|
|
55
|
+
|
|
56
|
+
**speaker** (`XAIVoice`): Voice ID to use for speech output. Built-in values are eve, ara, rex, sal, and leo. Custom xAI voice IDs are also supported. (Default: `'eve'`)
|
|
57
|
+
|
|
58
|
+
**instructions** (`string`): System instructions sent in session.update.
|
|
59
|
+
|
|
60
|
+
**turnDetection** (`XAITurnDetection`): Voice activity detection configuration. (Default: `{ type: 'server_vad' }`)
|
|
61
|
+
|
|
62
|
+
**audio** (`XAIAudioConfig`): Input and output audio format configuration. (Default: `24 kHz audio/pcm input and output`)
|
|
63
|
+
|
|
64
|
+
**serverTools** (`XAIServerTool[]`): xAI server-side tools to send in session.update. Supports file\_search, web\_search, x\_search, and mcp. These are merged with session.tools.
|
|
65
|
+
|
|
66
|
+
**session** (`Partial<XAISessionConfig>`): Additional xAI session fields to merge into the initial session.update event.
|
|
67
|
+
|
|
68
|
+
**url** (`string`): Override the xAI realtime WebSocket URL. (Default: `'wss://api.x.ai/v1/realtime'`)
|
|
69
|
+
|
|
70
|
+
**debug** (`boolean`): Enable debug logging for received xAI events. Debug logs can include transcripts and tool-call arguments. (Default: `false`)
|
|
71
|
+
|
|
72
|
+
### VoiceConfig pattern
|
|
73
|
+
|
|
74
|
+
You can also use Mastra's shared voice configuration shape:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const voice = new XAIRealtimeVoice({
|
|
78
|
+
speaker: 'ara',
|
|
79
|
+
realtimeConfig: {
|
|
80
|
+
model: 'grok-voice-think-fast-1.0',
|
|
81
|
+
apiKey: process.env.XAI_API_KEY,
|
|
82
|
+
options: {
|
|
83
|
+
instructions: 'Answer briefly.',
|
|
84
|
+
turnDetection: { type: 'server_vad', threshold: 0.85 },
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Authentication
|
|
91
|
+
|
|
92
|
+
Use `apiKey` or `XAI_API_KEY` for server-side applications. This provider is built for Node.js server-side runtimes. If you already mint xAI ephemeral tokens on your server, you can pass one as `ephemeralToken`; the provider uses the `xai-client-secret.<token>` WebSocket protocol instead of an authorization header. If both `apiKey` and `ephemeralToken` are configured, the provider uses the ephemeral token.
|
|
93
|
+
|
|
94
|
+
## Methods
|
|
95
|
+
|
|
96
|
+
### `connect()`
|
|
97
|
+
|
|
98
|
+
Establishes the WebSocket connection and sends the initial `session.update`.
|
|
99
|
+
|
|
100
|
+
**requestContext** (`RequestContext`): Optional Mastra request context passed to function tool executions.
|
|
101
|
+
|
|
102
|
+
Returns: `Promise<void>`
|
|
103
|
+
|
|
104
|
+
### `close()`
|
|
105
|
+
|
|
106
|
+
Closes the WebSocket connection, ends active speaker streams, and clears queued events, pending function-call state, and request context. `disconnect()` is an alias for `close()`.
|
|
107
|
+
|
|
108
|
+
Returns: `void`
|
|
109
|
+
|
|
110
|
+
### `addInstructions()`
|
|
111
|
+
|
|
112
|
+
Sets session instructions. If the WebSocket is open, the provider sends a `session.update`; passing `undefined` stores an empty string and clears the active instructions on the current session or the next connection.
|
|
113
|
+
|
|
114
|
+
**instructions** (`string`): System instructions to send to xAI.
|
|
115
|
+
|
|
116
|
+
Returns: `void`
|
|
117
|
+
|
|
118
|
+
### `addTools()`
|
|
119
|
+
|
|
120
|
+
Registers Mastra function tools and, when connected, refreshes the session tools with `session.update`.
|
|
121
|
+
|
|
122
|
+
**tools** (`ToolsInput`): Mastra tools to expose as xAI function tools.
|
|
123
|
+
|
|
124
|
+
Returns: `void`
|
|
125
|
+
|
|
126
|
+
### `updateConfig()`
|
|
127
|
+
|
|
128
|
+
Sends a `session.update` event with additional xAI session fields.
|
|
129
|
+
|
|
130
|
+
**sessionConfig** (`Partial<XAISessionConfig>`): Session fields to update.
|
|
131
|
+
|
|
132
|
+
Returns: `void`
|
|
133
|
+
|
|
134
|
+
### `speak()`
|
|
135
|
+
|
|
136
|
+
Sends a text turn using `conversation.item.create` and then requests a response.
|
|
137
|
+
|
|
138
|
+
**input** (`string | NodeJS.ReadableStream`): Text or a readable text stream to send as user input.
|
|
139
|
+
|
|
140
|
+
**options.speaker** (`XAIVoice`): Voice override. This updates the active xAI session voice and is used for subsequent turns.
|
|
141
|
+
|
|
142
|
+
**options.response** (`Record<string, unknown>`): Additional xAI response.create fields.
|
|
143
|
+
|
|
144
|
+
Returns: `Promise<void>`
|
|
145
|
+
|
|
146
|
+
### `send()`
|
|
147
|
+
|
|
148
|
+
Streams realtime audio chunks with `input_audio_buffer.append`.
|
|
149
|
+
|
|
150
|
+
`send()` requires an open connection. Use it for live microphone audio after `connect()` resolves. Readable stream chunks must be binary audio chunks (`Buffer`, `ArrayBuffer`, or a typed array).
|
|
151
|
+
|
|
152
|
+
**audioData** (`NodeJS.ReadableStream | Int16Array`): PCM audio stream or Int16Array audio data.
|
|
153
|
+
|
|
154
|
+
**eventId** (`string`): Optional xAI event ID.
|
|
155
|
+
|
|
156
|
+
Returns: `Promise<void>`
|
|
157
|
+
|
|
158
|
+
### `listen()`
|
|
159
|
+
|
|
160
|
+
Sends a finite audio stream with `input_audio_buffer.append`. By default it commits the input buffer and requests a response.
|
|
161
|
+
|
|
162
|
+
**audioData** (`NodeJS.ReadableStream`): Audio stream to send.
|
|
163
|
+
|
|
164
|
+
**options.commit** (`boolean`): Whether to send input\_audio\_buffer.commit after the audio item. (Default: `true`)
|
|
165
|
+
|
|
166
|
+
**options.createResponse** (`boolean`): Whether to send response.create after the audio item. (Default: `true`)
|
|
167
|
+
|
|
168
|
+
Returns: `Promise<void>`
|
|
169
|
+
|
|
170
|
+
### `answer()`
|
|
171
|
+
|
|
172
|
+
Sends `response.create` to ask xAI to continue the conversation.
|
|
173
|
+
|
|
174
|
+
Returns: `Promise<void>`
|
|
175
|
+
|
|
176
|
+
### `commitAudioBuffer()` and `clearAudioBuffer()`
|
|
177
|
+
|
|
178
|
+
Send the matching xAI realtime client events for manual turn control.
|
|
179
|
+
|
|
180
|
+
Returns: `Promise<void>`
|
|
181
|
+
|
|
182
|
+
### `cancelResponse()`
|
|
183
|
+
|
|
184
|
+
Sends `response.cancel` to interrupt an in-flight response.
|
|
185
|
+
|
|
186
|
+
**responseId** (`string`): Optional xAI response ID to cancel.
|
|
187
|
+
|
|
188
|
+
**eventId** (`string`): Optional xAI event ID.
|
|
189
|
+
|
|
190
|
+
Returns: `Promise<void>`
|
|
191
|
+
|
|
192
|
+
## Events
|
|
193
|
+
|
|
194
|
+
`XAIRealtimeVoice` maps xAI realtime server events onto Mastra voice events:
|
|
195
|
+
|
|
196
|
+
- `speaker`: emits a readable stream for assistant audio.
|
|
197
|
+
- `speaking`: emits assistant audio deltas.
|
|
198
|
+
- `speaking.done`: emits when an assistant audio response completes.
|
|
199
|
+
- `writing`: emits assistant text deltas and user input transcriptions.
|
|
200
|
+
- `error`: emits xAI errors, provider execution errors, tool execution errors, and malformed function-call arguments. Tool errors include `details.call_id` and `details.name`.
|
|
201
|
+
- `close`: emits when the WebSocket closes.
|
|
202
|
+
- `tool-call-start`: emits before a Mastra function tool is executed.
|
|
203
|
+
- `tool-call-result`: emits after a Mastra function tool returns.
|
|
204
|
+
|
|
205
|
+
Raw xAI event names are also emitted, so you can subscribe to events such as `response.output_audio.delta`, `response.text.delta`, `response.function_call_arguments.done`, and `response.done`.
|
|
206
|
+
|
|
207
|
+
## Tools
|
|
208
|
+
|
|
209
|
+
### Mastra function tools
|
|
210
|
+
|
|
211
|
+
Tools added with `addTools()` are converted into xAI function tools and included in `session.update`.
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { createTool } from '@mastra/core/tools'
|
|
215
|
+
import { z } from 'zod'
|
|
216
|
+
|
|
217
|
+
const weatherTool = createTool({
|
|
218
|
+
id: 'getWeather',
|
|
219
|
+
description: 'Get current weather for a location.',
|
|
220
|
+
inputSchema: z.object({
|
|
221
|
+
location: z.string(),
|
|
222
|
+
}),
|
|
223
|
+
execute: async ({ location }) => {
|
|
224
|
+
return { location, temperature: 22 }
|
|
225
|
+
},
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
voice.addTools({ getWeather: weatherTool })
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
When xAI emits `response.function_call_arguments.done`, the provider executes the matching Mastra tool and sends a `function_call_output` item. If xAI emits multiple function calls for one response, the provider waits for every tool result and the response's `response.done` event before sending one continuation `response.create`.
|
|
232
|
+
|
|
233
|
+
### xAI server-side tools
|
|
234
|
+
|
|
235
|
+
xAI server-side tools are passed through in the session configuration and executed by xAI. Tools passed in `session.tools` and `serverTools` are merged:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const voice = new XAIRealtimeVoice({
|
|
239
|
+
apiKey: process.env.XAI_API_KEY,
|
|
240
|
+
serverTools: [
|
|
241
|
+
{ type: 'web_search' },
|
|
242
|
+
{ type: 'x_search', allowed_x_handles: ['xai'] },
|
|
243
|
+
{ type: 'file_search', vector_store_ids: ['collection_123'], max_num_results: 10 },
|
|
244
|
+
{
|
|
245
|
+
type: 'mcp',
|
|
246
|
+
server_url: 'https://mcp.example.com/mcp',
|
|
247
|
+
server_label: 'business-tools',
|
|
248
|
+
allowed_tools: ['lookup_order'],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
})
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Audio formats
|
|
255
|
+
|
|
256
|
+
The default input and output format is 24 kHz PCM16. You can also configure supported PCM sample rates or telephony codecs:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
const voice = new XAIRealtimeVoice({
|
|
260
|
+
audio: {
|
|
261
|
+
input: { format: { type: 'audio/pcm', rate: 16000 } },
|
|
262
|
+
output: { format: { type: 'audio/pcm', rate: 16000 } },
|
|
263
|
+
},
|
|
264
|
+
})
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Supported format types are `audio/pcm`, `audio/pcmu`, and `audio/pcma`. PCM supports the documented sample rates from 8 kHz through 48 kHz. `audio/pcmu` and `audio/pcma` are G.711 telephony codecs and use 8 kHz.
|
|
@@ -70,6 +70,30 @@ const agent = new Agent({
|
|
|
70
70
|
|
|
71
71
|
**privileged** (`boolean`): Run in privileged mode. (Default: `false`)
|
|
72
72
|
|
|
73
|
+
**memory** (`number`): Memory limit in bytes. Docker treats 0 as unlimited. Maps to Docker HostConfig.Memory.
|
|
74
|
+
|
|
75
|
+
**memorySwap** (`number`): Total memory plus swap in bytes. Maps to Docker HostConfig.MemorySwap.
|
|
76
|
+
|
|
77
|
+
**cpuShares** (`number`): CPU shares relative weight. Maps to Docker HostConfig.CpuShares.
|
|
78
|
+
|
|
79
|
+
**cpuQuota** (`number`): CPU quota in microseconds per period. Maps to Docker HostConfig.CpuQuota.
|
|
80
|
+
|
|
81
|
+
**cpuPeriod** (`number`): CPU period in microseconds. Maps to Docker HostConfig.CpuPeriod.
|
|
82
|
+
|
|
83
|
+
**pidsLimit** (`number`): Maximum number of process IDs in the container. Maps to Docker HostConfig.PidsLimit.
|
|
84
|
+
|
|
85
|
+
**readonlyRootfs** (`boolean`): Mount the container root filesystem as read-only. Maps to Docker HostConfig.ReadonlyRootfs.
|
|
86
|
+
|
|
87
|
+
**capDrop** (`string[]`): Linux capabilities to drop. Use \['ALL'] to drop all capabilities before adding specific ones. Maps to Docker HostConfig.CapDrop.
|
|
88
|
+
|
|
89
|
+
**capAdd** (`string[]`): Linux capabilities to add back after drops, such as NET\_BIND\_SERVICE. Maps to Docker HostConfig.CapAdd.
|
|
90
|
+
|
|
91
|
+
**securityOpt** (`string[]`): Docker security options, such as \['no-new-privileges:true']. Maps to Docker HostConfig.SecurityOpt.
|
|
92
|
+
|
|
93
|
+
**ulimits** (`Array<{ name: string; soft: number; hard: number }>`): Ulimit entries for the container. Maps to Docker HostConfig.Ulimits.
|
|
94
|
+
|
|
95
|
+
**tmpfs** (`Record<string, string>`): tmpfs mount paths and options. Maps to Docker HostConfig.Tmpfs.
|
|
96
|
+
|
|
73
97
|
**workingDir** (`string`): Working directory inside the container. (Default: `'/workspace'`)
|
|
74
98
|
|
|
75
99
|
**labels** (`Record<string, string>`): Additional container labels. Mastra labels (mastra.sandbox, mastra.sandbox.id) are always included.
|
|
@@ -146,6 +170,42 @@ const sandbox = new DockerSandbox({
|
|
|
146
170
|
|
|
147
171
|
Bind mounts are applied at container creation time. The host paths must exist before the sandbox starts.
|
|
148
172
|
|
|
173
|
+
## Hardening
|
|
174
|
+
|
|
175
|
+
Use Docker-specific resource and hardening options to limit a sandbox container. The following example caps memory and process count, limits CPU to a single core with matching `cpuPeriod` and `cpuQuota` values, drops Linux capabilities, makes the root filesystem read-only, and mounts `/tmp` as writable scratch space:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const sandbox = new DockerSandbox({
|
|
179
|
+
image: 'node:22-slim',
|
|
180
|
+
memory: 512 * 1024 * 1024,
|
|
181
|
+
memorySwap: 512 * 1024 * 1024,
|
|
182
|
+
cpuPeriod: 100_000,
|
|
183
|
+
cpuQuota: 100_000,
|
|
184
|
+
pidsLimit: 256,
|
|
185
|
+
readonlyRootfs: true,
|
|
186
|
+
capDrop: ['ALL'],
|
|
187
|
+
capAdd: ['NET_BIND_SERVICE'],
|
|
188
|
+
securityOpt: ['no-new-privileges:true'],
|
|
189
|
+
ulimits: [{ name: 'nofile', soft: 1024, hard: 2048 }],
|
|
190
|
+
tmpfs: {
|
|
191
|
+
'/tmp': 'rw,noexec,nosuid,size=64m',
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
These options map directly to Docker `HostConfig` fields and aren't set unless you pass them.
|
|
197
|
+
|
|
198
|
+
Review these trade-offs before enabling hardening:
|
|
199
|
+
|
|
200
|
+
- `readonlyRootfs`: In-container package installs and tools that write outside mounted paths can fail. Add `tmpfs` entries for writable scratch paths such as `/tmp`, and mount tmpfs or volumes for package-manager caches such as `~/.npm` when needed.
|
|
201
|
+
- `capDrop`: Dropping all capabilities disables commands that need Linux capabilities, including `ping`, mount operations, and FUSE-backed tools. Add back only the capabilities your workload needs.
|
|
202
|
+
- `memory`: Docker treats `0` as unlimited. Omit `memory` or pass `0` only when you don't want a memory cap.
|
|
203
|
+
- `memorySwap`: Docker memory and swap behavior depends on the host and Docker daemon configuration. When you set `memory` without `memorySwap`, Docker allows swap up to twice the memory limit by default. Set `memorySwap` equal to `memory` when you want to disable swap for the container; Docker also accepts `-1` for unlimited swap.
|
|
204
|
+
- `pidsLimit`: Very low values can break `docker exec` workloads because each command starts additional processes inside the long-lived container.
|
|
205
|
+
- `privileged`: Privileged containers bypass capability and security-option controls. Don't combine `privileged: true` with capability or security options unless the workload requires it.
|
|
206
|
+
- Reconnection: `DockerSandbox` reuses an existing container when the sandbox ID matches and warns if inspected `HostConfig` hardening values differ. Destroy and recreate the sandbox to apply changed hardening options. Docker can normalize inspected values, and changing `memorySwap` on reconnect can trigger a warning if the original container used Docker's default swap behavior.
|
|
207
|
+
- Docker Desktop: Resource limits apply inside the Docker Desktop virtual machine on macOS and Windows, so the VM's allocated resources can cap what containers receive.
|
|
208
|
+
|
|
149
209
|
## Reconnection
|
|
150
210
|
|
|
151
211
|
`DockerSandbox` can reconnect to existing containers by matching labels. When `start()` is called, it checks for a container with the `mastra.sandbox.id` label matching the sandbox ID. If found:
|
|
@@ -290,19 +290,39 @@ A workspace provides tools to agents based on what's configured.
|
|
|
290
290
|
|
|
291
291
|
Added when a filesystem is configured:
|
|
292
292
|
|
|
293
|
-
| Tool | Description
|
|
294
|
-
| ----------------------------- |
|
|
295
|
-
| `mastra_workspace_read_file` | Read file contents.
|
|
296
|
-
| `mastra_workspace_write_file` | Create or overwrite a file with new content. Creates parent directories automatically.
|
|
297
|
-
| `mastra_workspace_edit_file` | Edit an existing file by finding and replacing text. Useful for targeted changes without rewriting the entire file.
|
|
298
|
-
| `mastra_workspace_list_files` | List directory contents as a tree structure. Supports recursive listing with depth limits, glob patterns, and `.gitignore` filtering (enabled by default).
|
|
299
|
-
| `mastra_workspace_delete` | Delete a file or directory. Supports recursive deletion for directories.
|
|
300
|
-
| `mastra_workspace_file_stat` | Get metadata about a file or directory including size, type, and modification time.
|
|
301
|
-
| `mastra_workspace_mkdir` | Create a directory. Creates parent directories automatically if they don't exist.
|
|
302
|
-
| `mastra_workspace_grep` | Search file contents using regex patterns. Supports glob filtering, context lines, and case-insensitive search.
|
|
293
|
+
| Tool | Description |
|
|
294
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
295
|
+
| `mastra_workspace_read_file` | Read file contents. Text files return as text (with optional line range). Images and PDFs return as native media parts the model can view directly. Other binaries return metadata only unless an explicit `encoding` is passed. |
|
|
296
|
+
| `mastra_workspace_write_file` | Create or overwrite a file with new content. Creates parent directories automatically. |
|
|
297
|
+
| `mastra_workspace_edit_file` | Edit an existing file by finding and replacing text. Useful for targeted changes without rewriting the entire file. |
|
|
298
|
+
| `mastra_workspace_list_files` | List directory contents as a tree structure. Supports recursive listing with depth limits, glob patterns, and `.gitignore` filtering (enabled by default). |
|
|
299
|
+
| `mastra_workspace_delete` | Delete a file or directory. Supports recursive deletion for directories. |
|
|
300
|
+
| `mastra_workspace_file_stat` | Get metadata about a file or directory including size, type, and modification time. |
|
|
301
|
+
| `mastra_workspace_mkdir` | Create a directory. Creates parent directories automatically if they don't exist. |
|
|
302
|
+
| `mastra_workspace_grep` | Search file contents using regex patterns. Supports glob filtering, context lines, and case-insensitive search. |
|
|
303
303
|
|
|
304
304
|
With a static filesystem, write tools (`write_file`, `edit_file`, `delete`, `mkdir`) are excluded when the filesystem is in read-only mode. With a [dynamic filesystem](https://mastra.ai/docs/workspace/filesystem), write tools are always included and read-only is enforced at runtime.
|
|
305
305
|
|
|
306
|
+
The `read_file` tool accepts `mediaTypes` and `maxMediaBytes` options to control which mime types are surfaced to the model as native media parts and how large those files can be:
|
|
307
|
+
|
|
308
|
+
**mediaTypes** (`string[] | ((mimeType: string) => boolean) | false`): Which mime types to surface to the model as media parts (file/image parts) rather than as text. Accepts an array of globs (e.g. \`\['image/\*']\`), a custom predicate function, or \`false\` to disable media detection. Defaults to the cross-provider-safe intersection of image formats plus PDF. Only applies when the caller doesn't pass an explicit \`encoding\`. (Default: `['image/png', 'image/jpeg', 'image/webp', 'application/pdf']`)
|
|
309
|
+
|
|
310
|
+
**maxMediaBytes** (`number`): Maximum file size (in bytes) to inline as a media part. Files larger than this fall back to metadata-only output rather than being fully base64-encoded into context and persisted in storage on rehydration. (Default: `10 * 1024 * 1024 (10 MiB)`)
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const workspace = new Workspace({
|
|
314
|
+
filesystem: new LocalFilesystem({ basePath: './workspace' }),
|
|
315
|
+
tools: {
|
|
316
|
+
[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: {
|
|
317
|
+
// Broaden to any image (including SVG, BMP, HEIC) — may fail on some providers
|
|
318
|
+
mediaTypes: ['image/*'],
|
|
319
|
+
// Raise the inline-media cap to 25 MiB
|
|
320
|
+
maxMediaBytes: 25 * 1024 * 1024,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
})
|
|
324
|
+
```
|
|
325
|
+
|
|
306
326
|
### Sandbox tools
|
|
307
327
|
|
|
308
328
|
Added when a sandbox is configured:
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @mastra/mcp-docs-server
|
|
2
2
|
|
|
3
|
+
## 1.1.37-alpha.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`bdb4cbf`](https://github.com/mastra-ai/mastra/commit/bdb4cbf8ba4b685d7481f28bb9dc3de6c79c9ed2)]:
|
|
8
|
+
- @mastra/core@1.34.0-alpha.2
|
|
9
|
+
|
|
10
|
+
## 1.1.37-alpha.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`fceae1f`](https://github.com/mastra-ai/mastra/commit/fceae1f5f5db4722cb078a663c6eb4bd22944123), [`bf02acb`](https://github.com/mastra-ai/mastra/commit/bf02acbb8a6110f638ac844e89f1ebf04cb7fe74), [`0fd3fbe`](https://github.com/mastra-ai/mastra/commit/0fd3fbe40fb63657aedd72f6e7b38c8e8ee6940d), [`fed0475`](https://github.com/mastra-ai/mastra/commit/fed0475ccfea31e4fc251469ac05640d0742c1f0), [`522f44d`](https://github.com/mastra-ai/mastra/commit/522f44d947214bfc06cff50599bae1ef3494880d)]:
|
|
15
|
+
- @mastra/core@1.34.0-alpha.1
|
|
16
|
+
|
|
17
|
+
## 1.1.37-alpha.0
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [[`20787de`](https://github.com/mastra-ai/mastra/commit/20787de5965234a1af28fe35f49437c537dbfa0d), [`784ad98`](https://github.com/mastra-ai/mastra/commit/784ad989549de91dc5d33ab8ef36caa6f7dcd34e), [`0d53730`](https://github.com/mastra-ai/mastra/commit/0d53730c1ed87ef80c87caa5701c4170ea8028e6)]:
|
|
22
|
+
- @mastra/core@1.34.0-alpha.0
|
|
23
|
+
|
|
3
24
|
## 1.1.36
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/dist/stdio.js
CHANGED
|
@@ -1444,12 +1444,12 @@ var readSourceMapTool = {
|
|
|
1444
1444
|
void logger.debug("Executing readMastraSourceMap tool", { args });
|
|
1445
1445
|
const sourceMap = await readSourceMap(args.package, args.projectPath);
|
|
1446
1446
|
if (!sourceMap) return `No SOURCE_MAP.json found for ${args.package}.`;
|
|
1447
|
-
let exports
|
|
1447
|
+
let exports = Object.entries(sourceMap.exports);
|
|
1448
1448
|
if (args.filter) {
|
|
1449
1449
|
const filterLower = args.filter.toLowerCase();
|
|
1450
|
-
exports
|
|
1450
|
+
exports = exports.filter(([name]) => name.toLowerCase().includes(filterLower));
|
|
1451
1451
|
}
|
|
1452
|
-
if (exports
|
|
1452
|
+
if (exports.length === 0) {
|
|
1453
1453
|
return args.filter ? `No exports matching "${args.filter}" in ${args.package}.
|
|
1454
1454
|
|
|
1455
1455
|
Try running without a filter to see all available exports.` : `No exports found in ${args.package}.`;
|
|
@@ -1457,9 +1457,9 @@ Try running without a filter to see all available exports.` : `No exports found
|
|
|
1457
1457
|
return [
|
|
1458
1458
|
`# ${sourceMap.package} v${sourceMap.version} - API Exports`,
|
|
1459
1459
|
"",
|
|
1460
|
-
`Found ${exports
|
|
1460
|
+
`Found ${exports.length} export(s)${args.filter ? ` matching "${args.filter}"` : ""}:`,
|
|
1461
1461
|
"",
|
|
1462
|
-
...exports
|
|
1462
|
+
...exports.map(([name, info]) => {
|
|
1463
1463
|
const line = info.line ? `:${info.line}` : "";
|
|
1464
1464
|
return `- **${name}**: \`${info.implementation}${line}\``;
|
|
1465
1465
|
}),
|