{"article":{"slug":"introducing-mcp-events-in-mastra","title":"Introducing MCP Events in Mastra","subtitle":null,"summary":"Mastra adds experimental MCP events: MCP servers can now emit real-time events such as failed deploys, merged pull requests or new signups to connected clients via push, poll or webhook delivery, using defineEvent(), .emit() and .subscribe() without a separate pub/sub service, and agents and workflows can react to them. Requires @mastra/mcp 2.5.0 and @mastra/core 1.79.0.","content_type":"announcement","language":"en","canonical_url":"https://mastra.ai/blog/introducing-mcp-events","author":{"name":"Paul Scanlon","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Mastra","url":"https://mastra.ai/","listing_slug":"mastra","listing":{"slug":"mastra","name":"Mastra","listing_type":"company","url":"https://listedstartups.com/companies/mastra"}},"topics":[{"name":"AI Agents","slug":"ai-agents","url":"https://listedarticles.com/topics/ai-agents"},{"name":"MCP","slug":"mcp","url":"https://listedarticles.com/topics/mcp"},{"name":"Developer Tools","slug":"developer-tools","url":"https://listedarticles.com/topics/developer-tools"}],"about_listings":[{"slug":"mastra-oss","name":"Mastra","listing_type":"product","url":"https://listedstartups.com/products/mastra-oss"}],"cover_image_url":null,"license":"all-rights-reserved","word_count":637,"reading_minutes":3,"published_at":"2026-10-23T00:00:00.000Z","added_at":"2026-10-28T17:17:41.576Z","updated_at":"2026-10-28T17:17:41.576Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/introducing-mcp-events-in-mastra","markdown_url":"https://listedarticles.com/articles/introducing-mcp-events-in-mastra.md","example":false,"citation":"Paul Scanlon, Mastra. \"Introducing MCP Events in Mastra.\" 23 Oct 2026. https://mastra.ai/blog/introducing-mcp-events (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://mastra.ai/blog/introducing-mcp-events"},"body_markdown":"*Paul Scanlon · Mastra · October 23, 2026*\n\nYour MCP server can now send [events](https://mastra.ai/docs/connections/mcp#mcp-events) to connected clients using push, poll, or webhook delivery methods.\n\nAgents 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.\n\nBefore 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](https://mastra.ai/blog/introducing-mcp-2) support, events can be used to make two-way communication easier to manage.\n\nWhen [observability](https://mastra.ai/docs/observability/overview) is configured, MCP event traces are captured automatically.\n\n## Get started\n\nIn this example, GitHub sends a request to a [webhook](https://docs.github.com/en/webhooks/about-webhooks) URL whenever repo activity occurs. The webhook URL is a [custom Mastra API endpoint](https://mastra.ai/docs/server/custom-api-routes), which is used to emit events from a Mastra `MCPServer`. A desktop Electron app subscribes to the same events using the Mastra `MCPClient`.\n\nTerminal\n\n```\nnpm install @mastra/mcp@latest @mastra/core@latest\n```\n\nnote\n\nRequires `@mastra/mcp@2.5.0` and `@mastra/core@1.79.0` or later, added in [PR #27324](https://github.com/mastra-ai/mastra/pull/27324).\n\nDefine events on the MCP server using `defineEvent()`:\n\nsrc/mastra/mcp/server.ts\n\n```\nexport const github = new MCPServer({\n  // ...\n  events: {\n    \"repo.starred\": defineEvent({\n      description: \"Someone starred the repository\",\n      inputSchema: z.object({ repo: z.string() }),\n      payloadSchema: z.object({\n        repo: z.string(),\n        user: z.string(),\n        stars: z.number()\n      }),\n      match: (args, data) => {\n        return data.repo === args.repo;\n      }\n    })\n  }\n});\n```\n\nPublish events using `.emit()`, passing in the data from the event payload:\n\nsrc/mastra/index.ts\n\n```\nexport const mastra = new Mastra({\n  mcpServers: { github },\n  server: {\n    apiRoutes: [\n      registerApiRoute(\"/github/webhook\", {\n        method: \"POST\",\n        handler: async (context) => {\n          const event = context.req.header(\"X-GitHub-Event\");\n          const body = await context.req.json();\n \n          if (event === \"star\" && body.action === \"created\") {\n            await github.events.emit(\"repo.starred\", {\n              repo: body.repository.full_name,\n              user: body.sender.login,\n              stars: body.repository.stargazers_count\n            });\n          }\n \n          return context.json({ ok: true });\n        }\n      })\n    ]\n  }\n});\n```\n\nSubscribe to events using `.subscribe()` to handle each event as it arrives. The `.subscribe()` method takes up to four arguments:\n\n- `\"github\"`: The name of the MCP server in the client's `servers` config.\n- `\"repo.starred\"`: The name of the event to subscribe to.\n- `{ repo }`: The arguments defined by the event's `inputSchema`.\n- `{ delivery }`: Optional. How events are delivered to the subscription.\n\nsrc/octocat-app/main.js\n\n```\nconst mcp = new MCPClient({\n  servers: {\n    github: {\n      url: new URL(\"http://<mcp-server-url>/api/mcp/github/mcp\")\n    }\n  }\n});\n \nconst starSubscription = await mcp.events.subscribe(\"github\", \"repo.starred\", { repo: \"PaulieScanlon/mastra-mcp-events\" }, { delivery: \"push\" });\n \nfor await (const event of starSubscription) {\n  const { user, stars } = event.data;\n  // trigger star animation with user and star count\n}\n```\n\n## Delivery methods\n\nSet `delivery` on `.subscribe()` to define the subscription behavior. The default is `push`:\n\n- `push`: The subscription holds one `events/stream` request open listening for server events.\n- `poll`: The subscription repeatedly asks the server for new events, at most once a second by default.\n- `webhook`: The server sends each event to a URL on the client as a signed POST request. Requires `webhook` settings on the `MCPClient`.\n\n## Events and agents\n\nAgents can react to MCP events using [MCPEventsSignalProvider](https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental). Each event is delivered to the agent's thread as a notification:\n\n```\nconst mcp = new MCPClient({\n  // ...\n});\n \nconst starSignal = new MCPEventsSignalProvider({\n  client: mcp,\n  subscribeOptions: { delivery: \"push\" }\n});\n \nexport const repoAgent = new Agent({\n  // ...\n  signals: [starSignal]\n});\n \nawait starSignal.subscribeThread(\n  { resourceId: \"repo-agent\", threadId: \"thread-1\" },\n  {\n    server: \"github\",\n    event: \"repo.starred\",\n    args: { repo: \"PaulieScanlon/mastra-mcp-events\" }\n  }\n);\n```\n\n## Events and workflows\n\nWorkflows can react to MCP events using a [subscription](https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental). Each event can be used to start a workflow run:\n\n```\nimport { repoWorkflow } from \"./src/mastra/workflows/repo-workflow.ts\";\n \nconst mcp = new MCPClient({\n  // ...\n});\n \nconst starSubscription = await mcp.events.subscribe(\"github\", \"repo.starred\", { repo: \"PaulieScanlon/mastra-mcp-events\" }, { delivery: \"push\" });\n \nfor await (const event of starSubscription) {\n  const run = await repoWorkflow.createRun();\n  await run.start({ inputData: event.data });\n}\n```\n\nFor more information and full configuration options, see:\n\n- [MCP events](https://mastra.ai/docs/connections/mcp#mcp-events)\n- [MCPServer events reference](https://mastra.ai/reference/tools/mcp-server#events-experimental)\n- [MCPClient events reference](https://mastra.ai/reference/tools/mcp-client#events-property-experimental)\n- [MCPEventsSignalProvider reference](https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental)\n- [Custom API routes](https://mastra.ai/docs/server/custom-api-routes)\n- [About webhooks](https://docs.github.com/en/webhooks/about-webhooks)\n\nMCP events are still experimental — the API may change between releases.\n\n---\n\n*Originally published at [the Mastra blog](https://mastra.ai/blog/introducing-mcp-events).*\n","body_html":"<p><em>Paul Scanlon · Mastra · October 23, 2026</em></p>\n<p>Your MCP server can now send <a href=\"https://mastra.ai/docs/connections/mcp#mcp-events\" rel=\"nofollow ugc noopener\">events</a> to connected clients using push, poll, or webhook delivery methods.</p>\n<p>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 <code>.emit()</code> and <code>.subscribe()</code> to events without the need for an additional pub/sub service.</p>\n<p>Before MCP events, MCP servers could only respond to requests. If connected clients needed updates, they&#39;d need to poll the server, which often required additional tooling and added complexity. Now, building on Mastra&#39;s <a href=\"https://mastra.ai/blog/introducing-mcp-2\" rel=\"nofollow ugc noopener\">MCP 2.0</a> support, events can be used to make two-way communication easier to manage.</p>\n<p>When <a href=\"https://mastra.ai/docs/observability/overview\" rel=\"nofollow ugc noopener\">observability</a> is configured, MCP event traces are captured automatically.</p>\n<h2 id=\"get-started\">Get started</h2>\n<p>In this example, GitHub sends a request to a <a href=\"https://docs.github.com/en/webhooks/about-webhooks\" rel=\"nofollow ugc noopener\">webhook</a> URL whenever repo activity occurs. The webhook URL is a <a href=\"https://mastra.ai/docs/server/custom-api-routes\" rel=\"nofollow ugc noopener\">custom Mastra API endpoint</a>, which is used to emit events from a Mastra <code>MCPServer</code>. A desktop Electron app subscribes to the same events using the Mastra <code>MCPClient</code>.</p>\n<p>Terminal</p>\n<pre><code>npm install @mastra/mcp@latest @mastra/core@latest</code></pre>\n<p>note</p>\n<p>Requires <code>@mastra/mcp@2.5.0</code> and <code>@mastra/core@1.79.0</code> or later, added in <a href=\"https://github.com/mastra-ai/mastra/pull/27324\" rel=\"nofollow ugc noopener\">PR #27324</a>.</p>\n<p>Define events on the MCP server using <code>defineEvent()</code>:</p>\n<p>src/mastra/mcp/server.ts</p>\n<pre><code>export const github = new MCPServer({\n  // ...\n  events: {\n    &quot;repo.starred&quot;: defineEvent({\n      description: &quot;Someone starred the repository&quot;,\n      inputSchema: z.object({ repo: z.string() }),\n      payloadSchema: z.object({\n        repo: z.string(),\n        user: z.string(),\n        stars: z.number()\n      }),\n      match: (args, data) =&gt; {\n        return data.repo === args.repo;\n      }\n    })\n  }\n});</code></pre>\n<p>Publish events using <code>.emit()</code>, passing in the data from the event payload:</p>\n<p>src/mastra/index.ts</p>\n<pre><code>export const mastra = new Mastra({\n  mcpServers: { github },\n  server: {\n    apiRoutes: [\n      registerApiRoute(&quot;/github/webhook&quot;, {\n        method: &quot;POST&quot;,\n        handler: async (context) =&gt; {\n          const event = context.req.header(&quot;X-GitHub-Event&quot;);\n          const body = await context.req.json();\n \n          if (event === &quot;star&quot; &amp;&amp; body.action === &quot;created&quot;) {\n            await github.events.emit(&quot;repo.starred&quot;, {\n              repo: body.repository.full_name,\n              user: body.sender.login,\n              stars: body.repository.stargazers_count\n            });\n          }\n \n          return context.json({ ok: true });\n        }\n      })\n    ]\n  }\n});</code></pre>\n<p>Subscribe to events using <code>.subscribe()</code> to handle each event as it arrives. The <code>.subscribe()</code> method takes up to four arguments:</p>\n<ul><li><code>&quot;github&quot;</code>: The name of the MCP server in the client&#39;s <code>servers</code> config.</li><li><code>&quot;repo.starred&quot;</code>: The name of the event to subscribe to.</li><li><code>{ repo }</code>: The arguments defined by the event&#39;s <code>inputSchema</code>.</li><li><code>{ delivery }</code>: Optional. How events are delivered to the subscription.</li></ul>\n<p>src/octocat-app/main.js</p>\n<pre><code>const mcp = new MCPClient({\n  servers: {\n    github: {\n      url: new URL(&quot;http://&lt;mcp-server-url&gt;/api/mcp/github/mcp&quot;)\n    }\n  }\n});\n \nconst starSubscription = await mcp.events.subscribe(&quot;github&quot;, &quot;repo.starred&quot;, { repo: &quot;PaulieScanlon/mastra-mcp-events&quot; }, { delivery: &quot;push&quot; });\n \nfor await (const event of starSubscription) {\n  const { user, stars } = event.data;\n  // trigger star animation with user and star count\n}</code></pre>\n<h2 id=\"delivery-methods\">Delivery methods</h2>\n<p>Set <code>delivery</code> on <code>.subscribe()</code> to define the subscription behavior. The default is <code>push</code>:</p>\n<ul><li><code>push</code>: The subscription holds one <code>events/stream</code> request open listening for server events.</li><li><code>poll</code>: The subscription repeatedly asks the server for new events, at most once a second by default.</li><li><code>webhook</code>: The server sends each event to a URL on the client as a signed POST request. Requires <code>webhook</code> settings on the <code>MCPClient</code>.</li></ul>\n<h2 id=\"events-and-agents\">Events and agents</h2>\n<p>Agents can react to MCP events using <a href=\"https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental\" rel=\"nofollow ugc noopener\">MCPEventsSignalProvider</a>. Each event is delivered to the agent&#39;s thread as a notification:</p>\n<pre><code>const mcp = new MCPClient({\n  // ...\n});\n \nconst starSignal = new MCPEventsSignalProvider({\n  client: mcp,\n  subscribeOptions: { delivery: &quot;push&quot; }\n});\n \nexport const repoAgent = new Agent({\n  // ...\n  signals: [starSignal]\n});\n \nawait starSignal.subscribeThread(\n  { resourceId: &quot;repo-agent&quot;, threadId: &quot;thread-1&quot; },\n  {\n    server: &quot;github&quot;,\n    event: &quot;repo.starred&quot;,\n    args: { repo: &quot;PaulieScanlon/mastra-mcp-events&quot; }\n  }\n);</code></pre>\n<h2 id=\"events-and-workflows\">Events and workflows</h2>\n<p>Workflows can react to MCP events using a <a href=\"https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental\" rel=\"nofollow ugc noopener\">subscription</a>. Each event can be used to start a workflow run:</p>\n<pre><code>import { repoWorkflow } from &quot;./src/mastra/workflows/repo-workflow.ts&quot;;\n \nconst mcp = new MCPClient({\n  // ...\n});\n \nconst starSubscription = await mcp.events.subscribe(&quot;github&quot;, &quot;repo.starred&quot;, { repo: &quot;PaulieScanlon/mastra-mcp-events&quot; }, { delivery: &quot;push&quot; });\n \nfor await (const event of starSubscription) {\n  const run = await repoWorkflow.createRun();\n  await run.start({ inputData: event.data });\n}</code></pre>\n<p>For more information and full configuration options, see:</p>\n<ul><li><a href=\"https://mastra.ai/docs/connections/mcp#mcp-events\" rel=\"nofollow ugc noopener\">MCP events</a></li><li><a href=\"https://mastra.ai/reference/tools/mcp-server#events-experimental\" rel=\"nofollow ugc noopener\">MCPServer events reference</a></li><li><a href=\"https://mastra.ai/reference/tools/mcp-client#events-property-experimental\" rel=\"nofollow ugc noopener\">MCPClient events reference</a></li><li><a href=\"https://mastra.ai/reference/tools/mcp-client#events-in-agents-and-workflows-experimental\" rel=\"nofollow ugc noopener\">MCPEventsSignalProvider reference</a></li><li><a href=\"https://mastra.ai/docs/server/custom-api-routes\" rel=\"nofollow ugc noopener\">Custom API routes</a></li><li><a href=\"https://docs.github.com/en/webhooks/about-webhooks\" rel=\"nofollow ugc noopener\">About webhooks</a></li></ul>\n<p>MCP events are still experimental — the API may change between releases.</p>\n<hr />\n<p><em>Originally published at <a href=\"https://mastra.ai/blog/introducing-mcp-events\" rel=\"nofollow ugc noopener\">the Mastra blog</a>.</em></p>","headings":[{"level":2,"text":"Get started","id":"get-started"},{"level":2,"text":"Delivery methods","id":"delivery-methods"},{"level":2,"text":"Events and agents","id":"events-and-agents"},{"level":2,"text":"Events and workflows","id":"events-and-workflows"}]}}