@mastra/mcp-docs-server 1.1.45 → 1.1.46-alpha.0

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.
Files changed (60) hide show
  1. package/.docs/docs/agents/code-mode.md +2 -0
  2. package/.docs/docs/agents/signal-providers.md +222 -0
  3. package/.docs/docs/agents/signals.md +63 -189
  4. package/.docs/docs/getting-started/build-with-ai.md +2 -2
  5. package/.docs/docs/mastra-platform/configuration.md +1 -1
  6. package/.docs/docs/mastra-platform/overview.md +1 -1
  7. package/.docs/docs/observability/config.md +139 -0
  8. package/.docs/docs/observability/{tracing → integrations}/bridges/datadog.md +7 -7
  9. package/.docs/docs/observability/{tracing → integrations}/bridges/otel.md +3 -3
  10. package/.docs/docs/observability/{tracing → integrations}/exporters/datadog.md +1 -1
  11. package/.docs/docs/observability/{tracing → integrations}/exporters/mastra-platform.md +1 -1
  12. package/.docs/docs/observability/{tracing → integrations}/exporters/mastra-storage.md +1 -1
  13. package/.docs/docs/observability/{tracing → integrations}/exporters/otel.md +4 -4
  14. package/.docs/docs/observability/{tracing → integrations}/exporters/posthog.md +16 -0
  15. package/.docs/docs/observability/integrations/overview.md +45 -0
  16. package/.docs/docs/observability/metrics/overview.md +1 -1
  17. package/.docs/docs/observability/metrics/querying.md +18 -0
  18. package/.docs/docs/observability/overview.md +8 -4
  19. package/.docs/docs/observability/storage.md +79 -0
  20. package/.docs/docs/observability/tracing/overview.md +98 -390
  21. package/.docs/guides/guide/signal-provider.md +217 -0
  22. package/.docs/guides/migrations/upgrade-to-v1/tracing.md +11 -11
  23. package/.docs/reference/agents/agent.md +150 -2
  24. package/.docs/reference/client-js/agents.md +4 -0
  25. package/.docs/reference/core/mastra-class.md +28 -0
  26. package/.docs/reference/harness/harness-class.md +1 -1
  27. package/.docs/reference/index.md +3 -0
  28. package/.docs/reference/observability/tracing/bridges/datadog.md +2 -2
  29. package/.docs/reference/observability/tracing/bridges/otel.md +2 -2
  30. package/.docs/reference/observability/tracing/configuration.md +1 -1
  31. package/.docs/reference/observability/tracing/exporters/arize.md +1 -1
  32. package/.docs/reference/observability/tracing/exporters/arthur.md +1 -1
  33. package/.docs/reference/observability/tracing/exporters/cloud-exporter.md +1 -1
  34. package/.docs/reference/observability/tracing/exporters/console-exporter.md +1 -1
  35. package/.docs/reference/observability/tracing/exporters/default-exporter.md +1 -1
  36. package/.docs/reference/observability/tracing/exporters/mastra-platform-exporter.md +1 -1
  37. package/.docs/reference/observability/tracing/exporters/mastra-storage-exporter.md +1 -1
  38. package/.docs/reference/observability/tracing/exporters/otel.md +2 -2
  39. package/.docs/reference/observability/tracing/span-filtering.md +1 -1
  40. package/.docs/reference/pubsub/base.md +24 -0
  41. package/.docs/reference/pubsub/caching-pubsub.md +6 -0
  42. package/.docs/reference/pubsub/event-emitter.md +36 -1
  43. package/.docs/reference/signals/create-notification-inbox-tool.md +67 -0
  44. package/.docs/reference/signals/signal-provider.md +406 -0
  45. package/.docs/reference/signals/webhook-signal-provider.md +137 -0
  46. package/.docs/reference/storage/clickhouse.md +3 -3
  47. package/.docs/reference/storage/composite.md +1 -1
  48. package/.docs/reference/storage/duckdb.md +1 -1
  49. package/.docs/reference/storage/libsql.md +1 -1
  50. package/.docs/reference/storage/postgresql.md +1 -1
  51. package/CHANGELOG.md +8 -0
  52. package/package.json +7 -7
  53. /package/.docs/docs/observability/{tracing → integrations}/exporters/arize.md +0 -0
  54. /package/.docs/docs/observability/{tracing → integrations}/exporters/arthur.md +0 -0
  55. /package/.docs/docs/observability/{tracing → integrations}/exporters/braintrust.md +0 -0
  56. /package/.docs/docs/observability/{tracing → integrations}/exporters/laminar.md +0 -0
  57. /package/.docs/docs/observability/{tracing → integrations}/exporters/langfuse.md +0 -0
  58. /package/.docs/docs/observability/{tracing → integrations}/exporters/langsmith.md +0 -0
  59. /package/.docs/docs/observability/{tracing → integrations}/exporters/sentry.md +0 -0
  60. /package/.docs/docs/observability/{tracing → integrations}/processors/sensitive-data-filter.md +0 -0
@@ -1,5 +1,7 @@
1
1
  # Code mode
2
2
 
3
+ **Added in:** `@mastra/core@1.38.0`
4
+
3
5
  > **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
4
6
 
5
7
  Code mode gives an agent a single tool that runs a short TypeScript program in a sandbox. Instead of calling tools one at a time, the model writes a program that orchestrates your existing tools as `external_*` functions, batching calls with `Promise.all`, aggregating with `reduce`, branching, and doing math in a real runtime, then returns a single result.
@@ -0,0 +1,222 @@
1
+ # Signal providers
2
+
3
+ **Added in:** `@mastra/core@1.39.0`
4
+
5
+ > **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
6
+
7
+ A signal provider monitors an external source, such as GitHub, Slack, continuous integration (CI), or your own API, and pushes [notification signals](https://mastra.ai/docs/agents/signals) into subscribed agent threads.
8
+
9
+ ## When to use a signal provider
10
+
11
+ Use a signal provider when an external system produces events that an agent should react to, and you want Mastra to manage the subscription bookkeeping for you.
12
+
13
+ - The source emits events tied to a resource a thread cares about, such as a pull request, a channel, or a build.
14
+ - You want one place that tracks which threads watch which external resources.
15
+ - You want to receive events by polling, by webhook, or both.
16
+
17
+ If you only need to push a one-off event into a thread, call [`agent.sendNotificationSignal()`](https://mastra.ai/reference/agents/agent) directly instead.
18
+
19
+ ## How signal providers work
20
+
21
+ A signal provider is the producing side of the [signals](https://mastra.ai/docs/agents/signals) system. It brings external events into a thread, while the signal APIs control how the thread consumes them.
22
+
23
+ A signal provider combines three capabilities:
24
+
25
+ - **Subscription tracking:** The `SignalProvider` base class keeps an in-memory registry that maps each agent thread to the external resources it watches.
26
+ - **Ingestion:** You override `poll()` for pull-based sources or `handleWebhook()` for push-based sources.
27
+ - **Delivery:** When an event matches a subscription, call the protected `notify()` helper to forward a notification signal to the connected agent's thread.
28
+
29
+ Register a provider by passing it to an agent. The agent connects the provider, starts polling if a `pollInterval` is set, and merges any processors or tools the provider exposes.
30
+
31
+ ```typescript
32
+ import { Agent } from '@mastra/core/agent'
33
+ import { CiSignals } from '../signals/ci-signals'
34
+
35
+ export const supportAgent = new Agent({
36
+ id: 'support-agent',
37
+ name: 'Support Agent',
38
+ instructions: 'Help the user triage updates.',
39
+ model: 'openai/gpt-5.5',
40
+ signals: [new CiSignals()],
41
+ })
42
+ ```
43
+
44
+ > **Note:** Notification delivery requires a storage adapter with notification support, such as [libSQL](https://mastra.ai/reference/storage/libsql), [PostgreSQL](https://mastra.ai/reference/storage/postgresql), or [MongoDB](https://mastra.ai/reference/storage/mongodb). Configure storage on the Mastra instance so `notify()` can store notification records.
45
+
46
+ ## Quickstart
47
+
48
+ The following example demonstrates a polling provider that watches CI pipelines and emits a notification when a subscribed pipeline fails.
49
+
50
+ ```typescript
51
+ import { SignalProvider } from '@mastra/core/signals'
52
+ import type { SignalProviderTarget, SignalSubscription } from '@mastra/core/signals'
53
+
54
+ type BuildStatus = {
55
+ id: string
56
+ status: 'passed' | 'failed'
57
+ }
58
+
59
+ const builds = new Map<string, BuildStatus>([
60
+ ['acme-app-main', { id: 'build_123', status: 'failed' }],
61
+ ])
62
+
63
+ async function fetchBuildStatus(pipeline: string): Promise<BuildStatus> {
64
+ return builds.get(pipeline) ?? { id: 'build_unknown', status: 'passed' }
65
+ }
66
+
67
+ export class CiSignals extends SignalProvider<'ci-signals'> {
68
+ readonly id = 'ci-signals' as const
69
+ readonly pollInterval = 30_000
70
+
71
+ watch(target: SignalProviderTarget, pipeline: string) {
72
+ return this.subscribe(target, pipeline)
73
+ }
74
+
75
+ unwatch(target: SignalProviderTarget, pipeline: string) {
76
+ return this.unsubscribe(target, pipeline)
77
+ }
78
+
79
+ async poll(subscriptions: SignalSubscription[]) {
80
+ for (const sub of subscriptions) {
81
+ const build = await fetchBuildStatus(sub.externalResourceId)
82
+ if (build.status !== 'failed') continue
83
+
84
+ await this.notify(
85
+ {
86
+ source: this.id,
87
+ kind: 'ci-status',
88
+ priority: 'high',
89
+ summary: `Build failed for ${sub.externalResourceId}`,
90
+ payload: build,
91
+ dedupeKey: `${this.id}:${sub.externalResourceId}:${build.id}`,
92
+ },
93
+ { resourceId: sub.resourceId, threadId: sub.threadId },
94
+ )
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ Register the provider with an agent and subscribe a thread to the pipeline you want to watch.
101
+
102
+ ```typescript
103
+ import { Agent } from '@mastra/core/agent'
104
+ import { CiSignals } from '../signals/ci-signals'
105
+
106
+ export const ciSignals = new CiSignals()
107
+
108
+ export const supportAgent = new Agent({
109
+ id: 'support-agent',
110
+ name: 'Support Agent',
111
+ instructions: 'Help the user triage CI updates.',
112
+ model: 'openai/gpt-5.5',
113
+ signals: [ciSignals],
114
+ })
115
+
116
+ ciSignals.watch({ resourceId: 'user_123', threadId: 'thread_456' }, 'acme-app-main')
117
+ ```
118
+
119
+ Mastra calls `poll()` on the `pollInterval` with all active subscriptions. It skips a cycle when there are no subscriptions and doesn't overlap cycles, so a slow `poll()` doesn't run concurrently with itself.
120
+
121
+ > **Note:** For a complete polling-provider build with notification storage, agent registration, thread subscription, and testing, follow [Building a signal provider](https://mastra.ai/guides/guide/signal-provider).
122
+
123
+ ## Polling and webhook providers
124
+
125
+ Use polling when the external source doesn't push events to your app. Set `pollInterval` and override `poll(subscriptions)`. Each subscription includes the thread target and the external resource id to inspect.
126
+
127
+ Use webhooks when the external source can call your app. Override `handleWebhook(request)`, parse the payload, find matching subscriptions, and call `notify()` for each match.
128
+
129
+ ```typescript
130
+ import { SignalProvider } from '@mastra/core/signals'
131
+ import type { SignalProviderWebhookRequest } from '@mastra/core/signals'
132
+
133
+ export class CiSignals extends SignalProvider<'ci-signals'> {
134
+ readonly id = 'ci-signals' as const
135
+
136
+ async handleWebhook(request: SignalProviderWebhookRequest) {
137
+ const payload = request.body as { pipeline: string; status: string }
138
+ const subscriptions = this.getSubscriptionsForResource(payload.pipeline)
139
+
140
+ for (const sub of subscriptions) {
141
+ await this.notify(
142
+ {
143
+ source: this.id,
144
+ kind: 'ci-status',
145
+ priority: 'high',
146
+ summary: `Build ${payload.status} for ${payload.pipeline}`,
147
+ payload,
148
+ },
149
+ { resourceId: sub.resourceId, threadId: sub.threadId },
150
+ )
151
+ }
152
+
153
+ return { status: 200, body: { matched: subscriptions.length } }
154
+ }
155
+ }
156
+ ```
157
+
158
+ `handleWebhook()` is a provider method, not an auto-mounted HTTP route. Invoke it from your own endpoint, passing the request body, headers, and any route params.
159
+
160
+ > **Note:** Visit [`SignalProvider` reference](https://mastra.ai/reference/signals/signal-provider) for subscription, polling, lifecycle, and `notify()` details. For the complete notification payload shape, including deduplication and coalescing fields, visit [`Agent.sendNotificationSignal()` reference](https://mastra.ai/reference/agents/agent).
161
+
162
+ ## Built-in webhook provider
163
+
164
+ For generic webhook sources, use [`WebhookSignalProvider`](https://mastra.ai/reference/signals/webhook-signal-provider) instead of writing a subclass. Configure it with a function that extracts a resource id from the payload, and an optional function that builds the notification.
165
+
166
+ ```typescript
167
+ import { Agent } from '@mastra/core/agent'
168
+ import { WebhookSignalProvider } from '@mastra/core/signals'
169
+
170
+ const webhooks = new WebhookSignalProvider({
171
+ extractResourceId: payload => (payload as { repository: string }).repository,
172
+ buildNotification: (payload, sub) => ({
173
+ source: 'ci',
174
+ kind: 'build-status',
175
+ priority: 'medium',
176
+ summary: `Build ${(payload as { status: string }).status} for ${sub.externalResourceId}`,
177
+ }),
178
+ })
179
+
180
+ export const supportAgent = new Agent({
181
+ id: 'support-agent',
182
+ name: 'Support Agent',
183
+ instructions: 'Help the user triage updates.',
184
+ model: 'openai/gpt-5.5',
185
+ signals: [webhooks],
186
+ })
187
+
188
+ webhooks.subscribeThread({ resourceId: 'user_123', threadId: 'thread_456' }, 'acme/app')
189
+ ```
190
+
191
+ When a webhook arrives, call `webhooks.handleWebhook({ body, headers })` from your route. The provider matches the extracted resource id against its subscriptions and notifies each matching thread.
192
+
193
+ ## Advanced provider capabilities
194
+
195
+ A provider can support more than event ingestion. Add only the capabilities your source needs.
196
+
197
+ - **Durable subscriptions:** The base registry is in-memory and per-process. Persist subscriptions yourself when they must survive a restart, then rehydrate them in [`start()`](https://mastra.ai/reference/signals/signal-provider).
198
+ - **Lifecycle hooks:** Override [`start()`](https://mastra.ai/reference/signals/signal-provider) for async setup and [`stop()`](https://mastra.ai/reference/signals/signal-provider) for cleanup. Call `super.stop()` when overriding `stop()` so the base provider can stop polling and clear its registry.
199
+ - **Processors and tools:** Return processors from [`getInputProcessors()`](https://mastra.ai/reference/signals/signal-provider) or [`getOutputProcessors()`](https://mastra.ai/reference/signals/signal-provider), and return agent-callable tools from [`getTools()`](https://mastra.ai/reference/signals/signal-provider).
200
+
201
+ The `@mastra/github-signals` package is a production signal provider that watches GitHub pull requests and notifies threads about comments, review state, continuous integration status, and merges. Use it as a reference for polling, durable subscriptions, tools, processors, and lifecycle hooks.
202
+
203
+ ```typescript
204
+ import { Agent } from '@mastra/core/agent'
205
+ import { GithubSignals } from '@mastra/github-signals'
206
+
207
+ export const devAgent = new Agent({
208
+ id: 'dev-agent',
209
+ name: 'Dev Agent',
210
+ instructions: 'Help triage pull request activity.',
211
+ model: 'openai/gpt-5.5',
212
+ signals: [new GithubSignals()],
213
+ })
214
+ ```
215
+
216
+ ## Related
217
+
218
+ - [Guide: Building a signal provider](https://mastra.ai/guides/guide/signal-provider)
219
+ - [Signals](https://mastra.ai/docs/agents/signals)
220
+ - [Notification signals](https://mastra.ai/docs/agents/signals)
221
+ - [`SignalProvider` reference](https://mastra.ai/reference/signals/signal-provider)
222
+ - [`WebhookSignalProvider` reference](https://mastra.ai/reference/signals/webhook-signal-provider)
@@ -1,25 +1,41 @@
1
1
  # Signals
2
2
 
3
+ **Added in:** `@mastra/core@1.39.0`
4
+
3
5
  > **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
4
6
 
5
7
  Signals are a way to interact with an agent through a thread. Instead of starting every interaction with `agent.stream()`, subscribe to a thread and send messages or signals. Mastra either wakes the agent when the thread is idle, drops input into the running agent loop, or queues input for the next turn.
6
8
 
7
9
  Use message APIs for user-authored input. Use `sendSignal()` for lower-level system context, such as background task notifications, policy reminders, or processor-generated context.
8
10
 
11
+ ## When to use signals
12
+
13
+ Use signals when an agent thread needs new input or context outside the original `stream()` call. Signals are useful when users send follow-up messages while a run is active, when background systems need to add context to a thread, or when external events should wake, update, or notify the agent.
14
+
15
+ Use `sendMessage()` and `queueMessage()` for user-authored input. Use `sendSignal()` for lower-level system context. Use `sendStateSignal()` for durable state lanes, and use `sendNotificationSignal()` when an external event should create a durable notification inbox record.
16
+
9
17
  ## Quickstart
10
18
 
11
- Subscribe to the thread before sending messages. The subscription receives the active stream when the message wakes the agent or enters a running loop.
19
+ Create an agent, subscribe to a thread, then send a message to that thread. The subscription receives the active stream when the message wakes the agent or enters a running loop.
12
20
 
13
21
  ```typescript
14
- const subscription = await agent.subscribeToThread({
15
- resourceId: 'user_123',
16
- threadId: 'thread_456',
22
+ import { Agent } from '@mastra/core/agent'
23
+
24
+ const agent = new Agent({
25
+ id: 'support-agent',
26
+ name: 'Support Agent',
27
+ instructions: 'Help the user compare options.',
28
+ model: 'openai/gpt-5.5',
17
29
  })
18
30
 
19
- agent.sendMessage('Compare that with the previous option.', {
31
+ const thread = {
20
32
  resourceId: 'user_123',
21
33
  threadId: 'thread_456',
22
- })
34
+ }
35
+
36
+ const subscription = await agent.subscribeToThread(thread)
37
+
38
+ await agent.sendMessage('Compare that with the previous option.', thread)
23
39
 
24
40
  for await (const chunk of subscription.stream) {
25
41
  console.log(chunk)
@@ -28,7 +44,9 @@ for await (const chunk of subscription.stream) {
28
44
 
29
45
  When the thread has a running agent stream, `sendMessage()` becomes new input inside that agent loop. When the thread is idle, Mastra starts a stream with the message as the first input.
30
46
 
31
- ## Send a message now
47
+ ## Message input
48
+
49
+ ### Send a message now
32
50
 
33
51
  Use `sendMessage()` when the user expects the active agent to see the message immediately.
34
52
 
@@ -53,7 +71,7 @@ The model receives attributed messages as XML-wrapped user input:
53
71
 
54
72
  Messages without attributes are sent as plain user input.
55
73
 
56
- ## Queue a message for the next turn
74
+ ### Queue a message for the next turn
57
75
 
58
76
  Use `queueMessage()` when a user sends a follow-up but the active model call should finish first. Mastra waits for the active run to complete, then starts a new run on the same thread.
59
77
 
@@ -66,7 +84,9 @@ agent.queueMessage('Also check whether the tests need updates.', {
66
84
 
67
85
  When the thread is idle, `queueMessage()` starts a run immediately. When the thread is active, it preserves turn order by starting a new run after the active run completes.
68
86
 
69
- ## Control low-level signal behavior
87
+ ## Signal context
88
+
89
+ ### Control low-level signal behavior
70
90
 
71
91
  Use `sendSignal()` when you need to send system-generated context instead of user-authored input. For external events, use `type: 'notification'`. By default, Mastra delivers signals to active runs and wakes idle threads. Use `ifActive.behavior` and `ifIdle.behavior` to change that behavior.
72
92
 
@@ -88,31 +108,11 @@ const result = agent.sendSignal(
88
108
  await result.persisted
89
109
  ```
90
110
 
91
- The behavior options are:
111
+ Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context.
92
112
 
93
- - `ifActive.behavior: 'deliver'`: Add the signal or message to the running agent loop. This is the default.
94
- - `ifActive.behavior: 'persist'`: Save the signal or message to memory without adding it to the running loop.
95
- - `ifActive.behavior: 'discard'`: Ignore the signal or message while the thread is active.
96
- - `ifIdle.behavior: 'wake'`: Start a stream with the signal or message as the first input. This is the default.
97
- - `ifIdle.behavior: 'persist'`: Save the signal or message to memory without starting a stream.
98
- - `ifIdle.behavior: 'discard'`: Ignore the signal or message while the thread is idle.
99
-
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
-
102
- ```typescript
103
- agent.sendMessage('Continue with the next step.', {
104
- resourceId: 'user_123',
105
- threadId: 'thread_456',
106
- ifIdle: {
107
- behavior: 'wake',
108
- streamOptions: {
109
- maxSteps: 3,
110
- },
111
- },
112
- })
113
- ```
113
+ > **Note:** Visit [`Agent.sendSignal()` reference](https://mastra.ai/reference/agents/agent) for `ifActive`, `ifIdle`, branch attributes, and `streamOptions`.
114
114
 
115
- ## Send notification context
115
+ ### Send notification context
116
116
 
117
117
  Signals have a semantic `type` and an LLM-facing `tagName`. Use `type` to describe the signal category. Use `tagName` to control the XML tag the model sees.
118
118
 
@@ -143,11 +143,11 @@ 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
146
+ #### Storage support
147
147
 
148
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
149
 
150
- ## Send processor context
150
+ ### Send processor context
151
151
 
152
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.
153
153
 
@@ -193,50 +193,19 @@ Reactive signals default to `tagName: 'system-reminder'`, so the model receives
193
193
 
194
194
  Awaiting `sendSignal()` preserves stream echo ordering when a subscribed thread is active.
195
195
 
196
- ## Conditional attributes
197
-
198
- Use `ifActive.attributes` and `ifIdle.attributes` to tag input with context that depends on whether the agent is active or idle at delivery time. Mastra resolves the correct branch when the input is accepted.
199
-
200
- ```typescript
201
- agent.sendMessage(
202
- {
203
- contents: 'Also cover the edge cases.',
204
- attributes: { source: 'chat' },
205
- },
206
- {
207
- resourceId: 'user_123',
208
- threadId: 'thread_456',
209
- ifActive: { attributes: { delivery: 'while-active' } },
210
- ifIdle: { attributes: { delivery: 'new-message' } },
211
- },
212
- )
213
- ```
214
-
215
- When the agent is working, the model sees:
196
+ ### Conditional attributes
216
197
 
217
- ```xml
218
- <user source="chat" delivery="while-active">Also cover the edge cases.</user>
219
- ```
220
-
221
- When the agent is idle:
198
+ Use `ifActive.attributes` and `ifIdle.attributes` to tag input with context that depends on whether the agent is active or idle at delivery time. Top-level `attributes` always apply, and Mastra merges the selected branch's `attributes` into them when the input is accepted.
222
199
 
223
- ```xml
224
- <user source="chat" delivery="new-message">Also cover the edge cases.</user>
225
- ```
200
+ > **Note:** Visit [`Agent.sendMessage()` reference](https://mastra.ai/reference/agents/agent) and [`Agent.sendSignal()` reference](https://mastra.ai/reference/agents/agent) for branch-specific attributes.
226
201
 
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.
202
+ ## State and notification signals
228
203
 
229
- ## State signals
204
+ ### State signals
230
205
 
231
206
  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
207
 
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.
208
+ Use `sendStateSignal()` when an external producer detects a state change. Each state signal identifies a state lane, a producer-owned cache key, and whether the update is a snapshot or delta.
240
209
 
241
210
  ```typescript
242
211
  await agent.sendStateSignal(
@@ -258,16 +227,9 @@ await agent.sendStateSignal(
258
227
  )
259
228
  ```
260
229
 
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:
230
+ When Mastra accepts a state signal, it stores compact tracking metadata on the thread. If a producer sends the same `cacheKey` and mode again while that state is still current, Mastra skips the duplicate.
264
231
 
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.
232
+ Use `computeStateSignal()` when a processor owns a state lane. Mastra calls it once per model input step after `processInputStep()`. Visit [`Agent.sendStateSignal()` reference](https://mastra.ai/reference/agents/agent) for state signal fields and return values.
271
233
 
272
234
  ```typescript
273
235
  import type { ComputeStateSignalArgs, Processor } from '@mastra/core/processors'
@@ -304,31 +266,15 @@ Mastra passes `lastSnapshot` and `deltasSinceSnapshot` into `computeStateSignal(
304
266
 
305
267
  The built-in browser context processor emits state under the `browser` id with snapshot and delta modes.
306
268
 
307
- ## Notification signals
269
+ ### Notification signals
308
270
 
309
271
  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
272
 
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:
273
+ Notification delivery has two phases. During ingress, `agent.sendNotificationSignal()` stores a notification record and resolves the agent's delivery policy. During dispatch, Mastra consumes due records and emits full notification or summary signals.
317
274
 
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.
275
+ The default delivery policy is priority-aware. Urgent notifications deliver immediately, while lower-priority notifications may be batched into summaries or wait until the thread is idle.
323
276
 
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 |
277
+ > **Note:** Visit [`Agent.sendNotificationSignal()` reference](https://mastra.ai/reference/agents/agent) for notification fields, [`Agent` constructor reference](https://mastra.ai/reference/agents/agent) for `notifications.deliveryPolicy` configuration, and [`createNotificationInboxTool()` reference](https://mastra.ai/reference/signals/create-notification-inbox-tool) for inbox tool actions.
332
278
 
333
279
  ```typescript
334
280
  await agent.sendNotificationSignal(
@@ -364,86 +310,21 @@ Notification summaries tell the model that inbox records are waiting:
364
310
 
365
311
  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
312
 
367
- Configure a delivery policy on the agent when some notifications should wait for a different dispatch window or summary rollup.
313
+ Configure a delivery policy on the agent when some notifications should wait for a different dispatch window or summary rollup. Enable scheduled dispatch at the Mastra level when deferred notifications and summary rollups should be delivered automatically.
368
314
 
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
- ```
315
+ > **Note:** Visit [`Agent` constructor reference](https://mastra.ai/reference/agents/agent) for `notifications.deliveryPolicy` and [`Mastra` class reference](https://mastra.ai/reference/core/mastra-class) for runtime notification dispatch configuration.
392
316
 
393
- Enable scheduled dispatch at the Mastra level so deferred notifications and summary rollups are delivered through the existing workflow scheduler.
317
+ #### Notification inbox tool
394
318
 
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
- ```
319
+ Use `createNotificationInboxTool()` to give agents one tool for inbox actions instead of many CRUD tools. Use `read` after a `<notification-summary>` signal when the agent needs the full records behind the summary. The notification contents are delivered as signals, not as normal tool output.
408
320
 
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.
321
+ > **Note:** Visit [`createNotificationInboxTool()` reference](https://mastra.ai/reference/signals/create-notification-inbox-tool) for the setup example, input schema, and action behavior.
410
322
 
411
- ### Notification inbox tool
323
+ `sendNotificationSignal()` requires a storage domain with `notifications` support. Use `sendSignal({ type: 'notification' })` only for lower-level notification-shaped context that should bypass inbox storage.
412
324
 
413
- Use `createNotificationInboxTool()` to give agents one tool for inbox actions instead of many CRUD tools.
325
+ ## Compatibility and APIs
414
326
 
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.
445
-
446
- ## Compatibility
327
+ ### Compatibility
447
328
 
448
329
  Mastra still accepts legacy signal payloads such as `type: 'user-message'` and `type: 'system-reminder'`. It normalizes them internally to the new category and tag shape:
449
330
 
@@ -454,26 +335,17 @@ Existing stored signal rows and older clients continue to load through the compa
454
335
 
455
336
  > **Note:** Visit [Agent signals reference](https://mastra.ai/reference/agents/agent) for the full message, signal, and subscription types.
456
337
 
457
- ## Approve tool calls
458
-
459
- When a subscribed run pauses for tool approval, approve or decline the tool call with the subscription-native methods. The call returns a JSON acknowledgement. The resumed chunks arrive through the existing thread subscription.
338
+ ### Approve tool calls
460
339
 
461
- ```typescript
462
- await agent.sendToolApproval({
463
- resourceId: 'user_123',
464
- threadId: 'thread_456',
465
- toolCallId: 'tool-call_456',
466
- approved: true,
467
- })
468
- ```
340
+ When a subscribed run pauses for tool approval, approve or decline the tool call with the subscription-native methods. The resumed chunks arrive through the existing thread subscription.
469
341
 
470
- Pass `approved: false` to decline the same pending tool call. Use the older `approveToolCall()` and `declineToolCall()` methods only when you are rendering the separate continuation stream directly.
342
+ > **Note:** Visit [`client.getAgent().sendToolApproval()` reference](https://mastra.ai/reference/client-js/agents) and [server agent routes](https://mastra.ai/reference/server/routes) for request and response shapes.
471
343
 
472
- ## Use HTTP routes
344
+ ### Use HTTP routes
473
345
 
474
346
  If you call Mastra over HTTP directly, use `POST /api/agents/:agentId/send-message` for immediate messages and `POST /api/agents/:agentId/queue-message` for next-turn messages. For subscription-native tool approval, use `POST /api/agents/:agentId/send-tool-approval`. See [Server routes reference](https://mastra.ai/reference/server/routes) for request and response schemas.
475
347
 
476
- ## Use the client SDK
348
+ ### Use the client SDK
477
349
 
478
350
  The JavaScript client exposes thread signal APIs. Use `subscribeToThread()` before sending thread input so the client can render the stream that wakes from, or receives, the input.
479
351
 
@@ -499,9 +371,9 @@ await subscription.processDataStream({
499
371
  })
500
372
  ```
501
373
 
502
- Use `reconnect: true` for long-lived subscriptions. The client resubscribes when the stream closes or a reconnect request fails, such as after a proxy idle timeout or a dropped network connection.
374
+ Use `reconnect: true` for long-lived subscriptions. Visit [`client.getAgent().subscribeToThread()` reference](https://mastra.ai/reference/client-js/agents) for reconnect options.
503
375
 
504
- ## Keep custom SSE subscriptions alive
376
+ ### Keep custom SSE subscriptions alive
505
377
 
506
378
  If you expose your own Server-Sent Events (SSE) endpoint for thread subscriptions, send periodic heartbeat frames while the stream is idle. This keeps browsers, proxies, and load balancers from closing the connection before the next signal or model chunk arrives.
507
379
 
@@ -524,7 +396,9 @@ Use heartbeats together with client-side reconnect logic. Heartbeats reduce idle
524
396
  - [`Agent.sendMessage()`](https://mastra.ai/reference/agents/agent)
525
397
  - [`Agent.queueMessage()`](https://mastra.ai/reference/agents/agent)
526
398
  - [`Agent.sendSignal()`](https://mastra.ai/reference/agents/agent)
399
+ - [`Agent.sendStateSignal()`](https://mastra.ai/reference/agents/agent)
527
400
  - [`Agent.subscribeToThread()`](https://mastra.ai/reference/agents/agent)
401
+ - [`createNotificationInboxTool()`](https://mastra.ai/reference/signals/create-notification-inbox-tool)
528
402
  - [`client.getAgent().sendMessage()`](https://mastra.ai/reference/client-js/agents)
529
403
  - [`client.getAgent().queueMessage()`](https://mastra.ai/reference/client-js/agents)
530
404
  - [`client.getAgent().sendSignal()`](https://mastra.ai/reference/client-js/agents)
@@ -89,9 +89,9 @@ Each `dist/docs` includes:
89
89
 
90
90
  ## Context files
91
91
 
92
- Mastra provides a root [`llms.txt`](https://mastra.ai/llms.txt) file that contains an overview of all available documentation pages.
92
+ Mastra provides a root [`llms.txt`](https://mastra.ai/llms.txt) file that contains an overview of all available documentation pages. It doesn't provide an `llms-full.txt` file as it's not useful to have all documentation in one file.
93
93
 
94
- Each documentation page also has its own `llms.txt` file. These files are streamlined markdown files. At the end of each docs page you'll find a link to the corresponding `llms.txt` file.
94
+ Instead, each documentation page has its own `llms.txt` file. These files are streamlined markdown files. At the end of each docs page you'll find a link to the corresponding `llms.txt` file.
95
95
 
96
96
  Add `/llms.txt` to any Mastra docs URL to access it. You can also request it by adding a `.md` extension to the end of the URL.
97
97
 
@@ -71,4 +71,4 @@ cp .mastra-project.production.json .mastra-project.json
71
71
  mastra studio deploy --env-file .env.production --yes
72
72
  ```
73
73
 
74
- Each project has its own Studio URL and can send observability data to the Mastra platform. When using [`MastraPlatformExporter`](https://mastra.ai/docs/observability/tracing/exporters/mastra-platform), set `MASTRA_PROJECT_ID` and `MASTRA_PLATFORM_ACCESS_TOKEN` per environment so traces route to the matching platform project.
74
+ Each project has its own Studio URL and can send observability data to the Mastra platform. When using [`MastraPlatformExporter`](https://mastra.ai/docs/observability/integrations/exporters/mastra-platform), set `MASTRA_PROJECT_ID` and `MASTRA_PLATFORM_ACCESS_TOKEN` per environment so traces route to the matching platform project.
@@ -32,4 +32,4 @@ Once you're ready to deploy your application to production, use [`mastra studio
32
32
 
33
33
  Follow the [Studio on Mastra platform](https://mastra.ai/docs/mastra-platform/studio) and [Server on Mastra platform](https://mastra.ai/docs/mastra-platform/server) docs for step-by-step instructions.
34
34
 
35
- If you host your Mastra application on your own infrastructure, you can still send observability data to Mastra platform using the [MastraPlatformExporter](https://mastra.ai/docs/observability/tracing/exporters/mastra-platform).
35
+ If you host your Mastra application on your own infrastructure, you can still send observability data to Mastra platform using the [MastraPlatformExporter](https://mastra.ai/docs/observability/integrations/exporters/mastra-platform).