Skip to main content
Glama
imap-mcp

imap-mcp

imap-mcp

A small Model Context Protocol server that lets an AI assistant read your IMAP mailboxes, built with security as the first concern:

  • No email is ever sent or forwarded without your explicit approval. The assistant can only request it. You see everything that will go out (recipients, subject, full text or the list of forwarded messages with their attachments, warnings) and approve it yourself, either in an approval dialog shown by your MCP client or in your own terminal.

  • Built against prompt-injection exfiltration like CVE-2025-32711 "EchoLeak". Email content is treated as untrusted data: hidden text, images, active links and invisible characters are removed or defanged before the model sees them. See SECURITY.md for the threat model.

  • Runs anywhere Node.js runs, including ARM (Raspberry Pi, Apple Silicon, AWS Graviton). Pure JavaScript, no native modules, no build step.

Tools

Tool

What it does

Writes?

list_accounts

Configured accounts and their permissions

no

list_folders

Folders with message/unread counts

no

list_messages

Newest messages in a folder (envelope only)

no

search_messages

Server-side search (from, to, subject, text, date range, unread, flagged, has attachments, not yet forwarded)

no

read_message

One message as sanitised plain text; attachments listed, not returned

no

create_draft

Saves a plain-text draft in the Drafts folder

Drafts folder only

send_email

Requests sending a plain-text email; only sent after you approve it

after approval

forward_messages

Requests forwarding existing messages with their original attachments to allow-listed recipients; only sent after you approve the batch

after approval

The server opens folders read-only and fetches with BODY.PEEK, so reading never marks messages as read. There are no tools to delete or move messages. The only flag the server ever sets is $Forwarded on messages you approved for forwarding.

Related MCP server: mcp-mail-server

Requirements

  • Node.js 20 or newer (node --version). On a Raspberry Pi or other ARM Linux machine, install Node from your distribution, from nodejs.org (ARM64/ARMv7 builds), or with nvm.

  • An IMAP account (and SMTP, if you want to send).

Installation

git clone https://github.com/carstenkiefer/imap-mcp.git
cd imap-mcp && npm ci --omit=dev

Configuration

The configuration file is read from ~/.config/imap-mcp/config.json, or from the path in the IMAP_MCP_CONFIG environment variable. Start from the example:

mkdir -p ~/.config/imap-mcp && cp config.example.json ~/.config/imap-mcp/config.json && chmod 600 ~/.config/imap-mcp/config.json

Accounts

Key

Default

Meaning

id

–

Short identifier the assistant uses ([A-Za-z0-9_-])

name

–

Optional display name

from

IMAP user

Sender address for drafts and sent mail. The assistant cannot change it.

imap / smtp

–

host, port, secure (implicit TLS, default true), auth

imap.secure: false

–

Uses STARTTLS, which is then required. Plaintext needs allowInsecure: true (testing only).

rejectUnauthorized

true

Certificate validation. Leave it on.

allowDrafts

true

Allow create_draft

allowSend

false

Allow send_email (always with approval). Requires smtp.

allowedRecipients

any

Optional allow list, e.g. ["*@example.com", "boss@partner.example"]. Other recipients are rejected before you are even asked.

maxRecipients

10

Maximum To + Cc + Bcc

allowForward

false

Allow forward_messages (always with approval). Requires smtp and forwardRecipients. Independent of allowSend.

forwardRecipients

–

Mandatory allow list for forwarding, e.g. ["buha@example.de"]. Same pattern syntax as allowedRecipients.

markForwarded

true

Set the $Forwarded flag on forwarded originals, so they are not forwarded twice

draftsFolder / sentFolder

auto

Detected via SPECIAL-USE; set them if detection fails

saveToSent

true

Store a copy of sent mail in the Sent folder

Credentials

Prefer not to put passwords into the config file. In auth use one of:

  • "passwordEnv": "VAR" – the password is read from an environment variable (recommended),

  • "passwordFile": "/path/to/file" – the password is read from a file (e.g. a Docker/systemd secret),

  • "accessTokenEnv": "VAR" – OAuth2 access token (XOAUTH2), e.g. for Microsoft 365 or Gmail,

  • "password": "..." – inline; the server warns if the file is readable by other users.

For Gmail, Microsoft 365 and other providers with 2FA, use an app password or OAuth2 token.

Security options

Key

Default

Meaning

urlMode

defang

How URLs in email content are shown to the model: defang (hxxps[://]example[.]com), remove, or keep (not recommended)

maxBodyChars

20000

Maximum body length returned to the model

maxMessageBytes

26214400

Larger messages are not downloaded

approvalMode

auto

auto: approval dialog if the client supports it, otherwise outbox. outbox: always approve in the terminal.

outboxDir

~/.local/state/imap-mcp/outbox

Where emails waiting for approval are kept (mode 0600)

pendingTtlHours

24

Unapproved emails expire after this time

Check the configuration and logins:

WORK_MAIL_PASSWORD='…' node bin/imap-mcp.js check

Connecting an MCP client

The server speaks MCP over stdio. Example for Claude Desktop (claude_desktop_config.json) or any client with the same format:

{
  "mcpServers": {
    "imap": {
      "command": "node",
      "args": ["/absolute/path/to/imap-mcp/bin/imap-mcp.js"],
      "env": { "WORK_MAIL_PASSWORD": "…" }
    }
  }
}

Claude Code:

claude mcp add imap -e WORK_MAIL_PASSWORD='…' -- node /absolute/path/to/imap-mcp/bin/imap-mcp.js

Sending email: how approval works

  1. You ask the assistant to send an email. It calls send_email.

  2. The server validates the message (allowed account, recipients on the allow list, no attachments, plain text only, invisible characters stripped) and freezes it.

  3. Approval:

    • Approval dialog (preferred). If your MCP client supports elicitation, it shows you the complete email with warnings (external recipients, BCC, links, suspicious encoded strings). Only if you tick "Yes, send this email now" and accept is it sent. Declining, cancelling or accepting without the tick sends nothing.

    • Terminal (fallback). Otherwise the email is placed in the local outbox and the assistant tells you its id. You review and send it yourself:

      node bin/imap-mcp.js outbox
      node bin/imap-mcp.js outbox send <id>

      The command shows the full email and sends only after you type send. It refuses to run without an interactive terminal. outbox show <id> and outbox discard <id> are also available.

No tool takes a "confirm" parameter: anything the model can pass, an injected instruction can pass too.

If you want the assistant to prepare emails but never send, leave allowSend at false and use drafts: you then send from your normal mail client.

Forwarding invoices to an accounting inbox

Typical request: "Find all emails with invoices from DPD and forward them to my accounting inbox buha@example.de."

  1. Allow forwarding to exactly that address only, and keep free-form sending off if you do not need it:

    "allowSend": false,
    "allowForward": true,
    "forwardRecipients": ["buha@example.de"]
  2. Ask the assistant. It searches (e.g. from: "dpd", has_attachments: true, exclude_forwarded: true), checks senders, subjects and attachment names, and calls forward_messages once with all matching UIDs.

  3. You get one approval for the whole batch, listing every message (date, sender, subject, attachment names and sizes), the recipient and the optional note. Approve, and one email per invoice is sent.

  4. The originals are flagged $Forwarded (your mail client shows them as forwarded). Next month, the same request with exclude_forwarded only picks up new invoices.

Two modes are available:

  • inline (default): the original text plus the original attachments (e.g. the PDF). Works best with accounting systems that import email attachments (DATEV, Lexoffice, sevDesk, GetMyInvoices, …).

  • attachment: the complete original email attached unchanged as .eml, for maximum fidelity or when the invoice is in the email body itself.

Even if a malicious email tricks the assistant, forwarded mail can only reach the addresses in forwardRecipients, and only after you approve it.

Running as a service / on a Raspberry Pi

The server is started by the MCP client on demand, so usually no service is needed. To run it on a different machine than the client, use any stdio-over-SSH setup, e.g. "command": "ssh", "args": ["pi@raspberrypi", "node", "/home/pi/imap-mcp/bin/imap-mcp.js"]. The approval dialog still appears in your client; the terminal fallback then runs on the Pi.

Development

npm ci
npm test

The tests start local IMAP and SMTP servers and drive the server through a real MCP client, including approval, rejection and prompt-injection cases.

Limitations

  • Attachments are listed but their content is not returned to the model. Emails written by the assistant cannot carry attachments; only forwards carry the original message's attachments.

  • Outgoing mail is plain text only (forwards in attachment mode keep the original unchanged).

  • At most 50 messages per forward request.

  • Hidden-text detection covers the common CSS techniques (display, visibility, opacity, font-size, zero height, off-screen positioning, mso-hide). Text coloured like its background is not detected.

  • Prompt injection cannot be ruled out completely by any tool – see SECURITY.md for what is guaranteed and what is not.

License

MIT

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to read and interact with a user's email inbox via IMAP, fetching recent emails and reading their full content.
      8
      ISC
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to read, search, and manage email via IMAP, and send emails with attachments via SMTP, using natural language commands.
      429 npm
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI assistants to read, send, organize, and search emails across multiple IMAP/SMTP mailboxes.
      796 npm
      MIT