@sendmux/ai-sdk
v0.5.2
Published
Vercel AI SDK tools for the Sendmux email API for AI agents - send email and read the agent inbox.
Maintainers
Readme
@sendmux/ai-sdk
Vercel AI SDK tools for Sendmux, the email API for AI agents.
Gives an agent its own mailbox: it can send email, read what arrives, and reply from its own address.
Requirements
- A Node.js version supported by your installed
aiversion (aiv7 requires Node.js 22 or newer) aiv5 or newer andzodv3.25.76 or newer, within the peer range accepted by your installedaiversion (peer dependencies — you already installaito callgenerateText)
Upgrading to 0.5.0
0.5.0 raises the zod peer dependency minimum from 3.24.0 to 3.25.76.
If you use Zod 3.24, upgrade Zod before adopting this wrapper release; do not
disable peer-dependency checks. Keep both ai and zod within their compatible
peer ranges and use the Node.js version required by ai.
Before upgrading, retain the prior known-working package manifest, lockfile,
and corresponding caller changes, including the compatible intersection of
the Sendmux wrapper, ai, and zod. To roll back, restore those files together
and reinstall dependencies with your project's existing lockfile workflow.
Run your tool integration checks before resuming agents. Keep peer-dependency
checks enabled rather than forcing an unsupported combination.
Installation
npm install @sendmux/ai-sdk ai zodGetting an API key
For API-key authentication, use a key that can both send and receive. Two ways to get one:
- Dashboard — create a mailbox and a mailbox-scoped key (
smx_mbx_*). See API keys. - Agent self-registration — the agent claims its own
@myagent.mxmailbox and gets ansmx_agent_*token, with no human signup first. See email for AI agents.
Note on agent tokens: a freshly self-registered smx_agent_* token can read and receive, but cannot send until a human owner has been invited and has approved it. Until then send_email and reply will fail. A dashboard smx_mbx_* key with send permission works immediately.
Read the key from the environment. Never hard-code it.
OAuth access tokens
Set accessToken to a bare REST OAuth token or a synchronous or asynchronous provider instead of apiKey:
import { sendmux } from "@sendmux/ai-sdk";
const tools = sendmux({
accessToken: () => process.env.SENDMUX_ACCESS_TOKEN!,
defaultFrom: "[email protected]",
});The provider runs before every tool request. Your application owns protected token storage, expiry checks, and refresh coordination. Request mailbox.read and email.send to use all three tools, and select one mailbox at consent; these tools do not supply a mailbox selector. See REST OAuth.
Quick start
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { sendmux } from "@sendmux/ai-sdk";
const { text } = await generateText({
model: openai("gpt-4o"),
tools: sendmux({
apiKey: process.env.SENDMUX_API_KEY!,
defaultFrom: "[email protected]",
}),
prompt: "Read the inbox and reply to anyone asking about pricing.",
});Tools
sendmux(config) returns a Vercel AI SDK ToolSet with three tools.
send_email
Sends through your configured sending providers, to any recipient.
| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| to | string | yes | Recipient email address |
| subject | string | yes | Subject line |
| text | string | yes | Plain-text body |
| html | string | no | HTML body. Generated from text if omitted |
| from | string | no | Sender address. Falls back to defaultFrom |
| idempotencyKey | string | no | Makes a retried send idempotent for 24 hours |
| deliveryGroup | string or string[] | no | Delivery group ID, or a non-empty list of IDs, that narrows the eligible provider pool |
list_messages
Lists messages in the agent's own mailbox, newest first.
| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| limit | integer | no | How many to return, 1 to 100 |
reply
Sends from the agent's own mailbox address, rather than through a sending provider. Use this to answer someone who wrote in.
| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| to | string | yes | Recipient email address |
| subject | string | yes | Subject line |
| text | string | yes | Plain-text body |
| html | string | no | HTML body. Generated from text if omitted |
| idempotencyKey | string | no | Makes a retried send idempotent for 24 hours |
Configuration
Supply exactly one of apiKey or accessToken.
sendmux({ apiKey, defaultFrom });| Option | Required | Purpose |
| --- | --- | --- |
| apiKey | If no accessToken | A send + receive mailbox key (smx_mbx_*) or a scoped agent token (smx_agent_*) |
| accessToken | If no apiKey | A bare REST OAuth token or a synchronous or asynchronous token provider |
| defaultFrom | no | Default sender for send_email. Without it, the model has to supply from on every call |
Retries and duplicate sends
Agents retry. Pass idempotencyKey on send_email and reply and Sendmux will send once, even if the same call arrives several times inside 24 hours. Any stable string works — a task id, a thread id, a hash of the message.
Details: idempotency.
Common errors
| What you see | Why | Fix |
| --- | --- | --- |
| No sender address | No from on the call and no defaultFrom set | Set defaultFrom, or have the model pass from |
| Send rejected on an agent token | The token is self-registered and not yet owner-approved | Complete the owner invite and approval |
| Auth failure | Key lacks send or receive permission | Check the key's scope in the dashboard |
Related
- Quickstart
- Mailboxes
- All Sendmux SDKs
- Pricing — usage-based, no per-seat or per-mailbox fees
Licence
MIT. See the licence file.
