Email MCP server
MAAC Go Email has a remote MCP server at https://edm.cresclab.com/api/mcp. Connect it to Claude Code, Cursor, VS Code, Windsurf, Claude Desktop or Codex and your agent can send transactional email, manage templates and contacts, send a campaign you already wrote, and read delivery reports and credit — 22 tools, authenticated with your API key. Every account gets a test key at signup, and the free plan includes 100 contacts and 200 emails a month with no credit card.
Every snippet uses the placeholder sk_test_... — put your own key there. Claude Code, Cursor, VS Code and Windsurf talk to the endpoint directly. Claude Desktop and Codex only start local servers, so they reach it through the open-source mcp-remote bridge, which needs Node.js 18 or later.
Run once:
claude mcp add --transport http maacgo-email https://edm.cresclab.com/api/mcp --header "Authorization: Bearer sk_test_..."
Paste into ~/.cursor/mcp.json for every project, or .cursor/mcp.json for one.
{
"mcpServers": {
"maacgo-email": {
"url": "https://edm.cresclab.com/api/mcp",
"headers": { "Authorization": "Bearer sk_test_..." }
}
}
}Save as .vscode/mcp.json in your workspace. VS Code asks for the key the first time the server starts and stores it, so the key never sits in the file. Note the top-level key is servers, not mcpServers.
{
"servers": {
"maacgo-email": {
"type": "http",
"url": "https://edm.cresclab.com/api/mcp",
"headers": { "Authorization": "Bearer ${input:maacgo-email-key}" }
}
},
"inputs": [
{
"type": "promptString",
"id": "maacgo-email-key",
"description": "MAAC Go Email API key",
"password": true
}
]
}Paste into ~/.codeium/windsurf/mcp_config.json. Windsurf names the URL field serverUrl.
{
"mcpServers": {
"maacgo-email": {
"serverUrl": "https://edm.cresclab.com/api/mcp",
"headers": { "Authorization": "Bearer sk_test_..." }
}
}
}Settings → Developer → Edit Config opens the file (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\). Restart Claude Desktop after saving. Needs Node.js 18+. The key sits in env so the space in “Bearer …” never has to pass through the command line.
{
"mcpServers": {
"maacgo-email": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://edm.cresclab.com/api/mcp",
"--header", "Authorization:${MAACGO_AUTH}"
],
"env": { "MAACGO_AUTH": "Bearer sk_test_..." }
}
}
}Add to ~/.codex/config.toml, then start a new Codex session. Needs Node.js 18+.
[mcp_servers.maacgo-email]
command = "npx"
args = ["-y", "mcp-remote", "https://edm.cresclab.com/api/mcp", "--header", "Authorization:${MAACGO_AUTH}"]
env = { MAACGO_AUTH = "Bearer sk_test_..." }Restart the client or reload its MCP servers, then ask: “Call get_me on maacgo-email.” The answer names your account and its key_mode — test or live. You can also open the endpoint in a browser for a summary without a key.
Paste this once into CLAUDE.md, AGENTS.md, your Cursor rules or your client’s custom instructions, so “email the receipt to Ada” goes to this server instead of a hand-written script.
When I ask you to send an email, a newsletter, or a transactional message (receipts, one-time codes, order updates), use themaacgo-emailMCP server. Callget_mefirst: a test key records sends without delivering them. For a campaign, runestimate_campaignbeforesend_campaignand tell me the recipient count. If a send is refused for credit, show me the top-up link from the error.
Every tool calls the public REST API with your key, so the same scopes, allowance, credit and suppression list apply as to a direct curl. There is no privileged path.
Read-only changes nothingWrites changes data in your accountSends email delivers with a live keyDestructive deletes something
| Send | ||
|---|---|---|
send_email | Send one transactional email — a receipt, a one-time code, an order update — with inline HTML or a stored template plus variables. | Sends email |
| Templates | ||
list_templates | Stored templates and the {{variables}} each one expects. | Read-only |
get_template | One stored template: subject, HTML, text and variables. | Read-only |
create_template | Save a reusable template; {{name|fallback}} works in subject, HTML and text. | Writes |
update_template | Change a stored template; only the fields you pass change. | Writes |
delete_template | Delete a stored template. Messages already sent with it are unaffected. | Destructive |
| Messages | ||
get_message | Whether one transactional message was delivered, bounced or is still in flight. | Read-only |
list_messages | The 100 most recent transactional messages with their status. | Read-only |
| Campaigns | ||
list_campaigns | Every campaign with its status and, once sent, its delivery funnel. | Read-only |
get_campaign | One campaign in full: subject, content, audience, status and schedule. | Read-only |
campaign_report | The full funnel for one campaign, plus per-recipient rows. | Read-only |
estimate_campaign | How many contacts an audience actually reaches after unsubscribes, bounces and exclusions. | Read-only |
send_campaign | Send or schedule a draft a person already wrote. Refused, with a priced breakdown, if credit cannot cover it. | Sends email |
| Contacts | ||
list_contacts | Contacts with their tags and whether each one can be mailed. | Read-only |
add_contact | Add one contact who agreed to hear from you. | Writes |
import_contacts | Add up to 5,000 contacts in one call; addresses already on the list and invalid ones are skipped. | Writes |
tag_contacts | Add or remove tags on many contacts at once. It never deletes a contact. | Writes |
contact_activity | One contact’s campaign history — sent, opened, clicked, bounced — newest first. | Read-only |
| Account & credit | ||
get_me | The account behind the key: plan, limits, usage and key_mode (test or live). | Read-only |
wallet_balance | Prepaid credit, this month’s usage and the free allowance left. | Read-only |
wallet_events | The credit ledger: top-ups, send charges and refunds, newest first. | Read-only |
quote_cost | What sending a given number of emails would cost right now: how many are free, how many are billed, and the balance. | Read-only |
The header. Send your key as Authorization: Bearer sk_test_... (or sk_live_...). A client that cannot set that header can send x-maacgo-api-key: <key> instead. initialize and tools/list answer without a key, so a client can show the tool list before you add one; every tools/call needs a key.
Test and live keys. The prefix decides. sk_test_ keys only record: send_email returns status: "sent" with test_mode: true, and nothing reaches any inbox or is charged. Every new account starts with a test key. When you want mail to arrive, create an sk_live_ key on the Developers page and swap it in. A live key is issued once the account has a verified sending domain (SPF, DKIM and a return-path MX — three DNS records, free on every plan), credit or a paid plan.
What a key cannot do. Keys are not granted campaigns.write: an agent can send a campaign a person wrote, but cannot create one. A key can never start a payment or issue another key. An unsubscribe, hard bounce or complaint anywhere on the account stops send_email too — campaigns and the API share one suppression list.
@maacgo/email-mcp is built but not published to npm yet. The HTTP endpoint does everything it would; stdio-only clients use mcp-remote as shown above.no-reply@edm.cresclab.com with your display name; campaigns can use your verified domain.https://edm.cresclab.com/api/mcp that gives an AI agent 22 tools for your MAAC Go Email account: send transactional email, manage templates and contacts, send a campaign you already wrote, and read delivery reports and credit. It speaks Streamable HTTP and authenticates with your API key.sk_test_ records every call, and send_email returns status sent with test_mode set to true, but nothing is delivered and nothing is charged. Call get_me to see which mode a key is in. To deliver, create an sk_live_ key on the Developers page; it is issued once the account has a verified sending domain (SPF, DKIM and a return-path MX, free on every plan), credit or a paid plan.estimate_campaign shows the reach first. delete_template is the only tool that deletes anything. An unsubscribe, hard bounce or complaint anywhere on the account blocks send_email too, because campaigns and the API share one suppression list.send_campaign answers with a priced breakdown, and the error carries a top-up link for you to open, because an agent cannot pay. Ask for quote_cost or estimate_campaign before a large send.@maacgo/email-mcp, is built but not published to npm. The HTTP endpoint does everything it would, and clients that only start local servers reach the endpoint through mcp-remote, as shown above.