Introducing MCP Tasks in Mastra

Unblock your agents during long-running MCP tool calls.

Paul ScanlonPaul Scanlon·

Nov 11, 2026

·

4 min read

You can now use tasks with Mastra MCPServer and MCPClient to run long-running tool calls in the background. The client can poll the server until the task is completed, then hand the result back to the agent.

While tool calls are in progress, agents are blocked and can't respond to user requests. Moving tool calls to tasks lets the agent keep responding while slow or expensive computations run in the background.

An agent keeps answering questions while a 30-day repo report runs as an MCP task, then shows the finished report as a dashboard.

Before tasks, MCP tool calls were synchronous. Each call was handled by a single HTTP request that remained open until complete, and blocked the agent loop. Mastra's existing background tasks primitive could be used to free up the agent loop, but if a tool call outlasted a proxy timeout or a load balancer's idle limit, it would eventually fail.

With tasks, MCP servers can quickly respond with a task ID (which completes the HTTP request and unblocks the agent). MCP clients then use the ID to poll the server, receiving a response that includes a task status of working, input_required, completed, failed, or cancelled. When the task completes, Mastra sends the agent a notification signal, which reaches an active run on its next model request, instead of waiting for the agent loop to finish.

Building on our MCP 2.0 support, tasks join MCP events as the latest addition to Mastra's MCP server and client primitives.

Get started

GNU BashTerminal
npm install @mastra/mcp@latest @mastra/core@latest
note
Requires @mastra/mcp@2.7.0 and @mastra/core@1.81.0 or later, added in PR #28420.

Enable backgroundTasks on your Mastra instance:

TypeScriptsrc/mastra/index.ts
export const mastra = new Mastra({
  // ...
  storage: new LibSQLStore({ id: "mastra-storage", url: "file:./mastra.db" }),
  backgroundTasks: { enabled: true }
});

MCP server

Tools can be configured to run as tasks using one of the following config options:

  • "always": The tool call always runs as a task.
  • "auto": The tool call runs as a task if it takes longer than syncWindowMs (2 seconds by default).
  • "off": The tool call never runs as a task. This is the default.
TypeScriptsrc/mastra/mcp/mcp-server.ts
import { MCPServer } from "@mastra/mcp";
import { reportTool } from "../tools/report-tool";
 
export const mcpServer = new MCPServer({
  id: "mcp-server",
  // ...
  tools: { reportTool },
  tasks: {
    tools: { reportTool: "always" }
  }
});

Register the server on your Mastra instance:

TypeScriptsrc/mastra/index.ts
export const mastra = new Mastra({
  // ...
  mcpServers: { mcpServer }
});

Tools that run as tasks can still use suspend() to ask for human input. The task pauses in an input_required state until the client responds:

TypeScriptsrc/mastra/tools/report-tool.ts
export const reportTool = createTool({
  // ...
  resumeSchema: z.object({
    approved: z.boolean()
  }),
  execute: async (inputData, context) => {
    if (!context.resumeData) {
      await context.suspend?.({ message: "Generate a report?" });
      return;
    }
    // ...
  }
});

MCP client

Set tasks on the MCPClient so it can poll tasks from the MCP server for their results, and use inputRequests to respond when a tool calls suspend() for human input:

TypeScriptsrc/mastra/mcp/mcp-client.ts
export const mcpClient = new MCPClient({
  servers: {
    mcpServer: {
      url: new URL("http://localhost:4111/api/mcp/mcp-server/mcp"),
      tasks: true,
      inputRequests: async () => {
        // content.approved matches the tool's resumeSchema
        return { action: "accept", content: { approved: true } };
      }
    }
  }
});

Add MCP server tools to an agent using the tools option:

TypeScriptsrc/mastra/agents/agent.ts
export const agent = new Agent({
  // ...
  tools: await mcpClient.listTools()
});

For more information and full configuration options, see:

MCP tasks 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 →
All posts