npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openmaxai/email-mcp

v0.1.0

Published

Stdio MCP server for email: send via SMTP, read via IMAP or POP3. Works with any provider that supports app passwords / authorization codes.

Downloads

136

Readme

@openmaxai/email-mcp

A stdio MCP server that lets an AI agent send email over SMTP and read email over IMAP or POP3, using any provider that supports app passwords / authorization codes (QQ Mail, 163, Tencent Exmail, Aliyun enterprise mail, Outlook, Gmail, self-hosted servers...).

  • One connection per tool call, closed right after (no long-lived IDLE sessions).
  • Every network operation has a timeout.
  • All configuration comes from environment variables. EMAIL_PASSWORD is the only secret.
  • Logs go to stderr only (stdout carries the MCP protocol). Passwords and message bodies are never logged.

Requires Node.js 20.19 or newer.

Install (Claude Code)

claude mcp add-json email '{
  "command": "npx",
  "args": ["-y", "@openmaxai/[email protected]"],
  "env": {
    "EMAIL_USER": "[email protected]",
    "EMAIL_PASSWORD": "<app password / authorization code>",
    "RECEIVE_PROTOCOL": "imap",
    "IMAP_HOST": "imap.example.com", "IMAP_PORT": "993", "IMAP_SECURE": "ssl",
    "SMTP_HOST": "smtp.example.com", "SMTP_PORT": "465", "SMTP_SECURE": "ssl"
  }
}'

To receive over POP3 instead, set "RECEIVE_PROTOCOL": "pop3" and replace the IMAP_* keys with "POP3_HOST": "pop.example.com", "POP3_PORT": "995", "POP3_SECURE": "ssl".

Any other MCP client works the same way: run npx -y @openmaxai/email-mcp with the environment below.

Configuration

| Variable | Required | Default | Notes | |---|---|---|---| | EMAIL_USER | yes | | Login name, usually the full email address. Also used as the From address. | | EMAIL_PASSWORD | yes | | App password / authorization code. The only secret. | | EMAIL_FROM_NAME | no | | Display name for the From header. | | RECEIVE_PROTOCOL | no | imap | imap or pop3. | | IMAP_HOST | if imap | | | | IMAP_PORT | no | 993 (ssl) / 143 | | | IMAP_SECURE | no | from port, else ssl | ssl (implicit TLS), starttls, or none. | | POP3_HOST | if pop3 | | | | POP3_PORT | no | 995 (ssl) / 110 | | | POP3_SECURE | no | from port, else ssl | ssl or none (STARTTLS is not supported for POP3). | | SMTP_HOST | yes | | | | SMTP_PORT | no | 465 (ssl) / 587 (starttls) / 25 (none) | | | SMTP_SECURE | no | from port, else ssl | ssl, starttls, or none. | | EMAIL_TLS_VERIFY | no | true | Verify server TLS certificates. Set to false only for servers with self-signed certificates. | | EMAIL_SAVE_SENT | no | true | IMAP only: after sending, save a copy (marked read, Bcc kept) to the Sent folder. | | EMAIL_ATTACHMENT_ROOTS | no | working directory + OS temp dir | Directories that attachments may be read from, separated by : (; on Windows). | | EMAIL_MAX_ATTACHMENT_MB | no | 25 | Size limit for each attachment and for the total per message. get_email also skips saving attachments above it. | | EMAIL_ALIASES | no | | Other addresses of this mailbox, comma-separated. Excluded from reply-all recipients. | | EMAIL_TIMEOUT_MS | no | 30000 | Timeout for each tool call's network work (1000 to 600000). | | EMAIL_LOG_LEVEL | no | info | debug, info, warn, or error (stderr). |

Security from the port. If *_SECURE is not set but *_PORT is, the security mode follows the port: SMTP 465 is ssl, 587 and 25 are starttls; IMAP 993 is ssl, 143 is starttls; POP3 995 is ssl. Other ports default to ssl. POP3 on port 110 is plaintext, so it needs an explicit POP3_SECURE=none. An explicit *_SECURE always wins.

starttls requires the upgrade: the connection fails if the server does not offer STARTTLS. none sends credentials in plaintext and logs a warning; use it only for local test servers.

The configuration is checked at startup. If something is missing or invalid, the server exits with code 2 and lists every problem it found. The password is never printed.

Provider presets

Before you start, most providers require you to enable IMAP/SMTP (or POP3/SMTP) in the web mail settings and to use an authorization code / app password instead of your normal login password.

| Provider | IMAP | POP3 | SMTP | Notes | |---|---|---|---|---| | QQ Mail (qq.com) | imap.qq.com:993 ssl | pop.qq.com:995 ssl | smtp.qq.com:465 ssl | Settings → Account → enable IMAP/SMTP, then generate an authorization code (授权码). | | NetEase 163 (163.com) | imap.163.com:993 ssl | pop.163.com:995 ssl | smtp.163.com:465 ssl | Settings → POP3/SMTP/IMAP → enable, then use the authorization code (授权码). | | Tencent Exmail (exmail.qq.com) | imap.exmail.qq.com:993 ssl | pop.exmail.qq.com:995 ssl | smtp.exmail.qq.com:465 ssl | Enable IMAP/SMTP in client settings. If "secure login" is on, create a client-specific password (客户端专用密码). | | Aliyun enterprise mail | imap.qiye.aliyun.com:993 ssl | pop.qiye.aliyun.com:995 ssl | smtp.qiye.aliyun.com:465 ssl | The admin may need to allow IMAP/POP/SMTP. Use a third-party client password if one is required. | | Outlook / Microsoft 365 | outlook.office365.com:993 ssl | outlook.office365.com:995 ssl | smtp.office365.com:587 starttls | Needs an app password (account with 2-step verification). Many Microsoft 365 tenants turn off basic auth for IMAP/POP/SMTP, and this server does not support OAuth. | | Gmail | imap.gmail.com:993 ssl | pop.gmail.com:995 ssl | smtp.gmail.com:465 ssl | Turn on 2-Step Verification, then create an App Password. Enable IMAP/POP in Gmail settings. |

Provider settings can change. Check the provider's help pages if a connection fails.

Tools

| Tool | Available | Description | |---|---|---| | send_email | always | to[], cc[], bcc[], subject, text, html, attachments[] (local file paths under the allowed directories). Under IMAP the result includes saved_to_sent, or warnings if the Sent copy failed. The send itself still succeeds in that case. | | reply_email | always | Reply to a message by uid or message_id (and folder). Sets In-Reply-To / References and adds Re: to the subject. The reply goes to Reply-To if present, otherwise From. reply_all also adds the original To/Cc, removing duplicates and your own addresses (EMAIL_USER and EMAIL_ALIASES). | | list_emails | always | folder (default INBOX), limit (1–100, default 20), unread_only. Returns summaries, newest first: uid, message_id, from, to, subject, date, flags, seen, snippet. | | get_email | always | uid, folder, format (full or headers), include_attachments. Attachments are saved to a private temp directory (mode 0600) and their paths are returned. Bodies longer than 100k characters are truncated and flagged. | | search_emails | always | from, to, subject, text, since, before (YYYY-MM-DD; since inclusive, before exclusive), folder, limit. | | list_folders | IMAP only | Folders with message and unseen counts. | | mark_read | IMAP only | uid, folder, read (true sets \Seen, false clears it). |

Reading a message never marks it as read. Use mark_read to do that.

Sent folder. The Sent folder is found through IMAP SPECIAL-USE \Sent. If the server doesn't advertise one, the first folder named Sent, Sent Messages, Sent Items, 已发送 or 已发送邮件 is used. If none of these exists, no folder is created and the result carries a warning.

POP3 limitations

  • Only INBOX exists. Any other folder returns INVALID_INPUT.
  • uid is the POP3 UIDL value (a string).
  • POP3 has no read/unread flags: seen is null, flags is empty, and unread_only returns the newest messages with a note saying the filter is not supported.
  • POP3 has no server-side search. search_emails downloads and filters the newest 200 messages locally. Older messages are not searched.
  • list_folders and mark_read are not registered.

Errors

Failed tool calls return isError: true with a JSON body {"error": {"code", "message"}}. The codes are stable:

| Code | Meaning | |---|---| | AUTH_FAILED | Wrong user/password, IMAP/SMTP not enabled, or an authorization code is required. The message includes a hint for the provider, detected from the host name. | | UNREACHABLE | DNS failure, connection refused or reset, or a TLS/certificate problem. The message suggests port/security fixes. | | SEND_REJECTED | The SMTP server rejected the recipients or the message. | | NOT_FOUND | No such message (uid / Message-ID) or folder. | | INVALID_INPUT | Bad arguments, for example a missing body, an unreadable attachment or a bad date. | | TIMEOUT | The server did not respond within EMAIL_TIMEOUT_MS. | | UNKNOWN | Anything else. Set EMAIL_LOG_LEVEL=debug for details on stderr. |

Security notes

  • The only secret is EMAIL_PASSWORD. It is removed from every error message and log line.
  • TLS certificates are verified by default.
  • Attachments can only be read from the allowed directories: the working directory and the OS temp dir, or EMAIL_ATTACHMENT_ROOTS. Paths are resolved with realpath, so ../ traversal and symlinks that point outside those directories are rejected.
  • Message bodies, subjects and addresses are never written to logs.

Development

npm install
npm run build
npm test                  # unit tests
npm run test:integration  # needs Docker: starts greenmail/standalone automatically

Integration tests start a throwaway GreenMail container. To use an existing GreenMail instance instead, set GREENMAIL_HOST (and optionally GREENMAIL_SMTP_PORT, GREENMAIL_IMAP_PORT, ...).

Releasing

Pushing a v* tag starts the Release workflow. It needs one approval (the publish job, release environment); provenance verification, dist-tag promotion and holding-tag cleanup then run automatically. A stuck, waiting or failed release does not notify anyone: after tagging, check the Actions tab until the run is green.

Releases are serialized (concurrency with queue: max): if a run's publish approval is never given, that run holds the queue for up to 30 days and every later tag's run waits behind it. To recover, cancel the stuck run in the Actions tab (nothing was published, so nothing needs cleaning up); the next queued run then starts. When re-running an older run's cleanup job by hand, do so only if no newer release run has started since: with that run's publish outputs missing or invalid it removes the publish-staging dist-tag whatever version it points at.

License

MIT