MCP Mail Server
Give your AI assistant a local bridge to your email.
Search, read, organize, reply to, and send email through supported password- or app-password-based IMAP/SMTP accounts—from Claude, Cursor, Codex, and other MCP clients.
Power your agent
Perintah milik penerbit sendiri. Bukan endpoint PlugMCP.
Host a copy with our keys and logs.
npx -y [email protected]Claude Code tidak punya tautan instal untuk perintah lokal. Salin perintah di bawah dan jalankan di terminal.
claude mcp add mcp-mail-server -- npx -y mcp-mail-server@2.1.3Jalankan di terminal.
{ "mcpServers": { "mcp-mail-server": { "command": "npx", "args": [ "-y", "[email protected]" ] } }}claude_desktop_config.json
URL remote atau perintah di mesin Anda? Perbedaan kedua cara instal
Jalankan di PlugMCP
A new server you create. It is not this listing's official endpoint. Use the publisher install when you want their URL and their credentials.
BukaDari penerbit
Give your AI assistant a local bridge to your email.
Search, read, organize, reply to, and send email through supported password- or app-password-based IMAP/SMTP accounts—from Claude, Cursor, Codex, and other MCP clients.
MCP server for IMAP/SMTP email access with environment-based configuration
English · 简体中文
Why this server · Quick start · Client setup · Tools · Configuration · Optional security · Development
“Find the unread messages from Alice this week, summarize them, and move the finished thread to Archive.”
[!IMPORTANT] Enable IMAP and SMTP for your account before starting. This server currently supports password or app-password authentication; OAuth2 is not yet supported.
Install Node.js 22.13.0 or newer before configuring your MCP client. All examples use npx -y mcp-mail-server, so there is no need to install the server globally.
Open Settings > Developer > Edit Config and add the server to claude_desktop_config.json:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json{
"mcpServers": {
"mcp-mail-server": {
"command": "npx",
"args": ["-y", "mcp-mail-server"],
"env": {
"IMAP_HOST": "your-imap-server.com",
"IMAP_PORT": "993",
"IMAP_SECURE": "true",
"SMTP_HOST": "your-smtp-server.com",
"SMTP_PORT": "465",
"SMTP_SECURE": "true",
"EMAIL_USER": "[email protected]",
"EMAIL_ADDRESS": "[email protected]",
"EMAIL_PASS": "your-app-password"
}
}
}
}
Save the file, completely quit Claude Desktop, and start it again. See the official local MCP server guide for current client instructions.
Add the server to one of Cursor's MCP configuration files:
.cursor/mcp.json~/.cursor/mcp.json{
"mcpServers": {
"mcp-mail-server": {
"command": "npx",
"args": ["-y", "mcp-mail-server"],
"env": {
"IMAP_HOST": "your-imap-server.com",
"IMAP_PORT": "993",
"IMAP_SECURE": "true",
"SMTP_HOST": "your-smtp-server.com",
"SMTP_PORT": "465",
"SMTP_SECURE": "true",
"EMAIL_USER": "[email protected]",
"EMAIL_ADDRESS": "[email protected]",
"EMAIL_PASS": "your-app-password"
}
}
}
}
See the Cursor MCP documentation for current configuration locations and behavior.
Add the server at user scope so it is available across projects:
claude mcp add \
--scope user \
--env IMAP_HOST=your-imap-server.com \
--env IMAP_PORT=993 \
--env IMAP_SECURE=true \
--env SMTP_HOST=your-smtp-server.com \
--env SMTP_PORT=465 \
--env SMTP_SECURE=true \
--env [email protected] \
--env [email protected] \
--env EMAIL_PASS=your-app-password \
--transport stdio \
mcp-mail-server \
-- npx -y mcp-mail-server
Use --scope local for the current project only (the default), or --scope project to create a shared .mcp.json in the project root. Claude Code does not read MCP servers from .claude/settings.json. Run claude mcp get mcp-mail-server or use /mcp inside Claude Code to verify the connection. See the Claude Code MCP documentation for scope and configuration details.
Add the server with the Codex CLI:
codex mcp add mcp-mail-server \
--env IMAP_HOST=your-imap-server.com \
--env IMAP_PORT=993 \
--env IMAP_SECURE=true \
--env SMTP_HOST=your-smtp-server.com \
--env SMTP_PORT=465 \
--env SMTP_SECURE=true \
--env [email protected] \
--env [email protected] \
--env EMAIL_PASS=your-app-password \
-- npx -y mcp-mail-server
Codex stores user configuration in ~/.codex/config.toml. For a trusted project-only configuration, use .codex/config.toml:
[mcp_servers.mcp-mail-server]
command = "npx"
args = ["-y", "mcp-mail-server"]
env_vars = [
"IMAP_HOST",
"IMAP_PORT",
"IMAP_SECURE",
"SMTP_HOST",
"SMTP_PORT",
"SMTP_SECURE",
"EMAIL_USER",
"EMAIL_ADDRESS",
"EMAIL_PASS"
]
Export those variables before starting Codex. The ChatGPT desktop app, Codex CLI, and Codex IDE extension share this configuration. See the Codex MCP documentation for current options.
Use your client's current MCP configuration format and register a local STDIO server with:
npx-y, mcp-mail-serverConfiguration file names and schemas are client-specific; do not assume every client accepts the mcpServers JSON format.
The server exposes 14 tools, with explicit mailbox references for message operations.
mailboxes, from, to, subject, body, IMAP keywords, unread, inclusive since, exclusive before, limit, and includeBody. Omit mailboxes to search INBOX and the detected sent mailbox. Date/time searches widen the IMAP calendar-day query by two days on each side, then apply the exact instant locally so the full UTC+14 to UTC-12 INTERNALDATE spread cannot discard valid messages early. All candidates within MAIL_MAX_SEARCH_CANDIDATES are sorted by internal date before limit is applied; wider searches fail with a narrowing hint instead of guessing from UID order. Results are summaries by default. Keywords must be atom-safe custom IMAP keywords; whitespace, control characters, IMAP syntax characters, and system flags are rejected. When includeBody is true, the call fails explicitly if a selected message disappears before hydration or the request-wide response-body budget would be exceeded.sender (required), mailboxes (optional, defaults to INBOX), since, before, and limit. Uses In-Reply-To and References with case-sensitive Message-ID matching and equivalent quoting normalized. Date filters select incoming candidates only: replies are checked across Sent thread headers regardless of their storage/import date. Incoming and Sent header scans share MAIL_MAX_SEARCH_CANDIDATES and MAIL_MAX_SEARCH_HEADER_BYTES; exceeding either limit fails explicitly rather than guessing “unreplied.” Messages without Message-ID are returned as unknownMessages instead of being guessed from their subject.{
"mailboxes": ["INBOX", "Archive"],
"from": "[email protected]",
"unread": true,
"since": "2026-07-01",
"before": "2026-08-01",
"limit": 20
}
mailbox (string), uid (number), uidValidity (number, optional), markSeen (boolean, optional)mailbox (string), uids (array), uidValidity (number, optional), markSeen (boolean, optional). The call fails before fetching bodies if any requested UID is missing, and fails explicitly if the combined returned bodies exceed MAIL_MAX_RESPONSE_CHARACTERS.mailbox (string), uid (number), targetMailbox (string), uidValidity (number, optional). The source UID and target mailbox must already exist. Fails safely unless the server supports MOVE or UIDPLUS. When the server returns a destination UID, the result also refreshes destinationUidValidity so the target reference can be reused safely. If a UIDPLUS fallback creates the destination copy but source cleanup reports an error, the tool reopens the source mailbox, verifies the UID and rolls back \\Deleted when possible. A connection loss before MOVE or COPY confirmation returns isError: true, partial: true, and copyOutcome: "unknown"; a confirmed copy followed by uncertain cleanup returns copyOutcome: "succeeded" plus the verified sourceState, optional sourceDeletedFlag, and destination reference when available. Inspect both mailboxes before retrying either result.mailbox (string), uids (array), targetMailbox (string), uidValidity (number, optional). Moves up to 200 UIDs out of one mailbox in a single call. IMAP offers no atomic multi-message MOVE, so each UID is moved and reported independently and one failure never aborts the remaining UIDs. Before each move, the source mailbox is selected read-write and checked against the UIDVALIDITY captured at the start of the batch, even if the caller omitted uidValidity. Failure recovery cannot leave later moves using a read-only mailbox or stale UIDs. The destination reference is refreshed only after the loop finishes. Returns requestedCount, movedCount, failedCount, movedUids and a per-UID results array that carries the same copyOutcome, sourceState and sourceDeletedFlag diagnostics as move_message. isError is set when any UID failed; inspect every entry whose moved flag is false before retrying that UID.mailbox (string), uid (number), uidValidity (number, optional). Verifies the UID exists and permanently deletes only that UID. If STORE or UID EXPUNGE reports an error, the tool verifies the source UID and rolls back \\Deleted when possible. A transport failure that cannot be confirmed returns a structured outcome: "unknown" instead of claiming the message was not deleted.mailbox (string), uids (array), uidValidity (number, optional). Permanently deletes up to 200 UIDs from one mailbox in a single call using targeted UID EXPUNGE. Each UID is deleted and reported independently and one failure never aborts the remaining UIDs. Before each deletion, the explicit source mailbox is selected read-write and checked against the UIDVALIDITY captured at the start of the batch, even if the caller omitted uidValidity; failed selection or changed UIDVALIDITY prevents that UID from being deleted. Returns requestedCount, deletedCount, failedCount, deletedUids and a per-UID results array carrying the same outcome and stage diagnostics as delete_message. isError is set when any UID failed; inspect every entry whose deleted flag is false before retrying that UID.to (string), subject (string), text (string, optional), html (string, optional), signature (object, optional: text and/or html), cc (string, optional), bcc (string, optional), attachments (string[], optional, absolute file paths). At least one of text or html is required.mailbox (string), originalUid (number), uidValidity (number, optional), text (string, optional), html (string, optional), signature (object, optional: text and/or html), replyToAll (boolean, default: false), includeOriginal (boolean, default: true). At least one of text or html is required.subject (string), recipient (string, optional narrowing match), since (string, optional), text (string, optional), html (string, optional), signature (object, optional), replyToAll (boolean, default: true), and includeOriginal (boolean, default: true). Finds the newest exact normalized subject in the detected sent mailbox, requires a Message-ID, then replies to that sent message so recurring reports remain in one thread and carry the complete previous body forward, subject to MAIL_MAX_BODY_CHARACTERS.Natural-language example for a recurring report:
Continue the "Development Daily Report" thread that I sent to
[email protected]today. Do not start a new thread. Add: "Completed the mail reply fix today; plan to finish regression testing tomorrow." Keep the complete previous message content and reply to all recipients.
Include "continue/reply to the previous message", the exact subject, a recipient or date, and the new body to help the client select continue_email_thread instead of starting a new thread with send_email.
Signatures are appended after the new message body. In replies, the signature is placed before the quoted original message. Provide both signature.text and signature.html for the best compatibility across mail clients; HTML signatures are treated as trusted email markup.
Outgoing HTML inherits a cross-platform system font stack (Segoe UI/PingFang SC/Microsoft YaHei/Noto Sans CJK SC with Arial and sans-serif fallbacks), a 14px base size, and a 1.6 line height. Explicit styles inside supplied HTML still override these defaults. When callers provide only text, the server preserves the text/plain body and automatically derives an equivalent styled text/html alternative, so HTML-capable clients do not fall back to a monospace plain-text display.
When includeOriginal is enabled, an HTML-only original is converted to readable plain text for the text alternative. Oversized quoted content is truncated to MAIL_MAX_BODY_CHARACTERS while preserving the new reply and signature.
After SMTP accepts a message, sending tools report sentFolderSaved and the detected sentFolder. Sent-mailbox candidates are retried only after a definite non-append; an ambiguous transport failure stops immediately to avoid duplicates. If saving fails, SMTP success is preserved and sentFolderError reports a password-redacted stage, code, message, mailbox, and per-candidate attempts when available.
mailbox (string), uid (number), uidValidity (number, optional), savePath (string, absolute path), attachmentIndex (number, optional, 0-based), attachmentFilename (string, optional, exact match), returnBase64 (boolean, optional, default: false). Select by index or filename, not both; duplicate filenames must be selected by index. Omit both selectors to save all attachments. When saving multiple attachments, a later write failure returns isError: true, partial, savedFiles, and failedAttachment so a retry does not silently duplicate files.Core mail variables are required. File and security policy variables are optional.
Search results include sourceMailbox, uid, and uidValidity. Pass these values back unchanged when reading, replying, moving, downloading attachments, or deleting so identical UIDs in different mailboxes cannot resolve to the wrong message. Unstable IMAP sequence numbers are not exposed as message IDs. size is the server-provided RFC822 byte size and is null when the server omits it. Search returns summaries by default; use get_message for full bodies and attachment metadata, or set includeBody: true explicitly.
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
IMAP_SECURE=true
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
[email protected]
[email protected]
EMAIL_PASS=your-app-password
Note: This server currently supports password-based authentication, not OAuth2. A regular Google account password will not work; use an App Password if your account permits one. Google recommends OAuth-based sign-in, and managed accounts may disable app passwords.
Outlook.com and Exchange Online require OAuth2/Modern Authentication for IMAP and SMTP. This server currently accepts only a username and password, so Outlook/Hotmail accounts are not currently supported.
Outlook SMTP also uses STARTTLS on port 587, which would require SMTP_SECURE=false; changing that flag alone does not solve the OAuth requirement. See Microsoft's current IMAP and SMTP settings.
SMTP_SECURE=true and requires STARTTLS before authentication when it is falseREJECT_UNAUTHORIZED settings at their default true unless you control and explicitly trust a private certificate authorityEMAIL_PASS in their local configuration. Restrict file permissions and never commit credentials to version control.env and .env.* are ignored by Git; use a sanitized .env.example only when sharing configuration templatesHOL Guard is a separate local security layer for AI agents. Its community mcp.mail-server extension adds opt-in policy defaults for reviewing permanent email deletion. Guard is not required to run this server, and installing mcp-mail-server alone does not activate this coverage.
To use the integration:
mcp.mail-server, and have a local administrator explicitly enable this external, opt-in extension through Guard's local protection controls. A directory listing, publisher claim, or Cloud setting does not activate it locally.When the extension is active, its reviewed policy contributes these defaults:
delete_message and delete_messages: review, adding a user-approval checkpoint before permanent deletion.list_mailboxes and search_messages: allow only when the reviewed npx launcher, STDIO transport, npm registry package selector, and source identity match, without package-manager overrides. A matching package name alone is insufficient.inherit, retaining host-policy handling rather than automatically allowing all email operations. In particular, get_message and get_messages are not treated as unconditionally read-only because markSeen can change message state.Local custom grants and stronger Guard constraints retain their precedence. Guard does not make permanent deletion reversible or replace mailbox permissions and backups; this integration is not a security certification. See the upstream contribution PR for the implementation and regression coverage.
Development and runtime require Node.js 22.13 or newer. The repository pins Node.js 22.23.0 LTS in .nvmrc for local development.
Clone the repository:
git clone https://github.com/yunfeizhu/mcp-mail-server.git
cd mcp-mail-server
Install dependencies:
npm install
Build the project:
npm run build
Run the complete local quality gate with:
npm run check
Use npm run format, npm run lint:fix, npm run format:check, and npm run lint for focused formatting and linting workflows.
Rollup resolves and transpiles src/*.ts directly into the single-file release bundle. Local TypeScript imports omit file extensions, while third-party package subpaths retain the extensions published by those packages. tsc performs type checking only and tests load source through tsx. Runtime libraries remain external and are installed from the package's declared dependencies.
Set environment variables:
export IMAP_HOST=your-imap-server.com
export IMAP_PORT=993
export IMAP_SECURE=true
export SMTP_HOST=your-smtp-server.com
export SMTP_PORT=465
export SMTP_SECURE=true
export [email protected]
export [email protected]
export EMAIL_PASS=your-app-password
Run the server:
npm start
Run:
npm run dev:inspector
The command builds the project and opens the version-pinned MCP Inspector 1.0.0 UI. In the connection pane, configure:
STDIOnodedist/index.jsClick Connect, open Tools, and call check_connection to verify IMAP and SMTP before testing search, read, or send tools. Other tools auto-connect as needed. Attachment tools also require MAIL_ALLOWED_ROOTS.
The MCP server and the version-pinned Inspector both require Node.js 22.13 or newer.
GitHub Actions validates every branch push and pull request on Node.js 22 and 24, including formatting, lint, types, the release build, tests, release metadata, and npm package contents. Release Please prepares a release PR that synchronizes package/lockfile versions, both changelogs, and both README release summaries. Merge that PR when you decide to release; its version tag triggers fresh verification and npm OIDC publishing of the verified tarball.
Maintainers must enable Actions-created PRs and configure the npm trusted publisher once. See the release guide for setup, automatic release preparation, and retry instructions.
Added
move_messages and delete_messages handle up to 200 distinct UIDs from one mailbox per call, bringing the server to 14 tools.save_attachment can select one attachment by exact attachmentFilename instead of attachmentIndex. Duplicate filenames require an index; omit both selectors to save all attachments.Improved
uidValidity. Destination references are refreshed after the move batch completes.Documentation
Fixed
Fixed
INTERNALDATE, avoiding the removed util.isDate API in [email protected].Breaking changes
search_messages, check_connection, find_unreplied_messages, and recurring-report continue_email_thread.Fixed
\\Deleted.null otherwise) and structured, password-redacted diagnostics when saving a sent copy fails.Added
move_message to move a mailbox-scoped message into an existing target mailbox.send_email and reply_to_email.Improved
Documentation
See CHANGELOG.md for the complete version history.
Bug reports, feature ideas, and pull requests are welcome. Start with the issue tracker or open a pull request directly.
Released under the MIT License.
MCP server for IMAP/SMTP email access with environment-based configuration
{ "mcpServers": { "mcp-mail-server": { "command": "npx", "args": [ "-y", "[email protected]" ] } }}Tool
Belum ada daftar tool. Server remote mendapatkannya setelah pemeriksaan kesehatan pertama.
FAQ
Salin konfigurasi stdio untuk Cursor, Claude Desktop, Claude Code, atau VS Code di halaman ini. Konfigurasi ini memakai instalasi dari penerbit, bukan proxy PlugMCP.
Tidak ada variabel lingkungan wajib yang tercantum di catatan ini.
MCP Mail Server berjalan secara lokal melalui stdio.
Terakhir diperiksa 2026-11-13. MCP server for IMAP/SMTP email access with environment-based configuration