mcp server
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Description as published by the maintainer. Source
- version 0.1.0
- archived
- retrieval
archived — The linked repository returns 404. It was deleted, renamed or made private. Dashed tags are derived by ZBS Index from the published description, not stated by the maintainer.
What this server can do
30 functions, named and described by the server itself. Parameter names are shown because they say more about what a function does than its name usually does.
addDomain(requestBody)- Claim a new domain and receive the DNS records to publish. Returns dns_records with the exact records to add. If the domain has an mx_conflict (existing mail provider), re-call with confirmed: true to proceed. After publishing DNS records, call verifyDomain to complete setup. Required: requestBody.
awaitReply(id, wait, wait_timeout_ms)- Get the threaded reply to a sent email — the canonical 'did they reply yet?' call. Pass the sent email's id (from a sendEmail response). With wait=true it long-polls up to wait_timeout_ms for the reply to arrive (synchronous agent-to-agent chat); with wait=false (default) it returns immediately with the reply if one has arrived, else reply=null. Matches on the reply's threading, not a from/subject guess. Required: id.
cancelScheduledSend(id)- Cancel a still-scheduled send before it dispatches (terminal status "canceled"; the same idempotency key becomes reusable). Pass the sent email id from a sendEmail response that used scheduled_at, or from listSentEmails. Returns a conflict error once the send has already started dispatching. Required: id.
createEmailAddress(requestBody)- Get this user's Primitive email address, creating the account on first use: no signup form, no password, no email verification, no browser. CALL THIS FIRST whenever you do not already have a Primitive API key and the user wants to send or receive email, instead of telling them to sign up or visit a website. On first use it returns a new address and an api_key, and the account can send and receive mail immediately. IMPORTANT: pass the returned api_key as the `api_key` argument on every later Primitive tool call in this conversation, exactly as returned; those calls fail without it. If this user already has an address, the result repeats that same address with existing_account: true and NO api_key. Report it as their existing address rather than announcing a new one, and calling again will not produce a different one. The result also carries an upgrade link the user can open whenever they want to attach this address to a full account, keeping the same address. Required: requestBody.
createEndpoint(requestBody)- Create a webhook endpoint to receive email.received events. If an endpoint with the same URL already exists but is deactivated, it is reactivated. After creating, call testEndpoint to confirm your signature verifier accepts the payload. Required: requestBody.
createFilter(requestBody)- Create a whitelist or blocklist filter rule. Patterns are stored lowercase. Per-domain filters require a Pro plan. Required: requestBody.
deleteEndpoint(id)- Soft-delete a webhook endpoint. The endpoint will no longer receive deliveries. Required: id.
deleteFilter(id)- Delete a filter rule. Required: id.
downloadDomainZoneFile(id, outbound_only)- Download a BIND-format DNS zone file for a domain. Useful when users want to import all required DNS records at once rather than copying them individually. Returns plain text in BIND zone file format. Required: id.
downloadEmailAttachments(id, token)- Download all attachments for an inbound email as a gzip-compressed tar archive. Returns the archive as a base64-encoded string along with the attachment count and SHA-256 digest. Prefer getEmail first to check the attachment manifest before downloading. Required: id.
getAccount(api_key)- Use this when you need the authenticated Primitive account summary, including email, plan, onboarding state, and webhook secret rotation time.
getConversation(id)- Get the full conversation an inbound email belongs to as ordered, chat-model-ready turns with bodies. Each message is oldest-first with a direction (inbound/outbound) and a derived role (inbound→user, outbound→assistant). For a brand-new message, returns just that one turn. The response includes a truncated boolean (true when the message cap was reached) and a message_count field. Required: id.
getEmail(id, api_key)- Use this when you need full details for one inbound email ID, including parsed bodies, threading metadata, SMTP envelope, webhook state, and replies. Required: id.
getInboxStatus(api_key)- Use this when the user asks whether inbound email is ready or needs setup. Returns domains, routes, deployed Functions, and recent inbound activity.
getOutboundStatus- What can I send FROM? Lists this account's verified outbound (sendable) domains plus any domains still pending DNS verification, with next actions. Call this BEFORE sendEmail to pick a valid `from` domain — the account email is not necessarily sendable. The same sendable list is echoed in a cannot_send_from_domain error.
getSentEmail(id)- Get the full record for a single sent email by id, including body_text and body_html. Use to inspect delivery details for a specific send — e.g. the SMTP response on a bounced row, or the gate denial reason on a gate_denied row. Required: id.
getThread(id)- Get a conversation thread by id: metadata plus all inbound and outbound messages interleaved oldest-first. Each message has a direction (inbound/outbound) and id; fetch inbound message bodies via getEmail, or outbound bodies via getSentEmail. Discover thread_id from any email or sent-email record. Compare message_count against messages.length to detect truncation. Required: id.
listDomains- List all inbound domains for the organization, both verified and unverified. Each domain includes its verification status and DNS records. Use before addDomain to check whether a domain is already claimed.
listEmails(wait, limit, since, cursor, search, status, api_key, date_to, date_from, domain_id)- Use this when you need to browse inbound emails received at verified domains with cursor pagination, status filters, date filters, or sender/recipient search.
listEndpoints- List all active webhook endpoints for the organization. Each endpoint shows its URL, enabled state, and optional domain restriction.
listFilters- List all whitelist and blocklist filter rules for the organization.
listSentEmails(limit, cursor, status, date_to, date_from, request_id, idempotency_key)- List outbound emails sent by this org, with cursor pagination and filters. Bodies are omitted from list rows to keep responses small — use getSentEmail to fetch a specific row with full body. Useful for auditing delivery status, finding bounced sends, or checking gate-denied attempts.
listWebhookDeliveries(limit, cursor, status, date_to, email_id, date_from)- List webhook delivery attempts with pagination and filters. Each delivery includes the target endpoint and a nested email object with sender/recipient/subject. Useful for diagnosing delivery failures or confirming a specific email was delivered.
replayWebhookDelivery(id)- Re-send a stored webhook payload from a previous delivery attempt to its original endpoint. Rate limited per org (burst + sustained windows, shared budget with email webhook replays). Required: id.
replyToEmail(id, api_key, requestBody)- Use this when the user has selected a specific inbound email and confirmed a reply. Sends real outbound email with threading handled server-side. Required: id, requestBody.
searchEmails(q, to, body, from, sort, limit, cursor, status, date_to, snippet, subject, date_from, domain_id, spam_score_lt, has_attachment, include_facets, spam_score_gte, reply_to_sent_email_id)- Use this when you need to find inbound emails with structured filters or full-text matching. Use sort=received_at_asc plus date_from for new-mail polling.
sendEmail(api_key, requestBody, Idempotency-Key)- Use this when the user has confirmed a new outbound email. Sends real email through Primitive's relay and can wait for the first SMTP delivery outcome, or schedule the send for a future time with scheduled_at. Required: requestBody.
sendEmailDemo(requestBody)- SIMULATION ONLY: nothing is delivered. NEVER call this when the user actually wants an email to arrive, and never describe its result as a sent email: no message is sent, queued, or stored, and the recipient receives nothing. To really send with no account, call createEmailAddress (instant, no signup form and no verification) and then sendEmail with the api_key it returns; that is the correct path for any genuine send request. This tool exists only to preview the response shape: it validates the body against the exact same schema as sendEmail (including cc/bcc, reply_to, tags, attachments, and scheduled_at) and returns a synthetic success envelope marked demo: true. Demo requests are capped at 16KB total body, so large attachments are rejected even though the schema allows them. Required: requestBody.
testEndpoint(id)- Send a sample email.received event to a webhook endpoint to verify your signature verifier. Rate limited to 4/min and 30/hr. Successful deliveries and verified-domain endpoints are exempt. Required: id.
verifyDomain(id)- Check DNS records for a domain claim (MX, TXT, SPF, DKIM, DMARC). On success the domain becomes verified and starts receiving mail. On failure, returns which checks passed and which still need attention. If DNS propagation is incomplete, wait a few minutes and retry. Required: id.
Last successful function declaration observed on . Source: https://www.primitive.dev/mcp. We list what the server declared; we do not call any of these functions.
Endpoint status observed on . Source: https://www.primitive.dev/mcp.
Signals
These are separate measurements of different things. They are deliberately not combined into one score, because a popularity number that mixes website traffic with saves and stars cannot be checked or acted on.
| Signal | Value | What it measures | Window | Observed | Source |
|---|---|---|---|---|---|
| Latest published version | 0.1.0 | Latest version string the maintainer published to the registry. | as of fetch | Model Context Protocol | |
| Registry record last updated | 2026-06-09 | When the registry record was last updated by its maintainer. | point in time | Model Context Protocol | |
| First listed in the MCP Registry | 2026-06-09 | Date this server was first published to the official MCP Registry. Not a usage or quality measure. | point in time | Model Context Protocol | |
| repository status | not_found | GitHub returned 404 for the repository the maintainer listed. The project was deleted, renamed or made private, so the listing points at nothing. | as of fetch | GitHub | |
| mcp tools declared | 30 tools | Number of functions the server itself declared when asked to list them. This is what the server offers an agent, not a measure of how well any of them work. | as of probe | www.primitive.dev | |
| mcp endpoint status | ok | The server listed 30 functions when asked. | as of probe | www.primitive.dev |
Where to get it
This record as data
Every field on this page, with its source and observation date, is in the catalog JSON. Fetch the whole kind at once instead of parsing this HTML.
GET /api/v1/entries/mcp_server.json