An MCP server, hosted or local
The Model Context Protocol is how an assistant calls a service through a typed set of tools instead of guessing at HTTP. eusend runs an MCP server two ways from one codebase, and both expose exactly the same tools.
Remote — nothing to install. Point a client at https://mcp.eusend.dev/mcp and send your key as a bearer token. The hosted server holds no key of its own; it forwards authenticated calls to the API, so it can never do anything your key couldn’t.
claude mcp add --transport http eusend https://mcp.eusend.dev/mcp \
--header "Authorization: Bearer eu_live_xxxxxxxxxxxx"Local — the server runs on your machine over stdio and reads the key from your own environment, so it never leaves your computer.
claude mcp add eusend --env EUSEND_API_KEY=eu_live_xxxxxxxxxxxx \
-- npx -y @eusend_dev/mcpWhat the tools cover
| Emails | send_email, list_emails, get_email, cancel_email |
| Domains | list_domains, get_domain, create_domain |
| Audiences & contacts | list_audiences, create_audience, list_contacts, create_contact |
| Broadcasts | list_broadcasts, get_broadcast, create_broadcast, send_broadcast |
Where we drew the line
Giving a model tools is giving it the ability to act on a production account, and the honest answer to “what if it gets it wrong” is to not hand it the dangerous verbs in the first place.
- No destructive tools exist. Deleting domains, audiences, contacts, or API keys is not exposed over MCP at all. Not gated behind a confirmation — simply absent.
- Send-only keys. A
sending_accesskey can send and nothing else; every other tool returns403 FORBIDDEN. That is the key to hand an agent you want writing mail but not reading your delivery log. - Test keys for the whole loop. An
eu_test_key lets an agent exercise sending, webhooks, and error handling end to end without a message reaching anyone. - Bulk sends ask first.
send_broadcastmails an entire audience, so the tool instructs clients to confirm before calling it.
A skill, so it knows how eusend behaves
Tools let an assistant act. They don’t tell it that the sender domain has to be verified first, that a retry without an idempotency key double-sends, or that a webhook signature covers the raw request body and not the parsed JSON. Those are the mistakes that reach production, and no amount of tool schema prevents them.
The eusend plugin for Claude Code ships a skill written around exactly those failures, plus the MCP server, in one install.
/plugin marketplace add eusend-dev/eusend-skill
/plugin install eusend@eusendClaude loads it on its own when a task involves eusend — an SDK import, an EUSEND_API_KEY in the environment, or a prompt that mentions us. “Add password reset emails to this app using eusend” produces an integration that already handles the things people usually discover in week three.
Docs a model can read in one fetch
An assistant working from memory invents endpoints. The fix is to give it the real thing, cheaply enough that fetching beats guessing.
| llms.txt | An index of every documentation page with its description — eusend.dev/llms.txt. |
| llms-full.txt | The entire documentation set as one file, for when you want the field-level detail in a single request — eusend.dev/llms-full.txt. |
| Raw Markdown | Any docs page is available as source at /llms.mdx/docs/<path>, without the site chrome. |
An API shaped for generated code
Some of this is design that predates the agents and happens to serve them well. A model writing an integration benefits from the same things a human does, only more so, because it cannot ask a follow-up question.
- Errors are codes.
DOMAIN_NOT_VERIFIEDis something generated code can branch on. A prose message is something it will string-match and get wrong. - Results, not exceptions. The SDKs return
{ data, error }, which is much harder to accidentally leave unhandled than a throw. - Idempotency is first-class. Retry logic is the thing generated code most often gets subtly wrong; an
Idempotency-Keymakes the wrong version harmless. - The surface is small. One send endpoint with optional fields, rather than five near-identical ones — fewer chances to pick the wrong one.
Migrating with an agent
Because our SDK mirrors Resend’s field for field, moving over is mostly mechanical — which is exactly the kind of work to hand to an assistant. The migration page has a prompt built for this: it points the agent at llms-full.txt first so it works from the real reference, branches on the provider it actually finds, names the fields it must not silently drop, and makes it report the DNS steps it cannot perform itself.
Create an account, grab a test key, and add the MCP server. Ask it to send you an email — the whole loop works before you have verified a domain.
Create a free account