Introducing MCP Events in Mastra

Send real-time events from MCP servers to agents, workflows, and apps.

Paul ScanlonPaul Scanlon·

Oct 23, 2026

·

4 min read

Your MCP server can now send events to connected clients using push, poll, or webhook delivery methods.

Agents and apps often need to act on changes that occur outside of conversations, like a failed deploy, merged pull request, new signup, or change in order status. MCP events give both ends of the pipe a standard way to .emit() and .subscribe() to events without the need for an additional pub/sub service.

Before MCP events, MCP servers could only respond to requests. If connected clients needed updates, they'd need to poll the server, which often required additional tooling and added complexity. Now, building on Mastra's MCP 2.0 support, events can be used to make two-way communication easier to manage.

When observability is configured, MCP event traces are captured automatically.

Get started

In this example, GitHub sends a request to a webhook URL whenever repo activity occurs. The webhook URL is a custom Mastra API endpoint, which is used to emit events from a Mastra MCPServer. A desktop Electron app subscribes to the same events using the Mastra MCPClient.

GNU BashTerminal
npm install @mastra/mcp@latest @mastra/core@latest
note
Requires @mastra/mcp@2.5.0 and @mastra/core@1.79.0 or later, added in PR #27324.

Define events on the MCP server using defineEvent():

TypeScriptsrc/mastra/mcp/server.ts
export const github = new MCPServer({
  // ...
  events: {
    "repo.starred": defineEvent({
      description: "Someone starred the repository",
      inputSchema: z.object({ repo: z.string() }),
      payloadSchema: z.object({
        repo: z.string(),
        user: z.string(),
        stars: z.number()
      }),
      match: (args, data) => {
        return data.repo === args.repo;
      }
    })
  }
});

Publish events using .emit(), passing in the data from the event payload:

TypeScriptsrc/mastra/index.ts
export const mastra = new Mastra({
  mcpServers: { github },
  server: {
    apiRoutes: [
      registerApiRoute("/github/webhook", {
        method: "POST",
        handler: async (context) => {
          const event = context.req.header("X-GitHub-Event");
          const body = await context.req.json();
 
          if (event === "star" && body.action === "created") {
            await github.events.emit("repo.starred", {
              repo: body.repository.full_name,
              user: body.sender.login,
              stars: body.repository.stargazers_count
            });
          }
 
          return context.json({ ok: true });
        }
      })
    ]
  }
});

Subscribe to events using .subscribe() to handle each event as it arrives. The .subscribe() method takes up to four arguments:

  • "github": The name of the MCP server in the client's servers config.
  • "repo.starred": The name of the event to subscribe to.
  • { repo }: The arguments defined by the event's inputSchema.
  • { delivery }: Optional. How events are delivered to the subscription.
TypeScriptsrc/octocat-app/main.js
const mcp = new MCPClient({
  servers: {
    github: {
      url: new URL("http://<mcp-server-url>/api/mcp/github/mcp")
    }
  }
});
 
const starSubscription = await mcp.events.subscribe("github", "repo.starred", { repo: "PaulieScanlon/mastra-mcp-events" }, { delivery: "push" });
 
for await (const event of starSubscription) {
  const { user, stars } = event.data;
  // trigger star animation with user and star count
}

Delivery methods

Set delivery on .subscribe() to define the subscription behavior. The default is push:

  • push: The subscription holds one events/stream request open listening for server events.
  • poll: The subscription repeatedly asks the server for new events, at most once a second by default.
  • webhook: The server sends each event to a URL on the client as a signed POST request. Requires webhook settings on the MCPClient.

Events and agents

Agents can react to MCP events using MCPEventsSignalProvider. Each event is delivered to the agent's thread as a notification:

const mcp = new MCPClient({
  // ...
});
 
const starSignal = new MCPEventsSignalProvider({
  client: mcp,
  subscribeOptions: { delivery: "push" }
});
 
export const repoAgent = new Agent({
  // ...
  signals: [starSignal]
});
 
await starSignal.subscribeThread(
  { resourceId: "repo-agent", threadId: "thread-1" },
  {
    server: "github",
    event: "repo.starred",
    args: { repo: "PaulieScanlon/mastra-mcp-events" }
  }
);

Events and workflows

Workflows can react to MCP events using a subscription. Each event can be used to start a workflow run:

import { repoWorkflow } from "./src/mastra/workflows/repo-workflow.ts";
 
const mcp = new MCPClient({
  // ...
});
 
const starSubscription = await mcp.events.subscribe("github", "repo.starred", { repo: "PaulieScanlon/mastra-mcp-events" }, { delivery: "push" });
 
for await (const event of starSubscription) {
  const run = await repoWorkflow.createRun();
  await run.start({ inputData: event.data });
}

For more information and full configuration options, see:

MCP events are still experimental — the API may change between releases.

Share on X or LinkedIn
Paul Scanlon
Paul ScanlonTechnical Product Marketing Manager

Paul Scanlon sits between Developer Education and Product Marketing at Mastra. Previously, he was a Technical Product Marketing Manager at Neon and worked in Developer Relations at Gatsby, where he created educational content and developer experiences.

All articles by Paul Scanlon →