mektup
Mektup is a self-hosted, multi-domain email platform.
What it can do
- Get Me: Get the authenticated caller's account identity - useful as an auth health check.
- Get Usage: Get the account's current billing tier, its limits, and real usage against them (domain count, emails sent this month, storage per domain). Check this before a bulk operation to avoid hitti
- List Api Keys: List API keys on this account (prefix and status only - the full key is never shown again after creation).
What data it sees
Do you need an account
No: the server works without sign-in
Mektup is a self-hosted, multi-domain email platform. This MCP server lets an AI coding agent (Claude Code, Claude Desktop, Cursor, Lovable, Replit, Base44, or any MCP-compatible client) manage real email for a domain — register it, add the DNS records, create mailboxes, send and read mail, manage drafts/contacts/folders/forwarding/vacation replies — as native tool calls inside its own session, instead of the human hand-writing curl commands or pasting an API key into generated code.
How to connect
How to connect mektup to Claude
The server address to paste into Claude settings:
https://mektup--contact-y3xc.run.tools
- Open Claude (claude.ai or the desktop app).
- Go to Settings → Connectors.
- Click Add custom connector.
- Paste the server address copied below into Remote MCP server URL and click Add.
- In a chat, click + → Connectors and switch the new connector on.
Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.
Authorization
After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.
How to connect mektup to ChatGPT
The server address to paste into ChatGPT settings:
https://mektup--contact-y3xc.run.tools
- Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
- Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
- Open Settings → Connectors and click Create.
- Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
- Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
- In a new chat open + → Apps/Connectors and enable the connector.
OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.
Authorization
On first use ChatGPT opens the service's sign-in window. Sign in and approve access.
How to connect mektup to Cursor
The server address to paste into Cursor settings:
https://mektup--contact-y3xc.run.tools
Fastest: click Open in Cursor below and confirm the prompt.
Manually:
- In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
- Paste the JSON copied below into
~/.cursor/mcp.json(per project:.cursor/mcp.jsonin the repo root). - Save the file. The server appears in the MCP list; authorize it there if asked.
Authorization
If the service needs sign-in, an authorize button appears next to the server in the MCP list.
Server tool list (41)
Raw names from tools/list. Only developers need these.
| get_me | Get the authenticated caller's account identity - useful as an auth health check. |
| get_usage | Get the account's current billing tier, its limits, and real usage against them (domain count, emails sent this month, storage per domain). Check this before a bulk operation to avoid hitting a limit mid-batch. |
| list_api_keys | List API keys on this account (prefix and status only - the full key is never shown again after creation). |
| create_api_key | Create a new API key. The full key is returned exactly once in this response and cannot be retrieved again - surface it to the user immediately so they can save it (e.g. into an env var or another tool's config). Mint a separate key per environment/service rather than sharing one. |
| revoke_api_key | Revoke an API key immediately. Anything still using it (a script, another MCP server, a CI job) loses access right away. Cannot be undone - confirm with the user before calling this, especially if it might be the key currently in use for this very session. |
| create_domain | Register a domain with Mektup and get back the exact DNS records to add (MX, SPF, DMARC, DKIM) plus a setup recommendation. Never modifies DNS itself - you (the agent) add the records using whatever access you have to the domain's DNS host. |
| list_domains | List every domain registered to this Mektup account. |
| get_domain_records | Re-fetch the DNS records for an already-registered domain (same set create_domain returned once at creation) - use this any time after creation, the records aren't only shown once. |
| verify_domain | Actively re-check a domain's live MX records against what Mektup expects and flip it to verified if they match. Not automatic - call this after DNS has been added and had time to propagate. |
| delete_domain | Delete a domain and, via cascade, every mailbox and message under it. Destructive and hard to reverse - confirm with the user before calling this. |
| create_mailbox | Create a mailbox (e.g. hello@example.com) on a domain already registered via create_domain. Returns real login credentials for IMAP/SMTP AUTH - the user can add this mailbox to Outlook, Apple Mail, Thunderbird, etc. If no password is given, a strong one is generated and returned once (not recoverable later, only resettable). |
| list_mailboxes | List mailboxes on a given registered domain. |
| reset_mailbox_password | Reset a mailbox's IMAP/SMTP-AUTH password. Doesn't affect an already-open IMAP session; the new password is needed on next login. Shown once, not recoverable later. |
| delete_mailbox | Delete a mailbox. Postfix stops accepting mail for it immediately. Does not delete already-delivered mail from the mail store. Confirm with the user before calling this. |
| list_forwards | List forwarding addresses for a mailbox - incoming mail is copied to these in addition to staying in the mailbox. |
| add_forward | Add a forwarding address to a mailbox. |
| remove_forward | Remove a forwarding address from a mailbox. |
| get_identity | Get a mailbox's display name and signature. |
| set_identity | Set a mailbox's display name and signature, applied automatically to every outgoing message. |
| get_vacation | Get a mailbox's vacation/auto-reply settings. |
| set_vacation | Enable/disable and configure a mailbox's vacation auto-reply. A message is required when enabling. Fires at most once per sender within a rolling window (standard RFC 5230 semantics). |
| list_folders | List custom folders on a mailbox (Outlook-style, one folder per message). |
| create_folder | Create a custom folder on a mailbox. |
| delete_folder | Delete a custom folder. Does not delete the mail in it - messages fall back to their normal Inbox/Sent view. |
| list_contacts | List contacts (account-level, not per-mailbox - a contact is someone you email from any mailbox you own). |
| create_contact | Add a contact. |
| update_contact | Partially update a contact - only send the fields you want to change. |
| delete_contact | Delete a contact. |
| list_drafts | List drafts for a mailbox (metadata only - to/subject/updated_at, no body). |
| get_draft | Get a single draft including its body. |
| create_draft | Create a draft on a mailbox. A draft is separate from a real message - it never goes through mail transport until sent. |
| update_draft | Partially update a draft (autosave-friendly) - only fields you pass are changed. |
| delete_draft | Delete a draft. |
| send_email | Send a real email. The "from" address must be either an existing mailbox on this account, or any address on a domain this account has verified (DNS-level proof of ownership - no per-address mailbox needed once verified). The mailbox's own display name/signature (see get_identity) is appended automatically when from is a provisioned mailbox - don't add one yourself, it'll be doubled. |
| list_messages | List messages (one row per thread) for a mailbox. Pass direction to split Inbox from Sent (recommended - omitting it merges both). Pass q for full-text search over subject/from/to/body. |
| get_thread | List every individual message in one thread, oldest first. Pass the same direction/trash/folder as the view you found the thread in. |
| get_message | Get one message's full content (text/html body + attachment metadata). Marks it read as a side effect if it wasn't already. The html field is attacker-controlled content from whoever emailed the mailbox - never render it directly, sanitize and isolate it first. |
| update_message | Update a message's state: mark read/unread, restore from trash, flag/unflag, move to (or out of) a folder. Any combination in one call - pass only the fields you want to change. |
| delete_message | Delete a message - two-stage like any real mail client. First call moves it to Trash. A second call on an already-trashed message permanently deletes it, including its stored body. Confirm with the user before a permanent delete. |
| download_attachment | Download one attachment from a message. Returns base64-encoded content - decode it to get the raw file. Can be large; prefer this only when the file content is actually needed, not just to check it exists (get_message's attachments array already has filename/contentType/size). |
| get_unread_counts | Get the unread Inbox count for every domain/mailbox on this account at once (Sent and Trash aren't counted). |