imap-mcp

imap-mcp

Read-only MCP server for IMAP email access, enabling AI agents to read, search, and monitor email without sending or deleting messages.

Category
Visit Server

README

imap-mcp

An MCP server that gives AI agents access to email over IMAP, designed for agents that need to read and reason about email without making changes to it.

Philosophy

Read-first, intentionally constrained. imap-mcp is built for agentic workflows where the agent needs to understand a user's email — triage, summarise, search, monitor — but should not be able to send, delete, or move messages. The server is currently read-only, with one deliberate exception: agents can set and clear custom IMAP keywords (flags) on messages. This lets an agent mark messages it has processed, acted on, or flagged for follow-up, without touching the messages themselves.

Standard IMAP first. The server targets standard IMAP servers. Gmail is well-supported for reading, but keyword flagging does not yet work on Gmail — Gmail maps IMAP keywords to labels, which requires special handling. Gmail flagging support is next on the roadmap. Outlook/Microsoft 365 requires OAuth2, which is not currently implemented, so Microsoft accounts are not supported.

Multi-inbox, unified view. Connect as many accounts as you need. All tools accept an optional account parameter — omit it to query across all configured accounts and get a combined, sorted result.

Connect one or more email accounts and agents can read mailboxes, search messages by sender, subject, date, or body text, download attachments, and monitor for new mail — all via the Model Context Protocol. Designed to work with Claude Desktop and any MCP-compatible client.

Quick Start

  1. Clone and install:

    git clone https://github.com/jonathanhowell/imap-mcp.git
    cd imap-mcp
    npm install && npm run build
    
  2. Copy the example config:

    mkdir -p ~/.config/imap-mcp
    cp config.example.yaml ~/.config/imap-mcp/config.yaml
    
  3. Edit the config — fill in your account details and set environment variables for passwords:

    accounts:
      - name: personal
        host: imap.gmail.com
        port: 993
        username: you@gmail.com
        password: $GMAIL_PASSWORD
    

    Then export the variable:

    export GMAIL_PASSWORD="your-app-password"
    
  4. Run the server:

    node build/index.js
    

The server reads the config from ~/.config/imap-mcp/config.yaml by default. Override with IMAP_MCP_CONFIG=/path/to/config.yaml.

Configuration Reference

The config file is YAML. Default location: ~/.config/imap-mcp/config.yaml. Override with the IMAP_MCP_CONFIG environment variable.

accounts[]

Field Type Required Default Description
name string yes Short identifier used by tools (e.g. personal, work)
host string yes IMAP hostname (e.g. imap.gmail.com)
port number yes Must be 993. TLS is enforced; port 143 and 587 are rejected
username string yes IMAP login username (usually your email address)
password string yes Use $ENV_VAR_NAME to read from environment variable
display_name string no Human-readable label shown in list_accounts responses

polling (optional)

Field Type Required Default Description
interval_seconds number no 300 How often to poll for new mail (minimum: 60s)

Setting environment variables for passwords:

export GMAIL_PASSWORD="your-app-password"
export WORK_PASSWORD="your-work-password"

In config.yaml, reference them as $GMAIL_PASSWORD and $WORK_PASSWORD.

Performance note: To verify performance on large mailboxes, connect to a mailbox with 10,000+ messages, run list_messages with default parameters, and confirm the response arrives within 5 seconds and contains only message headers (no bodies). The 200-result cap ensures response size is bounded.

Claude Desktop Setup

Add this entry to your claude_desktop_config.json (usually at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "imap-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/imap-mcp/build/index.js"],
      "env": {
        "IMAP_MCP_CONFIG": "/absolute/path/to/config.yaml",
        "GMAIL_PASSWORD": "your-app-password"
      }
    }
  }
}

Replace /absolute/path/to/imap-mcp with the directory where you cloned the repo. The IMAP_MCP_CONFIG key is optional — omit it to use the default ~/.config/imap-mcp/config.yaml. Any env vars referenced in your config file (e.g. $GMAIL_PASSWORD) must appear in the env block so Claude Desktop passes them to the server process.

Provider Compatibility

Gmail

Gmail requires an App Password — your regular Google account password will not work with IMAP.

  1. Enable IMAP in Gmail settings: Settings → See all settings → Forwarding and POP/IMAP → Enable IMAP
  2. Generate an App Password: myaccount.google.com/apppasswords
  3. Use the generated 16-character password as $GMAIL_PASSWORD in your config

Host: imap.gmail.com, Port: 993

Generic IMAP

Any IMAP server that supports TLS on port 993 and Basic Auth should work. Check your provider's documentation for the correct hostname.

Outlook / Hotmail / Microsoft 365

Outlook/Hotmail/Microsoft 365: Microsoft deprecated Basic Auth for IMAP in October 2022. Modern Microsoft accounts require OAuth2, which this server does not currently support. If you are using an Outlook, Hotmail, or Microsoft 365 account, it will not work with this server.

Tool Reference

All tools are available via MCP. account parameters accept the name field from your config. Results are capped at 200 items for list_messages and search_messages.

list_accounts

Returns all configured accounts. No parameters.

Response: Array of { account, email, display_name? } objects.


list_folders

Parameter Type Required Description
account string no Account name. Omit to list folders for all accounts.

Response (single account): Array of { name, delimiter, flags, messages, unseen }.

Response (all accounts): Same array, sorted alphabetically by folder name.


list_messages

Parameter Type Required Description
account string no Account name. Omit to query all accounts.
folder string no Folder name (default: INBOX)
limit number no Max messages to return (server cap: 200)
offset number no Pagination offset
sort newest|oldest no Sort order (default: newest)
unread_only boolean no Return only unread messages

Response (single account): Flat array of MessageHeader[] — each item includes uid, from, to[], cc[], subject, date, flags, and folder.

Response (all accounts): { results: MultiAccountMessageHeader[], errors?: Record<string, string> }. The errors key is present only when one or more accounts failed.


read_message

Parameter Type Required Description
account string yes Account name
uid number yes Message UID
format clean|full no clean strips reply chains (default). full returns raw body.

Response: Full message with headers, body, and attachments[] metadata. Inline text/calendar parts (calendar invites) are automatically surfaced as attachments with a default filename of invite.ics, even when they lack an explicit attachment disposition.


read_messages

Fetch multiple messages in a single call. All UIDs must belong to the same account and folder.

Parameter Type Required Description
account string yes Account name
uids number[] yes List of message UIDs to fetch (max 50)
folder string no Folder containing the messages (default: INBOX)
format clean|full|truncated no Body format (default: clean)
max_chars number no Max body characters when format is truncated (default: 2000)

Response: Array of message objects in the same order as uids. Each item includes headers, body, attachments[] metadata, and a uid field.


search_messages

Parameter Type Required Description
account string no Account name. Omit to search all accounts.
from string no Filter by sender address or name
subject string no Filter by subject text
body string no Filter by body text content (case-insensitive, server-side IMAP SEARCH BODY)
since string no ISO date string — messages on or after this date
before string no ISO date string — messages before this date
unread boolean no true = unread only, false = read only
folder string no Folder to search (default: INBOX). Use all to search every folder sequentially.
max_results number no Max results to return (server cap: 200)
exclude_keywords string[] no Exclude messages that have any of these custom IMAP keywords set (e.g. ["ClaudeProcessed", "ClaudeReplied"]). First keyword filtered server-side; additional keywords filtered in memory.
include_keywords string[] no Return only messages that have at least one of these custom IMAP keywords set (OR semantics). Single keyword uses server-side KEYWORD filter; multiple uses IMAP OR.

Response (single account): Flat array of SearchResultItem[] — each item includes uid, from, to[], cc[], subject, date, unread, folder, and keywords[].

Response (all accounts): { results: MultiAccountSearchResultItem[], errors?: Record<string, string> }.

Note: folder='all' searches every folder sequentially and can be slow on large mailboxes.


download_attachment

Parameter Type Required Description
account string yes Account name
uid number yes Message UID
part_id string no MIME part identifier (e.g. 2, 2.1). Faster when known.
filename string no Attachment filename. Used to look up the part ID when part_id is not known.
folder string no Folder containing the message (default: INBOX)

At least one of part_id or filename must be provided. When both are given, part_id takes precedence. Filename matching is case-insensitive.

Response: { filename, mimeType, size, data } where data is base64-encoded.

Calendar invites: Inline text/calendar parts are surfaced as attachments (typically named invite.ics). Use download_attachment with the part_id from the message's attachments[] to retrieve the ICS data.


get_new_mail

Parameter Type Required Description
since string yes ISO 8601 timestamp — return messages with internalDate after this time
account string no Account name. Omit to query all accounts.
exclude_keywords string[] no Exclude messages that have any of these custom IMAP keywords set (e.g. ["ClaudeProcessed"]). Filters cached results in memory.

Response: { results: MultiAccountMessageHeader[], errors?: Record<string, string> }. The server polls in the background at the configured interval; this tool reads from the cache, not live IMAP. Each result includes uid, from, subject, date, unread, folder, account, and keywords[].

Example Agent Prompts

Once connected to Claude Desktop, you can ask things like:

  • "Show me all unread emails from the last 24 hours across all my accounts"
  • "Search for emails from GitHub about pull requests in my work account from this week"
  • "Find any emails mentioning the invoice number INV-2024-042"
  • "Read the most recent email from alice@example.com and summarize it"
  • "Read all three emails in that thread and give me a summary"
  • "Download the PDF attachment from that email"
  • "Check if that email has a calendar invite and tell me the event details"

Troubleshooting

Connection refused / timeout

Check that port in your config is 993. This server enforces TLS — port 143 (plaintext) and port 587 (SMTP submission) will not work.

Authentication failed (Gmail)

Use an App Password, not your regular Google account password. Generate one at myaccount.google.com/apppasswords. Also verify IMAP is enabled in Gmail: Settings → See all settings → Forwarding and POP/IMAP → Enable IMAP.

Authentication failed (generic IMAP)

Verify the username and password are correct. Some providers require app-specific passwords even when not using Gmail — check your provider's security settings.

Outlook / Microsoft accounts not working

Microsoft deprecated Basic Auth for IMAP in October 2022. Microsoft 365, Outlook.com, and Hotmail accounts require OAuth2, which this server does not support. This is a Microsoft platform limitation that cannot be worked around with configuration changes.

Server crashes on startup

Check that the config file exists at the expected path (~/.config/imap-mcp/config.yaml by default, or the path in IMAP_MCP_CONFIG). Verify that all environment variables referenced in the config (e.g. $GMAIL_PASSWORD) are set before launching the server.

Performance: slow on large mailboxes

Using folder='all' in search_messages triggers a sequential search across every folder. On accounts with many folders or large mailboxes this can take several seconds. For faster results, specify a folder (e.g. folder='INBOX').

Contributing

Dev setup

npm install
npm run build
npm test

Guidelines

  • TypeScript strict mode throughout — no any types without explicit justification
  • All log output goes to stderr via logger.ts — never use console.log (enforced by ESLint)
  • Pre-commit hooks run lint + tests automatically via Husky
  • Install gitleaks for secret scanning (required for pre-commit hook): brew install gitleaks

PR flow

Branch from main, open a PR, CI must pass before merging.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured