Skip to main content
Glama
ni-c

imap-mcp

by ni-c

imap-mcp

CI npm version npm downloads node license container docs sponsor

A Model Context Protocol (MCP) server for any IMAP mailbox. It speaks IMAP rather than one vendor's API, so it works with whatever provider you already have.

Lets MCP clients like Claude Code, Claude Desktop or Codex read and search your mail, organise it into folders, save attachments and draft replies — with every message fenced as untrusted content, and the write tools off unless you turn them on.

Eleven tools, not fifty: a mail account is a workflow, not an API surface, so related operations are folded into one tool with a mode rather than split across many. And eleven is the ceiling, not the floor — IMAP_ALLOW_TOOLS=essential registers a curated six instead, and under the read-only default that narrows to four. See choosing which tools load.

What makes it different

It cannot send mail. That is the feature. An agent with access to private data, exposure to untrusted content, and a channel to the outside world is exploitable by anyone who can put a message in the inbox — the pattern that produced EchoLeak, where one crafted email exfiltrated internal data from Microsoft 365 Copilot with no user interaction. This server has the first two and deliberately not the third. save_draft writes the reply into your Drafts folder; you send it from your own mail client. No amount of clever text in a message can make this server post anything anywhere.

Writes are off until you turn them on. With only IMAP_HOST, IMAP_USER and IMAP_PASSWORD set, the server registers six read tools and nothing else. The mailbox tools appear with IMAP_READ_ONLY=false — note the default is true, the opposite of the other servers in this family, because this one reaches a mailbox. Tools that are off are not registered at all — a capability the model cannot see is one it cannot be talked into using.

Mail is treated as hostile input, because it is. Anyone in the world can put text in your inbox. Message bodies are fenced between markers carrying a per-call random nonce, and every line inside them is prefixed with that nonce, so the "this is data" signal does not stop at the edges of a long forwarded thread. A reminder follows the block, because otherwise the last instruction-shaped sentence in the model's context is the attacker's. Zero-width characters and directional overrides are stripped before the model sees anything, hidden HTML elements are dropped on a best-effort basis (the fencing, not the stripping, is what carries the weight), and markdown image syntax — inline and reference style — is defused so a rendering client cannot be made to fetch a tracking URL.

Alongside the message you get a server-side assessment: the SPF/DKIM/DMARC verdicts with the authserv-id they came from, which prompt-injection shapes matched, and which words mix Latin with Cyrillic or Greek letters. When something matches, the warning is the first thing in the result rather than a field buried in JSON.

Those verdicts carry a forgeable flag, and by default it is always true. A sender can write an Authentication-Results header of their own, and if your provider does not add one, theirs is the only one there — nothing inside the message distinguishes the two. Set IMAP_TRUSTED_AUTHSERV_ID to the id your provider stamps (it is the first token of the header on any message you already have) and only that id counts as authentic. Until you do, spf=pass is reported as what it is: a claim, from a header anyone could have written.

"New mail" that actually works. The server tags messages it has handed over with a custom IMAP keyword (AiSeen by default), so list_new_messages returns each message once. The human \Seen state is never touched — everything is read with BODY.PEEK.

Deleting asks a person. Where the client supports MCP elicitation, delete_messages and deleting a folder raise a real dialog that the model cannot answer on its behalf. Where it does not, they fall back to a two-call token — and say so, rather than implying somebody approved.

Related MCP server: Mac Local Mail MCP

Requirements

  • Node.js 22 or newer

  • An IMAP account. Providers with two-factor authentication generally need an app-specific password.

Configuration

Variable

Required

Default

Description

IMAP_HOST

yes

Hostname of the IMAP server, e.g. imap.example.net

IMAP_USER

yes

Account username, usually the address

IMAP_PASSWORD

yes

Password or app-specific password

IMAP_PORT

no

993 / 143

Defaults by TLS mode

IMAP_TLS

no

implicit

implicit, starttls or none

IMAP_MAILBOX

no

INBOX

Mailbox the message tools default to

IMAP_READ_ONLY

no

true

Exactly false registers the five mailbox tools

IMAP_ALLOW_TOOLS

no

Tool names, list_* prefixes or essential

IMAP_DENY_TOOLS

no

Same syntax; subtracted from the allow list

IMAP_SEEN_KEYWORD

no

AiSeen

Keyword for new-mail tracking; empty turns it off

IMAP_TRUSTED_AUTHSERV_ID

no

The authserv-id your provider stamps; see below

IMAP_DRAFTS_MAILBOX

no

auto

Overrides the folder found via the \Drafts flag

IMAP_MAX_MESSAGES

no

100

Default page size

IMAP_MAX_ATTACHMENT_BYTES

no

1048576

Ceiling for returning an attachment inline

IMAP_MAX_DOWNLOAD_BYTES

no

26214400

Ceiling for writing one to disk

IMAP_ATTACHMENT_TYPES

no

see below

Comma-separated content-type allowlist

IMAP_DOWNLOAD_DIR

no

Setting it allows saving attachments there

IMAP_INSECURE_TLS

no

false

Exactly true accepts a self-signed certificate

Booleans are compared against the literal string true; 1, yes and True are not true. IMAP_READ_ONLY is the mirror image: only the literal false turns it off, so a typo leaves the write tools unregistered.

IMAP_ALLOW_WRITE is gone. It has been replaced by IMAP_READ_ONLY, and an installation that still sets it refuses to start. Silently ignoring a removed security variable is the worst of the options: whoever set it once believes it is still in force. The default is unchanged — writes are still off unless you ask for them.

Choosing which tools load

IMAP_ALLOW_TOOLS and IMAP_DENY_TOOLS take comma-separated tool names; a trailing * matches a whole family. essential is a curated preset of six — list_mailboxes, list_new_messages, list_messages, get_message, set_message_flags and move_messages. Four of those are read tools, so it stays useful under the read-only default.

IMAP_ALLOW_TOOLS=essential
IMAP_ALLOW_TOOLS=list_new_messages,get_message,move_messages
IMAP_DENY_TOOLS=delete_messages

An entry that matches no tool aborts startup and names it, so a typo cannot silently hide a tool — an absent tool is not something anyone traces back to an environment variable. A filtered tool is never registered, so it is absent from tools/list and unknown to tools/call alike, exactly like a write tool under IMAP_READ_ONLY.

It covers tools. The attachment resources this server also exposes are not filtered.

If you run several of these servers at once, mcp-hub is the other answer — its /hub endpoint replaces every server's tools with six meta-tools. The password is deleted from the process environment as soon as it is read, so it is not visible to child processes or in /proc/<pid>/environ.

Without IMAP_DOWNLOAD_DIR this server never writes to the filesystem. The two size limits are separate on purpose: one protects the model's context window, the other protects your disk.

The server starts without credentials on purpose — it completes the handshake and lists its tools, and every call then fails with setup instructions instead of reaching a server.

Installation

Claude Code

claude mcp add imap-mcp \
  -e IMAP_HOST=imap.example.net -e IMAP_USER=you@example.net -e IMAP_PASSWORD=… \
  -- npx -y @ni-c/imap-mcp

Claude Desktop

{
  "mcpServers": {
    "imap-mcp": {
      "command": "npx",
      "args": ["-y", "@ni-c/imap-mcp"],
      "env": {
        "IMAP_HOST": "imap.example.net",
        "IMAP_USER": "you@example.net",
        "IMAP_PASSWORD": "…"
      }
    }
  }
}

Codex

[mcp_servers.imap-mcp]
command = "npx"
args = ["-y", "@ni-c/imap-mcp"]
env = { IMAP_HOST = "imap.example.net", IMAP_USER = "you@example.net", IMAP_PASSWORD = "…" }

Docker

docker run --rm -i \
  -e IMAP_HOST=imap.example.net \
  -e IMAP_USER=you@example.net \
  -e IMAP_PASSWORD=… \
  ghcr.io/ni-c/imap-mcp

Saving attachments needs a writable directory, and the image runs as uid 1000 — so a bind mount has to be owned by it on the host: -e IMAP_DOWNLOAD_DIR=/data -v "$PWD/attachments:/data" with chown 1000:1000 attachments. Without IMAP_DOWNLOAD_DIR the container never writes anything.

Tools

Read — always registered

Tool

What it does

get_server_info

Capabilities, permanent flags, whether the keyword is storable, which tool groups are on

list_mailboxes

Every folder with message and unseen counts and its special-use role

list_messages

Lists and searches: sender, recipient, subject, body, date range, flags

list_new_messages

Messages not handed over yet; marks them afterwards, dry_run to preview

get_message

Headers and body, fenced untrusted, plus the security assessment; include_thread

get_attachments

Without part_id lists them, with part_id reads or saves one

Mailbox — needs IMAP_READ_ONLY=false

Tool

Confirmation

set_message_flags

none — flags are reversible, and \Deleted is refused

move_messages

🔒 for both move and copy

delete_messages

👤 asks the user, 🔒 where the client cannot

manage_mailbox

👤 for delete, 🔒 for rename, none for create

save_draft

none — a draft does not leave the mailbox

👤 raises a dialog the model cannot answer · 🔒 needs a confirmation token: call once to receive one, then again with it.

copy is confirmed as well as move, because the thing that cannot be taken back is not the deletion — it is the disclosure. A destination is a free-form folder name, and on a shared account or a public namespace one call hands every message to everyone who can read it, leaving the source folder untouched. For the same reason set_message_flags refuses to add \Deleted: it is half a deletion, and the next client to close the mailbox may finish it. Use delete_messages, which asks.

Neither a confirmation nor a dialog quotes a mailbox name inside its own sentence — folder names come from the account, which on a shared mailbox means a colleague chose them.

Attachments are also available as MCP resources at imap://message/{uid}/part/{partId}, which matters where the server has no useful filesystem. The resource path runs the same allowlist, size limit and magic-byte check as the tool — it is not a second, unguarded door.

Not exposed, on purpose

No sending, no SMTP, no raw IMAP passthrough, no APPEND of arbitrary MIME, no HTML composition, no OAuth2. The first is the whole security argument (see SECURITY.md); the second would make every guard here optional; the last is planned but needs a test account before it ships.

And one thing the tool filter does not cover: attachment resources. IMAP_ALLOW_TOOLS narrows tools/list, not resources/list, so a server with a narrow allow list still serves those. IMAP_DOWNLOAD_DIR and the content-type allowlist are what constrain them — worth knowing before concluding that a filtered install reaches less of the mailbox than it does.

Safety

  • Every result carrying mailbox content is marked untrusted, message bodies additionally fenced with a per-call nonce and marked line by line.

  • Attachments pass two independent gates. The declaration is checked against a content-type allowlist, an executable-extension refusal list and a size ceiling; the bytes are then checked against magic numbers. An executable renamed to .pdf and declared application/pdf clears every declaration check and fails on its bytes — including when saving to disk, where it would be more dangerous, not less.

  • A part_id must come from a listing call, so the body cannot be pulled out through the attachment tool and escape its framing.

  • Downloads cannot escape their directory. The target comes only from the environment, the filename is sanitised, the resolved path is re-checked, and the file is opened with wx and mode 0600 — so nothing is overwritten and no planted symlink is followed.

  • Mailbox names, flags and addresses are refused if they contain line breaks. IMAP is a line protocol and a draft is a mail header; a CR is an injection primitive, not a typo.

  • TLS is never disabled globally. IMAP_INSECURE_TLS is scoped to the connection it names; NODE_TLS_REJECT_UNAUTHORIZED appears nowhere.

  • Every change to the mailbox is logged to stderr with the UIDs and folder — never the subject. stderr is the one channel the model does not read.

  • Responses are bounded. Whole items are dropped rather than the JSON being sliced, and the truncation notice comes first so the recovery hint survives.

SECURITY.md has the trust model, what these measures do not cover, and how to report a vulnerability.

Development

npm install
npm test
npm run build

The test suite runs against an in-memory IMAP fake, so it needs no server and no network. For a live server to point the real thing at, see CONTRIBUTING.md — it starts a throwaway mailbox in a container.

Releasing

  1. Add the CHANGELOG entry and bump package.json.

  2. npm run lint && npm run build && npm run test:coverage

  3. Commit, then push a signed tag: git tag -s vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z

The release workflow publishes to npm (Trusted Publishing, with provenance), creates the GitHub release from the CHANGELOG section and updates the MCP Registry entry.

License

MIT © Willi Thiel

Available Tools

6 tools
get_attachmentsList or download attachmentsA
Read-only

Without part_id: lists the attachments of a message with their type, size and whether the policy allows fetching them. With part_id: returns that one attachment. Small text and images come back inline so you can read them; anything larger is written to the download directory and you get the path. part_id must come from a listing call of this same tool. Executables are refused even when they claim to be something else — including when writing to disk.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYesIMAP UID of the message, as returned by the listing tools.
modeNo"auto" (default) reads small text and images inline and saves the rest to disk; "inline" always returns the content; "file" always saves it.
mailboxNoMailbox (folder) name exactly as returned by list_mailboxes, e.g. "INBOX" or "INBOX/Archive". Defaults to the configured mailbox.
part_idNoMIME part id from a previous listing call. Omit to list the attachments.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the readOnlyHint annotation by disclosing that small text/images are returned inline, larger payloads are written to the download directory with a path, and executables are refused even if disguised. It also mentions policy constraints on whether fetching is allowed. This gives an agent important behavioral context that annotations alone do not capture.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it explains both modes first, then behavior, then the source of part_id, then the safety constraint. Every sentence adds useful information without padding or repetition. It earns its length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description adequately covers what the agent will receive: attachment metadata when listing, inline content for small text/images, or a file path for larger files. It also covers policy restrictions, executables, and the required provenance of part_id. Nothing essential appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents all four parameters with 100% coverage, so the baseline is 3. The description adds meaningful value by explaining that part_id must originate from the same tool's listing call and by clarifying the mode behavior tied to auto/inline/file. This is helpful context beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly distinguishes the tool from siblings by specifying two modes: listing the attachments of a message without part_id and retrieving a single attachment with part_id. It names the resource (attachments of a message) and the verbs (list/returns), and its sibling relationships are obvious from context. This is more specific than the title and leaves no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit in-tool usage guidance: omit part_id to list, provide part_id to fetch a specific attachment, and part_id must come from a prior listing call of this same tool. It does not explicitly mention alternative tools such as get_message for reading message content, but the mode-based instructions are clear enough for an agent to select and invoke the tool correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_messageGet one messageA
Read-only

Fetches one message by UID and returns its headers and text body, fenced as untrusted content, together with a server-side security assessment (SPF/DKIM/DMARC verdicts, prompt-injection and homoglyph signals) and the list of its attachments. Does not change the read state. Set include_thread to also list the surrounding conversation.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYesIMAP UID of the message, as returned by the listing tools.
mailboxNoMailbox (folder) name exactly as returned by list_mailboxes, e.g. "INBOX" or "INBOX/Archive". Defaults to the configured mailbox.
include_threadNotrue also returns summaries of the other messages in the same conversation.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description explicitly states 'Does not change the read state' and discloses that the body is 'fenced as untrusted content' with a server-side security assessment. This adds meaningful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences place the core action first, then enrich with behavior and options. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the lack of an output schema, the description enumerates what is returned (headers, text body, security assessment, attachments), notes side effects, and covers the optional thread behavior. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all three parameters at 100%, so the description is not required to document them. It adds slight value by explaining include_thread as 'listing the surrounding conversation' and tying uid to the listing tools, but this is marginal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Fetches one message by UID' and enumerates the returned content (headers, text body, security assessment, attachments). This clearly differentiates it from list_messages and get_attachments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the use case clear: fetch a single message by UID when full content, security assessment, and attachment list are needed. It does not explicitly state when not to use it or name alternatives, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_server_infoServer and account informationA
Read-only

Reports what this account and server can do: the configured mailbox, IMAP capabilities, which flags the mailbox stores permanently, whether the new-mail keyword can be used, and which tool groups are enabled. Start here when a call fails for reasons that sound like configuration.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, and the description consistently describes a read-only reporting behavior ('Reports what this account and server can do'). It adds useful behavioral context by framing the tool as a diagnostic starting point and listing the categories of information returned, which goes beyond merely restating the annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states the core purpose and enumerates specific report contents, and the second sentence provides a practical usage cue. There is no filler or repetition of the tool name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete enough given the tool's simplicity: no parameters, a read-only annotation, and a clear enumeration of what is reported. It does not describe the exact output format, but for a zero-parameter diagnostic tool this is a minor gap rather than a blocking omission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the schema already fully covers the input surface. The description does not need to add parameter-level detail, and the baseline of 4 for a no-parameter tool is appropriate here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Reports') and identifies the resource ('what this account and server can do'), then enumerates concrete information categories such as configured mailbox, IMAP capabilities, stored flags, new-mail keyword support, and enabled tool groups. This clearly distinguishes it from the sibling tools, which focus on mailboxes, messages, and attachments rather than server/account configuration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance: 'Start here when a call fails for reasons that sound like configuration.' This is a clear trigger condition. It does not explicitly state when not to use it or name alternatives, but the sibling tools are sufficiently distinct that no exclusion is necessary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_mailboxesList mailboxesA
Read-only

Lists every folder in the account with its message and unseen counts, its special-use role (drafts, sent, trash, junk) and whether it can hold messages. Use the returned "path" verbatim wherever a tool takes a mailbox.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already signals safety, and the description adds useful behavioral detail: it returns message counts, unseen counts, special-use roles, and folder writability. This goes beyond the annotation without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences cover purpose, output contents, and a key usage directive with no filler. The essential information is front-loaded and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully enumerates what the agent can expect in the response—counts, roles, writability, and a reusable path. It also explains how to apply the result in later calls, making it complete for a parameterless listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so there is nothing for the description to explain. The baseline of 4 applies, and the description appropriately focuses on output usage instead of parameter details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists every folder in the account with counts, special-use roles, and message-holding capability. This distinguishes it from message-focused siblings like list_messages and get_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs that the returned 'path' should be reused verbatim wherever a mailbox is required, giving practical guidance for when to use this tool. It does not explicitly name alternatives, but the zero-parameter scope and mailbox-listing purpose make the use case clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_messagesList and search messagesA
Read-only

Lists messages newest first, optionally narrowed by sender, recipient, subject, body text, date range or flags. With no criteria it simply pages through the mailbox. Every filter is applied by the mail server, so searching a large folder is cheap. Returns summaries only — use get_message for the body.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoSubstring to match in the To header.
bodyNoSubstring to match in the message body.
fromNoSubstring to match in the From header.
seenNotrue for read messages only, false for unread only.
limitNoMaximum number of messages to return (default from IMAP_MAX_MESSAGES, hard cap 200).
sinceNoOnly messages received on or after this date (YYYY-MM-DD).
beforeNoOnly messages received before this date (YYYY-MM-DD).
offsetNoHow many messages to skip, newest first, for paging.
flaggedNotrue for flagged/starred messages only.
keywordNoOnly messages carrying this custom IMAP keyword.
mailboxNoMailbox (folder) name exactly as returned by list_mailboxes, e.g. "INBOX" or "INBOX/Archive". Defaults to the configured mailbox.
subjectNoSubstring to match in the subject.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint, so the description must supply behavioral depth. It adds sorting (newest first), output scope (summaries only), and a performance trait (server-side filter execution). This goes well beyond the annotation without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, no filler, with the core behavior and ordering in the opening line. Every sentence carries a distinct fact: filtering options, no-criteria behavior, server-side performance, and summary-only return. This is appropriately compact for a 12-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no required parameters and a fully described schema, the description covers the behavior that matters: ordering, summary output, body alternative, and paging behavior. It doesn't describe exact summary fields or explicitly distinguish all sibling tools, but the schema and the get_message pointer fill most of the gap. Given no output schema, the 'summaries only' statement is sufficient directional guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already documents all 12 parameters, so the baseline is 3. The description adds a useful grouping of filter types and clarifies that omitting criteria turns the call into a page-through of the mailbox. It also ties filtering to server-side execution, which is operational context the schema does not provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Lists messages newest first') and enumerates the viable filters, including sender, recipient, subject, body, date range, and flags. It also points to get_message for full body, which helps disambiguate from sibling list/get tools. However, it never explicitly contrasts this with list_new_messages, so sibling differentiation is incomplete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when to page without criteria and why: 'With no criteria it simply pages through the mailbox' and 'searching a large folder is cheap' due to server-side filtering. It explicitly routes body retrieval to get_message: 'Returns summaries only — use get_message for the body.' It doesn't mention when to prefer list_new_messages over this tool, so exclusions are partial.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_new_messagesList messages not seen beforeA

Returns messages this server has not handed over yet, newest first, and then marks them with the "AiSeen" keyword so the next call returns only what arrived since. This is separate from the human read/unread state, which is never touched. Use dry_run to preview without marking.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of messages to return (default from IMAP_MAX_MESSAGES, hard cap 200).
dry_runNotrue returns the messages without marking them, so the same set comes back next time.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description fully discloses the side-effecting behavior: messages are marked with the AiSeen keyword, while human read/unread state is 'never touched.' It also presents dry_run as a preview mechanism. This goes well beyond the annotations, which only state readOnlyHint=false and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences deliver the core behavior, the side effect, the read/unread distinction, and the dry_run option without any filler. The most important information is front-loaded, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers ordering, side effects, and preview behavior, which is enough for an agent to invoke the tool correctly. It does not describe the return format, but with no output schema the lack of explicit return-structure details is a minor gap given the tool's straightforward nature.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both limit and dry_run are already clearly documented in the schema. The description adds only a brief reminder to use dry_run for previewing, so it does not materially improve parameter understanding beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Returns messages this server has not handed over yet, newest first.' It also explains the distinctive AiSeen-marking behavior, clearly separating this tool from the sibling list_messages and the human read/unread state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a polling use case by explaining that marking ensures 'the next call returns only what arrived since,' and it gives a clear dry_run usage instruction. However, it never explicitly states when to choose this tool over alternatives like list_messages, nor does it name exclusions.

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. Dates show when Glama detected each change.

  1. 6 tool updatesv0.2.0
    • First observedget_attachments
    • First observedget_message
    • First observedget_server_info
    • First observedlist_mailboxes
    • First observedlist_messages
    • First observedlist_new_messages

TDQS

A4.4/5.0
Disambiguation4/5

Most tools map cleanly to distinct resources and actions: server info, mailboxes, messages, new-message queue, message detail, and attachments. The only mild overlap is between list_messages and list_new_messages, and between the attachment list in get_message and get_attachments, but the descriptions clearly separate those cases.

Naming Consistency5/5

All tools use a consistent verb_noun snake_case pattern: list_* for collections and get_* for individual items or pieces of data. list_new_messages is a clear modifier of list_messages, and get_server_info/get_attachments fit the same predictable scheme.

Tool Count5/5

Six tools is well-scoped for an IMAP retrieval server: one info call, one mailbox enumeration, two message-listing modes, one message fetch, and one attachment handler. Each tool occupies a clear place in the email inspection workflow without unnecessary redundancy.

Completeness4/5

The core read/inspect workflow is complete: discover capabilities, list mailboxes, search or page messages, consume new messages with the AiSeen marker, fetch full messages, and retrieve attachments. Missing operations like delete, move, or human-visible flag changes appear intentionally out of scope, though they would be expected from a broader IMAP client.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server for IMAP email access, enabling AI agents to read, search, and monitor email without sending or deleting messages.
    77
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to search, read, and inspect Apple Mail on macOS, including conversations and attachments. It can create new, reply, reply-all, or forward drafts, but cannot send or modify existing messages.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Safely searches, reads, flags, and drafts email through IMAP, with no send, delete, or move capabilities. Uses a local broker and OS credential store for secure authentication.
    16
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP-compatible AI assistants to securely search multiple mailboxes, reconstruct email threads, and inspect attachments through read-only tools without altering mailbox state.
    Apache 2.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ni-c/imap-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server