邮件管理MCP服务器

Email MCP Server(邮件管理MCP服务器)通过模型上下文协议(MCP)将常用邮件操作(读取、搜索、分类整理、移动、草稿、发送等)封装为工具,供Claude等大语言模型客户端调用,并支持多个命名邮箱账户,适用于由AI助手完成邮件管理和处理的场景。

  • by thegreystone
  • Java
  • 本地部署
  • 16 星标
  • 更新于
在 GitHub 查看 thegreystone/mcp-email

使用说明

Email MCP Server

An MCP (Model Context Protocol) server that exposes common email operations as tools for LLM clients like Claude. Supports multiple named email accounts (e.g., work + Gmail) from a single server instance.

For more information, see my blog.

Example prompts

"Find the tax emails from my tax lawyers for 2025, and check the content and attachments to fully understand what documentation I need to provide. Please provide an action plan to get that documentation."

"Please help triage the emails in my inboxes. As per usual, flag anything that is actionable. Don't hesitate to read emails that you are uncertain about. For anything actionable, provide an action plan. For anything non-actionable, file according to the folder layout."

WARNING: This server performs real operations on your mailbox, for example moving emails around. By default it will not allow deletions and directly sending emails (this can be changed in the MCP config). The author assumes no responsibility for any loss of data or unintended consequences resulting from the use of this MCP server. Use at your own risk.

NOTE: That said, the author has been using this daily for weeks without issues.

Features / Tools

Tool Description
Discovery
getVersion Returns the server version
listAccounts List configured account names (call first to discover accounts)
listFolders List all mail folders (INBOX, Sent, Drafts, etc.)
listFolderTree Full folder hierarchy with message/unread counts
createFolder Create a new mail folder
Reading
listEmails List emails in a folder with pagination. Sortable by date (default), size, or sender
readEmail Read the full content of a specific email. HTML bodies are converted to markdown by default
getAttachment Download an email attachment by name. Images are returned directly; PDFs are converted to extracted text; other types as base64 blobs
selfTestPdf Diagnostic: verify PDF text extraction works in this environment
searchEmails Search by subject, sender, or body
getUnreadCount Count unread emails in a folder
getNextUnreadEmail Get oldest unread email with all headers. HTML bodies are converted to markdown
Triage
triageCompact Compact triage — from, subject, spam score, flags (start here)
triageEmails Full-header triage — use when compact is not enough
Organizing
moveEmail Move a single email between folders (with optional mark-read)
moveEmails Batch move emails to one target folder
batchMoveEmails Move emails to multiple target folders in one call
moveToSpam Move emails to the cached spam folder
setEmailFlags Set any combination of seen, answered, forwarded, and flagged/starred on one or more emails
deleteEmail Delete an email: moved to the trash folder, or removed permanently if the account has none. Disabled by default — opt in via EMAIL_ALLOW_DELETION=true (see Enabling permanent deletion)
getTrashFolder Resolve and cache the trash folder that deleteEmail moves messages to (see Special folders)
setTrashFolder Override the trash folder for this session
Spam
getSpamFolder Resolve and cache the spam/junk folder (configured, special-use flag, or well-known name; see Special folders)
setSpamFolder Override the spam folder for this session
Composing
getDraftsFolder Resolve and cache the Drafts folder that saveDraft writes to (see Special folders)
setDraftsFolder Override the Drafts folder for this session
saveDraft Save a draft email for user review with CC/BCC (always available; preferred over send)
sendEmail Send an email via SMTP with CC/BCC. Disabled by default — opt in via EMAIL_ALLOW_SENDING=true (see Enabling outbound sending)
replyEmail Reply with proper threading headers and optional CC/BCC. Disabled by default — opt in via EMAIL_ALLOW_SENDING=true
forwardEmail Verbatim forward (body never enters LLM context). Disabled by default — opt in via EMAIL_ALLOW_SENDING=true
forwardEmailWithComment Forward with a comment prepended. Disabled by default — opt in via EMAIL_ALLOW_SENDING=true

All tools (except listAccounts) require an account parameter — the name of the account to operate on (e.g., work, gmail).

Quick Start

Plugin users: install Email MCP from the AI Plugins marketplace for Claude Code or Codex. See the plugin guide for installation and local credential setup.

The fastest way to get started is to download a pre-built release from the Releases page. Two options are available:

New builds use the email-mcp-server- filename prefix shown below. Older releases use mcp-email-server-; use the filenames attached to the release you download. When upgrading a manually configured client, update its executable or JAR path to the new filename.

Claude Desktop users: the simplest install is the MCP Bundle, email-mcp-server-<version>-macos-aarch64.mcpb or email-mcp-server-<version>-windows-x86_64.mcpb, see Setting up with Claude Desktop.

Option A: Native Binary (recommended)

No Java installation required. Download the binary for your platform:

Platform File
Linux x86_64 email-mcp-server-<version>-linux-x86_64
Linux aarch64 email-mcp-server-<version>-linux-aarch64
macOS Apple Silicon email-mcp-server-<version>-macos-aarch64
Windows x86_64 email-mcp-server-<version>-windows-x86_64.exe

On Linux and macOS, make the binary executable: chmod +x email-mcp-server-*

The macOS binary is signed and notarized, so Gatekeeper accepts it as downloaded. The one exception is a first launch while offline, because Gatekeeper fetches the notarization ticket from Apple; if that happens, clear the quarantine flag once:

xattr -d com.apple.quarantine email-mcp-server-<version>-macos-aarch64

Option B: Uber-jar

Runs on any platform with Java 21+ installed. Download email-mcp-server-<version>-runner.jar.

Then configure your MCP client (see Claude Desktop or Claude Code below).

Configuration

All credentials are passed via environment variables — nothing sensitive goes in source control. The LLM never sees these variables — it only sees tool names/descriptions and the text your tools return.

Accounts are defined by convention: EMAIL_ACCOUNTS_<NAME>_IMAP_* and EMAIL_ACCOUNTS_<NAME>_SMTP_*, where <NAME> is the account name in uppercase.

Per-account variables

Variable pattern Required Default Example
EMAIL_ACCOUNTS_<NAME>_IMAP_HOST yes imap.gmail.com
EMAIL_ACCOUNTS_<NAME>_IMAP_USERNAME yes you@gmail.com
EMAIL_ACCOUNTS_<NAME>_IMAP_PASSWORD yes abcd efgh ijkl mnop
EMAIL_ACCOUNTS_<NAME>_IMAP_PORT no 993 143
EMAIL_ACCOUNTS_<NAME>_IMAP_SSL no true, or false on port 143
EMAIL_ACCOUNTS_<NAME>_SMTP_HOST yes smtp.gmail.com
EMAIL_ACCOUNTS_<NAME>_SMTP_USERNAME yes you@gmail.com
EMAIL_ACCOUNTS_<NAME>_SMTP_PASSWORD yes abcd efgh ijkl mnop
EMAIL_ACCOUNTS_<NAME>_SMTP_PORT no 587 465
EMAIL_ACCOUNTS_<NAME>_SMTP_STARTTLS no true
EMAIL_ACCOUNTS_<NAME>_SMTP_SSL no false, or true on port 465
EMAIL_ACCOUNTS_<NAME>_FROM no the SMTP username Jane Doe <jane@example.com>
EMAIL_ACCOUNTS_<NAME>_DRAFTS_FOLDER no auto-detected INBOX.INBOX.Drafts
EMAIL_ACCOUNTS_<NAME>_SPAM_FOLDER no auto-detected INBOX.INBOX.Junk
EMAIL_ACCOUNTS_<NAME>_TRASH_FOLDER no auto-detected INBOX.INBOX.Trash

For Gmail, create an App Password.

FROM is the From address on everything the account sends or drafts, as a bare address or as Display Name <address>. It defaults to the SMTP username, which is the address itself for most providers; set it when the SMTP login is not an email address, to send from an alias, or to add a display name. Reply-all leaves the account's own addresses (the From address and the usernames) out of the recipients.

You can define as many accounts as needed. For example, to add a work and gmail account, set environment variables for both EMAIL_ACCOUNTS_WORK_* and EMAIL_ACCOUNTS_GMAIL_*.

Transport security

With the default ports, IMAP is TLS on 993 and SMTP is port 587 upgraded with STARTTLS; the STARTTLS upgrade is required, so a server that does not offer it is refused rather than sent the password in the clear. The two other common setups need only the port, since the TLS mode follows it:

  • SMTP on port 465 (implicit TLS, "SMTPS"), which some providers offer instead of 587: set EMAIL_ACCOUNTS_<NAME>_SMTP_PORT=465. The connection is then encrypted from the first byte and the STARTTLS setting is ignored.
  • Plain IMAP on port 143: set EMAIL_ACCOUNTS_<NAME>_IMAP_PORT=143. The connection is upgraded with STARTTLS when the server offers it, and stays unencrypted otherwise (for a local or test server).

For a non-standard port, set IMAP_SSL or SMTP_SSL explicitly; an explicit value always wins over the port rule. Set SMTP_STARTTLS=false only for a server that really has no TLS at all.

Special folders

saveDraft, moveToSpam and deleteEmail need to know the account's Drafts, spam and trash folders. Most servers need no configuration; each folder is resolved on first use, in this order:

  1. A folder set for the current session with setDraftsFolder / setSpamFolder / setTrashFolder.
  2. The configured EMAIL_ACCOUNTS_<NAME>_DRAFTS_FOLDER / _SPAM_FOLDER / _TRASH_FOLDER. A configured folder that does not exist on the server is reported as an error rather than silently falling back, so the LLM can point out the misconfiguration and work around it with the set*Folder tool for the session.
  3. The folder the server flags as \Drafts / \Junk / \Trash (RFC 6154 special-use, supported by Gmail, Dovecot, Exchange and most others).
  4. Well-known names such as Drafts, [Gmail]/Drafts, INBOX.Drafts, Spam, Junk, [Gmail]/Spam, Trash, [Gmail]/Trash, Deleted Items.
  5. Any folder whose last path element is Drafts, Draft, Spam, Junk, Junk E-mail, Bulk Mail, Junk Email, Trash, Deleted Items, Deleted Messages or a few localized trash names, which covers providers that nest everything under a namespace prefix (e.g. OVH's INBOX.INBOX.Drafts).

Set the variable explicitly if your provider uses a name none of the heuristics find, or if auto-detection picks the wrong folder. deleteEmail removes the message permanently only when no trash folder is found.

Network timeout

One setting covers every connection of every account:

Variable Default Effect
EMAIL_NETWORK_TIMEOUT 60 Seconds to wait when connecting to an IMAP or SMTP server, for the server to answer, and for a write to complete.

Without it a server that stops answering would hang the tool call, and with it the conversation, for good. The wait is per socket read, not per operation, so a large attachment over a slow link is fine as long as data keeps arriving. Raise it if a slow server times out on big searches; 0 disables the timeouts. Equivalent system property: -Demail.network-timeout=60.

Safety flags — opt-in for irreversible actions

Permanent and outbound operations are opt-in for safety. By default the destructive/outbound tools are disabled and return an explanatory error so the LLM can tell the user what's happening and fall back to a safer alternative (moveEmail to a Trash folder, or saveDraft for the user to send manually).

Variable Default Effect
EMAIL_ALLOW_DELETION false Set to true to allow deleteEmail to actually delete messages.
EMAIL_ALLOW_SENDING false Set to true to allow sendEmail, replyEmail, forwardEmail, and forwardEmailWithComment to actually transmit messages over SMTP.

Equivalent system properties: -Demail.allow-deletion=true and -Demail.allow-sending=true. Restart the server after changing them.

Enabling permanent deletion

When EMAIL_ALLOW_DELETION is unset (or false), deleteEmail is still listed (so the LLM can discover it and explain the limitation), but every invocation is rejected before any IMAP call is made. Use moveEmail to a Trash folder as the safe alternative.

Enabling outbound sending

When EMAIL_ALLOW_SENDING is unset (or false), the four outbound tools above all return an explanatory error and do nothing. saveDraft is unaffected — it only writes to the IMAP Drafts folder (see Special folders), so the LLM can still compose messages for the user to review and send manually from their mail client. This is the recommended default workflow even when sending is enabled.

Setting up with Claude Desktop

The easiest way is the MCP Bundle. There is no config file to edit:

  1. Download the .mcpb file for your platform from the Releases page: email-mcp-server-<version>-macos-aarch64.mcpb or email-mcp-server-<version>-windows-x86_64.mcpb.

  2. Install it: double-click the file, or in Claude Desktop open Settings → Extensions → Advanced settings → Install Extension… and pick the file. Claude Desktop shows its standard unsigned-extension notice, because the bundle file itself carries no signature (the binary inside it is signed); confirm with Install.

  3. Installing does not ask for the account details, so open the extension's settings: in Settings → Extensions, find Email MCP Server and click Configure. Fill in the IMAP and SMTP server, username and password (passwords go to the operating system keychain). For Gmail, use an App Password. The optional fields can usually stay empty: From only if the SMTP username is not your email address or you want a display name, and the Drafts, Spam and Trash folder fields only for providers where auto-detection picks the wrong folder (see Special folders). Leave the two switches, Allow sending and Allow permanent deletion, off unless you need them. Save.

  4. Make sure the extension is enabled and start a new chat. The email tools appear in the tool list; the account is called default in the tools.

The bundle contains the same native binary as the standalone download, signed and notarized on macOS and Authenticode-signed on Windows. It configures a single account with the default ports (993 with SSL for IMAP, 587 with STARTTLS for SMTP); for several accounts, or other ports and SSL settings, use the manual route below.

If you prefer the manual route:

  1. Download a release (see Quick Start) or build from source.

  2. Edit the Claude Desktop config file claude_desktop_config.json. On Windows it is located at C:\Users\<UserName>\AppData\Roaming\Claude\claude_desktop_config.json. On macOS it is at ~/Library/Application Support/Claude/claude_desktop_config.json.

  3. Add the email entry to the mcpServers section. Here is an example with two accounts (work and gmail):

Using the native binary (Windows):

{
  "mcpServers": {
    "email": {
      "command": "C:\\Users\\YourName\\path\\to\\email-mcp-server-windows-x86_64.exe",
      "args": [
        "-Dquarkus.mcp.server.stdio.enabled=true",
        "-Dquarkus.config.locations=.",
        "-Duser.dir=C:\\Users\\YourName\\claude"
      ],
      "env": {
        "EMAIL_ACCOUNTS_WORK_IMAP_HOST": "imap.example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_WORK_SMTP_HOST": "smtp.example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_HOST": "imap.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_PASSWORD": "your-gmail-app-password",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_HOST": "smtp.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_PASSWORD": "your-gmail-app-password"
      }
    }
  }
}

Using the uber-jar:

{
  "mcpServers": {
    "email": {
      "command": "java",
      "args": [
        "-Dquarkus.mcp.server.stdio.enabled=true",
        "-Dquarkus.config.locations=.",
        "-Duser.dir=C:\\Users\\YourName\\claude",
        "-jar",
        "C:\\Users\\YourName\\path\\to\\email-mcp-server-runner.jar"
      ],
      "env": {
        "EMAIL_ACCOUNTS_WORK_IMAP_HOST": "imap.example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_WORK_SMTP_HOST": "smtp.example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_HOST": "imap.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_PASSWORD": "your-gmail-app-password",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_HOST": "smtp.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_PASSWORD": "your-gmail-app-password"
      }
    }
  }
}
  1. Restart Claude Desktop. The email tools should appear in the tool list.

Setting up with Claude Code

  1. Download a release (see Quick Start) or build from source.

  2. Edit ~/.claude.json and add an mcpServers section. Here is an example with two accounts (work and gmail):

Using the native binary (Linux):

{
  "mcpServers": {
    "email": {
      "command": "/path/to/email-mcp-server-linux-x86_64",
      "args": [
        "-Dquarkus.mcp.server.stdio.enabled=true"
      ],
      "env": {
        "EMAIL_ACCOUNTS_WORK_IMAP_HOST": "imap.example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_WORK_SMTP_HOST": "smtp.example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_HOST": "imap.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_PASSWORD": "your-gmail-app-password",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_HOST": "smtp.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_PASSWORD": "your-gmail-app-password"
      }
    }
  }
}

Using the uber-jar:

{
  "mcpServers": {
    "email": {
      "command": "java",
      "args": [
        "-Dquarkus.mcp.server.stdio.enabled=true",
        "-jar",
        "/path/to/email-mcp-server-runner.jar"
      ],
      "env": {
        "EMAIL_ACCOUNTS_WORK_IMAP_HOST": "imap.example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_IMAP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_WORK_SMTP_HOST": "smtp.example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_USERNAME": "user@example.com",
        "EMAIL_ACCOUNTS_WORK_SMTP_PASSWORD": "your-app-password",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_HOST": "imap.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_IMAP_PASSWORD": "your-gmail-app-password",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_HOST": "smtp.gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_USERNAME": "you@gmail.com",
        "EMAIL_ACCOUNTS_GMAIL_SMTP_PASSWORD": "your-gmail-app-password"
      }
    }
  }
}
  1. Restart Claude Code (or run /mcp to reconnect). The email tools should appear in the tool list.

Note: Unlike Claude Desktop, Claude Code does not typically need the -Duser.dir and -Dquarkus.config.locations workarounds since it launches the server from a normal working directory.

Building from Source

Only needed if you want to contribute or run a development build. Building the uber-jar and the native images, running the integration tests, packing the MCP Bundles and signing the binaries are described in docs/DEVELOPMENT.md.

Troubleshooting

  • AccessDeniedException: C:\WINDOWS\system32\config: on Windows, Claude Desktop may launch the server with C:\WINDOWS\system32 as the working directory, causing Quarkus to fail when scanning for config files. The -Duser.dir argument in the example config overrides the working directory, and -Dquarkus.config.locations=. prevents Quarkus from scanning restricted system directories. Point -Duser.dir to any directory your user can write to.
  • Server disconnects immediately: make sure -Dquarkus.mcp.server.stdio.enabled=true is in the args before -jar.
  • No log output visible: Quarkus logs go to email-mcp-server.log (in the working directory), not to stdout/stderr, to avoid interfering with the STDIO transport. Check that file for errors. With the MCP Bundle the working directory is your home directory, so the log is ~/email-mcp-server.log.
  • Authentication errors: for Gmail, you need an App Password, not your regular password. Make sure 2-Step Verification is enabled on your Google account first.
  • "Unknown account" errors: call listAccounts first to see which accounts are configured. Account names are lowercase as defined in the environment variables (e.g., work, gmail).

License

The server is released under the BSD 3-Clause License, see LICENSE. The release artifacts bundle third-party libraries under their own licenses; they are listed, with their licenses, in docs/THIRD-PARTY.md. Note in particular that PDF text extraction uses iText 7, which is licensed under the GNU Affero General Public License v3.0; see the note in that file.