mailcow-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mailcow-mcp-serverGive me a reputation snapshot for the last 24 hours."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mailcow-mcp-server
An MCP server that gives Claude direct access to a Mailcow install and the mail host underneath it — built for the part of self-hosted email that actually hurts: sending reputation.
Wrapping the Mailcow API is the easy half. The useful half is the analysis layer, which reads Postfix delivery logs and answers the question you actually have: is a provider unhappy with us, and if so, why, and what do we do about it?
> Give me a reputation snapshot for the last 24 hours.
Verdict: HEALTHY
1,265 delivery attempts across 606 recipients at major providers
Yahoo/AOL 344 · Microsoft 87 · Apple 61 · Google 60 — all 100% delivered
Queue empty · 0 bans · 0 self-throttled · Rspamd 0 rejects⚠️ Read this before installing
This server hands a language model administrative control of a mail server, and some of the text it reads is written by strangers.
Untrusted input reaches tools that can delete things. mailcow_get_queued_message returns third-party message bodies. reputation_delivery_breakdown parses rejection strings written by remote mail servers. Both are attacker-influenced. The same session also has tools that can delete a mailbox, drop the queue, or rotate a DKIM key.
Two guardrails exist and you should not remove them:
Irreversible operations refuse without
confirm: true— deleting a domain, mailbox, alias, DKIM key or quarantine item, and flushing or dropping the queue. The refusal tells the model to show you the scope first.mailsrv_runallow-lists read-only commands (docker ps/logs/inspect,postqueue -p,rspamc stat,cat/grep/tail,df/free/uptime,dig,systemctl status). Everything else — restarts,postsuper, package installs, config edits — requiresconfirm: true.
If you want a lower-risk setup, issue a read-only Mailcow API key. Every read tool keeps working; the management tools fail cleanly with a message explaining why.
Related MCP server: ai-ssh-mcp
What's in it
Reputation analysis — the reason this exists.
Tool | Answers |
| "How are we doing right now?" Containers, queue, delivery outcomes, self-throttling, Rspamd, bans → a verdict of healthy / watch / degraded / critical. |
| "Who's unhappy and what did they say?" Per-recipient delivery outcomes grouped by mailbox provider, with each remote MTA's rejection text classified. |
| "Can we send more yet?" Per-provider acceptance against configured rate limits, returning increase / hold / reduce / stop for each. |
| "Is our DKIM actually valid?" Compares the key Mailcow signs with against what DNS publishes, plus SPF/DMARC presence and auth failures in the log. |
Mailcow administration — 19 tools covering domains, mailboxes, aliases, DKIM, rate limits, allow/block policy, the queue, quarantine, and netfilter. Plus mailcow_api_request, a raw passthrough for any route without a dedicated tool, so you're never boxed in.
Mail host access — 6 SSH-backed tools for Postfix queue inspection, Rspamd stats, deep log search beyond Mailcow's Redis retention, host health, DNS/PTR checks, and arbitrary commands.
Full tool list in Tools below.
Requirements
Node.js 18+
A Mailcow install (developed against 2026-07a)
A Mailcow API key — read-write for management, read-only if you'd rather not grant that
Optional: SSH access to the mail host with Docker permissions, for the
mailsrv_*tools and deeper log history
Install
git clone https://github.com/YOUR-USER/mailcow-mcp-server.git
cd mailcow-mcp-server
npm install
npm run build
cp .env.example .env # fill it in
node scripts/selftest.mjsselftest.mjs verifies the API key, checks whether it's read-write or read-only, confirms the queue and Postfix logs are readable, and — if SSH is configured — proves Docker access and resolves the Mailcow container names. Run it before registering. Every failure mode below is easier to diagnose there than through a chat client.
Getting a Mailcow API key
Mailcow UI → System → Configuration (/admin/system) → Access → Admins tab → scroll to Read-Write Access:
Tick Activate API, hit Save — the key field populates
Add the public IP of the machine running this server to "Allow API access from these IPs/CIDR network notations"
That second step causes most 401s. The IP that needs allow-listing is wherever the MCP server runs — usually your desktop, not the mail server. If your ISP rotates your address, either use a CIDR range or tick Skip IP check for API (which makes the key alone sufficient — treat it accordingly).
SSH setup
Generate a dedicated key rather than reusing your interactive one — it can be revoked independently and shows up distinctly in authorized_keys:
ssh-keygen -t ed25519 -N "" -C "mailcow-mcp" -f ~/.ssh/mailcow_mcp
ssh-copy-id -i ~/.ssh/mailcow_mcp.pub root@your-mail-host-N "" sets an empty passphrase. An encrypted key fails with "Encrypted private OpenSSH key detected" — this server talks to the key file directly and never consults ssh-agent, so a key your normal ssh opens silently via the agent will still fail here.
The SSH user needs Docker access (root, or a member of the docker group). Note that docker-group membership is effectively root — what a dedicated user buys you is a separate audit trail and independent revocation, not reduced privilege.
Without SSH the server still works. You lose the mailsrv_* tools and log history is capped at what Mailcow keeps in Redis (a few thousand lines).
Configuration
Variable | Required | Notes |
| yes | Mailcow UI origin, no trailing slash |
| yes | Read-write for management tools; read-only works for everything else |
| no | Enables |
| no | Default |
| no | Default |
| no | Absolute path. OpenSSH format — a PuTTY |
| no | Only if the key is encrypted |
| no | Alternative to key auth |
Note the server itself does not read .env — that file exists for selftest.mjs. At runtime, credentials come from your MCP client's config.
Registering
Claude Desktop — Settings → Developer → Edit Config:
{
"mcpServers": {
"mailcow": {
"command": "node",
"args": ["/absolute/path/to/mailcow-mcp-server/dist/index.js"],
"env": {
"MAILCOW_BASE_URL": "https://mail.example.com",
"MAILCOW_API_KEY": "your-key",
"MAIL_SSH_HOST": "203.0.113.10",
"MAIL_SSH_USER": "root",
"MAIL_SSH_KEY_PATH": "/home/you/.ssh/mailcow_mcp"
}
}
}
}On Windows, escape backslashes: "C:\\Users\\you\\.ssh\\mailcow_mcp". Then fully quit the app from the system tray — closing the window leaves the server process running with the old build.
Claude Code — one command:
claude mcp add mailcow -s user \
-e MAILCOW_BASE_URL=https://mail.example.com \
-e MAILCOW_API_KEY=your-key \
-e MAIL_SSH_HOST=203.0.113.10 \
-e MAIL_SSH_USER=root \
-e MAIL_SSH_KEY_PATH=/home/you/.ssh/mailcow_mcp \
-- node /absolute/path/to/mailcow-mcp-server/dist/index.jsTwo ideas worth understanding
Everything useful in the analysis layer rests on these.
Recipients, not attempts
Postfix retries a deferred address for days. One permanently refused subscriber can generate 150+ delivery attempts. Count attempts and a dozen dead addresses look like a provider-wide outage:
Attempts | Unique recipients | |
| 169 | 1 |
| 468 | 9 |
| 97 | 2 |
Read as attempts, that's a 56% deferral rate and an urgent French deliverability crisis. Read as recipients, it's about twenty dead addresses that need suppressing.
Every tool reports both. unique_recipients and delivery_rate are the real numbers; attempts and attempts_per_recipient exist to expose retry storms. No verdict is issued below 20 recipients — the tools return insufficient_data rather than a percentage computed from noise.
Failure categories, not a bounce rate
An aggregate bounce rate tells you nothing actionable. These do:
Category | Severity | Means | Do |
| critical | An RBL is named in the response | Delist first — sending more deepens it |
| critical | 5.x policy refusal; the provider has decided about you | Stop to that provider, fix the cause |
| critical | SPF/DKIM/DMARC failed at the receiver | Run |
| warning | 4.x rate signal | Slow down — volume is ahead of your standing |
| warning | Reachability, not reputation | Usually transient |
| warning | Certificate or handshake | Check your TLS config |
| info | Normal; retries succeed | Nothing |
| info | List hygiene | Suppress — a high rate causes reputation damage |
| info | Recipient-side | Nothing |
| info | Dead domain | Suppress |
Two rules the classifier enforces that are easy to get wrong:
The remote's SMTP code beats Postfix's DSN. Postfix records a connect-stage refusal as a deferral with a 4.x DSN even when the server plainly said 554. Trusting the DSN downgrades a hard reputation rejection into a throttle and buries it.
A 4.x response is never a permanent block. Gmail's 421-4.7.28 throttle contains the words "unusual rate of unsolicited mail" — matched naively, that reads as a hard block and sends you chasing the wrong fix. Blocklist mentions outrank both rules, because a deferral citing an RBL is still an RBL problem.
Tools
reputation_snapshot · reputation_delivery_breakdown · reputation_warmup_status · reputation_auth_audit
mailcow_status · mailcow_list_domains · mailcow_list_mailboxes · mailcow_list_aliases · mailcow_get_dkim · mailcow_get_logs · mailcow_get_queue · mailcow_get_queued_message · mailcow_get_quarantine · mailcow_get_ratelimits · mailcow_get_policy · mailcow_get_fail2ban · mailcow_get_rspamd_actions
mailcow_manage_domain · mailcow_manage_mailbox · mailcow_manage_alias · mailcow_manage_dkim · mailcow_manage_queue · mailcow_manage_quarantine · mailcow_set_ratelimit · mailcow_manage_policy · mailcow_edit_fail2ban · mailcow_api_request
mailsrv_postfix_queue · mailsrv_rspamd_stats · mailsrv_mail_log · mailsrv_host_health · mailsrv_dns_check · mailsrv_run
Every tool carries a full description with argument types, return schema, and worked examples — your client will show them.
Things it's good at
"Gmail deferrals are up — what exactly are they saying?"
"Does the DKIM record in DNS still match what Mailcow is signing with?"
"Are we clear to raise warmup volume this week?"
"The queue is at 4,000 — what's stuck and why?"
"Which addresses are being retried into the ground? I want a suppression list."
"Set the daily send limit on this domain to 2,000."Troubleshooting
401 from the Mailcow API — Either the key is wrong or the source IP isn't allow-listed. It's usually the IP, and it's the IP of this machine, not the mail server. A read-only key also returns 401 on write routes; selftest.mjs distinguishes these.
Cannot read SSH key at ~/.ssh/... — Use an absolute path. ~ expansion depends on HOME/USERPROFILE being set, which isn't guaranteed under a GUI-launched process.
Encrypted private OpenSSH key detected — The key has a passphrase. Either set MAIL_SSH_KEY_PASSPHRASE or generate a passphrase-free key for this purpose. ssh-agent doesn't help here.
Tools show old behavior after an update — dist/ is what runs. Run npm run build, then fully restart the client. The tests import from dist/, so a passing test suite proves the build is current and points at the client process instead.
No running container matching "postfix-mailcow" — The SSH user can't reach Docker, or Mailcow isn't up. Check docker ps as that user.
Quarantine tools return nothing — Mailcow disables quarantine until you set retentions per mailbox and a maximum size under quarantine settings. Expected on a send-focused install.
Testing
npm test # parser + classifier, then server boot and guard checks
node scripts/parser-test.mjs # 26 cases, offline — includes verbatim rejection strings from live logs
node scripts/smoke-test.mjs # boots over stdio, lists tools, verifies the confirm guards fire
node scripts/selftest.mjs # live connectivityThe classifier tests carry real rejection strings from KPN, MailChannels, Cisco IronPort, Orange, Rackspace, Gmail, Comcast and Cloudflare. Each one was misclassified at some point; they're pinned so it stays fixed.
Contributions welcome, and one kind especially: if your MTA gets told something this classifier mishandles, open an issue with the raw rejection string. That's the highest-value contribution to this project and it costs you a copy-paste.
Limitations
Developed and tested against one Mailcow install (2026-07a). Container naming, log formats and API surface vary across versions.
Log parsing assumes standard Postfix format from the
postfix-mailcowcontainer.Complaint rate is invisible. The recipient hitting "spam" never reaches your MTA. For volume sending, Google Postmaster Tools is mandatory alongside this — it measures the one threshold nothing here can see.
The provider map covers major consumer mailbox providers; anything unmapped groups by domain.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Cold email infrastructure — campaigns, prospects, mailbox health and replies via Claude.
Connect any mailbox to Claude, ChatGPT & AI: read, send, reply, schedule & search emails.
Official remote MCP server of MailSenpai, the EU-hosted email marketing platform. Connect Claude, ChatGPT, Cursor or another MCP client with OAuth 2.1 and PKCE. 74 tools manage lists, subscribers, segments, templates, draft campaigns and stats, and check email DNS, blacklists and spam. Sends and deletions require explicit confirmation; every call is logged. The same team also offers SMTP Senpai, an SMTP relay and email API for transactional sending: https://en.mailsenpai.com/smtp-senpai/.
DMARC analytics for AI assistants: SPF/DKIM, compliance, anomalies, p=reject readiness, onboarding.
Related MCP Servers
- AlicenseCqualityDmaintenanceEnables Claude to fully manage self-hosted Supabase instances, covering authentication, database, storage, edge functions, and more.423MIT
- AlicenseAqualityDmaintenanceEnables natural language SSH server management via Claude Code, allowing users to read logs, check services, run commands, and transfer files across multiple servers.6MIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude AI to execute commands across multiple remote servers via SSH, with TOTP 2FA authentication and 29 built-in MCP tools for server management.-
- -licenseNot gradedqualityNot gradedmaintenanceEnables Claude to manage a Mailcow mail server and analyze sending reputation by reading Postfix logs, providing tools for administration, reputation snapshots, and deliverability insights.-