@drin00/mcp
v0.1.0
Published
Model Context Protocol server for the Drin transactional email API — let any AI agent send & receive email, manage domains/inboxes/contacts, and read metrics with one API key.
Maintainers
Readme
@drin00/mcp
A Model Context Protocol server for the Drin transactional email API. Give any MCP-capable agent — Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, Devin, your own — the ability to send and receive email and manage domains, inboxes, contacts, suppressions, templates, webhooks, API keys and integrations, and read delivery metrics — full parity with the Drin dashboard, authenticated with a single Drin API key.
Zero third-party dependencies. Runs on Node 20+. Free on every Drin plan.
Install
No install needed — point your MCP client at it with npx:
{
"mcpServers": {
"drin": {
"command": "npx",
"args": ["-y", "@drin00/mcp"],
"env": { "DRIN_API_KEY": "drin_your_key" }
}
}
}Create an API key in the dashboard under Settings → API Keys. If the key is
account-wide (not scoped to one product), also set DRIN_SENDER to a product
externalId.
Claude Desktop
Add the block above to claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\),
then restart Claude.
Claude Code
claude mcp add drin -e DRIN_API_KEY=drin_your_key -- npx -y @drin00/mcpCursor / Windsurf / VS Code
Add the same mcpServers block to the editor's MCP config
(~/.cursor/mcp.json, Windsurf settings, or .vscode/mcp.json).
Configuration
| Env var | Required | Default | Purpose |
| --- | --- | --- | --- |
| DRIN_API_KEY | yes | — | Bearer token (Settings → API Keys) |
| DRIN_BASE_URL | no | https://api.drin.run | Override for self-hosted/preview |
| DRIN_SENDER | no | — | Default product externalId (account-wide keys) |
Flags --api-key, --base-url, --sender override the env vars.
Tools
54 tools spanning the whole Drin API — everything the dashboard does, an agent can do.
| Group | Tools |
| --- | --- |
| Sending | send_email, send_batch, reply_email |
| Reading | list_emails, get_email, get_email_body, list_email_attachments |
| Domains | list_domains, get_domain, add_domain, verify_domain, delete_domain, get_domain_receiving, set_domain_receiving |
| Inboxes | list_inboxes, create_inbox, get_inbox, delete_inbox |
| Threads | list_threads, get_thread |
| Inbound | simulate_inbound |
| Contacts | list_contacts, create_contact, get_contact, update_contact, unsubscribe_contact, resubscribe_contact, delete_contact |
| Suppressions | list_suppressions, add_suppression, remove_suppression |
| Templates | list_templates, get_template, create_template, update_template, delete_template, render_template, preview_template, list_template_gallery |
| Webhooks | list_webhooks, get_webhook, create_webhook, update_webhook, delete_webhook |
| API keys | list_api_keys, create_api_key, revoke_api_key |
| Metrics | get_metrics |
| Account | list_account_messages (tenant-wide feed across all products) |
| Integrations | list_integrations, get_integration, install_integration, update_integration, uninstall_integration |
Addresses accept "Name <email>" or a bare "email"; recipient fields accept a
string or an array of strings. Show-once secrets (new API keys, webhook signing
secrets) are returned only on the create call — persist them immediately.
Programmatic use
import { createDrinMcpServer } from "@drin00/mcp";
const server = createDrinMcpServer({
apiKey: process.env.DRIN_API_KEY!,
sender: "acme", // optional, for account-wide keys
});
await server.serve(); // wires stdin/stdoutSecurity
The server speaks only to the Drin API over HTTPS using your Bearer key — there
is no separate auth surface. Everything the key is allowed to do, the agent can
do; scope the key to one product and the minimum it needs. Keys are shown once
on creation; store them in your MCP client's env, never in source.
Develop
npm run typecheck # tsc on src + tests
npm run build # emit dist/
npm test # node:test unit suiteMIT licensed.
