Signals
Added in: @mastra/core@1.39.0
Signals let you send input to an agent's thread at any time, including while the agent is working. That input might be a user message, an update from a background job, or an external event. Each signal has a type that tells Mastra what kind of input it carries.
For an ongoing conversation, use signals to send input and a thread stream to receive output. Subscribe to the stream first, then send input whenever it becomes available. By default, Mastra delivers it to the active run or starts a run when the thread is idle. You don't need to check whether the agent is running before sending.
For a one-off request, use agent.stream() to start a run and read its response directly. It can also use Memory, but it doesn't give you a subscription that follows later runs on the same thread.
Watch Mastra signals overview to see how signals wake and steer long-running agents.
QuickstartDirect link to Quickstart
Create an agent, subscribe to a thread, then send input to that thread. Subscribing first means the subscription is already open when the input starts a run.
Use an AgentDirect link to Use an Agent
This example stores thread history with Memory, using a local libSQL database, so the same conversation is available across runs and process restarts. Memory accepts any supported storage adapter, and the thread is created on the first run.
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { LibSQLStore } from '@mastra/libsql'
const agent = new Agent({
id: 'support-agent',
name: 'Support Agent',
instructions: 'Help the user compare options.',
model: 'openai/gpt-6.1-sol',
memory: new Memory({
storage: new LibSQLStore({
id: 'signals-storage',
url: 'file:./signals.db',
}),
}),
})
const thread = {
resourceId: 'user_123',
threadId: 'thread_456',
}
const subscription = await agent.subscribeToThread(thread)
const result = agent.sendMessage('Compare that with the previous option.', thread)
await result.accepted
for await (const chunk of subscription.stream) {
console.log(chunk)
}
The loop prints output chunks as the agent responds. It stays subscribed after the run finishes, ready for output from later messages to the same thread. Call subscription.unsubscribe() when you no longer need output. Sending signals explains how to send further messages and other kinds of input.
Use the client SDKDirect link to Use the client SDK
The same order applies through client.getAgent(): call subscribeToThread() first, then send a message to the same thread. The client returns the subscription stream and leaves run ownership on the server. Thread streams shows the full client example.
How signals reach a threadDirect link to How signals reach a thread
Sending input to an active run doesn't always interrupt the model immediately. Mastra waits until the run can accept it. If the current answer needs to finish first, queue a follow-up instead. You can also store input for later without starting a run, or discard it based on the thread's state.
Sending signals explains these delivery choices and how to check whether input was accepted. When your app runs on several processes, configure a shared backend so signals reach the process running the thread.
Choose an API surfaceDirect link to Choose an API surface
| Surface | Use it for | Canonical reference |
|---|---|---|
Direct Agent methods | Server-side code that owns the agent instance | Agent reference |
| HTTP or the JavaScript client SDK | Applications that call a running Mastra server | Server agent routes, client.getAgent() |
AgentController Session | Long-running assistants and coding agents built on AgentController | Agent Controller |
Start with Agent methods when your code runs alongside the agent, or the client SDK when it calls a server. If you're already using Agent Controller, its Session manages the thread and subscription for you.
Next stepsDirect link to Next steps
Use this table to find the right page for what you want to do next:
| Goal | Start here |
|---|---|
| Stream a thread's output and lifecycle into your app | Thread streams |
| Send a user message, typed signal, state signal, or notification | Sending signals |
| Understand when a signal interrupts a run or waits for the next step | When the agent sees your input |
| Keep named, thread-scoped context across turns | State signals |
| Deliver external events through a durable inbox | Notifications |
| Connect polling sources or webhooks to agents | Signal providers |
| Coordinate threads across multiple processes | Running across processes |
| Look up notification records, priorities, and delivery policies | Notifications reference |
Observe queued messages with subscribeThreadEvents() | Thread events reference |