Mailgun’s REST API v3 has been production-stable since 2013, ships seven official SDKs, and covers the full transactional sending, tracking, validation, and inbound routing lifecycle. What sets it apart in 2026 is that Mailgun now ships an official Model Context Protocol server, released December 19, 2025 under Apache 2.0. That puts Mailgun six months behind Postmark on MCP but well ahead of Amazon SES, SparkPost, and SMTP2GO, none of which have shipped an official MCP as of August 2026. This tab inventories the API surface, the MCP setup path, authentication, rate limits, official SDKs, regional endpoints, and the developer gotchas a buyer should internalise before committing.
Model Context Protocol is the emerging standard for connecting LLM agents (Claude, ChatGPT, Cursor, Windsurf, custom OpenAI Agents SDK deployments) to external tools. Mailgun’s official MCP server closes a gap that had defined Postmark’s differentiation for most of 2025, and gives Mailgun customers a first-party path to AI-driven email operations without a Zapier bridge.
Shipped at github.com/mailgun/mailgun-mcp-server on December 19, 2025. Open source Apache 2.0, Node.js based, local execution only. Exposes tools covering send_email, template CRUD, mailing list management, delivery statistics, suppression lists, domain verification, webhooks, routes, and analytics queries. Compatible out of the box with Claude Desktop, Cursor, VS Code, Windsurf, and Cline. There is no hosted MCP endpoint from Mailgun as of August 2026; teams that want a managed remote MCP currently have to wrap the local server themselves or use one of the community bridges below.
Two options as of August 2026. The official server covers most use cases; the Zapier bridge exists for teams that already run Zapier and want to reuse its authentication and quota model.
First-party, Apache 2.0, Node.js. Local execution via npx or clone-and-build. Covers send_email, templates CRUD, mailing lists, delivery stats, suppressions, domain verification, webhooks, routes, and analytics. Requires API key plus domain in local env vars. No hosted variant.
Bridge access via Zapier’s ecosystem. One MCP tool call uses two tasks from your Zapier quota. Useful when you already run Zapier and want scoped action selection instead of running a local Node server.
The API follows REST conventions with a few Mailgun-specific quirks that trip up first-time users: region-scoped base URLs, HTTP Basic auth with a fixed username, and form-encoded POST bodies rather than JSON on most write endpoints.
| Base URL (US) | https://api.mailgun.net/v3/ |
|---|---|
| Base URL (EU) | https://api.eu.mailgun.net/v3/ — separate account not required, but domains are region-bound |
| Response format | JSON only |
| Request format | application/x-www-form-urlencoded on most POST endpoints, multipart/form-data for attachments |
| Auth | HTTP Basic. Username fixed to api. Password is the API key. |
| Pagination | Cursor-based on events, limit+skip on domains and lists |
| Idempotency | Not natively supported. Use custom v:my-var tags to deduplicate downstream. |
| Webhook signing | HMAC-SHA256 in X-Mailgun-Signature header on every callback |
The API surface is a mix of domain-scoped operations (send, events, logs, suppressions, webhooks, templates) and account-scoped operations (domains, IPs, mailing lists, routes). Domain-scoped paths always start with /{domain}/. Account-scoped paths do not.
One primary mechanism, with domain-scoping as the main permission control.
Send the API key as the HTTP Basic password with the fixed username api. Every SDK handles the base64 encoding of the Authorization header automatically. Domain-scoped keys limit blast radius to a single sending domain; account-wide keys can act on everything. Basic plan allows 2 API keys; higher tiers allow more. Rotate keys through the Control Panel under API Security. HMAC webhook signing is standard on every webhook payload (SHA-256 of timestamp + token in the X-Mailgun-Signature header).
Mailgun does not publish hard per-second rate limits publicly. Practical throughput is governed by the plan email quota per month, reputation-based throttling on new domains, and per-recipient rate limits on major mailbox providers (Gmail, Outlook, Yahoo).
| Constraint | Value | Notes |
|---|---|---|
| Per-second API cap | Not published | Reputation-based throttling on new domains, no documented ceiling once warmed up |
| New-domain warm-up ceiling | ~300/hr | Rises after positive reputation signals from mailbox providers |
| Basic plan monthly quota | 10,000 emails/mo | Overage $1.80 per 1,000 emails |
| Foundation plan quota | 50,000 emails/mo | Overage $1.30 per 1,000 |
| Scale plan quota | 100,000 emails/mo | Overage $1.10 per 1,000. Dedicated IP included. |
| Log retention | 1 day (Basic), 5 days (Foundation), 30 days (Scale) | Determines how far back GET /{domain}/events can query |
| Complaint rate threshold | 0.05% | Auto-triggers manual review or account suspension. Community-observed pattern, not always public. |
| Webhook response timeout | Not published | Exponential backoff retries over ~8 hours before permanent failure |
The complaint-rate threshold is the number one thing that surprises new Mailgun customers, especially those migrating from marketing-first ESPs where 0.1—0.3% complaint rates are considered normal. Mailgun applies transactional-grade thresholds to all sending, and hitting 0.05% for even a short window can trigger a suspension. Segment marketing sends onto a separate provider or a separate account, and monitor the Optimize dashboard for early warning.
Seven first-party libraries maintained by Mailgun engineering. All official SDKs implement send, templates, mailing lists, events, suppressions, and webhooks. Compare with Postmark (13 SDKs), SendGrid (7 SDKs), Amazon SES (SDK per AWS language).
| Language | Package | Install | Repo |
|---|---|---|---|
| Ruby | mailgun-ruby | gem install | GitHub |
| PHP | mailgun/mailgun-php | composer require | GitHub |
| Python | mailgun | pip install | GitHub |
| Java | com.mailgun:mailgun-java | maven | GitHub |
| Go | github.com/mailgun/mailgun-go/v4 | go get | GitHub |
| .NET | Mailgun | NuGet | GitHub |
| Node.js | mailgun.js | npm install | GitHub |
Mailgun does not ship official SDKs for Rust, Kotlin, Swift, or Elixir. Community wrappers exist for all four; quality varies. For Rust and Elixir most teams call the REST API directly with the standard HTTP client of the language.
The nine endpoint groups you will actually use. Full reference at documentation.mailgun.com/docs/mailgun/api-reference.
| Resource | HTTP methods | Description |
|---|---|---|
| Messages /{domain}/messages | POST | Send an email with from, to, subject, text/html, attachments, template variables, tags, tracking flags, and scheduling. |
| Events /{domain}/events | GET | Delivery logs (delivered, failed, opened, clicked, unsubscribed, complained). Retention scales with plan tier. |
| Templates /{domain}/templates | GET, POST, PUT, DELETE | Store, version, and render Handlebars templates server-side. Reference by name at send time. |
| Domains /domains | GET, POST, DELETE | Add, verify, list sending domains. Automatic Sender Security auto-generates CNAME-based DKIM records. |
| Suppressions /{domain}/bounces (etc.) | GET, POST, DELETE | Manage bounces, complaints, unsubscribes, and whitelists per domain. |
| Webhooks /domains/{domain}/webhooks | GET, POST, PUT, DELETE | Subscribe to delivered, permanent_fail, temporary_fail, opened, clicked, unsubscribed, complained. HMAC-signed payloads. |
| Mailing lists /lists | GET, POST, PUT, DELETE | Create mailing lists, manage members. Send to list address list@yourdomain and Mailgun fans out. |
| Routes /routes | GET, POST, PUT, DELETE | Filter and forward inbound emails via expression matching on recipient, from, subject, or headers. |
| IPs /ips | GET, POST | Manage shared and dedicated sending IPs. Dedicated IPs cost $59/mo per IP on Basic and Foundation, included on Scale. |
Two representative snippets covering the two most common first-day tasks: send an email, then set up a webhook to receive delivery events.
import requests
API_KEY = "key-your-mailgun-api-key"
DOMAIN = "mg.yourdomain.com"
response = requests.post(
f"https://api.mailgun.net/v3/{DOMAIN}/messages",
auth=("api", API_KEY),
data={
"from": f"SMTPedia <hello@{DOMAIN}>",
"to": "user@example.com",
"subject": "Your receipt from SMTPedia",
"text": "Thanks for your order.",
"html": "<h1>Thanks for your order.</h1>",
"o:tag": ["receipt", "python-example"],
"o:tracking": "yes"
}
)
print(response.status_code, response.json())const crypto = require('crypto');
const express = require('express');
const SIGNING_KEY = process.env.MAILGUN_WEBHOOK_SIGNING_KEY;
function verify(timestamp, token, signature) {
const hmac = crypto.createHmac('sha256', SIGNING_KEY);
hmac.update(timestamp + token);
return hmac.digest('hex') === signature;
}
const app = express();
app.use(express.json());
app.post('/mailgun/webhook', (req, res) => {
const { timestamp, token, signature } = req.body.signature;
if (!verify(timestamp, token, signature)) {
return res.status(401).send('bad signature');
}
console.log('event', req.body['event-data'].event);
res.status(200).send('ok');
});
app.listen(3000);Mailgun offers two regions with strict data isolation. Region is set at domain creation and cannot be changed without a full re-add and DNS re-verification.
api.mailgun.netapi.eu.mailgun.net — +$10/mo add-onNot your account email, not your account ID. The username in Basic auth is always api. Every SDK hides this; if you call the REST API directly with cURL or a bare HTTP client and pass your email as the username, you get 401 Unauthorized with a message that does not clearly explain why.
Send endpoints, events, templates, and suppressions all live under /{domain}/. If you configure a client with the base URL and forget to prepend the domain on the resource, you get 404. Domain confusion also shows up when moving between staging and production — the base URL is the same, only the domain path segment differs.
Mailgun applies transactional-grade complaint thresholds to every sending domain, regardless of message intent. Marketing-style sends that trigger 0.1% complaints in a single day can and do produce automatic suspensions with no warning email. If you plan to send anything promotional, separate it onto a dedicated account or migrate to an ESP with looser transactional/broadcast separation.
Delivery still happens for messages older than the log retention window; you just cannot query their events after that. Basic plan retention is 1 day. If you need audit-trail visibility beyond 1 day on Basic, stream events to your own storage via a webhook the moment they fire — do not rely on being able to query /{domain}/events later.
A domain added in the US region is invisible from the EU control panel and vice versa. Sending to api.mailgun.net with an API key generated in the EU region returns 401. If your team accidentally added the same domain in both regions, you will have two DKIM signatures competing and unpredictable deliverability. Consolidate on a single region per domain before doing anything else.
Mailgun signs every webhook payload with HMAC-SHA256 in the X-Mailgun-Signature header. Skipping verification is a common shortcut in prototypes that becomes a production security incident when a webhook endpoint is discovered by scanners. Verify signatures on every event, including opens and clicks that seem harmless.
Mailgun maintains public release notes at documentation.mailgun.com/docs/mailgun/release-notes. Key items to know:
/{domain}/analytics/metrics.Yes. Mailgun shipped an official MCP server at github.com/mailgun/mailgun-mcp-server on December 19, 2025. It is open source under Apache 2.0, Node.js based, and local execution only (no hosted variant). It covers send_email, templates, mailing lists, delivery stats, suppressions, domain management, webhooks, routes, and analytics. Compatible with Claude Desktop, Cursor, VS Code, Windsurf, and Cline.
Seven: Ruby, PHP, Python, Java, Go, .NET, and Node.js. All are maintained by Mailgun engineering and implement send, templates, mailing lists, events, suppressions, and webhooks. Rust, Kotlin, Swift, and Elixir do not have official SDKs; community wrappers exist but quality varies.
Mailgun does not publish a hard per-second rate limit. Practical throughput is governed by three factors: plan email quota per month (10,000 on Basic, 50,000 on Foundation, 100,000 on Scale, custom on Enterprise), reputation-based throttling on new domains (approximately 300 emails per hour warm-up ceiling that rises with positive reputation signals), and per-recipient rate limits at Gmail, Outlook, and Yahoo. The complaint-rate threshold of 0.05% is enforced automatically and will suspend sending without warning if exceeded.
HTTP Basic auth with the fixed username api and your API key as the password. Every SDK handles the base64 encoding automatically. If you call cURL or a bare HTTP client, remember the username is literally the string api, not your account email. Domain-scoped API keys are the recommended pattern for production; account-wide keys are convenient for scripts but they can also delete domains and modify billing settings.
Both regions expose the same API surface; only the base URL differs (api.mailgun.net versus api.eu.mailgun.net). EU data residency is a paid add-on ($10/month) that provides GDPR-friendly data isolation. Domains are region-bound: a domain created in the US region is invisible from the EU region and vice versa. Region cannot be changed without a full re-add and DNS re-verification.
Log retention scales with plan: 1 day on Basic and Free, 5 days on Foundation, 30 days on Scale. Delivery itself is not affected by the retention window — messages still deliver — but you cannot query /{domain}/events for events older than the retention window. If you need longer audit trails on Basic or Foundation, stream events to your own storage via a webhook as soon as they fire.
Yes, and it is required in practice. Every webhook payload is signed with HMAC-SHA256 using your webhook signing key. The signature is delivered in the X-Mailgun-Signature header and covers the timestamp + token pair. Verify every event, including opens and clicks. Skipping verification is a common shortcut in prototypes and a common production security incident when webhook endpoints are discovered by scanners.
This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.