
# Elastic Email MCP Server
The official [Model Context Protocol](https://modelcontextprotocol.io) server for the [Elastic Email](https://elasticemail.com) REST API v4. Written in C# / .NET.
[](https://modelcontextprotocol.io)
[](https://dotnet.microsoft.com/download/dotnet/10.0)
[](#tools)
[](https://elasticemail.com/developers/api-documentation/rest-api)
[](https://help.elasticemail.com/en/articles/12595879-elastic-email-mcp)
[](LICENSE)
[](https://github.com/ElasticEmail/elasticemail-mcp-server/releases)
[](https://github.com/ElasticEmail/elasticemail-mcp-server/commits/master)
[](https://github.com/ElasticEmail/elasticemail-mcp-server/issues)
[](https://github.com/ElasticEmail/elasticemail-mcp-server/stargazers)
[Installation](#installation) โข
[Quick start](#quick-start) โข
[Tools](#tools) โข
[Examples](#more-examples) โข
[Contributing](#contributing)
---
## Features
- **Transactional and bulk email.** Let your AI assistant send single messages or bulk sends, with plain content or an existing template.
- **Contacts and lists.** Add, import, list and delete contacts, and create and manage contact lists.
- **Campaigns.** Create, update, pause and list campaigns, including A/X split tests and scheduled sends.
- **Segments and templates.** Create and read segments, and look up personal or global templates.
- **Statistics.** Read opens, clicks and other numbers for one campaign or all of them.
- **Works with any MCP client.** VS Code (GitHub Copilot agent mode), Cursor, Claude Code and other clients that speak MCP over HTTP.
- **Per-request authentication.** Each client sends its own Elastic Email API key. The server keeps no credentials of its own.
> [!TIP]
> Don't want to run a server? Elastic Email hosts this server at **`https://mcp.elasticemail.com`**. See the [hosted MCP guide](https://help.elasticemail.com/en/articles/12595879-elastic-email-mcp). This repository is for running it yourself.
## Requirements
| Requirement | Version |
| --- | --- |
| [.NET SDK](https://dotnet.microsoft.com/download/dotnet/10.0) | 10.0 or later |
| Network | Port **5001** open for HTTP, outbound HTTPS to `api.elasticemail.com` |
| MCP client | Any client that supports MCP over HTTP |
You'll also need an Elastic Email **API key**. You can create one in your [API settings](https://app.elasticemail.com/marketing/settings/new/manage-api). Give it **view and modify** access to Account, Templates, Campaigns, Contacts, Files and Send HTTP, and at least **view** access to Access Tokens. The server rejects keys that can't list API keys.
## Installation
Clone the repository and build it:
```bash
git clone https://github.com/ElasticEmail/elasticemail-mcp-server.git
cd elasticemail-mcp-server
dotnet build src/ElasticEmail.Mcp.Service.sln
```
The build restores its NuGet dependencies ([ModelContextProtocol.AspNetCore](https://www.nuget.org/packages/ModelContextProtocol.AspNetCore), [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json) and [Serilog.AspNetCore](https://www.nuget.org/packages/Serilog.AspNetCore)) for you.
## Quick start
> [!IMPORTANT]
> Elastic Email only sends from verified domains. Before your first send, [verify your sending domain](https://help.elasticemail.com/en/articles/4934400-how-to-verify-your-domain) and use an address on that domain as the sender.
### Run the server
```bash
dotnet run --project src/ElasticEmail.Mcp.Service.csproj
```
The server listens on `http://0.0.0.0:5001/` and writes daily rolling logs to the working directory.
### Connect VS Code (GitHub Copilot)
Add the server to `.vscode/mcp.json` in your workspace:
```json
{
"inputs": [
{
"type": "promptString",
"id": "elasticemail-api-key",
"description": "Elastic Email API key",
"password": true
}
],
"servers": {
"elasticemail": {
"type": "http",
"url": "http://localhost:5001/",
"headers": {
"X-Auth-Token": "${input:elasticemail-api-key}"
}
}
}
}
```
Then open Copilot Chat, switch to **Agent** mode, click **Start** above the server entry, and check that the Elastic Email tools are selected in the tools picker.
> [!TIP]
> Keep your API key out of files you commit. The `inputs` prompt above asks for it once and stores it securely in VS Code.
### Connect Claude Code
```bash
claude mcp add --transport http elasticemail http://localhost:5001/ \
--header "X-Auth-Token: $ELASTICEMAIL_API_KEY"
```
### Connect Cursor
Add the server to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"elasticemail": {
"url": "http://localhost:5001/",
"headers": {
"X-Auth-Token": "YOUR_API_KEY"
}
}
}
}
```
### Try it
Ask your assistant something like:
- "Check that the Elastic Email MCP server is ready."
- "Send a transactional email to john.doe@example.com from no-reply@yourdomain.com with the subject *Welcome aboard!*"
- "Create a list called *beta-testers* with jane@example.com and john@example.com."
- "Show me open and click statistics for all my campaigns."
The `from` address must use a domain you've [verified in your Elastic Email account](https://help.elasticemail.com/en/articles/4934400-how-to-verify-your-domain). If you leave it out, the server uses your account's default sender.
## More examples
More complete, runnable samples are in the **[Elastic Email examples repository](https://github.com/ElasticEmail/elasticemail-examples)**. It covers transactional email, SMTP, webhooks, inbound email, contacts and serverless platforms across 20+ languages and frameworks.
- ๐ค [AI agent examples](https://github.com/ElasticEmail/elasticemail-examples/tree/main/ai-agents-elasticemail-examples) (LangChain, OpenAI Agents, Vercel AI SDK)
- ๐ฃ [.NET / C# examples](https://github.com/ElasticEmail/elasticemail-examples/tree/main/dotnet-elasticemail-examples)
- ๐ [All examples](https://github.com/ElasticEmail/elasticemail-examples)
## Authentication
| Header | Sent by | Used for |
| --- | --- | --- |
| `X-Auth-Token` | Your MCP client, on every request | Your Elastic Email API key. The server checks it against `GET /v4/security/apikeys` and forwards it on every API call. |
Requests without the header, or with a key the API rejects, get `401 Unauthorized`.
> [!IMPORTANT]
> The server speaks plain HTTP, so the API key travels unencrypted. Keep it on `localhost` or a private network. If you expose it, put it behind a reverse proxy that terminates TLS.
## API limits
The server calls the Elastic Email API v4 with your key, so the API's limits apply:
- Up to **20 concurrent connections** per account. The API doesn't return `429`; a `5xx` under load means slow down and retry with backoff
- A request with no response for about **50 seconds** fails with a gateway error (`5xx`)
- Up to **50 recipients** per `POST /emails/transactional` and **1000 contacts or suppressions** per upload (`413` above that)
## Tools
The server exposes **26 tools** in 6 groups: `EmailSending`, `ContactsManagement`, `CampaignManagement`, `SegmentsManagement`, `TemplatesManagement` and `HealthCheck`. Most tools return the API's JSON response as a string. Tools marked **bool** return only `true` or `false`.