Skip to main content

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

Watch Mastra signals overview to see how signals wake and steer long-running agents.

Quickstart
Direct 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 Agent
Direct 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.

src/mastra/signals.ts
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 SDK
Direct 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 thread
Direct 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 surface
Direct link to Choose an API surface

SurfaceUse it forCanonical reference
Direct Agent methodsServer-side code that owns the agent instanceAgent reference
HTTP or the JavaScript client SDKApplications that call a running Mastra serverServer agent routes, client.getAgent()
AgentController SessionLong-running assistants and coding agents built on AgentControllerAgent 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 steps
Direct link to Next steps

Use this table to find the right page for what you want to do next:

GoalStart here
Stream a thread's output and lifecycle into your appThread streams
Send a user message, typed signal, state signal, or notificationSending signals
Understand when a signal interrupts a run or waits for the next stepWhen the agent sees your input
Keep named, thread-scoped context across turnsState signals
Deliver external events through a durable inboxNotifications
Connect polling sources or webhooks to agentsSignal providers
Coordinate threads across multiple processesRunning across processes
Look up notification records, priorities, and delivery policiesNotifications reference
Observe queued messages with subscribeThreadEvents()Thread events reference
On this page