Vercel Chat SDK adapter for Mailtrap email. Bidirectional: receive emails via Mailtrap Inbound webhooks, send replies via the Mailtrap Email API.
npm add @mailtrap/chat-sdk-adapter chat @chat-adapter/state-memoryimport { createMailtrapAdapter } from "@mailtrap/chat-sdk-adapter";
import { MemoryStateAdapter } from "@chat-adapter/state-memory";
import { Chat } from "chat";
const mailtrap = createMailtrapAdapter({
fromAddress: "bot@yourdomain.com",
fromName: "My Bot", // optional
// apiKey: "...", // or set MAILTRAP_API_TOKEN
// webhookSecret: "...", // or set MAILTRAP_WEBHOOK_SECRET
// category: "chat-sdk", // Email API category on every outbound send
});
const chat = new Chat({
userName: "email-bot",
adapters: { mailtrap },
state: new MemoryStateAdapter(),
});
// New inbound email (new thread)
chat.onNewMention(async (thread, message) => {
await thread.subscribe();
await thread.post(`Got your email: ${message.text}`);
});
// Follow-up email in a subscribed thread
chat.onSubscribedMessage(async (thread, message) => {
await thread.post(`Reply: ${message.text}`);
});Point your Mailtrap Inbound webhook at your server's /webhook endpoint. See examples/basic for a full working server.
This adapter is for inbound / opted-in email loops: support replies, form submissions, demo requests, and other conversations the recipient started or agreed to.
Do not use it for cold outreach, scraped lists, or unsolicited sales prospecting. See Mailtrap's Acceptable Use Policy.
| Variable | Description |
|---|---|
MAILTRAP_API_TOKEN |
Mailtrap API token (overridden by config.apiKey) |
MAILTRAP_WEBHOOK_SECRET |
Webhook signing secret (overridden by config.webhookSecret) |
FROM_ADDRESS |
Sender address (overridden by config.fromAddress) |
FROM_NAME |
Sender display name (overridden by config.fromName) |
interface MailtrapAdapterConfig {
/** Sender email address. Falls back to FROM_ADDRESS. */
fromAddress?: string;
/** Display name for the From header. Falls back to FROM_NAME. */
fromName?: string;
/** Mailtrap API token. Falls back to MAILTRAP_API_TOKEN. */
apiKey?: string;
/** Webhook signing secret. Falls back to MAILTRAP_WEBHOOK_SECRET. */
webhookSecret?: string;
/** Email API `category` field (shown as X-MT-Category in SMTP/logs). Defaults to "chat-sdk". */
category?: string;
}```
## Features
### Email Threading
Threads are resolved using standard `Message-ID`, `In-Reply-To`, and `References` email headers. Reply chains are automatically grouped into Chat SDK threads.
### Outbound category
Every agent-sent message includes Mailtrap Email API `category` (dashboard `X-MT-Category`) so samples filter cleanly. Default: `chat-sdk`.
### Send Emails Proactively
For **opted-in** contacts only, start a new email thread:
```ts
const threadId = await chat.getAdapter("mailtrap").openDM("user@example.com");
const thread = await chat.thread("mailtrap", threadId);
await thread.post("Hello from the bot!");Email is inherently one-shot. The following operations throw NotImplementedError:
editMessage/deleteMessageaddReaction/removeReactionstartTyping
| Example | Description |
|---|---|
| basic | Echo / ack bot — replies to inbound and follow-ups |
cd examples/basic
cp .env.example .env
# fill MAILTRAP_API_TOKEN, MAILTRAP_WEBHOOK_SECRET, FROM_ADDRESS
npm install
npm startRequires a verified sending domain and Mailtrap Inbound (custom domain webhook) pointed at POST /webhook. Uses the production Email API — not Sandbox.
The @mailtrap npm org is owned by Mailtrap. This repo prepares @mailtrap/chat-sdk-adapter@0.1.0 for publish:
npm run build
npm publish --access publicCoordinate the initial publish and version bumps with Mailtrap until org ownership/transfer is complete.
MIT — see LICENSE.
