@mastra/mcp-docs-server 1.2.5-alpha.7 → 1.2.5-alpha.8

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.
@@ -4,7 +4,7 @@
4
4
 
5
5
  Agents use LLMs and tools to solve open-ended tasks. They reason about goals, decide which tools to use, retain conversation memory, and iterate internally until the model emits a final answer or an optional stop condition is met. Agents produce structured responses you can render in your UI or process programmatically. Use agents directly or compose them into workflows or multi-agent systems.
6
6
 
7
- **For AI agents:** If you're tasked to build a Mastra project from scratch, follow the condensed instructions until the next heading. Adjust the example code for the agent & tool to your needs.
7
+ **For AI agents:** If you're tasked to build a Mastra project from scratch, follow the condensed instructions until the next heading. Adjust the example code for the agent & tool to your needs. Important for later: Define `model` as a string in `provider/model` format, for example `openai/gpt-5.5`. For OpenAI, use `openai/<model>`, not `openai:<model>`, and don't import or pass a provider object.
8
8
 
9
9
  Create a `package.json` file with `{ "type": "module" }`. Install the required dependencies: `npm install @mastra/core@latest zod@latest typescript@latest @types/node@latest mastra@latest`
10
10
 
@@ -54,7 +54,7 @@ export const weatherTool = createTool({
54
54
  })
55
55
  ```
56
56
 
57
- If you need to create an agent, create a new file and use `import { Agent } from "@mastra/core/agent"`. Constructor takes `{ id, name, instructions, model: 'openai/gpt-5.5' }`. The model string is Mastra's model router format ('provider/model'; use / and not : to separate provider and model). It's a bundled model gateway. Do not install any ai-sdk package unless Mastra's documentation says otherwise.
57
+ If you need to create an agent, create a new file and use `import { Agent } from "@mastra/core/agent"`. The constructor takes `{ id, name, instructions, model }`. The `model` property is a string in Mastra's model router format: `provider/model`, for example `openai/gpt-5.5`. For OpenAI models, use `openai/<model>`, not `openai:<model>`, and don't pass a provider object. No provider import is needed for this format. Do not install any AI SDK package unless Mastra's documentation says otherwise.
58
58
 
59
59
  Add a tool an agent by importing the tool and passing it to the agent constructor as a tools object.
60
60
 
@@ -77,6 +77,7 @@ export const weatherAgent = new Agent({
77
77
 
78
78
  Use the weatherTool to fetch current weather data.
79
79
  `,
80
+ // Use a string in provider/model format, not provider:model or a provider object.
80
81
  model: 'openai/gpt-5.5',
81
82
  tools: { weatherTool },
82
83
  })
@@ -4,7 +4,7 @@
4
4
 
5
5
  Build AI agents your users actually depend on. Mastra is a TypeScript framework that gives you everything you need to prototype fast and ship with confidence. Create your first agent with a single command and start building.
6
6
 
7
- **For AI agents:** If you're tasked to build a Mastra project from scratch, follow the condensed instructions until the next heading. Adjust the example code for the agent & tool to your needs.
7
+ **For AI agents:** If you're tasked to build a Mastra project from scratch, follow the condensed instructions until the next heading. Adjust the example code for the agent & tool to your needs. Important for later: Define `model` as a string in `provider/model` format, for example `openai/gpt-5.5`. For OpenAI, use `openai/<model>`, not `openai:<model>`, and don't import or pass a provider object.
8
8
 
9
9
  Create a `package.json` file with `{ "type": "module" }`. Install the required dependencies: `npm install @mastra/core@latest zod@latest typescript@latest @types/node@latest mastra@latest`
10
10
 
@@ -54,7 +54,7 @@ export const weatherTool = createTool({
54
54
  })
55
55
  ```
56
56
 
57
- If you need to create an agent, create a new file and use `import { Agent } from "@mastra/core/agent"`. Constructor takes `{ id, name, instructions, model: 'openai/gpt-5.5' }`. The model string is Mastra's model router format ('provider/model'; use / and not : to separate provider and model). It's a bundled model gateway. Do not install any ai-sdk package unless Mastra's documentation says otherwise.
57
+ If you need to create an agent, create a new file and use `import { Agent } from "@mastra/core/agent"`. The constructor takes `{ id, name, instructions, model }`. The `model` property is a string in Mastra's model router format: `provider/model`, for example `openai/gpt-5.5`. For OpenAI models, use `openai/<model>`, not `openai:<model>`, and don't pass a provider object. No provider import is needed for this format. Do not install any AI SDK package unless Mastra's documentation says otherwise.
58
58
 
59
59
  Add a tool an agent by importing the tool and passing it to the agent constructor as a tools object.
60
60
 
@@ -77,6 +77,7 @@ export const weatherAgent = new Agent({
77
77
 
78
78
  Use the weatherTool to fetch current weather data.
79
79
  `,
80
+ // Use a string in provider/model format, not provider:model or a provider object.
80
81
  model: 'openai/gpt-5.5',
81
82
  tools: { weatherTool },
82
83
  })
@@ -6,13 +6,11 @@
6
6
 
7
7
  > **Beta:** This feature is in beta. Breaking changes may occur without a major version bump until the API is stable.
8
8
 
9
- A schedule runs an agent on a cron cadence. On each fire, Mastra sends a prompt to the agent, either as a [signal](https://mastra.ai/docs/long-running-agents/signals) into a thread or as a threadless `agent.generate()` run. Use schedules for recurring agent work such as daily summaries, periodic checks, or scheduled nudges into a conversation.
9
+ A schedule runs an agent on a cron cadence. On each fire, Mastra sends a prompt to the agent, either as a [signal](https://mastra.ai/docs/long-running-agents/signals) into a thread or as a threadless [`agent.generate()`](https://mastra.ai/reference/agents/generate) run. Use schedules for recurring agent work such as daily summaries, periodic checks, or scheduled nudges into a conversation.
10
10
 
11
- Schedules are persisted, so they survive restarts and redeploys. Manage them at runtime through `mastra.schedules`, the canonical create, read, update, and delete (CRUD) surface. The same surface also manages [workflow schedules](https://mastra.ai/docs/workflows/scheduled-workflows) pass `workflowId` instead of `agentId` to schedule a workflow.
11
+ Schedules are persisted, so they survive restarts and redeploys. Manage them at runtime through [`mastra.schedules`](https://mastra.ai/reference/schedules/overview), the canonical create, read, update, and delete (CRUD) surface. The same surface also manages [workflow schedules](https://mastra.ai/docs/workflows/scheduled-workflows) (pass `workflowId` instead of `agentId` to schedule a workflow).
12
12
 
13
- ## Prerequisites
14
-
15
- Schedules require a [storage](https://mastra.ai/docs/memory/storage) adapter that implements the schedules domain, for example `@mastra/libsql`. Without one, `mastra.schedules.create()` throws.
13
+ > **Note:** Schedules require a [storage](https://mastra.ai/docs/memory/storage) adapter that implements the schedules domain. See the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview) for supported adapters and API behavior.
16
14
 
17
15
  ## Quickstart
18
16
 
@@ -48,7 +46,7 @@ Mastra starts the scheduler the first time a schedule is created, then fires the
48
46
 
49
47
  Schedules fire on a cron expression. The `cron` field accepts a standard 5-, 6-, or 7-part cron expression, and it's validated when you create or update the schedule.
50
48
 
51
- Croner nicknames also work, for example `@hourly`, `@daily`, `@weekly`, `@monthly`, and `@midnight`. For day-and-time combinations, write the cron field directly:
49
+ `croner` nicknames also work, for example `@hourly`, `@daily`, `@weekly`, `@monthly`, and `@midnight`. For day-and-time combinations, write the cron field directly:
52
50
 
53
51
  ```typescript
54
52
  // Every weekday at 9am
@@ -85,15 +83,9 @@ await mastra.schedules.create({
85
83
  })
86
84
  ```
87
85
 
88
- Threaded schedules accept extra fields that control how the signal behaves. They mirror the options [`agent.sendSignal`](https://mastra.ai/docs/long-running-agents/signals) accepts and stay JSON-serializable so they persist with the schedule.
89
-
90
- - `signalType`: the [signal type](https://mastra.ai/docs/long-running-agents/signals) to send, for example `notification` or `system-reminder`. Defaults to `notification`.
91
- - `tagName`: the XML tag the signal renders as. Defaults to `schedule`, so a fire surfaces to the agent as `<schedule>…</schedule>`.
92
- - `attributes`: values rendered onto the signal's XML tag.
93
- - `ifActive`: behavior when the thread is already streaming, as `{ behavior, attributes }`. `behavior` is one of `deliver`, `persist`, or `discard`.
94
- - `ifIdle`: behavior when the thread is idle, as `{ behavior, attributes, streamOptions }`. `behavior` is one of `wake`, `persist`, or `discard`. `streamOptions.requestContext` is applied to the woken run.
86
+ Threaded schedules accept extra fields that control how the signal behaves, including the signal type, XML tag, tag attributes, and active-or-idle delivery behavior. They mirror the options [`agent.sendSignal()`](https://mastra.ai/docs/long-running-agents/signals) accepts and stay JSON-serializable so they persist with the schedule.
95
87
 
96
- These fields require a `threadId`. Passing them on a threadless schedule throws.
88
+ These fields require a `threadId`. For the full threaded input shape, see the [agent schedule input reference](https://mastra.ai/reference/schedules/overview).
97
89
 
98
90
  ```typescript
99
91
  await mastra.schedules.create({
@@ -116,39 +108,21 @@ await mastra.schedules.create({
116
108
 
117
109
  ## Managing schedules
118
110
 
119
- Use `mastra.schedules` for all schedule operations. To scope to a single agent, pass `agentId` to `create` or `list`.
111
+ Use `mastra.schedules` for all schedule operations. The service can create, read, update, pause, resume, manually run, and delete schedules.
120
112
 
121
113
  ```typescript
122
- // Create
123
114
  const schedule = await mastra.schedules.create({
124
115
  agentId: 'pinger',
125
116
  cron: '0 * * * *',
126
117
  prompt: 'Status check.',
127
118
  })
128
119
 
129
- // Read
130
- await mastra.schedules.get(schedule.id)
131
- await mastra.schedules.list({ agentId: 'pinger' })
132
-
133
- // Update — changing cron or timezone recomputes the next fire time
134
- await mastra.schedules.update(schedule.id, { cron: '*/30 * * * *' })
135
-
136
- // Pause and resume
137
120
  await mastra.schedules.pause(schedule.id)
138
121
  await mastra.schedules.resume(schedule.id)
139
-
140
- // Fire once now, off-schedule
141
- await mastra.schedules.run(schedule.id)
142
-
143
- // Delete
144
- await mastra.schedules.delete(schedule.id)
122
+ await mastra.schedules.run(schedule.id) // Fire once now, off-schedule
145
123
  ```
146
124
 
147
- A few rules worth knowing:
148
-
149
- - `pause` and `resume` are durable and idempotent. A paused schedule survives restarts, and `resume` recomputes the next fire time from now rather than firing backlogged runs.
150
- - `run` fires the schedule once immediately without affecting its cadence.
151
- - `list` filters by `agentId`, `workflowId`, `threadId`, `resourceId`, `name`, and `status`. Without a filter it returns every schedule, agent and workflow alike.
125
+ `pause` and `resume` are durable. `run` fires the schedule once immediately without affecting its cadence. For the complete method list, filters, and patch fields, see the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview).
152
126
 
153
127
  ### Workflow schedules
154
128
 
@@ -166,7 +140,7 @@ Workflow schedules created this way are independent of the declarative `schedule
166
140
 
167
141
  ### Custom IDs
168
142
 
169
- By default `create` generates a random `agent_<uuid>` id. Pass `id` to choose a stable one, for example when you want a predictable handle to look up, update, or delete later:
143
+ Pass `id` when you need a predictable handle to look up, update, or delete later.
170
144
 
171
145
  ```typescript
172
146
  await mastra.schedules.create({
@@ -175,14 +149,13 @@ await mastra.schedules.create({
175
149
  cron: '0 9 * * *',
176
150
  prompt: 'Summarize anything new since yesterday.',
177
151
  })
178
- // stored as `agent_nightly-summary`
179
152
  ```
180
153
 
181
- The id is normalized to `agent_<slug>`: the `agent_` prefix is added if missing and the rest is slugified. Workflow schedules normalize to `schedule_<slug>` instead. Creating a schedule with an id that already exists throws, so use `update` to change an existing one.
154
+ See the [`create(input)` reference](https://mastra.ai/reference/schedules/overview) for ID normalization rules and duplicate ID behavior.
182
155
 
183
156
  ### From the client
184
157
 
185
- The same operations are available from `@mastra/client-js` over the `/api/schedules` routes (`client.createSchedule`, `client.listSchedules`, `client.runSchedule`, and so on), so you can manage schedules from a separate process or a UI.
158
+ The same operations are available from `@mastra/client-js` over the `/api/schedules` routes, so you can manage schedules from a separate process or a UI. See the [client-js agent schedules reference](https://mastra.ai/reference/client-js/agents) for the client method list.
186
159
 
187
160
  ## Lifecycle hooks
188
161
 
@@ -223,5 +196,6 @@ Hook exceptions are caught and logged. They never re-route the worker or trigger
223
196
 
224
197
  ## Related
225
198
 
199
+ - [`mastra.schedules`](https://mastra.ai/reference/schedules/overview): API reference for creating and managing schedules.
226
200
  - [Signals](https://mastra.ai/docs/long-running-agents/signals): the delivery mechanism behind threaded schedules.
227
201
  - [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows): declare a cron schedule on a workflow definition.
@@ -0,0 +1,305 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # Using LiveKit with Mastra
4
+
5
+ [LiveKit](https://livekit.io) is an open source WebRTC platform for realtime audio and video. The [`@mastra/livekit`](https://mastra.ai/reference/voice/livekit) package connects Mastra agents to the [LiveKit Agents framework](https://docs.livekit.io/agents/): LiveKit owns the audio loop like voice activity detection, streaming speech-to-text, semantic turn detection, barge-in, and text-to-speech. Your Mastra agent generates every reply with its own model, tools, and memory.
6
+
7
+ Use this integration when you need low-latency, interruptible voice conversations. For provider-based speech-to-speech without LiveKit, see [Speech to Speech](https://mastra.ai/docs/voice/speech-to-speech).
8
+
9
+ ## Quickstart
10
+
11
+ These steps take you from an empty project to a voice agent you can talk to. A voice session has two moving parts you set up here: an API route on your Mastra server that hands out access tokens, and a separate worker process that runs the audio pipeline and calls your agent each turn.
12
+
13
+ 1. Install the integration package along with the LiveKit plugins for voice activity detection and turn detection:
14
+
15
+ **npm**:
16
+
17
+ ```bash
18
+ npm install @mastra/livekit @livekit/agents @livekit/agents-plugin-silero @livekit/agents-plugin-livekit
19
+ ```
20
+
21
+ **pnpm**:
22
+
23
+ ```bash
24
+ pnpm add @mastra/livekit @livekit/agents @livekit/agents-plugin-silero @livekit/agents-plugin-livekit
25
+ ```
26
+
27
+ **Yarn**:
28
+
29
+ ```bash
30
+ yarn add @mastra/livekit @livekit/agents @livekit/agents-plugin-silero @livekit/agents-plugin-livekit
31
+ ```
32
+
33
+ **Bun**:
34
+
35
+ ```bash
36
+ bun add @mastra/livekit @livekit/agents @livekit/agents-plugin-silero @livekit/agents-plugin-livekit
37
+ ```
38
+
39
+ 2. Set your LiveKit credentials inside an `.env` file. Create a free project on [LiveKit Cloud](https://cloud.livekit.io), or run a local server with [`livekit-server --dev`](https://docs.livekit.io/home/self-hosting/local/):
40
+
41
+ ```bash
42
+ LIVEKIT_URL=wss://your-project.livekit.cloud
43
+ LIVEKIT_API_KEY=your-api-key
44
+ LIVEKIT_API_SECRET=your-api-secret
45
+ ```
46
+
47
+ 3. Add a voice agent to your Mastra instance and expose a connection route. The `liveKitConnectionRoute()` helper adds a `POST /voice/livekit/connection-details` endpoint that mints a LiveKit token and dispatches your agent into a room:
48
+
49
+ ```typescript
50
+ import { Mastra } from '@mastra/core/mastra'
51
+ import { Agent } from '@mastra/core/agent'
52
+ import { liveKitConnectionRoute } from '@mastra/livekit'
53
+
54
+ const supportAgent = new Agent({
55
+ id: 'support',
56
+ name: 'Support',
57
+ instructions: 'You are a friendly phone support agent. Keep replies short and conversational.',
58
+ model: 'openai/gpt-5-mini',
59
+ })
60
+
61
+ export const mastra = new Mastra({
62
+ agents: { support: supportAgent },
63
+ server: {
64
+ apiRoutes: [liveKitConnectionRoute({ agentName: 'mastra-voice' })],
65
+ },
66
+ })
67
+ ```
68
+
69
+ 4. Create the worker. It runs as a separate process, answers LiveKit sessions, and calls your agent each turn. Worker APIs live on the `@mastra/livekit/worker` entry point, so the Mastra server never loads the LiveKit agents runtime. This example uses LiveKit Inference model strings for speech-to-text and text-to-speech, so no provider plugins are required:
70
+
71
+ ```typescript
72
+ import { fileURLToPath } from 'node:url'
73
+ import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker'
74
+ import { mastra } from './index'
75
+
76
+ export default createLiveKitWorker({
77
+ mastra,
78
+ agent: 'support',
79
+ stt: 'deepgram/nova-3',
80
+ tts: 'cartesia/sonic-3',
81
+ turnDetection: 'multilingual',
82
+ greeting: 'Hi! How can I help you today?',
83
+ })
84
+
85
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
86
+ runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' })
87
+ }
88
+ ```
89
+
90
+ The `agent` option selects which Mastra agent answers each session. Pass a fixed key as shown, or omit it to use the `agentId` from the dispatch metadata, so one worker can serve every agent on your Mastra instance.
91
+
92
+ 5. Download the turn detection and voice activity detection models once. Then run the worker in one terminal and your Mastra server in another:
93
+
94
+ ```bash
95
+ npx livekit-agents download-files
96
+ npx tsx src/mastra/voice-worker.ts dev
97
+ ```
98
+
99
+ **npm**:
100
+
101
+ ```bash
102
+ npm run dev
103
+ ```
104
+
105
+ **pnpm**:
106
+
107
+ ```bash
108
+ pnpm run dev
109
+ ```
110
+
111
+ **Yarn**:
112
+
113
+ ```bash
114
+ yarn dev
115
+ ```
116
+
117
+ **Bun**:
118
+
119
+ ```bash
120
+ bun run dev
121
+ ```
122
+
123
+ The worker registers with your LiveKit server and waits for sessions, while `mastra dev` serves the connection route.
124
+
125
+ 6. Talk to your agent. Open the hosted [LiveKit Agents Playground](https://agents-playground.livekit.io) and connect it to your project to start a call without building a frontend.
126
+
127
+ To wire up your own app instead, call the connection route for a token. `POST /voice/livekit/connection-details` accepts optional `agentId`, `threadId`, and `resourceId` fields in the request body and returns:
128
+
129
+ ```json
130
+ {
131
+ "serverUrl": "wss://your-project.livekit.cloud",
132
+ "roomName": "mastra-voice-a1b2c3d4",
133
+ "participantName": "user-1",
134
+ "participantToken": "eyJhbGci..."
135
+ }
136
+ ```
137
+
138
+ This response matches the contract used by LiveKit's frontend starters, so apps built from [agent-starter-react](https://github.com/livekit-examples/agent-starter-react) or the [LiveKit React components](https://docs.livekit.io/reference/components/react/) work without changes.
139
+
140
+ ## Turn detection and interruptions
141
+
142
+ LiveKit decides when the user finished speaking and when the agent was interrupted. The defaults work well; tune them with `turnHandling`:
143
+
144
+ ```typescript
145
+ export default createLiveKitWorker({
146
+ mastra,
147
+ agent: 'support',
148
+ stt: 'deepgram/nova-3',
149
+ tts: 'cartesia/sonic-3',
150
+ turnDetection: 'multilingual',
151
+ turnHandling: {
152
+ endpointing: { mode: 'dynamic', minDelay: 300, maxDelay: 3000 },
153
+ interruption: { minDuration: 500, resumeFalseInterruption: true },
154
+ },
155
+ })
156
+ ```
157
+
158
+ - `turnDetection: 'multilingual'`: Runs LiveKit's semantic end-of-turn model locally on CPU. It reads the live transcript to avoid cutting users off mid-thought. Use `'vad'` or `'stt'` for silence-based endpointing instead.
159
+ - `endpointing`: Bounds how long the agent waits after the user stops speaking.
160
+ - `interruption`: Controls barge-in. When the user speaks over the agent, LiveKit stops playback and cancels the in-flight Mastra stream, so token generation stops too.
161
+ - `preemptiveGeneration`: Starts the Mastra agent's reply while the user is still finishing, hiding time-to-first-token. The worker disables it by default: each preemptive attempt runs the Mastra agent on an interim transcript, and every run persists the user message, which duplicates messages in the thread. Re-enable it with `preemptiveGeneration: { enabled: true }` if latency matters more than exact thread history.
162
+
163
+ See the [LiveKit turn detection docs](https://docs.livekit.io/agents/logic/turns/) for all options.
164
+
165
+ ## Memory and threads
166
+
167
+ When the resolved Mastra agent has memory configured, each call becomes one memory thread:
168
+
169
+ - `thread` defaults to the `threadId` from dispatch metadata, then to the room name.
170
+ - `resource` defaults to the `resourceId` from dispatch metadata, then to the thread. Send your end user's id here so calls group under the right user. Mastra Studio sends the agent id, matching how its sidebar lists threads.
171
+ - When the thread doesn't exist yet, the worker creates it titled "Voice call" with metadata `{ source: 'livekit' }`, and the spoken greeting is saved as the first assistant message so the thread reads as a full call transcript (disable with `persistGreeting: false`).
172
+
173
+ Each turn sends only the new user input; Mastra Memory supplies history, semantic recall, and working memory. Pin a session to an existing thread by passing `threadId` in the connection request body, which is useful for continuing a text conversation by voice. In Studio, starting a call from an open chat binds the call to that thread, and the transcript fills into the chat after each exchange.
174
+
175
+ One caveat: when a user interrupts the agent, Mastra Memory stores the full generated reply even though the user only heard part of it. LiveKit's own transcript is truncated to what was spoken.
176
+
177
+ ## Speak while tools run
178
+
179
+ Voice conversations can't go silent while a slow tool runs. Use `toolFeedback` to speak a short phrase when the Mastra agent starts a tool call:
180
+
181
+ ```typescript
182
+ export default createLiveKitWorker({
183
+ mastra,
184
+ agent: 'support',
185
+ stt: 'deepgram/nova-3',
186
+ tts: 'cartesia/sonic-3',
187
+ toolFeedback: ({ toolName }) =>
188
+ toolName === 'searchOrders' ? 'Let me look that up.' : undefined,
189
+ })
190
+ ```
191
+
192
+ The phrase is spoken as part of the reply and appears in the transcript.
193
+
194
+ ## Generate replies with a workflow
195
+
196
+ By default the worker generates each reply with a Mastra agent. To run multi-step logic per turn (for example classify intent, route, call tools in sequence, then compose a reply), generate replies with a Mastra [workflow](https://mastra.ai/docs/workflows/overview) instead. Set `workflow` in place of `agent`.
197
+
198
+ LiveKit still owns the audio loop and calls into Mastra once per turn, so the workflow runs to completion each turn. There is no suspend or resume, and no conversation state is carried between turns. Pass the transcript in through `workflowInput` so the workflow stays stateless:
199
+
200
+ ```typescript
201
+ import { createLiveKitWorker, chatContextToMessages } from '@mastra/livekit/worker'
202
+ import { mastra } from './index'
203
+
204
+ export default createLiveKitWorker({
205
+ mastra,
206
+ workflow: 'phoneConversation',
207
+ workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }),
208
+ replyStep: 'generateResponse',
209
+ stt: 'deepgram/nova-3',
210
+ tts: 'cartesia/sonic-3',
211
+ turnDetection: 'multilingual',
212
+ })
213
+ ```
214
+
215
+ A workflow streams structured step events, not text. To speak tokens as they generate, the reply step pipes its agent's text into the step `writer`:
216
+
217
+ ```typescript
218
+ const generateResponse = createStep({
219
+ id: 'generateResponse',
220
+ // input and output schemas omitted
221
+ execute: async ({ inputData, mastra, writer, abortSignal }) => {
222
+ const stream = await mastra.getAgent('voice').stream(inputData.history, { abortSignal })
223
+ await stream.textStream.pipeTo(writer)
224
+ return { assistantMessage: await stream.text }
225
+ },
226
+ })
227
+ ```
228
+
229
+ - `replyStep`: Restricts spoken output to one step. Omit it to speak every step that writes to its `writer`.
230
+ - `resultText`: A fallback that derives the reply from the final run result when no step streams text. Streaming through `writer` gives lower time-to-first-token, so prefer it.
231
+ - `abortSignal`: Forward the step's `abortSignal` into `agent.stream()` so barge-in stops generation promptly. When the user interrupts, the worker cancels the run.
232
+ - `generate`: For full control, pass a `generate` function instead. It can be any reply generator that turns a turn into a text stream.
233
+
234
+ With a workflow, the worker doesn't persist turns automatically the way an agent's `stream()` does. Persist conversation history inside the workflow, or keep the LiveKit transcript as the source of truth and pass it in each turn.
235
+
236
+ ## Server-initiated sessions
237
+
238
+ Use `dispatchVoiceSession()` to add a voice agent to a room from your own code, for example to join an existing room or to drive an outbound [SIP call](https://docs.livekit.io/sip/):
239
+
240
+ ```typescript
241
+ import { dispatchVoiceSession } from '@mastra/livekit'
242
+
243
+ await dispatchVoiceSession({
244
+ roomName: 'support-call-42',
245
+ agentName: 'mastra-voice',
246
+ metadata: { agentId: 'support', threadId: 'thread-42', resourceId: 'user-7' },
247
+ })
248
+ ```
249
+
250
+ ## Observability
251
+
252
+ When the Mastra instance has [observability](https://mastra.ai/docs/observability/overview) configured, the worker traces each call. It opens one `voice call` span per session and nests everything under it:
253
+
254
+ - Every turn's Mastra agent run, with model generation, tool calls, and memory operations, exactly as a text chat records them.
255
+ - A child span for each LiveKit pipeline metric: speech-to-text, text-to-speech, end-of-utterance (turn detection), voice activity detection, and the model's time-to-first-token. These carry the latency and audio measurements that text traces can't show.
256
+ - A per-model usage roll-up (token, character, and audio totals for the whole call) written to the span when the session ends.
257
+
258
+ The worker is a separate process, so point storage at a backend that accepts concurrent writes from both the server and the worker. SQLite-backed [LibSQL](https://mastra.ai/reference/storage/libsql) works; single-writer stores do not. Traces, memory, and threads can share one store:
259
+
260
+ ```typescript
261
+ import { Mastra } from '@mastra/core/mastra'
262
+ import { LibSQLStore } from '@mastra/libsql'
263
+ import { Observability, MastraStorageExporter } from '@mastra/observability'
264
+
265
+ export const mastra = new Mastra({
266
+ storage: new LibSQLStore({ url: 'file:./voice-agent.db' }),
267
+ observability: new Observability({
268
+ configs: {
269
+ default: {
270
+ serviceName: 'voice-agent',
271
+ exporters: [new MastraStorageExporter()],
272
+ },
273
+ },
274
+ }),
275
+ })
276
+ ```
277
+
278
+ Tracing is on by default. Pass `observability: false` to `createLiveKitWorker` to turn it off.
279
+
280
+ ## Deployment
281
+
282
+ The worker is a separate process from your Mastra server. Deploy it as a long-running Node service with the production command:
283
+
284
+ ```bash
285
+ node dist/voice-worker.js start
286
+ ```
287
+
288
+ LiveKit's guidance on sizing, graceful shutdown, and hosting applies unchanged; see [Deploying agents](https://docs.livekit.io/agents/ops/deployment/). Workers connect outbound to LiveKit, so they don't need inbound ports.
289
+
290
+ ## How it works
291
+
292
+ A LiveKit voice session involves three pieces:
293
+
294
+ 1. Your Mastra server mints a LiveKit access token and dispatches your agent into a room. The dispatch carries metadata such as the Mastra agent id, memory thread, and resource.
295
+ 2. A LiveKit agent worker (a separate long-running process) receives the job and runs the audio pipeline. Audio flows between the browser and the worker over WebRTC and never passes through your Mastra HTTP server.
296
+ 3. Each time the user finishes a turn, the worker calls the Mastra agent's `stream()` with the new input and speaks the streamed text. When the user interrupts, LiveKit cancels the stream and Mastra stops generating.
297
+
298
+ Conversation history lives in Mastra Memory, so voice sessions and text chat can share one thread.
299
+
300
+ ## Related
301
+
302
+ - [`@mastra/livekit` reference](https://mastra.ai/reference/voice/livekit)
303
+ - [Speech to Speech](https://mastra.ai/docs/voice/speech-to-speech)
304
+ - [Agent Memory](https://mastra.ai/docs/memory/overview)
305
+ - [LiveKit Agents docs](https://docs.livekit.io/agents/)
@@ -494,6 +494,94 @@ if (output.finishReason === 'suspended') {
494
494
  }
495
495
  ```
496
496
 
497
+ ## Agent schedules
498
+
499
+ Use the client SDK schedule methods to manage persisted agent schedules over the `/api/schedules` routes. For concepts and server-side examples, see [Schedules](https://mastra.ai/docs/long-running-agents/schedules) and the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview).
500
+
501
+ ### `createSchedule()`
502
+
503
+ Create an agent schedule by passing `agentId`.
504
+
505
+ ```typescript
506
+ const schedule = await mastraClient.createSchedule({
507
+ agentId: 'pinger',
508
+ cron: '0 * * * *',
509
+ prompt: 'Give me a status update.',
510
+ })
511
+ ```
512
+
513
+ ### `listSchedules()`
514
+
515
+ List agent schedules. Filter by fields such as `agentId`, `threadId`, `resourceId`, `name`, or `status`.
516
+
517
+ ```typescript
518
+ const schedules = await mastraClient.listSchedules({
519
+ agentId: 'pinger',
520
+ status: 'active',
521
+ })
522
+ ```
523
+
524
+ ### `getSchedule()`
525
+
526
+ Fetch a single agent schedule by ID.
527
+
528
+ ```typescript
529
+ const schedule = await mastraClient.getSchedule('agent_pinger')
530
+ ```
531
+
532
+ ### `updateSchedule()`
533
+
534
+ Update an agent schedule. Agent schedules can update fields such as `cron`, `timezone`, `prompt`, `name`, signal delivery options, metadata, and `status`.
535
+
536
+ ```typescript
537
+ const updated = await mastraClient.updateSchedule('agent_pinger', {
538
+ cron: '*/30 * * * *',
539
+ prompt: 'Give me a status update every 30 minutes.',
540
+ })
541
+ ```
542
+
543
+ ### `deleteSchedule()`
544
+
545
+ Delete an agent schedule.
546
+
547
+ ```typescript
548
+ await mastraClient.deleteSchedule('agent_pinger')
549
+ ```
550
+
551
+ ### `runSchedule()`
552
+
553
+ Fire an agent schedule once immediately without changing its cron cadence.
554
+
555
+ ```typescript
556
+ const run = await mastraClient.runSchedule('agent_pinger')
557
+ ```
558
+
559
+ ### `pauseSchedule()`
560
+
561
+ Pause an agent schedule so the scheduler stops firing it. Returns the updated schedule.
562
+
563
+ ```typescript
564
+ await mastraClient.pauseSchedule('agent_pinger')
565
+ ```
566
+
567
+ ### `resumeSchedule()`
568
+
569
+ Resume a paused agent schedule. The next fire time is recomputed from now, so a long-paused schedule doesn't fire a backlog. Returns the updated schedule.
570
+
571
+ ```typescript
572
+ await mastraClient.resumeSchedule('agent_pinger')
573
+ ```
574
+
575
+ ### `listScheduleTriggers()`
576
+
577
+ List the trigger history for an agent schedule, including the joined run summary for each fire.
578
+
579
+ ```typescript
580
+ const { triggers } = await mastraClient.listScheduleTriggers('agent_pinger', {
581
+ limit: 50,
582
+ })
583
+ ```
584
+
497
585
  ## Client tools
498
586
 
499
587
  Client-side tools allow you to execute custom functions on the client side when the agent requests them.
@@ -214,11 +214,23 @@ A workflow run result yields the following:
214
214
 
215
215
  ## Schedules
216
216
 
217
- Schedules are declared in code via the `schedule` field on `createWorkflow`. The client SDK exposes read and operational methods for managing them at runtime. See [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows).
217
+ Schedules are declared in code via the `schedule` field on `createWorkflow`. The client SDK exposes read and operational methods for managing workflow schedules at runtime. See [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows).
218
+
219
+ ### `createSchedule()`
220
+
221
+ Create a workflow schedule by passing `workflowId`.
222
+
223
+ ```typescript
224
+ const schedule = await mastraClient.createSchedule({
225
+ workflowId: 'daily-report',
226
+ cron: '0 9 * * *',
227
+ inputData: { reportType: 'summary' },
228
+ })
229
+ ```
218
230
 
219
231
  ### `listSchedules()`
220
232
 
221
- List all schedules, optionally filtered by workflow id or status.
233
+ List workflow schedules, optionally filtered by workflow ID or status.
222
234
 
223
235
  ```typescript
224
236
  const schedules = await mastraClient.listSchedules({
@@ -229,15 +241,42 @@ const schedules = await mastraClient.listSchedules({
229
241
 
230
242
  ### `getSchedule()`
231
243
 
232
- Fetch a single schedule by id.
244
+ Fetch a single workflow schedule by ID.
233
245
 
234
246
  ```typescript
235
247
  const schedule = await mastraClient.getSchedule('daily-report')
236
248
  ```
237
249
 
250
+ ### `updateSchedule()`
251
+
252
+ Update a workflow schedule.
253
+
254
+ ```typescript
255
+ const updated = await mastraClient.updateSchedule('daily-report', {
256
+ cron: '0 10 * * *',
257
+ inputData: { reportType: 'summary' },
258
+ })
259
+ ```
260
+
261
+ ### `deleteSchedule()`
262
+
263
+ Delete a workflow schedule.
264
+
265
+ ```typescript
266
+ await mastraClient.deleteSchedule('daily-report')
267
+ ```
268
+
269
+ ### `runSchedule()`
270
+
271
+ Fire a workflow schedule once immediately without changing its cron cadence.
272
+
273
+ ```typescript
274
+ const run = await mastraClient.runSchedule('daily-report')
275
+ ```
276
+
238
277
  ### `pauseSchedule()`
239
278
 
240
- Pause a schedule so the scheduler stops firing it. Returns the updated schedule. Idempotent.
279
+ Pause a schedule so the scheduler stops firing it. Returns the updated schedule.
241
280
 
242
281
  ```typescript
243
282
  await mastraClient.pauseSchedule('daily-report')
@@ -245,7 +284,7 @@ await mastraClient.pauseSchedule('daily-report')
245
284
 
246
285
  ### `resumeSchedule()`
247
286
 
248
- Resume a paused schedule. The next fire time is recomputed from now, so a long-paused schedule doesn't fire a backlog. Returns the updated schedule. Idempotent.
287
+ Resume a paused schedule. The next fire time is recomputed from now, so a long-paused schedule doesn't fire a backlog. Returns the updated schedule.
249
288
 
250
289
  ```typescript
251
290
  await mastraClient.resumeSchedule('daily-report')
@@ -253,7 +292,7 @@ await mastraClient.resumeSchedule('daily-report')
253
292
 
254
293
  ### `listScheduleTriggers()`
255
294
 
256
- List the trigger history for a schedule, including the joined run summary for each fire.
295
+ List the trigger history for a workflow schedule, including the joined run summary for each fire.
257
296
 
258
297
  ```typescript
259
298
  const { triggers } = await mastraClient.listScheduleTriggers('daily-report', {
@@ -230,6 +230,7 @@ The Reference section provides documentation of Mastra's API, including paramete
230
230
  - [rerank()](https://mastra.ai/reference/rag/rerank)
231
231
  - [rerankWithScorer()](https://mastra.ai/reference/rag/rerankWithScorer)
232
232
  - [.chunk()](https://mastra.ai/reference/rag/chunk)
233
+ - [Overview](https://mastra.ai/reference/schedules/overview)
233
234
  - [createRoute()](https://mastra.ai/reference/server/create-route)
234
235
  - [Express Adapter](https://mastra.ai/reference/server/express-adapter)
235
236
  - [Fastify Adapter](https://mastra.ai/reference/server/fastify-adapter)
@@ -309,6 +310,7 @@ The Reference section provides documentation of Mastra's API, including paramete
309
310
  - [Google Gemini Live](https://mastra.ai/reference/voice/google-gemini-live)
310
311
  - [Inworld](https://mastra.ai/reference/voice/inworld)
311
312
  - [Inworld Realtime](https://mastra.ai/reference/voice/inworld-realtime)
313
+ - [LiveKit](https://mastra.ai/reference/voice/livekit)
312
314
  - [Mastra Voice](https://mastra.ai/reference/voice/mastra-voice)
313
315
  - [Murf](https://mastra.ai/reference/voice/murf)
314
316
  - [OpenAI](https://mastra.ai/reference/voice/openai)
@@ -0,0 +1,199 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # `mastra.schedules`
4
+
5
+ **Added in:** `@mastra/core@1.50.0`
6
+
7
+ `mastra.schedules` is the CRUD service for persisted cron schedules. Use it to create, list, update, pause, resume, manually run, and delete schedules for agents or workflows.
8
+
9
+ For usage patterns and concepts, see [Schedules](https://mastra.ai/docs/long-running-agents/schedules).
10
+
11
+ ## Usage example
12
+
13
+ Create an agent schedule:
14
+
15
+ ```typescript
16
+ const schedule = await mastra.schedules.create({
17
+ agentId: 'pinger',
18
+ cron: '0 * * * *',
19
+ prompt: 'Give me a status update.',
20
+ })
21
+ ```
22
+
23
+ Create a workflow schedule:
24
+
25
+ ```typescript
26
+ const schedule = await mastra.schedules.create({
27
+ workflowId: 'daily-report',
28
+ cron: '0 9 * * *',
29
+ inputData: { reportType: 'summary' },
30
+ })
31
+ ```
32
+
33
+ Schedules require a storage adapter that implements the schedules domain. Supported adapters include `@mastra/libsql`, `@mastra/pg`, `@mastra/mysql`, `@mastra/mongodb`, `@mastra/convex`, and `@mastra/spanner`.
34
+
35
+ ## Methods
36
+
37
+ ### Create schedules
38
+
39
+ #### `create(input)`
40
+
41
+ Creates an agent or workflow schedule. Pass `agentId` to create an agent schedule, or `workflowId` to create a workflow schedule.
42
+
43
+ ```typescript
44
+ const schedule = await mastra.schedules.create({
45
+ agentId: 'pinger',
46
+ cron: '0 * * * *',
47
+ prompt: 'Give me a status update.',
48
+ })
49
+ ```
50
+
51
+ ##### Agent schedule input
52
+
53
+ **id** (`string`): Optional stable schedule ID. The value is normalized to agent\_\<slug>. When omitted, Mastra generates an agent\_\<uuid> ID.
54
+
55
+ **agentId** (`string`): ID of the agent to run on each schedule fire.
56
+
57
+ **cron** (`string`): Cron expression for the schedule. Accepts 5-, 6-, or 7-part cron expressions and Croner nicknames.
58
+
59
+ **prompt** (`string`): Prompt sent to the agent on each schedule fire.
60
+
61
+ **name** (`string`): Free-form label for distinguishing multiple schedules on the same agent or thread.
62
+
63
+ **timezone** (`string`): IANA timezone used to resolve cron fire times, for example America/New\_York.
64
+
65
+ **threadId** (`string`): Thread that receives the scheduled signal. When omitted, each fire runs threadless with agent.generate().
66
+
67
+ **resourceId** (`string`): Resource ID for threaded schedules. Required when threadId is set.
68
+
69
+ **signalType** (`AgentSignalType`): Signal type for threaded schedule fires. Defaults to notification.
70
+
71
+ **tagName** (`string`): XML tag name used to render the scheduled signal. Defaults to schedule.
72
+
73
+ **attributes** (`AgentSignalAttributes`): Attributes rendered on the scheduled signal XML tag.
74
+
75
+ **providerOptions** (`Record<string, unknown>`): JSON-safe provider options merged into the schedule signal payload on every fire.
76
+
77
+ **ifActive** (`ScheduleIfActive`): Behavior when the target thread is actively streaming. Requires threadId.
78
+
79
+ **ifIdle** (`ScheduleIfIdle`): Behavior when the target thread is idle. Requires threadId.
80
+
81
+ **metadata** (`Record<string, unknown>`): Arbitrary metadata stored with the schedule row.
82
+
83
+ **status** (`'active' | 'paused'`): Initial lifecycle status. Defaults to active. (Default: `'active'`)
84
+
85
+ ##### Workflow schedule input
86
+
87
+ **id** (`string`): Optional stable schedule ID. The value is normalized to schedule\_\<slug>. When omitted, Mastra generates a schedule\_\<uuid> ID.
88
+
89
+ **workflowId** (`string`): ID of the workflow to start on each schedule fire.
90
+
91
+ **cron** (`string`): Cron expression for the schedule. Accepts 5-, 6-, or 7-part cron expressions and Croner nicknames.
92
+
93
+ **timezone** (`string`): IANA timezone used to resolve cron fire times.
94
+
95
+ **inputData** (`unknown`): Input data passed to the workflow run.
96
+
97
+ **initialState** (`unknown`): Initial workflow state for the scheduled run.
98
+
99
+ **requestContext** (`Record<string, unknown>`): Request context passed to the workflow run.
100
+
101
+ **metadata** (`Record<string, unknown>`): Arbitrary metadata stored with the schedule row.
102
+
103
+ **status** (`'active' | 'paused'`): Initial lifecycle status. Defaults to active. (Default: `'active'`)
104
+
105
+ ### Read schedules
106
+
107
+ #### `get(id)`
108
+
109
+ Gets a schedule by ID. Bare agent schedule IDs are also resolved to the normalized `agent_<slug>` form.
110
+
111
+ ```typescript
112
+ const schedule = await mastra.schedules.get('pinger')
113
+ ```
114
+
115
+ #### `list(filter?)`
116
+
117
+ Lists schedules. Without a filter, it returns agent and workflow schedules.
118
+
119
+ ```typescript
120
+ const schedules = await mastra.schedules.list({
121
+ agentId: 'pinger',
122
+ status: 'active',
123
+ })
124
+ ```
125
+
126
+ **filter** (`ListSchedulesFilter`): Optional filters for the list operation.
127
+
128
+ **filter.agentId** (`string`): Return only agent schedules for this agent.
129
+
130
+ **filter.workflowId** (`string`): Return only workflow schedules for this workflow.
131
+
132
+ **filter.threadId** (`string`): Return only agent schedules for this thread.
133
+
134
+ **filter.resourceId** (`string`): Return only agent schedules for this resource.
135
+
136
+ **filter.name** (`string`): Return only agent schedules with this label.
137
+
138
+ **filter.status** (`'active' | 'paused'`): Return only schedules with this status.
139
+
140
+ ### Update schedules
141
+
142
+ #### `update(id, patch)`
143
+
144
+ Updates a schedule. Changing `cron` or `timezone` recomputes the next fire time. Updating `status` from `paused` to `active` also recomputes the next fire time.
145
+
146
+ ```typescript
147
+ const updated = await mastra.schedules.update('pinger', {
148
+ cron: '*/30 * * * *',
149
+ prompt: 'Give me a status update every 30 minutes.',
150
+ })
151
+ ```
152
+
153
+ Agent schedule patches can update `cron`, `timezone`, `prompt`, `name`, `signalType`, `tagName`, `attributes`, `providerOptions`, `ifActive`, `ifIdle`, `metadata`, and `status`. `threadId` and `resourceId` aren't patchable; create a new schedule when the thread target needs to change.
154
+
155
+ Workflow schedule patches can update `cron`, `timezone`, `inputData`, `initialState`, `requestContext`, `metadata`, and `status`. Agent-only patch fields such as `prompt`, `signalType`, and `ifIdle` throw on workflow schedules.
156
+
157
+ ### Lifecycle
158
+
159
+ #### `pause(id)`
160
+
161
+ Pauses a schedule. Pausing is durable and idempotent.
162
+
163
+ ```typescript
164
+ const paused = await mastra.schedules.pause('pinger')
165
+ ```
166
+
167
+ #### `resume(id)`
168
+
169
+ Resumes a paused schedule and recomputes the next fire time from the current time.
170
+
171
+ ```typescript
172
+ const active = await mastra.schedules.resume('pinger')
173
+ ```
174
+
175
+ #### `run(id)`
176
+
177
+ Fires a schedule once immediately without changing its cron cadence.
178
+
179
+ ```typescript
180
+ const run = await mastra.schedules.run('pinger')
181
+ ```
182
+
183
+ For agent schedules, `claimId` uses `manual_<scheduleId>_<timestamp>`. For workflow schedules, `claimId` uses `sched_<scheduleId>_<timestamp>` and is reused as the workflow run ID.
184
+
185
+ #### `delete(id)`
186
+
187
+ Deletes a schedule. Deleting a missing schedule is a no-op.
188
+
189
+ ```typescript
190
+ await mastra.schedules.delete('pinger')
191
+ ```
192
+
193
+ ## Schedule behavior
194
+
195
+ - Agent schedule IDs use the `agent_` prefix. Workflow schedule IDs created through `mastra.schedules.create()` use the `schedule_` prefix.
196
+ - Threaded agent schedules require `resourceId` when `threadId` is set.
197
+ - `signalType`, `ifActive`, `ifIdle`, and `resourceId` require `threadId`.
198
+ - Workflow schedules don't accept agent-only patch fields such as `prompt`, `signalType`, or `ifIdle`.
199
+ - `run()` publishes a manual fire immediately and doesn't change the stored cron cadence.
@@ -0,0 +1,218 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # LiveKit
4
+
5
+ The `@mastra/livekit` package connects Mastra agents to the LiveKit Agents framework. LiveKit runs the audio pipeline (voice activity detection, speech-to-text, turn detection, text-to-speech, barge-in) and the package bridges reply generation to a Mastra agent's `stream()` call.
6
+
7
+ See [Using LiveKit with Mastra](https://mastra.ai/docs/voice/livekit) for setup and concepts.
8
+
9
+ The package has two entry points, one per process:
10
+
11
+ - `@mastra/livekit`: server-side APIs — [`liveKitConnectionRoute()`](#livekitconnectionroute), [`dispatchVoiceSession()`](#dispatchvoicesession), [`pipeAgentReplyToWriter()`](#pipeagentreplytowriter), and [`serializeSessionMetadata()`](#livekitsessionmetadata). Import these from Mastra server code. This entry never loads the LiveKit agents runtime.
12
+ - `@mastra/livekit/worker`: the worker runtime — [`createLiveKitWorker()`](#createlivekitworker), [`runLiveKitWorker()`](#runlivekitworker), and [`chatContextToMessages()`](#chatcontexttomessages). Import it only from the worker entry file.
13
+
14
+ ## `createLiveKitWorker()`
15
+
16
+ Builds a LiveKit agent definition that answers voice sessions with Mastra agents. Use it as the default export of your worker entry file.
17
+
18
+ ```typescript
19
+ import { fileURLToPath } from 'node:url'
20
+ import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker'
21
+ import { mastra } from './index'
22
+
23
+ export default createLiveKitWorker({
24
+ mastra,
25
+ agent: 'support',
26
+ stt: 'deepgram/nova-3',
27
+ tts: 'cartesia/sonic-3',
28
+ turnDetection: 'multilingual',
29
+ })
30
+
31
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
32
+ runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' })
33
+ }
34
+ ```
35
+
36
+ ### Options
37
+
38
+ **mastra** (`Mastra`): The Mastra instance whose agents handle voice sessions.
39
+
40
+ **agent** (`string | (args) => string | Agent | Promise<string | Agent>`): Which Mastra agent answers each session: a fixed agent key or id, or a resolver called per session with the dispatch metadata and job context. Defaults to the agentId from the dispatch metadata.
41
+
42
+ **workflow** (`string | Workflow | (args) => string | Promise<string>`): Generate each turn's reply with a Mastra workflow instead of an agent: a Workflow instance, a fixed workflow key or id, or a resolver that returns a workflow id per session. The workflow runs once to completion per turn (no suspend or resume). Mutually exclusive with agent; requires workflowInput.
43
+
44
+ **workflowInput** (`(args: VoiceTurnContext & { metadata }) => unknown | Promise<unknown>`): Maps a turn into the workflow inputData. Required when workflow is set. A stateless mapping that passes the full transcript each turn avoids carrying conversation state in the workflow.
45
+
46
+ **replyStep** (`string`): Only stream text from this workflow step id. Defaults to every step that writes to its writer.
47
+
48
+ **resultText** (`(result: unknown) => string | undefined`): Fallback when the workflow streams no text via writer: derive the spoken reply from the final run result.
49
+
50
+ **generate** (`VoiceReplyGenerator`): Lowest-level escape hatch: supply any reply generator directly (a custom workflow, remote bridge, and so on).
51
+
52
+ **stt** (`STT | string`): Speech-to-text: a LiveKit plugin instance or an inference model string such as 'deepgram/nova-3'.
53
+
54
+ **tts** (`TTS | string`): Text-to-speech: a LiveKit plugin instance or an inference model string such as 'cartesia/sonic-3'.
55
+
56
+ **vad** (`VAD | 'silero' | false`): Voice activity detection. 'silero' loads the Silero VAD from @livekit/agents-plugin-silero during prewarm. Pass an instance to bring your own, or false to disable. (Default: `'silero'`)
57
+
58
+ **turnDetection** (`'multilingual' | 'english' | TurnDetectionMode`): End-of-turn detection. 'multilingual' and 'english' load LiveKit's semantic turn detector from @livekit/agents-plugin-livekit. Other values such as 'vad', 'stt', or 'manual' pass through.
59
+
60
+ **turnHandling** (`Partial<TurnHandlingOptions>`): Turn handling tuning: endpointing delays, interruption sensitivity, preemptive generation. The worker disables preemptiveGeneration unless set here — each preemptive attempt re-runs the Mastra agent and persists a duplicate user message.
61
+
62
+ **sessionOptions** (`Partial<AgentSessionOptions>`): Extra LiveKit AgentSession options merged over what this helper builds.
63
+
64
+ **memory** (`false | ((args) => { thread, resource } | false)`): Memory mapping. Defaults to { thread: metadata.threadId ?? room name, resource: metadata.resourceId ?? thread } when the resolved agent has memory configured. Pass false to disable, or a function to customize.
65
+
66
+ **toolFeedback** (`(toolCall) => string | undefined`): Called when the Mastra agent starts a tool call mid-reply. Return a short phrase to speak while the tool runs.
67
+
68
+ **greeting** (`string`): Static greeting spoken when the session starts.
69
+
70
+ **persistGreeting** (`boolean`): Save the spoken greeting to the memory thread as an assistant message, making the saved thread a faithful call transcript. Only applies when a greeting is set and memory is enabled. (Default: `true`)
71
+
72
+ **observability** (`boolean`): Trace each call when the Mastra instance has observability configured. Opens a voice call span per session: every turn's agent run nests under it, LiveKit's STT, TTS, end-of-utterance, VAD, and LLM latency metrics become child spans, and the span closes with a per-model usage roll-up. Pass false to disable. (Default: `true`)
73
+
74
+ **inputOptions** (`Partial<RoomInputOptions>`): LiveKit room input options passed to session.start().
75
+
76
+ **outputOptions** (`Partial<RoomOutputOptions>`): LiveKit room output options passed to session.start().
77
+
78
+ **onSessionStart** (`(args: { session, ctx, agent, metadata }) => void | Promise<void>`): Called after the session starts. Attach event listeners or trigger replies here.
79
+
80
+ ## `runLiveKitWorker()`
81
+
82
+ Starts the LiveKit worker CLI (`dev`, `start`, and `connect` subcommands) for a worker entry file. Call it from the file that default-exports the worker definition, guarded so it only runs when executed directly (the worker spawns a child process per session that re-imports the same file). Using this helper instead of `cli.runApp` from `@livekit/agents` guarantees the worker runtime and the bridge share one copy of the LiveKit SDK.
83
+
84
+ ### Options
85
+
86
+ **entry** (`string | URL`): The worker entry module whose default export is the agent definition. Pass import.meta.url.
87
+
88
+ **agentName** (`string`): LiveKit agent name for explicit dispatch. (Default: `'mastra-voice'`)
89
+
90
+ **serverOptions** (`Partial<ServerOptions>`): Extra LiveKit ServerOptions merged over what this helper builds.
91
+
92
+ ## `pipeAgentReplyToWriter()`
93
+
94
+ Streams a Mastra agent's reply into a workflow step's `writer` on the workflow reply path. It forwards the agent's text deltas, so text-to-speech starts before the full reply is ready, and its tool-call chunks, so `toolFeedback` fires and `onTurnComplete` sees the tool list. Piping only `stream.textStream` silently drops tool calls. Pass the step's `abortSignal` to `agent.stream()` so barge-in stops generation promptly.
95
+
96
+ ```typescript
97
+ import { pipeAgentReplyToWriter } from '@mastra/livekit'
98
+
99
+ const generateResponse = createStep({
100
+ id: 'generateResponse',
101
+ // input and output schemas omitted
102
+ execute: async ({ inputData, mastra, writer, abortSignal }) => {
103
+ const stream = await mastra.getAgent('support').stream(inputData.turn, { abortSignal })
104
+ const reply = await pipeAgentReplyToWriter(stream, writer)
105
+ return { reply }
106
+ },
107
+ })
108
+ ```
109
+
110
+ Returns: `Promise<string>`, the accumulated reply text.
111
+
112
+ ### Parameters
113
+
114
+ **agentStream** (`AgentReplyStreamLike`): The stream returned by agent.stream() — anything exposing a fullStream async iterable.
115
+
116
+ **writer** (`WritableStream<unknown>`): The workflow step's writer.
117
+
118
+ ## `chatContextToMessages()`
119
+
120
+ Converts a LiveKit chat context into plain messages accepted by `agent.stream()`, excluding instructions and function calls. Use it in `workflowInput` to pass the full transcript into a stateless workflow.
121
+
122
+ ```typescript
123
+ import { createLiveKitWorker, chatContextToMessages } from '@mastra/livekit/worker'
124
+
125
+ export default createLiveKitWorker({
126
+ mastra,
127
+ workflow: 'phoneConversation',
128
+ workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }),
129
+ })
130
+ ```
131
+
132
+ Returns: `VoiceTurnMessage[]`, where each entry is `{ role: 'system' | 'user' | 'assistant'; content: string }`.
133
+
134
+ ## `liveKitConnectionRoute()`
135
+
136
+ Returns an [API route](https://mastra.ai/docs/server/custom-api-routes) that mints a LiveKit access token with the voice agent dispatched into the room. Frontends call it to join a session.
137
+
138
+ ```typescript
139
+ import { Mastra } from '@mastra/core/mastra'
140
+ import { liveKitConnectionRoute } from '@mastra/livekit'
141
+
142
+ export const mastra = new Mastra({
143
+ server: {
144
+ apiRoutes: [liveKitConnectionRoute({ agentName: 'mastra-voice' })],
145
+ },
146
+ })
147
+ ```
148
+
149
+ The route accepts a JSON body with optional `agentId`, `threadId`, and `resourceId` fields and responds with `{ serverUrl, roomName, participantName, participantToken }`. The `threadId` defaults to the generated room name.
150
+
151
+ ### Options
152
+
153
+ **path** (`string`): Route path. (Default: `'/voice/livekit/connection-details'`)
154
+
155
+ **serverUrl** (`string`): LiveKit server URL. (Default: `process.env.LIVEKIT_URL`)
156
+
157
+ **apiKey** (`string`): LiveKit API key. (Default: `process.env.LIVEKIT_API_KEY`)
158
+
159
+ **apiSecret** (`string`): LiveKit API secret. (Default: `process.env.LIVEKIT_API_SECRET`)
160
+
161
+ **agentName** (`string`): LiveKit agent name for explicit dispatch. Must match the worker's agentName. (Default: `'mastra-voice'`)
162
+
163
+ **ttl** (`string | number`): Token time-to-live. (Default: `'15m'`)
164
+
165
+ **requiresAuth** (`boolean`): Whether the route requires authentication. (Default: `true`)
166
+
167
+ **roomName** (`string | (args) => string`): Room name or a function that derives one from the request.
168
+
169
+ **participantIdentity** (`string | (args) => string`): Participant identity or a function that derives one from the request.
170
+
171
+ **metadata** (`(args) => LiveKitSessionMetadata | Promise<LiveKitSessionMetadata>`): Builds the session metadata delivered to the worker. Defaults to passing through agentId, threadId, and resourceId from the request body.
172
+
173
+ ## `dispatchVoiceSession()`
174
+
175
+ Dispatches a Mastra voice agent into a LiveKit room programmatically — for server-initiated sessions such as outbound calls.
176
+
177
+ ```typescript
178
+ import { dispatchVoiceSession } from '@mastra/livekit'
179
+
180
+ await dispatchVoiceSession({
181
+ roomName: 'support-call-42',
182
+ agentName: 'mastra-voice',
183
+ metadata: { agentId: 'support', threadId: 'thread-42' },
184
+ })
185
+ ```
186
+
187
+ ### Options
188
+
189
+ **roomName** (`string`): Room to dispatch the agent into. Created on demand.
190
+
191
+ **agentName** (`string`): Must match the worker's agentName. (Default: `'mastra-voice'`)
192
+
193
+ **metadata** (`LiveKitSessionMetadata`): Session metadata: agentId, threadId, resourceId, requestContext.
194
+
195
+ **serverUrl** (`string`): LiveKit server URL. (Default: `process.env.LIVEKIT_URL`)
196
+
197
+ **apiKey** (`string`): LiveKit API key. (Default: `process.env.LIVEKIT_API_KEY`)
198
+
199
+ **apiSecret** (`string`): LiveKit API secret. (Default: `process.env.LIVEKIT_API_SECRET`)
200
+
201
+ ## `LiveKitSessionMetadata`
202
+
203
+ The metadata passed from the Mastra server to the worker through LiveKit job dispatch.
204
+
205
+ **agentId** (`string`): Mastra agent to run, by registered key or agent id.
206
+
207
+ **threadId** (`string`): Memory thread id. Defaults to the LiveKit room name.
208
+
209
+ **resourceId** (`string`): Memory resource id, typically the end user id.
210
+
211
+ **requestContext** (`Record<string, unknown>`): Plain-object entries restored into a RequestContext for agent execution.
212
+
213
+ The metadata travels as a JSON string. `liveKitConnectionRoute()` and `dispatchVoiceSession()` serialize it for you; use `serializeSessionMetadata(metadata)` when dispatching through your own code, or write the JSON directly in LiveKit-side configuration such as a SIP dispatch rule. Entries in `requestContext` reach the agent's dynamic instructions, tools, and input processors on every turn of the call.
214
+
215
+ ## Related
216
+
217
+ - [Using LiveKit with Mastra](https://mastra.ai/docs/voice/livekit)
218
+ - [LiveKit Agents docs](https://docs.livekit.io/agents/)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @mastra/mcp-docs-server
2
2
 
3
+ ## 1.2.5-alpha.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`a0085fa`](https://github.com/mastra-ai/mastra/commit/a0085fa0934e52c37c8c8b3d75a6bb5cd199af36)]:
8
+ - @mastra/core@1.50.0-alpha.5
9
+
3
10
  ## 1.2.5-alpha.7
4
11
 
5
12
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/mcp-docs-server",
3
- "version": "1.2.5-alpha.7",
3
+ "version": "1.2.5-alpha.8",
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/mcp": "^1.13.1-alpha.0",
32
- "@mastra/core": "1.50.0-alpha.4"
31
+ "@mastra/core": "1.50.0-alpha.5",
32
+ "@mastra/mcp": "^1.13.1-alpha.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@hono/node-server": "^1.19.11",
@@ -46,8 +46,8 @@
46
46
  "typescript": "^6.0.3",
47
47
  "vitest": "4.1.8",
48
48
  "@internal/lint": "0.0.111",
49
- "@internal/types-builder": "0.0.86",
50
- "@mastra/core": "1.50.0-alpha.4"
49
+ "@mastra/core": "1.50.0-alpha.5",
50
+ "@internal/types-builder": "0.0.86"
51
51
  },
52
52
  "homepage": "https://mastra.ai",
53
53
  "repository": {