npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mastra/ai-sdk

v1.4.2

Published

Adds custom API routes to be compatible with the AI SDK UI parts

Readme

@mastra/ai-sdk

The recommended way of using Mastra and AI SDK together is by installing the @mastra/ai-sdk package. @mastra/ai-sdk provides custom API routes and utilities for streaming Mastra agents in AI SDK-compatible formats. Including chat, workflow, and network route handlers, along with utilities and exported types for UI integrations.

Installation

npm install @mastra/ai-sdk

Usage

If you want to use dynamic agents you can use a path with :agentId.

import { chatRoute } from '@mastra/ai-sdk';

export const mastra = new Mastra({
  server: {
    apiRoutes: [
      chatRoute({
        path: '/chat/:agentId',
      }),
    ],
  },
});

Or you can create a fixed route (i.e. /chat):

import { chatRoute } from '@mastra/ai-sdk';

export const mastra = new Mastra({
  server: {
    apiRoutes: [
      chatRoute({
        path: '/chat',
        agent: 'weatherAgent',
      }),
    ],
  },
});

After defining a dynamic route with :agentId you can use the useChat() hook like so:

type MyMessage = {};

const { error, status, sendMessage, messages, regenerate, stop } = useChat<MyMessage>({
  transport: new DefaultChatTransport({
    api: 'http://localhost:4111/chat/weatherAgent',
  }),
});

chatRoute() forwards the incoming request AbortSignal to agent.stream(). If the client disconnects, Mastra aborts the in-flight generation. If you need generation to continue and persist server-side after disconnect, build a custom route around agent.stream(), avoid passing the request signal, and call consumeStream() on the returned MastraModelOutput.

Workflow route

Stream a workflow in AI SDK-compatible format.

import { workflowRoute } from '@mastra/ai-sdk';

export const mastra = new Mastra({
  server: {
    apiRoutes: [
      workflowRoute({
        path: '/workflow',
        agent: 'weatherAgent',
      }),
    ],
  },
});

Network route

Stream agent networks (routing + nested agent/workflow/tool executions) in AI SDK-compatible format.

import { networkRoute } from '@mastra/ai-sdk';

export const mastra = new Mastra({
  server: {
    apiRoutes: [
      networkRoute({
        path: '/network',
        agent: 'weatherAgent',
      }),
    ],
  },
});

Framework-agnostic handlers

For use outside the Mastra server (e.g., Next.js App Router, Express), you can use the standalone handler functions directly. These handlers return a compatibility ReadableStream that can be passed to AI SDK response helpers like createUIMessageStreamResponse and pipeUIMessageStreamToResponse:

handleChatStream

import { handleChatStream } from '@mastra/ai-sdk';
import { createUIMessageStreamResponse } from 'ai';
import { mastra } from '@/src/mastra';

export async function POST(req: Request) {
  const params = await req.json();
  const stream = await handleChatStream({
    mastra,
    agentId: 'weatherAgent',
    params,
  });
  return createUIMessageStreamResponse({ stream });
}

handleWorkflowStream

import { handleWorkflowStream } from '@mastra/ai-sdk';
import { createUIMessageStreamResponse } from 'ai';
import { mastra } from '@/src/mastra';

export async function POST(req: Request) {
  const params = await req.json();
  const stream = await handleWorkflowStream({
    mastra,
    workflowId: 'myWorkflow',
    params,
  });
  return createUIMessageStreamResponse({ stream });
}

handleNetworkStream

Pass AI SDK UIMessage[] from your installed ai version so TypeScript can infer the correct stream overload.

Handlers keep the existing v5/default behavior. If your app is typed against ai@6, pass version: 'v6'.

import { handleNetworkStream } from '@mastra/ai-sdk';
import { createUIMessageStreamResponse, type UIMessage } from 'ai';
import { mastra } from '@/src/mastra';

export async function POST(req: Request) {
  const params = (await req.json()) as { messages: UIMessage[] };
  const stream = await handleNetworkStream({
    mastra,
    agentId: 'routingAgent',
    version: 'v6',
    params,
  });
  return createUIMessageStreamResponse({ stream });
}

Agent versioning

All route handlers and standalone stream functions accept an optional agentVersion parameter to target a specific agent version. This requires the Editor to be configured.

Pass a version ID or resolve by status:

chatRoute({
  path: '/chat',
  agent: 'weatherAgent',
  agentVersion: { status: 'published' },
});

For route handlers (chatRoute, networkRoute), callers can also override the version at request time with query parameters: ?versionId=<id> or ?status=draft|published. Query parameters take precedence over the static agentVersion option.

The standalone handlers (handleChatStream, handleNetworkStream) accept agentVersion directly:

const stream = await handleChatStream({
  mastra,
  agentId: 'weatherAgent',
  agentVersion: { versionId: 'ver_abc123' },
  params,
});

Manual transformation

If you have a raw Mastra stream, you can manually transform it to AI SDK UI message parts:

Use toAISdkStream for both versions. If your app is typed against ai@6, pass version: 'v6'.

import { toAISdkStream } from '@mastra/ai-sdk';
import { createUIMessageStream, createUIMessageStreamResponse } from 'ai';

export async function POST(req: Request) {
  const { messages } = await req.json();
  const agent = mastra.getAgent('weatherAgent');
  const stream = await agent.stream(messages);

  // deduplicate messages https://ai-sdk.dev/docs/troubleshooting/repeated-assistant-messages
  const uiMessageStream = createUIMessageStream({
    originalMessages: messages,
    execute: async ({ writer }) => {
      for await (const part of toAISdkStream(stream, { from: 'agent' })) {
        writer.write(part);
      }
    },
  });

  return createUIMessageStreamResponse({ stream: uiMessageStream });
}

For AI SDK v6, select the v6 stream contract explicitly:

const uiMessageStream = createUIMessageStream({
  originalMessages: messages,
  execute: async ({ writer }) => {
    for await (const part of toAISdkStream(stream, {
      from: 'agent',
      version: 'v6',
    })) {
      writer.write(part);
    }
  },
});

Loading stored messages

Use toAISdkMessages from @mastra/ai-sdk/ui to convert stored Mastra messages for useChat() and other AI SDK UI hooks.

The helper keeps the existing v5/default behavior. If your app is typed against ai@6, pass version: 'v6'. That uses the MessageList AI SDK v6 UI output path. MessageList input detection and ingestion remain unchanged.

import { toAISdkMessages } from '@mastra/ai-sdk/ui';

const v5Messages = toAISdkMessages(storedMessages);
const v6Messages = toAISdkMessages(storedMessages, { version: 'v6' });