@mastra/mcp-docs-server 1.1.42 → 1.1.43
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/acp.md +21 -158
- package/.docs/docs/agents/processors.md +143 -0
- package/.docs/docs/agents/signals.md +229 -9
- package/.docs/docs/build-with-ai/skills.md +3 -3
- package/.docs/docs/editor/overview.md +11 -10
- package/.docs/docs/getting-started/build-with-ai.md +37 -0
- package/.docs/docs/mastra-platform/observability.md +4 -4
- package/.docs/docs/memory/multi-user-threads.md +1 -1
- package/.docs/docs/memory/working-memory.md +27 -0
- package/.docs/docs/observability/metrics/querying.md +1 -1
- package/.docs/docs/server/pubsub.md +124 -0
- package/.docs/docs/studio/auth.md +20 -0
- package/.docs/reference/acp/acp-agent.md +228 -0
- package/.docs/reference/acp/create-acp-tool.md +131 -0
- package/.docs/reference/agents/agent.md +51 -1
- package/.docs/reference/agents/durable-agent.md +239 -0
- package/.docs/reference/cli/mastra.md +5 -5
- package/.docs/reference/client-js/agents.md +41 -7
- package/.docs/reference/index.md +9 -0
- package/.docs/reference/processors/response-cache.md +2 -2
- package/.docs/reference/pubsub/base.md +168 -0
- package/.docs/reference/pubsub/caching-pubsub.md +102 -0
- package/.docs/reference/pubsub/event-emitter.md +72 -0
- package/.docs/reference/pubsub/google-cloud-pubsub.md +94 -0
- package/.docs/reference/pubsub/redis-streams.md +108 -0
- package/.docs/reference/pubsub/unix-socket-pubsub.md +52 -0
- package/.docs/reference/storage/libsql.md +6 -0
- package/.docs/reference/storage/mongodb.md +3 -0
- package/.docs/reference/storage/postgresql.md +3 -0
- package/CHANGELOG.md +16 -0
- package/package.json +6 -6
- package/.docs/docs/agents/response-caching.md +0 -150
|
@@ -97,7 +97,7 @@ The behavior options are:
|
|
|
97
97
|
- `ifIdle.behavior: 'persist'`: Save the signal or message to memory without starting a stream.
|
|
98
98
|
- `ifIdle.behavior: 'discard'`: Ignore the signal or message while the thread is idle.
|
|
99
99
|
|
|
100
|
-
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context. You
|
|
100
|
+
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context. You don't need to repeat `memory.resource` or `memory.thread`; Mastra uses the top-level `resourceId` and `threadId` for the thread.
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
103
|
agent.sendMessage('Continue with the next step.', {
|
|
@@ -143,6 +143,10 @@ The model receives the signal as context like this:
|
|
|
143
143
|
|
|
144
144
|
Use XML-safe `tagName` and attribute names. They can contain letters, numbers, underscores, periods, and hyphens. They must start with a letter or underscore.
|
|
145
145
|
|
|
146
|
+
### Storage support
|
|
147
|
+
|
|
148
|
+
Notification inbox storage is available in the storage adapters that support richer memory and signal workflows: [libSQL](https://mastra.ai/reference/storage/libsql), [PostgreSQL](https://mastra.ai/reference/storage/postgresql), and [MongoDB](https://mastra.ai/reference/storage/mongodb). These adapters expose notification records through `getStore('notifications')`.
|
|
149
|
+
|
|
146
150
|
## Send processor context
|
|
147
151
|
|
|
148
152
|
Processors can send reactive signals during a run. A processor should inspect the chat history, react to a specific trigger, and avoid sending the same context more than once.
|
|
@@ -220,7 +224,224 @@ When the agent is idle:
|
|
|
220
224
|
<user source="chat" delivery="new-message">Also cover the edge cases.</user>
|
|
221
225
|
```
|
|
222
226
|
|
|
223
|
-
Top-level `attributes` always apply. The selected branch's `attributes` are merged into them at delivery time. The `delivery` name shown above
|
|
227
|
+
Top-level `attributes` always apply. The selected branch's `attributes` are merged into them at delivery time. The `delivery` name shown above isn't a special Mastra API field. It's a custom attribute name used for this example. Add any attribute names that suit your use case.
|
|
228
|
+
|
|
229
|
+
## State signals
|
|
230
|
+
|
|
231
|
+
State signals expose named, thread-scoped context lanes. Use them for durable context that changes over time, such as browser state, editor state, or a background watcher result.
|
|
232
|
+
|
|
233
|
+
Each state signal needs:
|
|
234
|
+
|
|
235
|
+
- `id`: The state lane name, such as `browser`.
|
|
236
|
+
- `cacheKey`: A producer-owned key for deduping the current state.
|
|
237
|
+
- `mode`: `snapshot` for an authoritative state copy, or `delta` for a change event.
|
|
238
|
+
|
|
239
|
+
Use `sendStateSignal()` when an external producer detects a state change.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
await agent.sendStateSignal(
|
|
243
|
+
{
|
|
244
|
+
id: 'browser',
|
|
245
|
+
mode: 'snapshot',
|
|
246
|
+
cacheKey: 'browser:https://example.com:3-tabs',
|
|
247
|
+
contents: 'Browser is open on https://example.com with 3 tabs.',
|
|
248
|
+
value: {
|
|
249
|
+
activeUrl: 'https://example.com',
|
|
250
|
+
tabCount: 3,
|
|
251
|
+
open: true,
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
resourceId: 'user_123',
|
|
256
|
+
threadId: 'thread_456',
|
|
257
|
+
},
|
|
258
|
+
)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
When Mastra accepts a state signal, it stores compact tracking metadata on the thread. The metadata records the lane's current `cacheKey`, current mode, version, last signal id, and last snapshot signal id. If a producer sends the same `cacheKey` and mode again while that state is still current, Mastra skips the duplicate.
|
|
262
|
+
|
|
263
|
+
State signal fields have separate roles:
|
|
264
|
+
|
|
265
|
+
- `contents`: The representation the model reads.
|
|
266
|
+
- `value`: The structured snapshot for `mode: 'snapshot'`.
|
|
267
|
+
- `delta`: The structured change for `mode: 'delta'`.
|
|
268
|
+
- `metadata.state`: The runtime tracking envelope with `id`, `mode`, `cacheKey`, `version`, and `threadId`.
|
|
269
|
+
|
|
270
|
+
Use `computeStateSignal()` when a processor owns a state lane. Mastra calls it once per model input step after `processInputStep()`. If the processor omits `id`, Mastra uses the processor id as the state lane id. Set `stateId` when the public state lane should differ from the processor id.
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import type { ComputeStateSignalArgs, Processor } from '@mastra/core/processors'
|
|
274
|
+
|
|
275
|
+
export const browserStateProcessor: Processor = {
|
|
276
|
+
id: 'browser-state',
|
|
277
|
+
stateId: 'browser',
|
|
278
|
+
computeStateSignal(args: ComputeStateSignalArgs) {
|
|
279
|
+
const browser = readCurrentBrowserState()
|
|
280
|
+
const previous = readMostRecentBrowserState(args.activeStateSignals)
|
|
281
|
+
const changed = previous ? diffBrowserState(previous, browser) : browser
|
|
282
|
+
const shouldRefreshSnapshot = Boolean(args.lastSnapshot && !args.contextWindow.hasSnapshot)
|
|
283
|
+
|
|
284
|
+
if (previous && Object.keys(changed).length === 0 && !shouldRefreshSnapshot) {
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const isDelta = Boolean(previous && !shouldRefreshSnapshot)
|
|
289
|
+
|
|
290
|
+
return {
|
|
291
|
+
mode: isDelta ? 'delta' : 'snapshot',
|
|
292
|
+
cacheKey: stableBrowserStateCacheKey(browser),
|
|
293
|
+
contents: isDelta ? describeBrowserDelta(changed) : describeBrowserSnapshot(browser),
|
|
294
|
+
value: browser,
|
|
295
|
+
...(isDelta ? { delta: changed } : {}),
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Mastra passes `lastSnapshot` and `deltasSinceSnapshot` into `computeStateSignal()`. It resolves them from message history when the current message list doesn't contain the latest snapshot. The processor still owns merge and diff logic.
|
|
302
|
+
|
|
303
|
+
`contextWindow.hasSnapshot` tells the processor whether the active message window already contains a snapshot for this state lane. If it's `false`, return a fresh `snapshot` so the model sees the current state even after older state messages are trimmed from the context window.
|
|
304
|
+
|
|
305
|
+
The built-in browser context processor emits state under the `browser` id with snapshot and delta modes.
|
|
306
|
+
|
|
307
|
+
## Notification signals
|
|
308
|
+
|
|
309
|
+
Notification signals represent external events such as GitHub activity, email, Slack mentions, CI status, incidents, recordings, or direct messages. Use `agent.sendNotificationSignal()` when the event should create a durable inbox record.
|
|
310
|
+
|
|
311
|
+
Notification delivery has two phases:
|
|
312
|
+
|
|
313
|
+
- **Ingress**: `agent.sendNotificationSignal()` stores a notification record, then resolves the agent's delivery policy.
|
|
314
|
+
- **Dispatch**: Mastra consumes due records stamped with `deliverAt` or `summaryAt` and emits full notification or summary signals.
|
|
315
|
+
|
|
316
|
+
A notification record stores the source, kind, priority, summary, payload, resource id, thread id, agent id, coalescing keys, and delivery metadata. The delivery decision controls what happens after ingress:
|
|
317
|
+
|
|
318
|
+
- `deliver` or `queue`: Emit a full `<notification>` signal and mark the record `delivered`.
|
|
319
|
+
- `defer`: Keep the record `pending` with `deliverAt`.
|
|
320
|
+
- `summarize`: Keep the record `pending` with `summaryAt`, or emit an immediate summary when the policy requests it.
|
|
321
|
+
- `persist`: Keep the record `pending` in the inbox without scheduled delivery.
|
|
322
|
+
- `discard`: Mark the record `discarded` and emit no signal.
|
|
323
|
+
|
|
324
|
+
The default delivery policy is priority-aware:
|
|
325
|
+
|
|
326
|
+
| Priority | Active thread | Idle thread |
|
|
327
|
+
| -------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
328
|
+
| `urgent` | Deliver a full notification immediately | Deliver a full notification immediately |
|
|
329
|
+
| `high` | Emit a summary immediately, keep `deliverAt`, then deliver the full notification when the thread is idle | Deliver a full notification immediately |
|
|
330
|
+
| `medium` | Batch with `summaryAt` and later deliver one notification summary | Deliver a full notification immediately |
|
|
331
|
+
| `low` | Batch with `summaryAt` and later deliver one notification summary | Batch with `summaryAt` and later deliver one notification summary without waking the model loop |
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
await agent.sendNotificationSignal(
|
|
335
|
+
{
|
|
336
|
+
source: 'github',
|
|
337
|
+
kind: 'ci-status',
|
|
338
|
+
priority: 'high',
|
|
339
|
+
summary: 'CI failed on main: 3 tests failed.',
|
|
340
|
+
payload: {
|
|
341
|
+
repository: 'acme/app',
|
|
342
|
+
branch: 'main',
|
|
343
|
+
},
|
|
344
|
+
dedupeKey: 'github:acme/app:main:ci',
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
resourceId: 'user_123',
|
|
348
|
+
threadId: 'thread_456',
|
|
349
|
+
},
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The model receives full notifications as context:
|
|
354
|
+
|
|
355
|
+
```xml
|
|
356
|
+
<notification source="github" type="ci-status" priority="high" status="delivered">CI failed on main: 3 tests failed.</notification>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Notification summaries tell the model that inbox records are waiting:
|
|
360
|
+
|
|
361
|
+
```xml
|
|
362
|
+
<notification-summary pending="10">github: 3, email: 5, slack: 2</notification-summary>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
When Mastra emits a summary, it clears `summaryAt` and sets `summarySignalId` on each summarized record. The records stay pending and readable. When Mastra emits a full notification, it sets `deliveredSignalId` and marks the record `delivered`. If the inbox tool reads a notification first, it can inject the full notification signal and mark the record `seen`, which prevents duplicate full delivery.
|
|
366
|
+
|
|
367
|
+
Configure a delivery policy on the agent when some notifications should wait for a different dispatch window or summary rollup.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
export const supportAgent = new Agent({
|
|
371
|
+
id: 'support-agent',
|
|
372
|
+
name: 'Support Agent',
|
|
373
|
+
instructions: 'Help the user triage updates.',
|
|
374
|
+
model: 'openai/gpt-5.5',
|
|
375
|
+
notifications: {
|
|
376
|
+
deliveryPolicy: {
|
|
377
|
+
priorities: {
|
|
378
|
+
urgent: 'deliver',
|
|
379
|
+
},
|
|
380
|
+
decide: ({ record }) => {
|
|
381
|
+
if (record.priority === 'low') {
|
|
382
|
+
return {
|
|
383
|
+
action: 'summarize',
|
|
384
|
+
summaryAt: new Date(Date.now() + 30 * 60 * 1000),
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
})
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Enable scheduled dispatch at the Mastra level so deferred notifications and summary rollups are delivered through the existing workflow scheduler.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
export const mastra = new Mastra({
|
|
397
|
+
agents: { supportAgent },
|
|
398
|
+
storage,
|
|
399
|
+
notifications: {
|
|
400
|
+
dispatch: {
|
|
401
|
+
enabled: true,
|
|
402
|
+
cron: '*/1 * * * *',
|
|
403
|
+
batchSize: 100,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
})
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
`notifications.dispatch.enabled` registers an internal workflow with the default cron `*/1 * * * *`. The dispatcher reads due notification records from storage, groups summaries by `agentId`, `resourceId`, and `threadId`, and emits signals through the Agent thread runtime. It isn't a user-facing entrypoint.
|
|
410
|
+
|
|
411
|
+
### Notification inbox tool
|
|
412
|
+
|
|
413
|
+
Use `createNotificationInboxTool()` to give agents one tool for inbox actions instead of many CRUD tools.
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import { createNotificationInboxTool } from '@mastra/core/notifications'
|
|
417
|
+
|
|
418
|
+
const notificationsStorage = await storage.getStore('notifications')
|
|
419
|
+
|
|
420
|
+
export const supportAgent = new Agent({
|
|
421
|
+
id: 'support-agent',
|
|
422
|
+
name: 'Support Agent',
|
|
423
|
+
instructions: 'Help the user triage updates.',
|
|
424
|
+
model: 'openai/gpt-5.5',
|
|
425
|
+
tools: {
|
|
426
|
+
notificationInbox: createNotificationInboxTool({ storage: notificationsStorage }),
|
|
427
|
+
},
|
|
428
|
+
})
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
The tool id is `notification-inbox`. It supports these actions:
|
|
432
|
+
|
|
433
|
+
- `list`: List notifications for the current thread.
|
|
434
|
+
- `read`: Deliver readable full notification signals into the chat when possible, then mark records `seen`.
|
|
435
|
+
- `markSeen`: Mark one record `seen`.
|
|
436
|
+
- `dismiss`: Mark one record `dismissed`.
|
|
437
|
+
- `archive`: Mark one record `archived`.
|
|
438
|
+
- `search`: Search notification summaries in the current thread.
|
|
439
|
+
|
|
440
|
+
The tool uses the current `threadId` from the tool execution context unless one is provided. Use `read` after a `<notification-summary>` signal when the agent needs the full records behind the summary. The `read` result reports how many notifications will be delivered; it doesn't use normal tool output as the main context channel for the notification contents.
|
|
441
|
+
|
|
442
|
+
`sendNotificationSignal()` requires a storage domain with `notifications` support. LibSQL supports notifications. Other storage adapters need matching notification domain support before they can store notification records.
|
|
443
|
+
|
|
444
|
+
Use `sendSignal({ type: 'notification' })` only for lower-level notification-shaped context that should bypass inbox storage.
|
|
224
445
|
|
|
225
446
|
## Compatibility
|
|
226
447
|
|
|
@@ -229,7 +450,7 @@ Mastra still accepts legacy signal payloads such as `type: 'user-message'` and `
|
|
|
229
450
|
- `type: 'user-message'`: Normalizes to `type: 'user'` and `tagName: 'user'`
|
|
230
451
|
- `type: 'system-reminder'`: Normalizes to `type: 'reactive'` and `tagName: 'system-reminder'`
|
|
231
452
|
|
|
232
|
-
Existing stored signal rows and older clients continue to load through the compatibility layer.
|
|
453
|
+
Existing stored signal rows and older clients continue to load through the compatibility layer. New clients call the message routes when the server supports them; React's thread signal path falls back to the legacy `/signals` route when it detects an older server.
|
|
233
454
|
|
|
234
455
|
> **Note:** Visit [Agent signals reference](https://mastra.ai/reference/agents/agent) for the full message, signal, and subscription types.
|
|
235
456
|
|
|
@@ -264,11 +485,8 @@ const subscription = await agent.subscribeToThread({
|
|
|
264
485
|
threadId: 'thread_456',
|
|
265
486
|
})
|
|
266
487
|
|
|
267
|
-
await agent.
|
|
268
|
-
|
|
269
|
-
type: 'user-message',
|
|
270
|
-
contents: 'Show the shorter version.',
|
|
271
|
-
},
|
|
488
|
+
await agent.sendMessage({
|
|
489
|
+
message: 'Show the shorter version.',
|
|
272
490
|
resourceId: 'user_123',
|
|
273
491
|
threadId: 'thread_456',
|
|
274
492
|
})
|
|
@@ -307,7 +525,9 @@ Use heartbeats together with client-side reconnect logic. Heartbeats reduce idle
|
|
|
307
525
|
- [`Agent.queueMessage()`](https://mastra.ai/reference/agents/agent)
|
|
308
526
|
- [`Agent.sendSignal()`](https://mastra.ai/reference/agents/agent)
|
|
309
527
|
- [`Agent.subscribeToThread()`](https://mastra.ai/reference/agents/agent)
|
|
310
|
-
- [
|
|
528
|
+
- [`client.getAgent().sendMessage()`](https://mastra.ai/reference/client-js/agents)
|
|
529
|
+
- [`client.getAgent().queueMessage()`](https://mastra.ai/reference/client-js/agents)
|
|
311
530
|
- [`client.getAgent().sendSignal()`](https://mastra.ai/reference/client-js/agents)
|
|
531
|
+
- [Server agent routes](https://mastra.ai/reference/server/routes)
|
|
312
532
|
- [`client.getAgent().subscribeToThread()`](https://mastra.ai/reference/client-js/agents)
|
|
313
533
|
- [`client.getAgent().sendToolApproval()`](https://mastra.ai/reference/client-js/agents)
|
|
@@ -32,6 +32,8 @@ bun x skills add mastra-ai/skills
|
|
|
32
32
|
|
|
33
33
|
Mastra skills work with any coding agent that supports the [Skills standard](https://agentskills.io/), including Claude Code, Cursor, Codex, OpenCode, and others.
|
|
34
34
|
|
|
35
|
+
They're also available on [GitHub](https://github.com/mastra-ai/skills).
|
|
36
|
+
|
|
35
37
|
## Update skill
|
|
36
38
|
|
|
37
39
|
To update to the latest version of the Mastra skill, run:
|
|
@@ -58,6 +60,4 @@ yarn dlx skills update mastra
|
|
|
58
60
|
|
|
59
61
|
```bash
|
|
60
62
|
bun x skills update mastra
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
They're also available on [GitHub](https://github.com/mastra-ai/skills).
|
|
63
|
+
```
|
|
@@ -149,16 +149,17 @@ The `editor.agent` namespace also exposes `getById`, `list`, `listResolved`, and
|
|
|
149
149
|
|
|
150
150
|
The same operations are available over HTTP through the Mastra server. Use these when you want to manage stored agents from a separate service or from a non-TypeScript client:
|
|
151
151
|
|
|
152
|
-
| Method | Path
|
|
153
|
-
| -------- |
|
|
154
|
-
| `GET` | `/stored/agents`
|
|
155
|
-
| `POST` | `/stored/agents`
|
|
156
|
-
| `GET` | `/stored/agents/:storedAgentId`
|
|
157
|
-
| `PATCH` | `/stored/agents/:storedAgentId`
|
|
158
|
-
| `DELETE` | `/stored/agents/:storedAgentId`
|
|
159
|
-
| `
|
|
160
|
-
|
|
161
|
-
|
|
152
|
+
| Method | Path | Description |
|
|
153
|
+
| -------- | ------------------------------------------ | ---------------------------------------------------------------- |
|
|
154
|
+
| `GET` | `/stored/agents` | List all stored agents. |
|
|
155
|
+
| `POST` | `/stored/agents` | Create a stored agent. |
|
|
156
|
+
| `GET` | `/stored/agents/:storedAgentId` | Get a stored agent by ID. |
|
|
157
|
+
| `PATCH` | `/stored/agents/:storedAgentId` | Update a stored agent. |
|
|
158
|
+
| `DELETE` | `/stored/agents/:storedAgentId` | Delete a stored agent. |
|
|
159
|
+
| `GET` | `/stored/agents/:storedAgentId/dependents` | List agents that reference this agent as a sub-agent. |
|
|
160
|
+
| `POST` | `/stored/agents/:storedAgentId/export` | Export a stored agent's override as a deterministic JSON config. |
|
|
161
|
+
|
|
162
|
+
The dependents endpoint helps warn before deleting or unsharing an agent that other agents depend on: `dependents` lists caller-readable agents by `id` and `name`, while `hiddenCount` aggregates cross-workspace references the caller cannot read (surfaced only when the target is public). The export endpoint returns only the fields the agent's [`editor` config](https://mastra.ai/reference/agents/agent) allows, so the output matches the per-agent file the code source writes to disk. The Client SDK wraps these endpoints with `client.listStoredAgents()`, `client.createStoredAgent()`, `client.getStoredAgent()`, `client.getStoredAgent(id).dependents()`, and `client.getStoredAgent(id).export()`. Version management endpoints live under `/stored/agents/:storedAgentId/versions`, see [version management](https://mastra.ai/reference/client-js/agents) for the full list.
|
|
162
163
|
|
|
163
164
|
### Automated experimentation
|
|
164
165
|
|
|
@@ -40,6 +40,43 @@ In addition to documentation access, the [MCP Docs Server](https://mastra.ai/doc
|
|
|
40
40
|
|
|
41
41
|
Learn how to use the [MCP Docs Server](https://mastra.ai/docs/build-with-ai/mcp-docs-server).
|
|
42
42
|
|
|
43
|
+
## Mastra CLI
|
|
44
|
+
|
|
45
|
+
The [Mastra CLI](https://mastra.ai/reference/cli/mastra) gives your coding agent a direct line to your Mastra runtime. Agents can invoke agents, run workflows, execute tools, inspect memory, run evals, and query traces and logs.
|
|
46
|
+
|
|
47
|
+
**npm**:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install mastra@latest -g
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**pnpm**:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm add mastra@latest -g
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Yarn**:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
yarn global add mastra@latest
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Bun**:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bun add mastra@latest --global
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For example, your coding agent can run an agent, then pull traces to inspect the results:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
mastra api --url http://localhost:4111 agent run weather-agent '{"messages":"What is the weather in London?"}'
|
|
75
|
+
mastra api --url http://localhost:4111 trace list
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See the [CLI commands reference](https://mastra.ai/reference/cli/mastra) for the full list of available commands.
|
|
79
|
+
|
|
43
80
|
## Embedded package docs
|
|
44
81
|
|
|
45
82
|
Mastra packages ship with embedded documentation in `dist/docs`. When you install a Mastra package, your AI agent can read these files directly from `node_modules` to understand the package's APIs and patterns.
|
|
@@ -105,25 +105,25 @@ After your project is publishing traces, logs, or scores to Mastra Platform Obse
|
|
|
105
105
|
**npm**:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
npx mastra api trace list
|
|
108
|
+
npx mastra api trace list
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
**pnpm**:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
|
-
pnpm dlx mastra api trace list
|
|
114
|
+
pnpm dlx mastra api trace list
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
**Yarn**:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
yarn dlx mastra api trace list
|
|
120
|
+
yarn dlx mastra api trace list
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
**Bun**:
|
|
124
124
|
|
|
125
125
|
```bash
|
|
126
|
-
bun x mastra api trace list
|
|
126
|
+
bun x mastra api trace list
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
For observability commands, the CLI targets the hosted observability API and can infer credentials from your project environment. See the [`mastra api` CLI reference](https://mastra.ai/reference/cli/mastra) for available observability commands, filtering, pagination, credential resolution, and direct `curl` examples.
|
|
@@ -135,7 +135,7 @@ const memory = new Memory({
|
|
|
135
135
|
|
|
136
136
|
The model reads identity from the `<turn>` tag on the current message and from prior tagged messages brought back through `lastMessages`.
|
|
137
137
|
|
|
138
|
-
### With
|
|
138
|
+
### With Observational Memory (recommended)
|
|
139
139
|
|
|
140
140
|
[Observational Memory](https://mastra.ai/docs/memory/observational-memory) (OM) extracts per-user facts into a background log without burning the agent's tool budget. The default Observer model reads `<turn>` tags natively and produces named attribution like `Alice stated her favorite color is teal.` and `Bob asked for QA sign-off before publish.`
|
|
141
141
|
|
|
@@ -393,6 +393,33 @@ const response = await agent.generate('What do you know about me?', {
|
|
|
393
393
|
})
|
|
394
394
|
```
|
|
395
395
|
|
|
396
|
+
## Opt in to state signals (experimental)
|
|
397
|
+
|
|
398
|
+
By default, working memory reaches the model as part of the system message. You can opt into delivering it as a [state signal](https://mastra.ai/docs/agents/signals) instead by setting `useStateSignals: true`:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
const memory = new Memory({
|
|
402
|
+
storage: new LibSQLStore({ url: 'file:./mastra.db' }),
|
|
403
|
+
options: {
|
|
404
|
+
workingMemory: {
|
|
405
|
+
enabled: true,
|
|
406
|
+
template: '# User\n- name:\n- location:',
|
|
407
|
+
useStateSignals: true, // experimental: deliver as state signal
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
})
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
What changes:
|
|
414
|
+
|
|
415
|
+
- **Storage is identical.** The same resource/thread `workingMemory` field is read and written.
|
|
416
|
+
- **The tool is the same shape, exposed under a new name.** Writes still flow through the same underlying tool; on this path it is registered as `setWorkingMemory` (instead of `updateWorkingMemory`). The rename keeps legacy strip filters from removing tool-call parts so they persist as a normal audit trail and the next model step picks the new value up automatically.
|
|
417
|
+
- **Delivery only.** Instead of folding into the system prompt, `Memory` auto-attaches a `WorkingMemoryStateProcessor` that emits the current working memory as a `state` signal with `stateId: 'working-memory'`.
|
|
418
|
+
|
|
419
|
+
You inherit the standard state-signal benefits: thread-scoped tracking metadata, `cacheKey` dedup so identical snapshots are only emitted once, and `contextWindow.hasSnapshot` re-injection when an older snapshot rolls out of the window.
|
|
420
|
+
|
|
421
|
+
The default (`useStateSignals: false`) keeps the existing system-message behavior unchanged. `useStateSignals` is not supported with template working memory `version: 'vnext'`.
|
|
422
|
+
|
|
396
423
|
## Examples
|
|
397
424
|
|
|
398
425
|
- [Working memory with template](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-template)
|
|
@@ -78,7 +78,7 @@ The `@mastra/client-js` SDK wraps the same routes as `mastraClient.getMetricAggr
|
|
|
78
78
|
```bash
|
|
79
79
|
mastra api metric aggregate \
|
|
80
80
|
'{"name":["mastra_agent_duration_ms"],"aggregation":"avg"}' \
|
|
81
|
-
--url http://localhost:4111
|
|
81
|
+
--url http://localhost:4111
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
By default the CLI targets hosted Mastra observability (`https://observability.mastra.ai`). Pass `--url http://localhost:4111` to query a local `mastra dev` server. See [`mastra api metric aggregate`](https://mastra.ai/reference/cli/mastra) and the surrounding entries for the full command list.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# PubSub
|
|
2
|
+
|
|
3
|
+
Mastra uses a publish/subscribe (pub/sub) system as its internal event bus. Components publish events to named topics, and other components subscribe to those topics to react. The backend you configure decides how far those events travel: within one process, across processes on one host, or across separate instances.
|
|
4
|
+
|
|
5
|
+
You set the backend once on the `Mastra` instance, and the rest of the system uses it without changes. By default, Mastra uses an in-process backend that needs no setup.
|
|
6
|
+
|
|
7
|
+
## How Mastra uses PubSub
|
|
8
|
+
|
|
9
|
+
Several built-in systems publish and subscribe to events through the same pub/sub bus:
|
|
10
|
+
|
|
11
|
+
- **Workflow execution**: The scheduler publishes a `workflow.start` event, and a long-lived worker consumes it to run the workflow. Step and lifecycle events flow over pub/sub during execution.
|
|
12
|
+
- **Scheduled workflows**: The scheduler dispatches due runs by publishing to the workflow topic. See [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows).
|
|
13
|
+
- **Background tasks**: A task manager dispatches work to a worker group and fans task lifecycle updates out to subscribers, which is how background task streams stay live. See [Background task streaming](https://mastra.ai/docs/streaming/background-task-streaming).
|
|
14
|
+
- **Agent signals**: Sending a signal to an active agent run publishes an event on a thread topic, so a run executing in another process receives the signal.
|
|
15
|
+
- **Resumable streams**: Stream chunks are published per run, so a client that reconnects can replay what it missed.
|
|
16
|
+
|
|
17
|
+
Because these systems run on one bus, the backend you choose applies to all of them at once.
|
|
18
|
+
|
|
19
|
+
## Delivery modes
|
|
20
|
+
|
|
21
|
+
Backends deliver events in one of two modes, defined by the [`PubSub`](https://mastra.ai/reference/pubsub/base) contract:
|
|
22
|
+
|
|
23
|
+
- **Pull**: Consumers read from the backend on their own, which Mastra does with a long-lived worker loop. Distributed backends such as [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) use this mode.
|
|
24
|
+
- **Push**: Events arrive without the consumer asking, either in process or over HTTP. The default [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter) delivers this way in process.
|
|
25
|
+
|
|
26
|
+
Subscribers can also opt into work distribution. A group of subscribers that share a consumer group split the events between them, so each event is handled once. Subscribers without a group each receive every event, which fans the stream out to all of them.
|
|
27
|
+
|
|
28
|
+
## Default backend
|
|
29
|
+
|
|
30
|
+
When you do not set the `pubsub` option, Mastra uses [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). It delivers events in process using a Node.js [`EventEmitter`](https://nodejs.org/api/events.html#class-eventemitter), so it works without any external service.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { Mastra } from '@mastra/core'
|
|
34
|
+
|
|
35
|
+
// No pubsub option: Mastra uses EventEmitterPubSub
|
|
36
|
+
export const mastra = new Mastra({})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Because it runs in process, events are not persisted and do not reach other processes. The default suits a single instance, which covers most applications.
|
|
40
|
+
|
|
41
|
+
## Choosing a backend
|
|
42
|
+
|
|
43
|
+
Set the `pubsub` option on the `Mastra` instance to choose a backend. Each backend implements the same [`PubSub`](https://mastra.ai/reference/pubsub/base) contract, so the rest of your application does not change.
|
|
44
|
+
|
|
45
|
+
The deciding question is where the subscriber runs.
|
|
46
|
+
|
|
47
|
+
| Backend | Scope | Mode | Package |
|
|
48
|
+
| ----------------------------------------------------------------------------- | ---------------------------- | ------------- | ----------------------------- |
|
|
49
|
+
| [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter) | Single process | Pull and push | `@mastra/core` |
|
|
50
|
+
| [`UnixSocketPubSub`](https://mastra.ai/reference/pubsub/unix-socket-pubsub) | Multiple processes, one host | Push | `@mastra/core` |
|
|
51
|
+
| [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) | Distributed, multiple hosts | Pull | `@mastra/redis-streams` |
|
|
52
|
+
| [`GoogleCloudPubSub`](https://mastra.ai/reference/pubsub/google-cloud-pubsub) | Distributed, multiple hosts | Pull | `@mastra/google-cloud-pubsub` |
|
|
53
|
+
|
|
54
|
+
### Multiple processes on one host
|
|
55
|
+
|
|
56
|
+
Use [`UnixSocketPubSub`](https://mastra.ai/reference/pubsub/unix-socket-pubsub) when several processes on the same machine need to share a stream. It delivers events over a Unix domain socket and elects one process as a broker. If the broker exits, the remaining processes elect a new one.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Mastra } from '@mastra/core'
|
|
60
|
+
import { UnixSocketPubSub } from '@mastra/core/events'
|
|
61
|
+
|
|
62
|
+
export const mastra = new Mastra({
|
|
63
|
+
pubsub: new UnixSocketPubSub('/tmp/mastra/events.sock'),
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Distributed deployments
|
|
68
|
+
|
|
69
|
+
Use a distributed backend when you run more than one instance or host, so every instance receives the same events. This matters whenever a request handled by one instance must reach work running on another. For example, sending a signal to an agent run requires the signal event to cross the process boundary to the instance that owns the run. With the in-process default, that instance never receives the event.
|
|
70
|
+
|
|
71
|
+
Both backends below deliver across processes and hosts and persist events for redelivery.
|
|
72
|
+
|
|
73
|
+
The following example uses [Redis Streams](https://redis.io/docs/latest/develop/data-types/streams/):
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { Mastra } from '@mastra/core'
|
|
77
|
+
import { RedisStreamsPubSub } from '@mastra/redis-streams'
|
|
78
|
+
|
|
79
|
+
export const mastra = new Mastra({
|
|
80
|
+
pubsub: new RedisStreamsPubSub({
|
|
81
|
+
url: 'redis://localhost:6379',
|
|
82
|
+
}),
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The following example uses [Google Cloud Pub/Sub](https://cloud.google.com/pubsub/docs):
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { Mastra } from '@mastra/core'
|
|
90
|
+
import { GoogleCloudPubSub } from '@mastra/google-cloud-pubsub'
|
|
91
|
+
|
|
92
|
+
export const mastra = new Mastra({
|
|
93
|
+
pubsub: new GoogleCloudPubSub({
|
|
94
|
+
projectId: 'my-project',
|
|
95
|
+
}),
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Resumable streams
|
|
100
|
+
|
|
101
|
+
Resumable streams let a client reconnect and replay events it missed, which requires the backend to keep recent history. Distributed backends such as [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) persist events, so they support replay on their own.
|
|
102
|
+
|
|
103
|
+
In-process delivery does not keep history. To add replay on top of [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter), wrap it in [`CachingPubSub`](https://mastra.ai/reference/pubsub/caching-pubsub), which records published events per topic so a late or reconnecting subscriber can catch up before continuing with live events.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { Mastra } from '@mastra/core'
|
|
107
|
+
import { CachingPubSub, EventEmitterPubSub } from '@mastra/core/events'
|
|
108
|
+
import { InMemoryServerCache } from '@mastra/core/cache'
|
|
109
|
+
|
|
110
|
+
const cache = new InMemoryServerCache()
|
|
111
|
+
|
|
112
|
+
export const mastra = new Mastra({
|
|
113
|
+
pubsub: new CachingPubSub(new EventEmitterPubSub(), cache),
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> **Note:** Visit the [PubSub reference](https://mastra.ai/reference/pubsub/base) for the full delivery contract and the configuration options for each backend.
|
|
118
|
+
|
|
119
|
+
## Related
|
|
120
|
+
|
|
121
|
+
- [PubSub reference](https://mastra.ai/reference/pubsub/base)
|
|
122
|
+
- [Mastra class](https://mastra.ai/reference/core/mastra-class)
|
|
123
|
+
- [Background task streaming](https://mastra.ai/docs/streaming/background-task-streaming)
|
|
124
|
+
- [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows)
|
|
@@ -46,6 +46,26 @@ Setting [`server.auth`](https://mastra.ai/reference/configuration) does two thin
|
|
|
46
46
|
|
|
47
47
|
Studio detects available capabilities by calling the `GET /api/auth/capabilities` endpoint. The response tells Studio which login methods to render and, if the user is already authenticated, includes their user info and permissions.
|
|
48
48
|
|
|
49
|
+
## Pass a token through the URL
|
|
50
|
+
|
|
51
|
+
When another application embeds or links to Studio, it can hand over an authorization token through the `auth_header` URL parameter. This is useful when an external host already holds a token and wants to open an authenticated Studio session without showing the login screen.
|
|
52
|
+
|
|
53
|
+
The `auth_header` value always populates the `Authorization` request header. The parameter sets that one header only, so include any scheme prefix the server expects in the value, such as `Bearer`.
|
|
54
|
+
|
|
55
|
+
Open Studio with the token in the query string:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
https://your-studio-host/?auth_header=Bearer%20your-token
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Studio handles the token as follows:
|
|
62
|
+
|
|
63
|
+
- It reads `auth_header` once on load and sends the value as the `Authorization` header on every API request in that session.
|
|
64
|
+
- It removes `auth_header` from the address bar while preserving other query parameters and the hash.
|
|
65
|
+
- It keeps the token in memory only and never writes it to local storage, so the token stays transient and does not persist across page reloads.
|
|
66
|
+
|
|
67
|
+
The token rides in a URL parameter, so the host application is responsible for how that URL is generated and transmitted. URL parameters can be exposed through browser history, referrer headers, and server access logs.
|
|
68
|
+
|
|
49
69
|
## Role-based access control
|
|
50
70
|
|
|
51
71
|
RBAC lets you control what each user can see and do inside Studio. It's separate from authentication: `server.auth` handles who the user is, while `server.rbac` handles what they can do.
|