Email for Vercel AI SDK agents

The AI SDK ships an MCP client. Point it at MCPmailer, spread the tools into your generateText or streamText call, and the model can send mail and read replies like any other tool.

Setup

  1. 01

    Install the MCP package

    @ai-sdk/mcp carries the client; ai carries generateText.

  2. 02

    Create a mailbox

    One per agent, so its address and its key are the same identity.

  3. 03

    Open the client once

    Reuse it across requests. Every tools() call reaches the server.

  4. 04

    Close it when done

    The transport holds a connection open until you do.

Install
npm install ai @ai-sdk/mcp
AI SDK (TypeScript)
import { createMCPClient } from '@ai-sdk/mcp';
import { generateText } from 'ai';

const mcp = await createMCPClient({
  transport: {
    type: 'http',
    url: 'https://connect.mcpmailer.com/mcp',
    headers: { Authorization: 'Bearer mmk_live_...' }
  }
});

const { text } = await generateText({
  model: 'openai/gpt-5.4',
  tools: await mcp.tools(),
  prompt: 'Email anna@customer.com her order status.'
});

Answer unread mail

stopWhen lets the model take several turns: list, read, reply. Without it the SDK stops after the first tool call and nothing is sent.

Answer unread mail
import { createMCPClient } from '@ai-sdk/mcp';
import { generateText, isStepCount } from 'ai';

const mcp = await createMCPClient({
  transport: {
    type: 'http',
    url: 'https://connect.mcpmailer.com/mcp',
    headers: { Authorization: `Bearer ${process.env.MCPMAILER_KEY}` }
  }
});

try {
  const { text } = await generateText({
    model: 'openai/gpt-5.4',
    tools: await mcp.tools(),
    stopWhen: isStepCount(8),
    system: 'You answer support email. Reply in thread, never start new ones.',
    prompt: 'Check for unread mail and answer anything you can.'
  });
  console.log(text);
} finally {
  await mcp.close();
}

Worth knowing

01

Give it room to finish

A reply is at least three tool calls: list_messages, read_message, reply_all. The default stops after one step, so set stopWhen or the run ends having read a message and sent nothing.

02

One client, many requests

createMCPClient opens a connection. Creating one per request in a server route leaks them; open it at module scope, or close it in a finally block as above.

03

Tool names come from us

The keys in tools() are our tool names, so a model prompted to "use send_email" matches what it is given. You can narrow the set by picking keys off the object before passing it.

What Vercel AI SDK can reach

The endpoint speaks Streamable HTTP MCP with 67 tools across mail, contacts, notes, and a vault, including send_email, read_message, search_inbox, and wait_for_reply. Errors are structured so Vercel AI SDK can react: a quota rejection includes the reset time.