AI SDK
Add one narrow, approval-gated sendEmail tool to a Vercel AI SDK agent.
Email SDK exposes an optional /ai entry point for AI SDK. It binds the sender in application code, restricts model-visible input, requires approval, and returns a secret-safe result.
Install
bun add ai @opencoredev/email-sdkCreate the tool
import { createEmailTools } from "@opencoredev/email-sdk/ai";
import { email } from "../email.js";
export const emailTools = createEmailTools({
client: email,
from: "Acme <hello@acme.com>",
});The helper returns tools.sendEmail and a matching toolApproval policy.
import { generateText, type ModelMessage } from "ai";
import { emailTools } from "./email-tools.js";
export function respond(messages: ModelMessage[]) {
return generateText({
model: "openai/gpt-5.5",
messages,
tools: emailTools.tools,
toolApproval: emailTools.toolApproval,
});
}The first call returns a tool-approval-request instead of sending. Render that request, collect the user's decision, append a tool-approval-response to the messages, and call the model again. The tool executes only after an approved response. AI SDK 6 can still read the tool-level needsApproval: true fallback; AI SDK 7 applications should pass the returned top-level toolApproval map.
What the model can request
The input schema accepts only:
tosubjecttextand/orhtml
The application binds from. The model cannot choose adapters, fallbacks, retries, idempotency keys, schedules, attachments, CC, BCC, headers, metadata, or provider URLs.
Approved execution derives email-tool:${toolCallId} as the idempotency key and forwards the abort signal. Success returns only { status: "sent", adapter, id? }. Failures become Error("Email could not be sent."), so provider responses and raw errors do not reach the model.
Approval UI
Render the exact recipients, subject, and body before approval. A denial is terminal and must result in zero provider calls.
Chat SDK
Use Email SDK from multi-platform chat handlers.
