cancel_scheduled_send
Cancel a pending provider-held scheduled send. Only verified scheduled drafts can be cancelled.
Read, search and file mail across several mailboxes at once, draft freely while sending stays behind an allowlist, and create server-side inbox rules that keep sorting after the session ends.
LABSCO SUMMARY
The allowlist is enforced on the send path and bypassed on the draft path, and an edit to a draft is checked when it is sent rather than when it is written. The rule tools carry their own warnings instead of leaving you to work them out — a created rule keeps acting on the mailbox after the session ends, and deleting one can silently re-expose the mailbox to mail it was filtering. The project is also honest where honesty costs it something: it says plainly that the read-only profile removes the write tools everywhere, but only narrows the OAuth token on a mailbox that never consented to the write scopes, so on a previously-configured mailbox it is defence in depth rather than a real boundary.
A local email server for agents over Microsoft 365 / Outlook and Gmail: reading, search, threads, attachments, folders, labels, drafts, scheduled sends and server-side inbox rules. Its defaults are the point — an agent cannot send until you configure an allowlist, and the destructive tools are off until you turn them on. An interactive wizard walks the OAuth setup.
At least one configured mailbox on Microsoft 365 or Gmail, connected through the setup wizard's OAuth flow. A send allowlist, which decides who send_email, reply_to_email and send_draft will actually mail; without one, sending is off. Deletion needs explicit configuration before it runs at all — delete_email, delete_folder and delete_inbox_rule are disabled by default and each also takes an explicit caller flag. The read-only scope profile has to be set for both configuration and runtime, so that the consent granted and the tools exposed agree.
One command — npx -y email-agent-mcp
USE CASES
List and read what came in, mark, label and file it — the send path stays closed unless you opened it.
Pull the whole thread for context, write the draft into it, and leave the send for a human — a draft is never a sent message.
Schedule it with the provider, list what is pending, and cancel before it goes if the answer changes.
List the attachments on the message and pull the one you want back inline, under the size ceiling.
Create a server-side rule so the mailbox keeps filing on its own, and read back the rules already in place before adding another.
Enumerate what is configured, see which ones authenticated, and target a specific mailbox by its logical name.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
cancel_scheduled_sendCancel a pending provider-held scheduled send. Only verified scheduled drafts can be cancelled.
create_draftCreate an email draft. Supports body_file with YAML frontmatter. Use reply_to for threaded reply drafts; pass reply_all=false with reply_to to draft a sender-only reply.
create_folderCreate a custom child mail folder (defaults to a child of Inbox)
create_inbox_ruleCreate a persistent server-side inbox rule using safe actions only; forwarding, redirection, and deletion are blocked. Confirm with the user before calling — this creates a rule that keeps acting on the mailbox 24/7 after the session ends.
delete_emailDelete an email (disabled by default, requires explicit configuration)
delete_folderDelete a custom mail folder, including any mail it contains (disabled by default, requires explicit configuration). Well-known/system folders are protected.
delete_inbox_ruleDelete a server-side inbox rule by id (disabled by default, requires explicit configuration). Removing a rule can silently re-expose the mailbox to mail the rule was filtering.
download_attachmentDownload a single attachment as inline base64. Default max_size_mb=5 (hard ceiling 25). File attachments only — Microsoft item/reference attachments return NOT_SUPPORTED.
flag_emailFlag or unflag an email as important/starred
get_mailbox_statusGet mailbox connection status, unread count, and warnings
get_threadRetrieve all messages in a conversation thread by message ID. A thread can end with an unsent draft reply: a message with isDraft: true has NOT been sent, so it is not a sent reply — though earlier sent replies from the same author may exist elsewhere in the thread. Never describe such a message as a sent, delivered, or received email.
label_emailApply labels or categories to one or more emails
list_attachmentsList attachments for a specific email message
list_emailsList recent emails with filtering by unread status, folder, sender, and limit. Use offset for pagination. A row with isDraft: true is an unsent draft — it has NOT been sent, and its receivedAt is provider-supplied metadata, not evidence of delivery. Never describe such a row as a sent, delivered, or received email.
list_foldersRecursively list mail folders, including computed paths for nested folders
list_inbox_rulesList server-side inbox rules with all fields reported by the provider
list_mailboxesList every configured mailbox: its logical name (pass this as the mailbox argument to other tools), its emailAddress, provider, connection status, and which one is the default. Reports mailboxes that failed to authenticate too, so it stays useful for diagnosing a broken setup.
list_scheduled_sendsList pending provider-held scheduled sends for a mailbox
mark_readMark an email as read or unread
move_to_folderMove an email to a specific folder (inbox, archive, trash, etc.). Returns the new message ID since Graph assigns a new ID after moving.
read_emailRead the full content of an email by ID, transformed to token-efficient markdown. When the response has isDraft: true the message is an unsent draft — it has NOT been sent, and receivedAt is provider-supplied metadata, not evidence of delivery; never describe it as a sent, delivered, or received email. Set format to 'html' to get the raw body HTML instead of markdown — use this when you need to preserve inline styling (colour, background-colour, underline, strikethrough) that the markdown conversion discards, e.g. to change one sentence of a formatted body and leave the rest alone. Raw HTML costs far more tokens than markdown, so leave the default alone unless you need the styling; check bodyFormat (text means the message had no HTML part, so do not send it as HTML) before writing a body back, and never write one back with bodyTruncated: true — you do not have the whole body. strip_quoted_history and strip_signatures are markdown-shaped text transforms and are NOT applied when format is 'html'; the HTML is returned verbatim. To write it back, call create_draft/update_draft with format: 'html' AND force_black: false — force_black defaults to true and wraps your HTML in a force-black div, so leaving it on nests another wrapper on every round trip. Set strip_quoted_history to true to drop the terminal "On … wrote:" / Outlook-header / >-prefix reply chain and replace it with a short marker. Set strip_signatures to true to remove detected signatures and legal disclaimers; it defaults to false here for MCP compatibility even though the core action defaults to true.
reply_to_emailReply to an email within an existing thread. Default reply_all=true cc's the original thread; pass reply_all=false to reply only to the sender. Send path validates all effective recipients against the send allowlist; draft path bypasses.
search_emailsSearch emails using full-text query across one or all mailboxes. Use offset for pagination. Results include unsent drafts: a row with isDraft: true has NOT been sent — its receivedAt is provider-supplied metadata, not evidence of delivery. Never describe such a row as a sent, delivered, or received email.
send_draftSend a previously created draft. Enforces send allowlist before sending. Rate-limited.
send_emailCompose and send a new email. Gated by send allowlist. Draft mode bypasses allowlist.
update_draftUpdate a draft email. Body edits are refused for reply drafts; non-reply body edits require replace_body=true and replace the body wholesale. Subject, recipients, and attachments remain editable. Allowlist is enforced at send_draft time, not here.
BEFORE YOU INSTALL
26 tools when we connected. EMAIL_AGENT_MCP_SCOPE_PROFILE=observe removes mailbox-changing tools and list_inbox_rules. The six folder and inbox-rule tools return NOT_SUPPORTED on Gmail, and delete_email, delete_folder and delete_inbox_rule need an operator env var plus a per-call flag.
npx on PATH
CONTEXT COST
Rated by the size of the 26 tool definitions that ride along on every turn, not by how many there are
INSTALLATION
npx -y email-agent-mcpRun this once in a terminal first: its interactive setup wizard walks you through the OAuth sign-in and mailbox selection (npx email-agent-mcp configure runs the wizard on its own). Your client then launches the same command as the server.
{
"mcpServers": {
"email-agent-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"email-agent-mcp"
]
}
}
}{
"mcpServers": {
"email-agent-mcp": {
"command": "npx",
"args": [
"-y",
"email-agent-mcp"
]
}
}
}gemini extensions install https://github.com/UseJunior/email-agent-mcp