primitivedotdev avatar

Email

primitivedotdev/primitive-mono-repo

Gives Claude a complete email stack over MCP with seven tools: sendEmail, replyToEmail, listEmails, searchEmails, getEmail, getInboxStatus, and getAccount. You get managed addresses at *.primitive.email that can run JavaScript handlers on inbound messages, plus a chat verb that sends a message and waits for the threaded reply in one round trip. The underlying API does synchronous SMTP delivery so you get back the recipient's queue ID and response code in the same call. Useful when you need an agent to monitor an inbox, handle support threads, or contact other agents and humans without managing your own mail infrastructure. Uses streamable HTTP transport and supports both API keys and OAuth tokens.

tools
14
transport
HTTP
last updated
Oct 10, 2026

Install

From registry metadata
$ npx add-mcp https://www.primitive.dev/mcp --name email

Run in your terminal. add-mcp asks which agents to add it to (Claude Code, Codex, Cursor and more). Add -g to install it for every project.

Review the command, arguments and environment values before installing. MCP servers run with your local permissions.

Other ways

Claude Code

$ claude mcp add --transport http email https://www.primitive.dev/mcp

Run in your terminal. Add --scope user to make it available in every project.

Tools

Verified live · 14 tools

Verified live against the running server on Nov 6, 2026.

getAccountThe authenticated Primitive account. managed_inbox_address is a domain, not a mailbox; sender_address (such as agent@pink-ram.primitive.email) is the mailbox sendEmail sends from by default. Result: id, email, plan, managed_inbox_address, created_at, limits, entitlements, onbo...1 params

The authenticated Primitive account. managed_inbox_address is a domain, not a mailbox; sender_address (such as agent@pink-ram.primitive.email) is the mailbox sendEmail sends from by default. Result: id, email, plan, managed_inbox_address, created_at, limits, entitlements, onbo...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
getInboxStatusCheck whether inbound email is ready. Domains are added and verified with the domain management tools at /mcp/full. Result: ready, receiving_ready, processing_ready, summary, next_actions, domains, endpoints, functions and recent_emails.1 params

Check whether inbound email is ready. Domains are added and verified with the domain management tools at /mcp/full. Result: ready, receiving_ready, processing_ready, summary, next_actions, domains, endpoints, functions and recent_emails.

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
getOutboundStatusWhat this account can send from, and to whom. Call it before sending outside Primitive or from a domain other than the managed inbox. Result: ready, summary, sendable_domains, domains, next_actions, and can_send_to, the recipients it may email.1 params

What this account can send from, and to whom. Call it before sending outside Primitive or from a domain other than the managed inbox. Result: ready, summary, sendable_domains, domains, next_actions, and can_send_to, the recipients it may email.

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
listEmailsPage through inbound email newest first, or tail new mail with since and wait. Filters by domain, status, date and sender, recipient or subject words; for body text, attachments or replies to a send, use searchEmails. Rows carry id, thread_id, received_at, from, to, subject, s...11 params

Page through inbound email newest first, or tail new mail with since and wait. Filters by domain, status, date and sender, recipient or subject words; for body text, attachments or replies to a send, use searchEmails. Rows carry id, thread_id, received_at, from, to, subject, s...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
cursorstring
History cursor: the cursor of the page before. Returns emails OLDER than it, newest first. Not a date (use date_from or date_to); not with since.
date_fromstring
Only rows whose created_at is at or after this date or time (UTC unless it has an offset).
date_tostring
Only rows whose created_at is at or before this; a bare date covers that whole day (UTC).
domain_idstring
One of your receiving domains, by the id getInboxStatus returns.
fullboolean
Return the stored record, with envelope addresses, message id and spam score, instead of the compact view for reading.default: false
limitinteger
How many emails this call returns; follow cursor for more.default: 50
searchstring
Sender, recipient or subject words to match. To match message text, use searchEmails.
sincestring
Tail cursor: start (from the first email), or the cursor of the page before. Returns emails NEWER than it, oldest first, to poll new mail without gaps. Not a date; not with cursor.
statusstring
Processing stage: pending or accepted while in progress, completed when done, rejected if a filter or check refused it.one of pending · accepted · completed · rejected
waitinteger
Long-poll: how many seconds to hold the call open for new mail, so a since poll returns the moment mail arrives.default: 0
searchEmailsFind particular inbound emails: a full-text query (q) over subject, body, sender and recipient, or filters on sender, recipient, subject, body, attachments, spam score, or the sent email they reply to, ranked by relevance or date. To page through the inbox newest first, or to...19 params

Find particular inbound emails: a full-text query (q) over subject, body, sender and recipient, or filters on sender, recipient, subject, body, attachments, spam score, or the sent email they reply to, ranked by relevance or date. To page through the inbox newest first, or to...

Parameters* required
bodystring
Words from the message text to match.
cursorstring
Where the next page starts: the cursor of the page before.
date_fromstring
Only rows whose received_at is at or after this date or time (UTC unless it has an offset).
date_tostring
Only rows whose received_at is at or before this; a bare date covers that whole day (UTC).
domain_idstring
One of your receiving domains, by the id getInboxStatus returns.
fromstring
Who sent it: a full address, or a domain for everyone there.
fullboolean
Return the stored record, with envelope addresses, message id and spam score, instead of the compact view for reading.default: false
has_attachmentboolean
Filter to emails that have (true) or lack (false) attachments.
include_facetsboolean
Set true to also get counts by sender, domain, status and attachment presence across the whole result set.default: false
limitinteger
How many matches this call returns; follow cursor for more.default: 50
qstring
Words to find in the subject, body, sender or recipient; each added word narrows the results. Understands quoted phrases, upper-case OR, and filters such as from:, subject: and has:attachment.
reply_to_sent_email_idstring
Find the replies to one of your sends, by the id sendEmail or listSentEmails returned.
snippetboolean
Whether rows read with full: true carry highlighted match fragments for a text query. The body snippet on each row is returned either way.default: true
sortstring
Order of results. Left out, best match first when there is text to rank (q, subject or body), else newest first. Use received_at_asc with date_from to poll for new mail.one of relevance · received_at_desc · received_at_asc
spam_score_gtenumber
Filter to emails with a spam score at or above this value.
spam_score_ltnumber
Filter to emails with a spam score strictly below this value.
statusstring
Processing stage: pending or accepted while in progress, completed when done, rejected if a filter or check refused it.one of pending · accepted · completed · rejected
subjectstring
Words from the subject line to match.
tostring
Which of your addresses it was sent to.
getEmailRead one inbound email by id; read its attachments with getEmailAttachment. By default body_text leaves out quoted history and shows each link as an [n] marker; the links argument returns their targets. When body_next_offset is not null, call again with offset set to it. If pa...6 params

Read one inbound email by id; read its attachments with getEmailAttachment. By default body_text leaves out quoted history and shows each link as an [n] marker; the links argument returns their targets. When body_next_offset is not null, call again with offset set to it. If pa...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
fullboolean
Return the stored record, with the HTML body, links, quoted history and authentication results, instead of the compact view for reading.default: false
id*string
Inbound email ID from listEmails or searchEmails.
linksstring
Link targets to include in `links`: all of them, or the [n] numbers you want. Leave it out for none. Not used with full.
max_charsinteger
How much of body_text to return per call; read the rest with offset. Not used with full.default: 16000
offsetinteger
Character position in the body to start from: the body_next_offset of the previous result. Not used with full.default: 0
replyToEmailReply to one inbound email, threaded server-side. This sends a real email immediately and it cannot be undone or recalled, so call it only after the user has confirmed the reply. Expecting an answer? Pass await_reply: true to wait for it in this call. Result: the sent email's...8 params

Reply to one inbound email, threaded server-side. This sends a real email immediately and it cannot be undone or recalled, so call it only after the user has confirmed the reply. Expecting an answer? Pass await_reply: true to wait for it in this call. Result: the sent email's...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
attachmentsarray
Files to attach to the reply.
await_replyboolean
Set true when you expect an answer: after sending, this call waits up to 30 seconds for it, returned as `reply`. No reply in time is still a successful send, with reply_wait.status "no_reply_yet"....default: false
body_htmlstring
HTML reply body. Provide at least one of body_text or body_html.
body_textstring
Plain-text reply body. Provide at least one of body_text or body_html.
fromstring
Sender mailbox. Omit it to reply from the address the original message was sent to, which is almost always what you want.
id*string
Inbound email ID to reply to. Threading headers are set server-side.
waitboolean
Set true to hold the call until the recipient's mail server answers (or 30 seconds pass) and return the delivery outcome. Left out, it returns once the reply is queued; getSentEmail reads the outco...default: false
sendEmailSend a new email. It goes out immediately (or at scheduled_at) and cannot be recalled, so confirm the message with the user first. Leave `from` out to send from your managed inbox. To send later, set scheduled_at, at most 30 days ahead and without wait or attachments. Expectin...18 params

Send a new email. It goes out immediately (or at scheduled_at) and cannot be recalled, so confirm the message with the user first. Leave `from` out to send from your managed inbox. To send later, set scheduled_at, at most 30 days ahead and without wait or attachments. Expectin...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
attachmentsarray
Files to attach. Not allowed with scheduled_at.
await_replyboolean
Set true when you expect an answer: after sending, this call waits up to 30 seconds for it, returned as `reply`. No reply in time is still a successful send, with reply_wait.status "no_reply_yet"....default: false
bccvalue
People copied privately; no other recipient sees them.
body_htmlstring
HTML message body. Provide at least one of body_text or body_html. Reference inline attachments via cid: URLs matching their content_id.
body_textstring
Plain-text message body. Provide at least one of body_text or body_html.
ccvalue
People copied on the message; every recipient sees them.
fromstring
Sender mailbox. Omit it to send from your managed inbox; set it only for a mailbox on a domain verified for sending.
idempotency_keystring
A name you choose for this send: a retry with it returns the first result instead of sending twice. Without one, a recent identical send is replayed, not resent.
in_reply_tostring
Message-ID of the email this answers, so it threads, such as "<abc@example.com>".
referencesarray
Message-IDs of the earlier messages in the thread, oldest first, so it threads.
reply_tovalue
Where replies should go (the Reply-To header). Adds no recipients.
scheduled_atstring
When the email goes out, for a send that should wait. Until then it can be canceled with the tools at /mcp/full.
subject*string
What the email is about, shown as its subject.
tagsarray
Labels with unique names, kept on the send record to find it later with listSentEmails. Never put in headers or delivered.
to*value
Who receives it: one address, or a list for one message to several people. to, cc and bcc share one recipient limit.
waitboolean
Set true to hold the call until the recipient's mail server answers (or wait_timeout_ms passes) and return the delivery outcome. Left out, it returns once the email is queued; getSentEmail reads th...default: false
wait_timeout_msnumber
How long wait holds the call for the delivery outcome, in milliseconds.default: 30000
listSentEmailsList sent emails to audit delivery. Rows carry id, thread_id, created_at, status, from, to, subject and snippet, plus error_code, smtp_response_code or gates when a send did not deliver. Read one with getSentEmail. Result: sent_emails, cursor for the next page (null at the end...8 params

List sent emails to audit delivery. Rows carry id, thread_id, created_at, status, from, to, subject and snippet, plus error_code, smtp_response_code or gates when a send did not deliver. Read one with getSentEmail. Result: sent_emails, cursor for the next page (null at the end...

Parameters* required
cursorstring
Where the next page starts: the cursor of the page before.
date_fromstring
Only rows whose created_at is at or after this date or time (UTC unless it has an offset).
date_tostring
Only rows whose created_at is at or before this; a bare date covers that whole day (UTC).
fullboolean
Return the stored record, with envelope addresses, the request id and every outcome field, instead of the compact view for reading.default: false
idempotency_keystring
Filter to rows with the given client idempotency key.
limitinteger
How many sends this call returns; follow cursor for more.default: 50
request_idstring
Filter to the row matching a specific server-issued request_id from a /send-mail response.
statusstring
Filter to rows in this status. Use "scheduled" to find pending scheduled sends and "canceled" for ones already canceled.one of queued · submitted_to_agent · agent_failed · gate_denied · unknown · delivered
getSentEmailRead a single sent email by id, to inspect its delivery, such as the SMTP response on a bounced send or the gate denial on a gate_denied one. Pass full: true for the stored record. Result: id, thread_id, created_at, status, from, to, subject, from_address, to_address, cc, bcc,...2 params

Read a single sent email by id, to inspect its delivery, such as the SMTP response on a bounced send or the gate denial on a gate_denied one. Pass full: true for the stored record. Result: id, thread_id, created_at, status, from, to, subject, from_address, to_address, cc, bcc,...

Parameters* required
fullboolean
Return the stored record, with the HTML body and quoted history, instead of the compact view for reading.default: false
id*string
Sent email ID from listSentEmails or a /send-mail response.
awaitReplyWait for the threaded reply to a sent email (an id sendEmail or replyToEmail returned) when that send's own wait got none. Do not tell the user nobody replied unless this returns reply null with timed_out true. Threading is not proof of who wrote the reply: trust it only when...4 params

Wait for the threaded reply to a sent email (an id sendEmail or replyToEmail returned) when that send's own wait got none. Do not tell the user nobody replied unless this returns reply null with timed_out true. Threading is not proof of who wrote the reply: trust it only when...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
id*string
The sent email id to fetch the reply for (from a sendEmail/replyToEmail response).
waitboolean
Hold the call until a reply arrives or wait_timeout_ms passes. Set false only for one immediate check.default: true
wait_timeout_msnumber
How long wait holds the call for a reply, in milliseconds.default: 30000
getConversationRead a whole conversation with message bodies: the tool for finding out what was said. Pass the id of any inbound email in the thread. Each message has a direction and a role (inbound→user, outbound→assistant). Texts have links as [link] and quoted history removed; full: true...2 params

Read a whole conversation with message bodies: the tool for finding out what was said. Pass the id of any inbound email in the thread. Each message has a direction and a role (inbound→user, outbound→assistant). Texts have links as [link] and quoted history removed; full: true...

Parameters* required
fullboolean
Return the stored record, with links, quoted history and message ids, instead of the compact view for reading.default: false
id*string
Any inbound email in the thread, by its id from listEmails or searchEmails.
getEmailAttachmentRead ONE attachment of an email. A text file (plain text, CSV, JSON, XML, Markdown, calendar and similar) comes back as text, HTML reduced to text; a PNG, JPEG, GIF or WebP image up to 1 MB as an image; any other file as base64 up to 256 KB, and larger ones only described. PDF...7 params

Read ONE attachment of an email. A text file (plain text, CSV, JSON, XML, Markdown, calendar and similar) comes back as text, HTML reduced to text; a PNG, JPEG, GIF or WebP image up to 1 MB as an image; any other file as base64 up to 256 KB, and larger ones only described. PDF...

Parameters* required
api_keystring
API key from createEmailAddress, used in place of sign-in.
filenamestring
The attachment's filename, when part_index is not to hand. Matched exactly, then ignoring case.
id*string
ID of the email the attachment belongs to.
max_charsinteger
For text: the most characters to return in this call.default: 20000
offsetinteger
For text: the character to start from. Use next_offset from the previous call to continue.default: 0
part_indexinteger
The attachment's part_index from the email's attachments list. Preferred over filename, which need not be unique.
sourcestring
Whether id is an email you received or one you sent.one of received · sentdefault: received
createEmailAddressCreate an email account with no signup and get its api_key; call this first when you have no Primitive API key and the user wants to send or receive email. Pass api_key as the `api_key` argument on every later Primitive call, exactly as returned. address is a domain, not a mai...2 params

Create an email account with no signup and get its api_key; call this first when you have no Primitive API key and the user wants to send or receive email. Pass api_key as the `api_key` argument on every later Primitive call, exactly as returned. address is a domain, not a mai...

Parameters* required
device_namestring
Name of the app creating the account, such as ChatGPT. The user sees it later and recognises where the account came from.
terms_accepted*boolean
Confirms the user agrees to Primitive's terms of service (primitive.dev/terms).

Sponsors

Readme

Details

Repository
github.com/primitivedotdev/primitive-mono-repo
Website
www.primitive.dev
Categories
Cloud & Infrastructure, Communication & Messaging, Search & Web Crawling
Transport
HTTP
Registry
MCP registry, active
Resources
1
Prompts
2
Tools verified
Nov 6, 2026

Related Cloud & Infrastructure MCP servers

View all
1dotnova avatarContextLayerdotnova/context-layerIntelligent context infrastructure for AI teams: knowledge graph, sessions, tasks, documents.0stars
2eltociear avatarSecrets Audit Mcpeltociear/secrets-audit-mcpDetects leaked secrets & API keys: 32+ provider rules (AWS, GitHub, Stripe, OpenAI…), zero deps.0stars
3holiday-forever avatarHoliday Photo Plusholiday-forever/holiday-photo-plusShow holiday photos from Vercel Blob inline in Claude chats.0stars
4br0ski777 avatarDNS Lookup APIbr0ski777/dns-lookup-x402DNS record lookup — A, AAAA, MX, TXT, CNAME, NS via Cloudflare. x402 micropayment.0stars
5dailyaiagents-cpu avatarMonthly Burndailyaiagents-cpu/dailyai-osAggregates monthly cash burn across Anthropic, ElevenLabs, Cloudflare, Stripe fees, GitHub Action...0stars
6expertvagabond avatarOracle Cloudexpertvagabond/oracle-cloud-mcpOracle Cloud Infrastructure MCP server0stars