IMAP MCP Server
This server enables AI assistants to manage email accounts and perform comprehensive email operations via IMAP and SMTP.
Account Management: Add, update, list, remove, connect, disconnect, and test IMAP accounts. Credentials are stored with AES-256 encryption. Supports multiple simultaneous accounts and 15+ pre-configured email providers.
Email Retrieval & Search: Search emails by sender, recipient, subject, body, date range, read/flagged status, or custom keywords — across single or all folders. Get latest emails, read full content (Markdown/HTML/plain text), find thread messages, and locate emails by Message-ID.
Sending & Drafting: Send new emails with plain text/HTML and attachments, reply (with reply-all support), forward messages, and save drafts. Upload large files as attachments without hitting context window limits.
Email Organization: Move emails between folders (with optional auto-creation), mark as read/unread, flag/unflag, add/remove custom IMAP keywords/labels, and delete individually or in bulk by UIDs or search criteria (with dry-run preview).
Folder Management: List all folders, get folder status (including message counts and custom keywords), create new folders, and get unread counts per folder or across all folders.
Spam & Domain Management: Analyze emails for spam using disposable/spam domain lists, delete spam by confidence level, view sender domain statistics, add/remove custom spam domains, whitelist trusted domains, and delete all emails from a specific domain — all with dry-run options.
Security & Access Control: AES-256 encrypted credential storage, read-only mode via environment variable to restrict to non-destructive tools, and a tool allowlist to expose only specific tools to the agent.
Allows managing 1&1 (IONOS) email accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing AOL Mail accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing Apple iCloud Mail accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing Gmail accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing GMX email accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing iCloud Mail accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing IONOS email accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing mailbox.org email accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing ProtonMail accounts via IMAP (requires ProtonMail Bridge), enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing WEB.DE email accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Allows managing Zoho Mail accounts via IMAP, enabling operations such as searching, reading, sending, moving, and deleting emails, as well as folder management.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@IMAP MCP ServerShow me my last 5 unread emails from today"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
IMAP MCP Server
A powerful Model Context Protocol (MCP) server that provides seamless IMAP email integration with secure account management and connection pooling.
Features
🔐 Secure Account Management: Encrypted credential storage with AES-256 encryption
🚀 Connection Pooling: Efficient IMAP connection management
📧 Comprehensive Email Operations: Search, read, move, mark, delete, and bulk delete emails
✉️ Email Sending: Send, reply, and forward emails via SMTP
📁 Folder Management: List folders, check status, get unread counts
🔄 Multiple Account Support: Manage multiple IMAP accounts simultaneously
🛡️ Type-Safe: Built with TypeScript for reliability
🌐 Web-Based Setup Wizard: Easy account configuration with provider presets
📱 15+ Email Providers: Pre-configured settings for Gmail, Outlook, Yahoo, and more
🔗 Auto SMTP Configuration: Automatic SMTP settings based on IMAP provider
Related MCP server: IMAP MCP Server
Installation
Requires Node.js 22.12 or newer. Node 18 and 20 have both reached end-of-life, and several of this package's dependencies no longer support them. Check yours with
node --version.
Run via npx (No Installation Required)
Once published to npm, you can run the server directly without cloning or building anything — npx downloads the prebuilt package and runs it:
npx -y imap-mcp-serverThis is the easiest way to use the server in an MCP client (see Configuration for ready-to-paste npx configs).
Quick Install (Recommended)
macOS/Linux:
curl -fsSL https://raw.githubusercontent.com/nikolausm/imap-mcp-server/main/install.sh | bashWindows (PowerShell as Administrator):
iwr -useb https://raw.githubusercontent.com/nikolausm/imap-mcp-server/main/install.ps1 | iexManual Installation
Clone the repository:
git clone https://github.com/nikolausm/imap-mcp-server.git
cd imap-mcp-serverInstall dependencies:
npm installBuild the project:
npm run buildAccount Setup
Accounts are stored encrypted in ~/.imap-mcp/accounts.json. This file is shared by all run modes — whether you start the server via npx, a global install, or a local clone, they all read the same accounts. So you only need to set up your accounts once.
Setting Up Accounts in npx Mode
If you run the server via npx (no clone), you have two ways to add accounts:
Option A — Run the setup wizard directly via npx (no install needed):
npx -p imap-mcp-server imap-setupThis launches the same web-based wizard described below and writes to ~/.imap-mcp/accounts.json, which your npx-configured MCP server then picks up automatically.
Option B — Add accounts straight from your AI client:
Once the MCP server is configured, just ask your assistant to add an account — it uses the imap_add_account tool. For example:
"Add my IMAP account: host imap.gmail.com, port 993, user me@gmail.com, password …"
No separate setup step required.
Web-Based Setup Wizard (Recommended)
After installation, run the setup wizard:
npm run setupOr if installed globally:
imap-setupOr directly via npx without installing:
npx -p imap-mcp-server imap-setupThis will:
Start a local web server
Open your browser to the setup wizard
Guide you through adding email accounts with pre-configured settings
Overriding Credentials via Environment Variables
You can override the username and password of an already-configured account at
runtime with environment variables — useful when you inject secrets from a
password manager or CI system instead of storing them in accounts.json.
The variables are keyed by the account name, uppercased with every
non-alphanumeric character replaced by _. For an account named Work Gmail
(key WORK_GMAIL):
Variable | Overrides |
| IMAP username ( |
| IMAP password |
| SMTP username ( |
| SMTP password |
Notes:
Overrides apply only to existing accounts; if no account's normalized name matches, the variable is ignored.
They are applied in memory only — nothing is written back to
accounts.json, and the values are used as-is (not re-encrypted).Variables are consumed at startup: on server start they are captured into an AES-256-encrypted in-memory cache and removed from
process.env, so the plaintext secret does not linger in the environment (where it could leak to child processes or diagnostics). Set them before launching the server.
The setup wizard integrates with this: each credential field (IMAP password,
IMAP username, SMTP username, SMTP password) has a "Do not save to config; set
later using an environment variable" checkbox. When ticked, the value you enter
is still used to test the connection, but it is not written to accounts.json —
the wizard shows the exact variable name to export, and the account picks the
credential up from that variable at runtime.
SMTP variables take effect only when the account already has an SMTP config.
Each variable takes effect independently; set only the ones you need.
If the variable is missing, the account still holds the empty placeholder the wizard wrote. Rather than dialing out with a blank credential — which providers answer with a generic authentication failure that looks exactly like a wrong password — the server refuses the connection and names what to set:
Account "Work Gmail" has IMAP credentials marked as environment-managed, but
this variable was not set when the server started:
IMAP_MCP_ACCOUNT_WORK_GMAIL_IMAP_PASSWORD. Set it and restart the server, or
store the credentials on the account via imap_update_account.Because the variables are read once at startup, setting one in an already-running shell has no effect until the server is restarted.
Supported Email Providers
The setup wizard includes pre-configured settings for:
Gmail / Google Workspace
Microsoft Outlook / Hotmail / Live
Yahoo Mail
Apple iCloud Mail
GMX
WEB.DE
IONOS (1&1)
ProtonMail (with Bridge)
Fastmail
Zoho Mail
AOL Mail
mailbox.org
Posteo
Custom IMAP servers
Configuration
Claude Code (CLI)
Option A — via npx (no clone/build needed)
claude mcp add imap -- npx -y imap-mcp-serverThis always runs the latest published version and requires no local build.
Option B — from a local clone
If you use Claude Code in the terminal, add the MCP server with a single command:
Step 1: Make sure you have built the project first (see Manual Installation).
Step 2: Run this command in your terminal:
claude mcp add imap -- node /absolute/path/to/imap-mcp-server/dist/index.jsImportant: Replace
/absolute/path/to/imap-mcp-serverwith the actual path where you cloned the repository. For example:# macOS/Linux example: claude mcp add imap -- node /Users/yourname/imap-mcp-server/dist/index.js # Windows example: claude mcp add imap -- node C:\Users\yourname\imap-mcp-server\dist\index.js
Step 3: Verify it was added:
claude mcp listYou should see imap in the list of configured MCP servers. That's it — the IMAP tools are now available in your Claude Code sessions.
Tip: If you want to remove the server later, run:
claude mcp remove imap
Claude Desktop (GUI App)
Add the IMAP MCP server to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Option A — via npx (recommended, no clone/build needed):
{
"mcpServers": {
"imap": {
"command": "npx",
"args": ["-y", "imap-mcp-server"],
"env": {}
}
}
}Option B — from a local clone:
{
"mcpServers": {
"imap": {
"command": "node",
"args": ["/path/to/imap-mcp-server/dist/index.js"],
"env": {}
}
}
}Restricting tool access (read-only mode / allowlist)
By default all tools are exposed. You can restrict which tools the agent sees
using two environment variables (set them under the env key of your MCP
config). This is useful when you want to give an assistant read-only access
to a mailbox, or expose only a hand-picked subset of tools.
Variable | Effect |
| When truthy ( |
| Comma-separated allowlist of tool names — only these are registered. Names are case-insensitive and the |
Example — read-only access:
{
"mcpServers": {
"imap": {
"command": "npx",
"args": ["-y", "imap-mcp-server"],
"env": { "IMAP_MCP_READ_ONLY": "true" }
}
}
}Example — explicit allowlist:
{
"mcpServers": {
"imap": {
"command": "npx",
"args": ["-y", "imap-mcp-server"],
"env": { "IMAP_MCP_ENABLED_TOOLS": "imap_search_emails,imap_get_email,imap_get_latest_emails" }
}
}
}The read-only subset is: imap_list_accounts, imap_connect, imap_disconnect,
imap_test_account, imap_search_emails, imap_get_email,
imap_get_latest_emails, imap_download_attachment, imap_find_thread_messages,
imap_find_email_by_message_id, imap_list_folders, imap_folder_status,
imap_get_unread_count, imap_check_spam, imap_domain_stats,
imap_list_spam_domains.
Usage
Once configured, the IMAP MCP server provides the following tools in Claude:
Choosing an account. For the email and folder tools,
accountIdis optional and backward-compatible. You may instead passaccountName, and if you only have a single account configured you can omit both — that account is used by default. With multiple accounts and no selector, the tool returns a clear error listing your options (imap_list_accounts).
Account Management
imap_add_account: Add a new IMAP account
Parameters: - name: Friendly name for the account - host: IMAP server hostname - port: Server port (default: 993) - user: Username - password: Password - tls: Use TLS/SSL (default: true) - sentFolder: Explicit Sent-folder name for sent-mail copies, e.g. "Gesendet" (optional — only needed when the server has no \Sent SPECIAL-USE folder and auto-detection fails) - defaultBcc: Optional BCC address(es) applied automatically to every outbound send, reply, forward, and draft for this account. Merged with any per-call `bcc` (duplicates removed case-insensitively)imap_update_account: Update an existing account (fix SMTP settings, rename, etc.)
Parameters: - accountId: ID of the account to update - name, host, port, user, password, tls, email: IMAP fields (all optional) - smtpHost, smtpPort, smtpSecure, smtpUser, smtpPassword: SMTP fields (optional) - saveToSent: Save sent emails to the Sent folder (optional) - sentFolder: Explicit Sent-folder override (optional). Pass an empty string to clear the override and re-enable auto-detection - defaultBcc: Optional default BCC address(es) (optional). Pass an empty string to clearimap_list_accounts: List all configured accounts
imap_remove_account: Remove an account
Parameters: - accountId: ID of the account to removeimap_connect: Connect to an account
Parameters: - accountId OR accountName: Account identifierimap_disconnect: Disconnect from an account
Parameters: - accountId: Account to disconnect
Email Operations
imap_search_emails: Search for emails
Parameters: - accountId: Account ID - folder: Folder name (default: INBOX; ignored when searchAllFolders is true) - searchAllFolders: Search across ALL folders at once (default: false). Skips Trash/Spam/Drafts and non-selectable folders by default. Use when a message may have been filed/moved/archived and you don't know its folder. - includeTrash, includeSpam, includeDrafts: Opt those noisy folders back into a searchAllFolders run (default: false each) - from, to, subject, body: Search criteria - since, before: Date filters - seen, flagged: Status filters - keywords: Match messages with ANY of these custom keywords (server-side OR). Read a mailbox's available custom keywords from `imap_folder_status`'s `customKeywords` field first. - unKeywords: Exclude messages with ANY of these custom keywords (result has NONE of them). Same keyword source as `keywords`. - limit: Max results (default: 50) - includeBody: Include parsed message body in the response (default: false). Fetches the RFC822 source once and parses it with mailparser, so you get uid + body in a single tool call instead of paying the N+1 cost of one `imap_get_email` per match. Body is rendered per `bodyFormat` and capped at `bodyMaxLength` per field. - bodyFormat: How to render the body when `includeBody` is true — `markdown` (default, clean Markdown via Turndown), `text`, `html`, or `auto`. - bodyMaxLength: Per-field cap when `includeBody` is true (default: 10000).With
searchAllFolders, results include afolderfield per message plusfoldersSearched, and any folder that failed to open is reported infoldersErrored(so a 0-result answer is never silently incomplete).includeBodyis honored in the single-folder path only. For a cross-folder sweep the lightweight header shape is preserved by design — pulling RFC822 source for every match across many folders would multiply bandwidth and parse cost. Follow up withimap_get_emailfor the specific uids whose bodies you need.On some servers a "flagged"/starred message carries a custom keyword (e.g. an Open-Xchange color label or Apple's
$MailFlagBit*) instead of, or in addition to, the\Flaggedsystem flag — after any flagged search, check each result'scustomKeywordsfield before concluding a message is or isn't flagged.imap_get_email: Get full email content
Parameters: - accountId: Account ID - folder: Folder name - uid: Email UID - maxContentLength: Max characters for text/html body (default: 10000) - includeAttachmentText: Include text attachment previews (default: true) - maxAttachmentTextChars: Max characters per text attachment (default: 100000)imap_get_latest_emails: Get recent emails
Parameters: - accountId: Account ID - folder: Folder name (default: INBOX) - count: Number of emails (default: 10) - includeBody: Include parsed message body (default: false). Same semantics as the `includeBody` option on `imap_search_emails` — one round-trip instead of N×`imap_get_email`. - bodyFormat: `markdown` (default), `text`, `html`, or `auto`. - bodyMaxLength: Per-field cap (default: 10000).imap_mark_as_read/unread: Change email read status
Parameters: - accountId: Account ID - folder: Folder name - uid: Email UID, OR an array of UIDs to flag in one call. Batch uses a single IMAP STORE so the operation is atomic at the server level — all UIDs are flagged, or none. Useful when triaging many messages at once.imap_flag_email/unflag_email: Star/unstar an email (sets or clears the IMAP \Flagged system flag — shows as a "star" in Gmail and Apple Mail). Some servers/clients (Open-Xchange, Apple Mail) also set a separate custom keyword (e.g.
$cl_N,$MailFlagBit*) when flagging; unflag only clears\Flagged, so if a message still shows as flagged, checkcustomKeywordsviaimap_get_emailand clear it withimap_remove_keyword.Parameters: - accountId: Account ID - folder: Folder name - uid: Email UIDimap_add_keyword/remove_keyword: Set or clear an arbitrary custom (non-system) IMAP keyword/label on an email, passed through verbatim (e.g. provider color labels like Open-Xchange's
$cl_1..$cl_10or Apple Mail's$MailFlagBit0..$MailFlagBit2, or any other custom keyword). Backslash-prefixed system flags (e.g.\Flagged,\Seen,\Deleted) are rejected — use the dedicated flag/read tools for those. Not every server permits custom-keyword changes (see the mailbox's PERMANENTFLAGS); if the server rejects or silently ignores the change, the call fails instead of reporting success.Parameters: - accountId: Account ID - folder: Folder name - uid: Email UID - keyword: IMAP keyword to set/remove (e.g. "$cl_3")imap_delete_email: Delete an email
Parameters: - accountId: Account ID - folder: Folder name - uid: Email UIDimap_move_email: Move an email from one folder to another
Parameters: - accountId: Account ID - folder: Source folder name (default: INBOX) - uid: Email UID, OR an array of UIDs to move in one call. Batch moves are attributed per-uid in the response (`results[]` with per-uid `uidMap` and any errors). Single-uid calls return the legacy response shape. - targetFolder: Destination folder name - createDestinationIfMissing: Create the destination folder if it does not exist (default: false)imap_find_thread_messages: Find inbox messages that belong to the same conversation threads as messages already sorted into another folder. Uses RFC 3501 HEADER search on In-Reply-To and References — works on any IMAP server.
Parameters: - accountId: Account ID - sourceFolder: Folder containing the already-sorted thread messages - searchFolder: Folder to search for related messages (default: INBOX) - searchReferences: Also match the References header for multi-level threads (default: true) - includeBody: Include parsed message body for each found thread message (default: false). Same semantics as the `includeBody` option on `imap_search_emails` — one round-trip instead of N×`imap_get_email`. - bodyFormat: `markdown` (default), `text`, `html`, or `auto`. - bodyMaxLength: Per-field cap (default: 10000).imap_download_attachment: Download an email attachment (returns images inline, extracts text from PDFs, or saves to downloads directory)
Parameters: - accountId: Account ID - folder: Folder name (default: INBOX) - uid: Email UID - filename: Attachment filename or contentId - savePath: Optional file path to save the attachment to - extractText: For PDFs, extract and return text content inline (default: true)imap_bulk_delete: Delete multiple emails at once with chunking and auto-reconnection
Parameters: - accountId: Account ID - folder: Folder name (default: INBOX) - uids: Array of email UIDs to delete - chunkSize: Emails to delete per batch (default: 50)imap_bulk_delete_by_search: Search for emails matching criteria and delete them all
Parameters: - accountId: Account ID - folder: Folder name (default: INBOX) - from, to, subject: Search criteria (optional) - before, since: Date filters (optional) - chunkSize: Emails to delete per batch (default: 50) - dryRun: Preview what would be deleted without deleting (default: false)At least one concrete criterion (
from,to,subject,before, orsince) is required — a call with no criteria is refused, so it can never match and delete an entire folder.imap_send_email: Send a new email
Parameters: - accountId: Account ID to send from - to: Recipient email address(es) — an array, or a single comma-separated string - subject: Email subject - text: Plain text content (optional) - html: HTML content (optional) - cc: CC recipients (optional) - bcc: BCC recipients (optional) - replyTo: Reply-to address (optional) - attachments: Array of attachments (optional) - filename: Attachment filename - content: Base64 encoded content - path: File path to attach - contentType: MIME type - contentDisposition: "attachment" (default) or "inline" — use "inline" for images shown in the HTML body via cid: - cid: Content-ID for inline attachments; must match the `cid:` value used in an `<img src="cid:...">` tag in `html`After sending, a copy is saved to the account's Sent folder (unless
saveToSentis disabled on the account). The folder is resolved via the account'ssentFolderoverride → the server's\SentSPECIAL-USE flag → a list of known localized names ("Sent", "Gesendet", "Éléments envoyés", …). The response reports the outcome:savedToSent(boolean),sentFolder(the folder used), and — when the save fails —sentSaveErrorexplaining why, instead of failing silently. The same applies toimap_reply_to_emailandimap_forward_email.When the account has
defaultBccconfigured, those address(es) are always BCC'd on send, reply, forward, and draft (merged with any per-callbcc; duplicates removed case-insensitively). The Bcc header is kept in the MIME stored for drafts and Sent-folder copies so mail clients show it.imap_save_draft: Save an email as a draft (no send). Takes the same fields as
imap_send_email, plusinReplyTo,references, and an optionalfolderoverride for the Drafts folder.imap_reply_to_email: Reply to an existing email
Parameters: - accountId: Account ID - folder: Folder containing the original email - uid: UID of the email to reply to - text: Plain text reply content (optional) - html: HTML reply content (optional) - replyAll: Reply to all recipients (default: false) - bcc: BCC recipients (optional; merged with account defaultBcc) - attachments: Array of attachments (optional, same shape as imap_send_email, including contentDisposition/cid for inline images)imap_forward_email: Forward an existing email
Parameters: - accountId: Account ID - folder: Folder containing the original email - uid: UID of the email to forward - to: Forward to email address(es) - text: Additional text to include (optional) - bcc: BCC recipients (optional; merged with account defaultBcc) - includeAttachments: Include original attachments (default: true)
Folder Operations
imap_list_folders: List all folders
Parameters: - accountId: Account IDEach folder includes its
attributes(raw IMAP LIST flags) and, when the server advertises it,specialUse— the RFC 6154 role (\Sent,\Drafts,\Trash,\Junk,\Archive) that identifies a folder independent of its localized display name (e.g. "Gesendet" carriesspecialUse: "\Sent").imap_folder_status: Get folder information
Parameters: - accountId: Account ID - folder: Folder name Returns: - messages: { total, new, unseen } — from IMAP STATUS - uidvalidity, uidnext - flags, permanentFlags: string arrays - customKeywords: the mailbox's non-system keywords, usable as the `keywords` / `unKeywords` input of imap_search_emailsimap_create_folder: Create a new IMAP folder/mailbox. Most servers also create any missing parent folders. Returns success even if the folder already exists.
Parameters: - accountId: Account ID - folder: Full folder path to create (e.g. "Archives/2026/2026-05" or "INBOX.Archive")imap_get_unread_count: Count unread emails
Parameters: - accountId: Account ID - folders: Specific folders (optional)
Security
Credentials are encrypted using AES-256-CBC encryption
Encryption keys are stored separately in
~/.imap-mcp/.keyAccount configurations are stored in
~/.imap-mcp/accounts.jsonThe store directory,
.key, andaccounts.jsonare written owner-only (0700/0600) so other local users cannot read the key or the credentialsThe web setup wizard's HTTP API never returns stored passwords to the browser
Downloaded attachments are confined to the downloads directory; sender-supplied filenames cannot write outside it
Never commit or share your encryption key or account configurations
Development
Running in Development Mode
npm run devBuilding
npm run buildProject Structure
src/
├── index.ts # MCP server entry point
├── services/
│ ├── imap-service.ts # IMAP connection management
│ ├── smtp-service.ts # SMTP service for sending emails
│ └── account-manager.ts # Account configuration
├── tools/
│ ├── index.ts # Tool registration
│ ├── account-tools.ts # Account management tools
│ ├── email-tools.ts # Email operation tools (including send/reply/forward)
│ └── folder-tools.ts # Folder operation tools
└── types/
└── index.ts # TypeScript type definitionsExample Usage in Claude
Add an account: "Add my Gmail account with username john@gmail.com"
Check new emails: "Show me the latest 5 emails from my Gmail account"
Search emails: "Search for emails from boss@company.com in the last week"
Send an email: "Send an email to client@example.com with subject 'Project Update'"
Reply to emails: "Reply to the latest email from my boss"
Forward emails: "Forward the email with subject 'Meeting Notes' to team@company.com"
Move an email: "Move the invoice email from INBOX to my Taxes folder"
Manage folders: "List all folders in my email account and show unread counts"
Troubleshooting
Connection Issues
Ensure your IMAP server settings are correct
Check if your email provider requires app-specific passwords
Verify that IMAP is enabled in your email account settings
For sending emails, ensure your account has SMTP access enabled
Recipients arriving as ["a@x.com","b@y.com"]
to, cc, bcc, references and uid accept either a single value or an
array. In JSON Schema that is an anyOf, and some MCP clients drop the anyOf
before showing the schema to the model — the field then looks untyped or
string-typed, and the client serializes the model's array into a string. The
server used to pass that string straight to nodemailer, which folded the
literal [ and ] into the first and last address, so every recipient was
rejected by the receiving mail server (issue #127).
The server now detects a stringified array and restores it, both when
validating tool input and again before composing the message, and logs a
warning to stderr naming the field. Nothing needs to change on your side. If
you want to bypass the client behavior entirely, pass recipients as one
comma-separated string: "Alice <alice@example.com>, Bob <bob@example.org>".
SMTP Configuration
The server automatically configures SMTP settings based on your IMAP provider. If you need custom SMTP settings, you can specify them when adding an account:
{
"smtp": {
"host": "smtp.example.com",
"port": 587,
"secure": false
}
}Common IMAP Settings
Gmail:
Host: imap.gmail.com
Port: 993
Requires app-specific password
Outlook/Hotmail:
Host: outlook.office365.com
Port: 993
Yahoo:
Host: imap.mail.yahoo.com
Port: 993
Requires app-specific password
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Available Tools
13 toolsimap_add_accountB
Add a new IMAP account configuration
| Name | Required | Description | Default |
|---|---|---|---|
| tls | No | Use TLS/SSL (default: true) | |
| host | Yes | IMAP server hostname | |
| name | Yes | Friendly name for the account | |
| port | No | IMAP server port (default: 993) | |
| user | Yes | Username for authentication | |
| No | Email address (From: header). Defaults to user if omitted | ||
| password | Yes | Password for authentication | |
| smtpHost | No | SMTP server hostname. Defaults to IMAP host with imap.→smtp. rewrite | |
| smtpPort | No | SMTP server port (465 for SMTPS, 587 for STARTTLS). Defaults to 587 | |
| smtpSecure | No | Use implicit TLS (SMTPS). Ignored for port 587/25 which always use STARTTLS, and for port 465 which always uses implicit TLS |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It does not mention that the tool likely validates credentials, stores configuration, or what happens if the account already exists. Essential side effects are omitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence but could be slightly expanded to include key context without becoming verbose. It is front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is insufficient given the tool's complexity (10 parameters, no output schema, no annotations). It lacks context about the overall workflow, such as being a prerequisite to imap_connect or imap_test_account.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter described. The tool description adds no additional meaning beyond what the schema already provides, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly uses the verb 'Add' and explicitly states the resource 'a new IMAP account configuration', distinguishing it from sibling tools like imap_update_account or imap_connect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool instead of alternatives such as imap_test_account (for testing) or imap_connect (for connecting). There are no prerequisites or exclusion conditions mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_connectC
Connect to an IMAP account
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | No | Account ID to connect to | |
| accountName | No | Account name to connect to |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavioral effects, yet it only says 'Connect to an IMAP account.' It does not say whether this establishes a persistent session, authenticates, requires the account to already exist, or what happens on repeated connection attempts. This is a significant transparency gap for a tool that likely changes connection state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and front-loaded, which is structurally fine. However, the single sentence essentially restates the tool name and provides no additional substance, making it under-specified rather than effectively concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no annotations and no output schema, so the description must carry most of the context. It omits prerequisites, account selection logic, connection lifecycle, return values, and failure behavior. An agent would struggle to invoke this tool correctly with only the provided text.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even if the description adds nothing. The description itself adds no extra meaning beyond the parameter names: both accountId and accountName are optional, and their relationship (mutual exclusivity, precedence, or requirements) is left unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a verb ('connect') and a resource ('an IMAP account'), which conveys the basic action. However, it is vague about what connecting entails and does not differentiate this tool from related siblings like imap_test_account or imap_add_account. It reads more as a generic restatement of the tool name than a precise capability definition.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, no mention of prerequisites such as an already-registered account, and no exclusions. The sibling list includes lifecycle tools like imap_add_account and imap_disconnect, but the description does not explain how imap_connect fits into that workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_disconnectB
Disconnect from an IMAP account
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | Account ID to disconnect from |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of disclosing behavior. It states only the action itself and does not clarify whether disconnecting preserves the stored account, whether it fails if no connection exists, or whether it is idempotent. This is a meaningful gap for a state-changing operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly scoped sentence with no filler or redundant phrasing. It is front-loaded with the verb and clearly names the target resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool, the description is minimally adequate: it states the action and the required input. However, without annotations, output schema, or any note about the connection lifecycle, an agent has no information about expected outcomes or failure conditions, so the definition is not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents accountId with 100% coverage, and the description merely echoes the same meaning without adding format, source, or lifecycle details. The schema handles the heavy lifting, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Disconnect') and a clear resource ('IMAP account'), which cleanly distinguishes it from sibling operations like imap_connect and imap_remove_account. An agent can tell exactly what action is being performed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives such as imap_remove_account or imap_connect. There is no mention of prerequisites like requiring an active connection, nor any exclusion of cases where removal or reconnection would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_download_attachmentA
Download a single attachment from an email (folder + uid + attachment filename/contentId, as listed by imap_get_email). Images are returned inline for viewing; PDFs are saved and their text is extracted inline (extractText); other files are saved to the shared downloads directory (or savePath). Use when the user wants the actual file contents, not just the message body.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | Email UID | |
| folder | No | Folder name | INBOX |
| filename | Yes | Attachment filename or contentId | |
| savePath | No | Optional file path to save the attachment to. If not provided, files are saved to the shared downloads directory. | |
| accountId | No | Account ID (from imap_list_accounts). Optional if accountName is given or only one account is configured. | |
| accountName | No | Account name instead of accountId. Optional if accountId is given or only one account is configured. | |
| extractText | No | For PDFs, extract and return text content inline |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the behavioral burden. It explains behavior per file type: images returned inline, PDFs saved with optional text extraction, other files saved to downloads or custom savePath. No destructive actions are mentioned, and it appears consistent with a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each essential and front-loaded. The first sentence defines the tool, the second explains behavior, the third gives usage guidance. No wasted words, and structure is logical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, no output schema, and no annotations, the description covers key behavioral aspects and usage. It references related tool for listing. Missing error handling details, but overall it's sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining how file type affects behavior (e.g., 'extractText' for PDFs) and connects to imap_get_email for listing. This goes beyond the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool downloads a single attachment, specifying the required inputs (folder, uid, filename/contentId). It distinguishes between different file types and contrasts with just getting the message body, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when the user wants the actual file contents, not just the message body,' providing clear usage context. It also references imap_get_email for listing attachments. While it doesn't list explicit when-not-to-use scenarios or alternatives beyond the implied contrast, the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_get_emailA
Read the FULL content of a single email by its UID (body, sender/recipients, date, attachment list, optional raw headers and text-attachment previews). By default the body is returned as clean Markdown in markdownContent and raw HTML is omitted so it never crosses the boundary; set bodyFormat to "html" for the legacy raw htmlContent, or "text" for plain text only. Use after imap_search_emails or imap_get_latest_emails gives you a uid. Body text is truncated to maxContentLength to protect the context window — raise it for long messages. To fetch attachment bytes, use imap_download_attachment.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | Email UID | |
| folder | No | Folder name | INBOX |
| accountId | No | Account ID (from imap_list_accounts). Optional if accountName is given or only one account is configured. | |
| bodyFormat | No | How to return the body. "markdown" (default): clean Markdown via Turndown in markdownContent, raw htmlContent omitted so HTML never crosses the boundary. "text": plain text only in textContent. "html": legacy raw htmlContent. "auto": substantive text/plain if available, else Markdown. | markdown |
| accountName | No | Account name instead of accountId. Optional if accountId is given or only one account is configured. | |
| includeHeaders | No | Include raw email headers (e.g. List-Unsubscribe, List-Unsubscribe-Post) | |
| maxContentLength | No | Maximum characters to return for each body field (text/markdown/html) | |
| includeAttachmentText | No | Include text attachment previews when available | |
| maxAttachmentTextChars | No | Maximum characters to return per text attachment |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and meets it: it discloses the default output behavior (clean Markdown in markdownContent), the intentional safety boundary (raw HTML is omitted 'so it never crosses the boundary'), the truncation guardrail (maxContentLength protects the context window), and what the tool deliberately does not do (attachment bytes). These are precisely the behavioral traits an agent needs to trust the tool's output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five sentences, each earning its place: core purpose, default behavior and format variants, workflow prerequisite, truncation guidance, and sibling routing. The most decision-critical information (what it reads, default format) is front-loaded, and there is zero filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no output schema and no annotations, the description covers a great deal: return fields, format semantics, truncation, workflow, and alternatives. The remaining gap is that IMAP UIDs are folder-scoped, and with folder defaulting to INBOX, an agent could fetch from the wrong folder after a search in another folder — a subtle correctness point the description leaves to schema inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter, warranting a baseline of 3. The description adds genuine value beyond the schema: it explains the rationale for maxContentLength ('protect the context window — raise it for long messages') and ties uid to the output of sibling tools. Some bodyFormat detail is restated from the schema rather than extended, which keeps this from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource — "Read the FULL content of a single email by its UID" — and enumerates the full scope of what is returned (body, sender/recipients, date, attachment list, optional raw headers, text-attachment previews). It naturally distinguishes itself from siblings like imap_search_emails and imap_download_attachment, and the contrast with imap_get_latest_emails ('Use after imap_get_latest_emails gives you a uid') clarifies that the sibling only produces UIDs, not content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The prerequisite is explicit: 'Use after imap_search_emails or imap_get_latest_emails gives you a uid.' The exclusion is also explicit: 'To fetch attachment bytes, use imap_download_attachment.' This is textbook routing — the agent knows exactly when to invoke this tool and when to pick a sibling, with nothing left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_list_accountsA
List all configured IMAP accounts
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral disclosure burden. It conveys a non-mutating enumeration operation, but it does not explicitly state that there are no side effects, does not require a connection, or what the returned account representation looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short declarative sentence with no filler. The key scope ('all configured') is front-loaded, and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool, purpose and invocation are clearly complete enough for selection and execution. Without an output schema, a brief note about the returned account identifiers or how results feed into account-scoped sibling tools would improve completeness, but the low complexity makes this a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero properties and no required parameters, so there are no parameter details for the description to add. The baseline for a zero-parameter tool applies, and 'list all configured accounts' is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' plus the clear resource 'configured IMAP accounts', making it obvious this is a read-only enumeration operation. It is distinctly different from siblings like imap_add_account, imap_remove_account, and imap_connect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit when-to-use or when-not-to-use guidance, nor does it name alternatives. The word 'configured' implies existing accounts rather than creation/connection, but an agent must infer when this is the right tool versus account-scoped operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_mark_as_readA
Mark one or many emails as read. Accepts a single UID or an array — pass an array to flag N messages in one IMAP STORE round-trip (useful when triaging).
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | Email UID, or array of UIDs to mark as read in one call (avoids N round-trips when triaging). All listed UIDs share the same IMAP STORE command, so the operation is atomic at the server level. | |
| folder | No | Folder name | INBOX |
| accountId | No | Account ID (from imap_list_accounts). Optional if accountName is given or only one account is configured. | |
| accountName | No | Account name instead of accountId. Optional if accountId is given or only one account is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It does reveal a notable behavioral trait: batching multiple UIDs into a single IMAP STORE round-trip. However, it does not mention side effects, reversibility, error behavior, or what happens on a successful call, which are meaningful gaps for a mutating tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, front-loaded with the core action and followed by a relevant batching tip. Every word earns its place; there is no filler or redundant preamble.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity mutation tool with all parameters documented in the schema and no output schema, the description provides enough for an agent to invoke it correctly. It omits return/error details, but those are not forced by an output schema or complex side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description's array/round-trip guidance is already present in the uid parameter's schema description, so the free text adds little new semantic value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Mark one or many emails as read.' This makes the core operation clear. However, it does not explicitly differentiate itself from the sibling imap_mark_as_unread or imap_flag_email beyond the verb phrase, so sibling differentiation is inferred rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit batch guidance: 'pass an array to flag N messages in one IMAP STORE round-trip (useful when triaging).' This tells an agent when the array form is valuable. It does not explicitly state when not to use this tool or name alternatives, so no exclusion or alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_mark_as_unreadA
Mark one or many emails as unread. Accepts a single UID or an array — pass an array to flag N messages in one IMAP STORE round-trip.
| Name | Required | Description | Default |
|---|---|---|---|
| uid | Yes | Email UID, or array of UIDs to mark as unread in one call (avoids N round-trips when triaging). All listed UIDs share the same IMAP STORE command, so the operation is atomic at the server level. | |
| folder | No | Folder name | INBOX |
| accountId | No | Account ID (from imap_list_accounts). Optional if accountName is given or only one account is configured. | |
| accountName | No | Account name instead of accountId. Optional if accountId is given or only one account is configured. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It does disclose the single IMAP STORE round-trip behavior for arrays, which is useful. It does not mention connection requirements, error outcomes, or reversibility, but the core effect of marking emails unread is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the purpose is front-loaded, and the batching/IMAP STORE detail is directly useful for choosing how to pass UIDs. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation tool with a fully documented schema, the description is largely sufficient. It lacks any statement about the return value or prerequisites like an existing connection, and there is no output schema to fill that gap, so it is adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides full descriptions for all four parameters, including UID array semantics, atomicity, folder, and account resolution. The description repeats the single-vs-array distinction but adds little beyond what the schema already communicates, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies a clear verb and resource: 'mark one or many emails as unread'. It also explains that it accepts a single UID or an array, and the operation is clearly distinct from siblings like imap_mark_as_read.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides useful batching guidance ('pass an array to flag N messages in one IMAP STORE round-trip'), so the agent knows when to use the array form. However, it does not explicitly compare this tool to imap_mark_as_read, imap_flag_email, or other alternatives, leaving tool selection mostly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_remove_accountB
Remove an IMAP account configuration
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | ID of the account to remove |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It reveals the action ('Remove') but does not state whether removal is permanent, whether it deletes stored credentials, or what happens to existing connections or dependent operations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is concise and easy to scan, though it sacrifices context that could have been included without bloating the text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (one required parameter) and the explicit name/action, the description is minimally viable. However, because this is a destructive operation with no annotations and no output schema, an agent would benefit from a note about permanence or side effects, which is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the input schema already explains accountId as 'ID of the account to remove'. The tool description adds no parameter semantics beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Remove') and a clear resource ('IMAP account configuration'), making the operation unambiguous. Despite the description mirroring the tool name, it clearly identifies the destructive removal action and is distinct from sibling tools like imap_add_account or imap_update_account.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides no guidance on when to use this tool versus alternatives such as imap_disconnect, imap_test_account, or imap_update_account. There is no mention of prerequisites, consequences, or conditions that would select this removal operation over others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_search_emailsA
Note: on some servers a 'flagged' or starred message carries a custom keyword (e.g. an Open-Xchange color label or Apple's $MailFlagBit*) instead of, or in addition to, the \Flagged system flag. After any flagged search, inspect each result's customKeywords field before concluding a message is or isn't flagged — do not rely on the flagged filter alone. Search for emails matching criteria (sender, recipient, subject, body text, date range, read/flagged status). Use this to FIND messages when you know something about them but not their UID — e.g. "emails from amazon last week", "unread invoices". By default searches a single folder (INBOX). Set searchAllFolders=true to scan every mailbox at once — this catches messages filed away by rules (e.g. a receipt routed to a custom folder); Trash/Spam/Drafts are skipped unless you opt in. By default returns lightweight headers (uid, from, subject, date, and folder when searching across folders); set includeBody=true to also return the parsed body in one round-trip instead of paying the N+1 cost of calling imap_get_email per match. For the newest messages without criteria, prefer imap_get_latest_emails.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Search by recipient | |
| body | No | Search in body text | |
| from | No | Search by sender | |
| seen | No | Filter by read/unread status | |
| limit | No | Maximum number of results | |
| since | No | Search emails since date (YYYY-MM-DD) | |
| before | No | Search emails before date (YYYY-MM-DD) | |
| folder | No | Folder name to search (default: INBOX). Ignored when searchAllFolders is true. | INBOX |
| flagged | No | Filter by flagged status | |
| subject | No | Search by subject | |
| keywords | No | Match messages that have ANY of these CUSTOM keywords (server-side OR; not system flags like \Seen/\Flagged). Read a mailbox's available custom keywords from imap_folder_status's customKeywords field, then pass the ones you want here. | |
| accountId | No | Account ID (from imap_list_accounts). Optional if accountName is given or only one account is configured. | |
| messageId | No | Search by RFC822 Message-ID header (substring match) | |
| bodyFormat | No | How to render the body when `includeBody` is true. Mirrors `imap_get_email` — "markdown" (default) returns clean Markdown and omits raw HTML so it never crosses the MCP boundary; "text" returns plain text; "html" returns raw HTML; "auto" prefers substantive text/plain, else Markdown. | markdown |
| unKeywords | No | Exclude messages that have ANY of these CUSTOM keywords (server-side; result has NONE of them). Same keyword source as `keywords` — check imap_folder_status first. | |
| accountName | No | Account name instead of accountId. Optional if accountId is given or only one account is configured. | |
| includeBody | No | If true, also fetch the parsed message body in the same round-trip and return it alongside headers (avoids the N+1 cost of calling imap_get_email per match). Body is rendered per `bodyFormat` and capped at `bodyMaxLength` characters per field. Off by default to preserve lightweight behavior. | |
| includeSpam | No | When searchAllFolders is true, also search Spam/Junk folders (off by default — noisy). | |
| includeTrash | No | When searchAllFolders is true, also search Trash/Bin/Deleted folders (off by default — noisy). | |
| bodyMaxLength | No | Per-message cap (in characters) for each rendered body field when `includeBody` is true. Defaults to 10000 to match `imap_get_email`. | |
| includeDrafts | No | When searchAllFolders is true, also search the Drafts folder (off by default). | |
| searchAllFolders | No | Search across ALL folders instead of just `folder`. Skips Trash/Spam/Drafts and non-selectable folders by default. Use when a message might have been filed/archived/moved and you do not know which folder it is in. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden, and it delivers: it warns about the flagged/custom-keyword pitfall, explains that Trash/Spam/Drafts are skipped unless opted in, clarifies that lightweight headers are returned by default, and documents body rendering behavior. This goes well beyond a simple 'search emails' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense with valuable information, and it is structured around key behaviors, defaults, and alternatives. However, it opens with a caveat about flagged searches before stating the tool's core purpose, which slightly delays the main 'what does this do' message. Each sentence earns its place, but the front-loading could be tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 22 optional parameters and no output schema, the description provides a thorough operational picture: default folder, return fields, body inclusion trade-offs, folder exclusions, opt-in flags, and a critical edge case. It covers the essential behaviors an agent needs to invoke the tool correctly and interpret its results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds substantial meaning beyond the schema: it explains the searchAllFolders behavior, the N+1 rationale for includeBody, how keywords relate to imap_folder_status customKeywords, and the flagged-filter caveat. This is genuinely actionable guidance, not a restatement of parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Search for emails matching criteria' and lists concrete filters like sender, recipient, subject, body, date range, and read/flagged status. It also ties the tool to a specific use case — finding messages when you know something about them but not their UID — and distinguishes it from imap_get_latest_emails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool ('Use this to FIND messages when you know something about them but not their UID') and when to prefer a sibling ('For the newest messages without criteria, prefer imap_get_latest_emails'). It also gives practical guidance on searchAllFolders for messages filed away by rules and on includeBody to avoid the N+1 cost of calling imap_get_email per match.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_test_accountA
Test an existing account connection without re-entering credentials. Validates IMAP connectivity and returns folder count and message count.
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | Account ID to test |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that the operation is a connection test, does not require re-entering credentials, and produces folder and message counts. It does not detail failure modes or whether a network connection is established, but it gives a clear behavioral picture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences lead with the purpose and then the output. Every sentence contributes necessary information, with no filler or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no annotations and no output schema, the description adequately covers purpose, usage context, and return values (folder count and message count). It could mention expected behavior on failure, but this is a minor gap given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the sole parameter is described as 'Account ID to test'. The description adds the nuance 'existing account connection', which slightly reinforces that the ID must refer to an existing account, but it does not materially expand beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states a specific verb ('Test') and resource ('existing account connection'), and specifies what the test validates (IMAP connectivity) and what it returns (folder count and message count). This distinguishes it from sibling account-management tools like imap_list_accounts or imap_connect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'existing account connection' and 'without re-entering credentials' clearly conveys when this tool is appropriate: for testing already-configured accounts. It does not explicitly name alternatives or state exclusions, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_update_accountA
Update an existing IMAP account. Useful for fixing SMTP settings without removing and re-adding the account.
| Name | Required | Description | Default |
|---|---|---|---|
| tls | No | Use TLS for IMAP | |
| host | No | IMAP host | |
| name | No | New friendly name | |
| port | No | IMAP port | |
| user | No | IMAP username | |
| No | Email address (From: header) | ||
| password | No | New password | |
| smtpHost | No | SMTP hostname | |
| smtpPort | No | SMTP port (465 for SMTPS, 587 for STARTTLS) | |
| smtpUser | No | SMTP username (if different from IMAP user) | |
| accountId | Yes | ID of the account to update | |
| saveToSent | No | Save sent emails to the Sent folder | |
| smtpSecure | No | Use implicit TLS (SMTPS). Port 587/25 always use STARTTLS regardless | |
| smtpPassword | No | SMTP password (if different from IMAP password) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must cover behavioral traits. It implies mutation but does not disclose whether updates are partial, destructive, or require specific permissions. Basic transparency is present but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences front-loaded with purpose. No wasted words, efficiently conveys core information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 14 parameters and no output schema or annotations, the description is minimal. It does not explain return values, partial update behavior, or parameter relationships, leaving gaps for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% parameter descriptions, so the description adds limited value. It hints at SMTP-related parameters but does not provide additional semantics beyond what the schema already offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Update an existing IMAP account') and specifies a common use case ('fixing SMTP settings without removing and re-adding the account'), effectively distinguishing it from sibling tools like imap_add_account and imap_remove_account.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear context for use (fixing SMTP settings) but does not explicitly state when not to use or mention alternatives. The implication is sufficient, but lacking explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imap_upload_fileA
Upload a file to the server for use as an email attachment. Returns a path that can be used with imap_send_email attachments. This allows sending large attachments without hitting context window limits. Max size: 26214400 bytes (configurable via IMAP_MAX_UPLOAD_SIZE). Uploads are auto-deleted after 86400000 ms (configurable via IMAP_UPLOAD_TTL_MS).
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Base64 encoded file content | |
| filename | Yes | Filename to save as | |
| contentType | No | MIME type (optional, used for metadata only) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description takes on the full burden. It discloses maximum upload size (configurable), auto-deletion after a TTL (configurable), and that the upload returns a path. This covers key behavioral aspects for a temporary upload tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise at three sentences, each providing valuable information: purpose, integration detail, and behavioral constraints. No redundant or extraneous wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description adequately explains the return value (a path for attachments) and important limits. For a tool with 3 simple parameters, this is complete and meets all needs for selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all three parameters (content, filename, contentType) with 100% coverage. The description adds no extra semantics beyond stating the tool's overall purpose, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: uploading a file to the server for use as an email attachment. It distinguishes it from siblings like imap_download_attachment and imap_send_email by specifying the output is a path for attachments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains that the tool is useful for sending large attachments to avoid context window limits and that the returned path integrates with imap_send_email. It does not explicitly state when not to use or list alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v1.5.2- Added
imap_download_attachment - Removed
imap_flag_email - Added
imap_get_email - Added
imap_mark_as_read - Added
imap_search_emails - Removed
imap_unflag_email - Added
imap_upload_file
31 tool updates
v1.5.2- Removed
imap_add_spam_domain - Removed
imap_add_whitelist_domain - Removed
imap_bulk_delete - Removed
imap_bulk_delete_by_search - Removed
imap_check_spam - Removed
imap_create_folder - Removed
imap_delete_by_domain - Removed
imap_delete_email - Removed
imap_delete_spam - Removed
imap_domain_stats - Removed
imap_download_attachment - Removed
imap_find_email_by_message_id - Removed
imap_find_thread_messages - Added
imap_flag_email - Removed
imap_folder_status - Removed
imap_forward_email - Removed
imap_get_email - Removed
imap_get_latest_emails - Removed
imap_get_unread_count - Removed
imap_list_folders - Removed
imap_list_spam_domains - Removed
imap_mark_as_read - Changed
imap_mark_as_unread3 fields changed- added
Input schema / properties / uid / anyOfAdded value: +[ + { + "type": "number" + }, + { + "items": { + "type": "number" + }, + "type": "array" + } +] - changed
Input schema / properties / uid / descriptionPrevious value: -"Email UID"New value: +"Email UID, or array of UIDs to mark as unread in one call (avoids N round-trips when triaging). All listed UIDs share the same IMAP STORE command, so the operation is atomic at the server level." - removed
Input schema / properties / uid / typeRemoved value: -"number"
- Removed
imap_move_email - Removed
imap_remove_spam_domain - Removed
imap_reply_to_email - Removed
imap_save_draft - Removed
imap_search_emails - Removed
imap_send_email - Added
imap_unflag_email - Removed
imap_upload_file
36 tool updates
v1.5.0- First observed
imap_add_account - First observed
imap_add_spam_domain - First observed
imap_add_whitelist_domain - First observed
imap_bulk_delete - First observed
imap_bulk_delete_by_search - First observed
imap_check_spam - First observed
imap_connect - First observed
imap_create_folder - First observed
imap_delete_by_domain - First observed
imap_delete_email - First observed
imap_delete_spam - First observed
imap_disconnect - First observed
imap_domain_stats - First observed
imap_download_attachment - First observed
imap_find_email_by_message_id - First observed
imap_find_thread_messages - First observed
imap_folder_status - First observed
imap_forward_email - First observed
imap_get_email - First observed
imap_get_latest_emails - First observed
imap_get_unread_count - First observed
imap_list_accounts - First observed
imap_list_folders - First observed
imap_list_spam_domains - First observed
imap_mark_as_read - First observed
imap_mark_as_unread - First observed
imap_move_email - First observed
imap_remove_account - First observed
imap_remove_spam_domain - First observed
imap_reply_to_email - First observed
imap_save_draft - First observed
imap_search_emails - First observed
imap_send_email - First observed
imap_test_account - First observed
imap_update_account - First observed
imap_upload_file
TDQS
Scored across 13 tools
Account management, connection, search/retrieve, attachment transfer, and read-state tools are clearly separated by resource and action. Only imap_connect and imap_test_account could be momentarily confused, but their descriptions distinguish establishing a connection from validating an existing configuration.
Every tool follows the same imap_ prefix with snake_case verb_noun naming, such as list_accounts, add_account, search_emails, mark_as_read. The pattern is highly predictable and consistent across the entire set.
13 tools is well within the ideal range for an IMAP server surface. Each tool covers a distinct part of the account lifecycle, connection handling, email retrieval, attachment transfer, and read-state management without feeling bloated.
There are significant gaps: imap_upload_file references imap_send_email, but no send tool is exposed, making uploads a dead end. The set also lacks folder listing, move/copy, delete, and flagging operations beyond read/unread, so many common email workflows cannot complete.
Maintenance
Related MCP Connectors
Connect any mailbox to Claude, ChatGPT & AI: read, send, reply, schedule & search emails.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables seamless email management through natural language conversations with Claude. Supports searching, reading, and sending emails securely with Gmail and other email providers.4MIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude to read, search, send, and manage emails across multiple IMAP/SMTP accounts via a single deployment.-
- FlicenseNot gradedqualityBmaintenanceEnables Claude to read, search, draft, send, flag, and move email across multiple IMAP/SMTP mailboxes while keeping credentials local.-
- FlicenseNot gradedqualityDmaintenanceEnables Claude Code to manage email inboxes via IMAP, including reading, categorizing, phishing detection, archiving, junking, and sending emails with user permission.-