Skip to main content
Glama
yandex-mail-mcp

yandex-mail-mcp

by imdeniil

Yandex Mail MCP Server

MCP (Model Context Protocol) server for Yandex Mail. Enables Claude Desktop and other MCP clients to read, search, and manage emails via Yandex Mail — 28 tools covering every common mail workflow.

Features

  • Folders — list, create, rename, delete (with Cyrillic names via IMAP UTF-7)

  • Search — full IMAP syntax: FROM/TO/SUBJECT/BODY, LARGER/SMALLER, SENTSINCE/SENTBEFORE, HEADER <field> <value>, KEYWORD/UNKEYWORD, OR/NOT. Cyrillic queries supported.

  • Read — full content, text + HTML body, attachment list

  • Inspect — fetch MIME structure + size WITHOUT downloading bodies (inspect_email/fetch_part) — critical for large messages

  • Flags — mark_read/mark_unread/mark_flagged/mark_answered + generic set_flags

  • Send — plain/HTML, attachments (RFC 2231 for non-ASCII names), save-to-Sent

  • Reply — proper In-Reply-To/References threading, deduped Re: prefix, reply_all with RFC 5322 address parsing

  • Forward — as message/rfc822 attachment or inline quoted body

  • Move/Delete — atomic UID MOVE (RFC 6851) when supported, smart Trash discovery via \Trash SPECIAL-USE

  • Bulk — bulk_move/bulk_delete/bulk_set_flags etc. — chunked UID operations for batch workflows

  • Convenience — empty_trash, get_unread_summary (counts across all folders in one session)

All operations use stable IMAP UIDs (not sequence numbers), and connection helpers retry transiently on DNS/network flakes.

Related MCP server: Email MCP Server

No install, no venv — uvx fetches the package and runs it sandboxed. Add this to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%/Claude/claude_desktop_config.json (Windows):

Option 1: From PyPI

{
  "mcpServers": {
    "yandex-mail": {
      "command": "uvx",
      "args": ["yandex-mail-mcp"],
      "env": {
        "YANDEX_EMAIL": "your-address@yandex.ru",
        "YANDEX_APP_PASSWORD": "your-app-password-here"
      }
    }
  }
}

Option 2: From GitHub (latest development build)

{
  "mcpServers": {
    "yandex-mail": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/imdeniil/yandex-mail-mcp",
        "yandex-mail-mcp"
      ],
      "env": {
        "YANDEX_EMAIL": "your-address@yandex.ru",
        "YANDEX_APP_PASSWORD": "your-app-password-here"
      }
    }
  }
}

Restart Claude Desktop. The server will appear as yandex-mail with 28 tools available.

To pin to a specific release:

"--from", "git+https://github.com/imdeniil/yandex-mail-mcp@v0.1.1"

Getting a Yandex app password

  1. Go to Yandex ID

  2. Enable Two-Factor Authentication (required for app passwords)

  3. Go to Security → App Passwords

  4. Create new app password for "Mail"

  5. Paste the generated password into YANDEX_APP_PASSWORD above

Alternative: Install from source

If you want to hack on the code or don't want uvx:

git clone https://github.com/imdeniil/yandex-mail-mcp.git
cd yandex-mail-mcp

python3 -m venv .venv
source .venv/bin/activate
pip install -e .            # installs as editable package with deps
# or for dev tools too:
pip install -e ".[dev]"

cp .env.example .env
# Edit .env with your Yandex email and app password

Then point Claude Desktop at the venv's Python:

{
  "mcpServers": {
    "yandex-mail": {
      "command": "/absolute/path/to/yandex-mail-mcp/.venv/bin/yandex-mail-mcp"
    }
  }
}

Configuration

Credentials

The server looks for credentials in this order (first wins):

  1. Environment variables YANDEX_EMAIL / YANDEX_APP_PASSWORD (best for uvx + Claude Desktop)

  2. $YANDEX_MAIL_MCP_ENV override path to a .env file

  3. $PWD/.env (project-local, for direct invocation)

  4. $XDG_CONFIG_HOME/yandex-mail-mcp/.env (typically ~/.config/yandex-mail-mcp/.env)

  5. .env next to yandex_mail_mcp.py (source checkout)

For Claude Desktop + uvx, just put them in the env block of the config as shown above.

Log file location

The server writes to a log file (stdout is reserved for MCP protocol). Resolution order:

  1. $YANDEX_MAIL_MCP_LOG_FILE override

  2. $XDG_STATE_HOME/yandex-mail-mcp/yandex_mail_mcp.log (typically ~/.local/state/yandex-mail-mcp/yandex_mail_mcp.log)

  3. Next to yandex_mail_mcp.py in source checkouts

  4. $TMPDIR/yandex_mail_mcp.log last-resort fallback

Available Tools

28 tools across 6 categories. See CHANGELOG.md for the full list. Key ones:

Tool

Purpose

list_folders()

Enumerate mailbox folders with attrs

get_unread_summary()

Unread counts across all folders

search_emails(folder, query, limit, offset)

IMAP query with pagination

inspect_email(folder, email_id)

Headers + MIME structure, no body download

fetch_part(folder, email_id, part_number)

Download a specific MIME part

read_email(folder, email_id)

Full text + HTML + attachments

send_email(to, subject, body, cc, bcc, html, attachments)

Send

reply_email(folder, email_id, body, reply_all, ...)

Reply with threading

forward_email(folder, email_id, to, body, as_attachment, ...)

Forward

move_email / delete_email

Atomic where possible

mark_read / mark_unread / mark_flagged / mark_answered

Flag shortcuts

bulk_move / bulk_delete / bulk_set_flags

Batch operations

create_folder / rename_folder / delete_folder

Mailbox management

empty_trash()

One-call trash cleanup

Search Query Examples

ALL                                  # All emails
UNSEEN                               # Unread
FROM sender@example.com              # From specific sender
SUBJECT hello                        # Subject contains "hello"
SINCE 01-Dec-2024                    # Received since date
SENTSINCE 01-Jan-2024                # Sent since date
LARGER 1048576                       # Larger than 1 MB
HEADER List-Id announce              # Custom header search
HEADER X-Custom "multi word value"   # Multi-word via shlex
KEYWORD Important                    # User keyword flag
UNSEEN FROM boss@company.com         # Combined (implicit AND)
OR FROM alice@x.com FROM bob@x.com   # Logical OR
NOT DELETED                          # Negation
UNSEEN LARGER 500000 SINCE 01-Jan-2024  # Multi-criteria

Running Tests

# Install dev deps
pip install -e ".[dev]"

# Safe tests (always run — unit + read-only integration)
pytest

# Full suite including destructive + send (modifies mailbox, sends mail)
pytest --run-destructive

# Specific category
pytest -m destructive --run-destructive
pytest -m send --run-destructive

Integration tests require .env with valid credentials. Destructive and send tests are gated behind --run-destructive for safety.

Security Notes

  • send_email attachments can read any file accessible to the server process. The attachments parameter accepts absolute file paths, so in principle an LLM could be prompt-injected (e.g. via the body of an incoming email read through read_email) into attaching sensitive files such as ~/.ssh/id_rsa to an outgoing message. This is inherent to exposing a filesystem-reading primitive over MCP.

    Mitigations:

    • Every send_email call must be approved by you in the MCP client (Claude Desktop shows tool calls before executing them — always read which files are being attached before approving).

    • Every attachment path is written to the log file for audit.

    • Run the server as a user that only has access to files you are willing to send by email.

  • download_attachment sanitises filenames from received email (strips path components, asserts the resolved path stays within save_dir) so a malicious sender cannot write outside the target directory.

  • delete_folder is destructive. Behavior on non-empty folders is server-dependent per RFC 3501 §6.3.4. Approve carefully.

  • Credentials come from environment variables (MCP client config) or a .env file. Keep .env out of version control.

Not supported (intentionally)

Verified empirically against imap.yandex.com:

  • ManageSieve / server-side filters — Yandex does not expose the ManageSieve protocol (port 4190 closed, no SIEVE capability). User filter rules ("Правила обработки писем") can only be managed through the Yandex web UI. This MCP server provides client-side equivalents via bulk_* + conditional logic.

  • SORT / THREAD extensions (RFC 5256) — Yandex returns BAD Command syntax error. Sort client-side if needed.

  • IDLE push notifications — supported by Yandex but not exposed as an MCP tool because long-polling doesn't fit the stateless request/response model. Use get_folder_status or get_unread_summary for polling instead.

License

MIT

Available Tools

28 tools
bulk_deleteA

Delete multiple messages at once.

If permanent=False (default), moves to Trash (discovered via \Trash SPECIAL-USE with localized fallbacks). If permanent=True or no Trash folder is found, marks +FLAGS \Deleted and EXPUNGEs immediately.

Deleting from within the Trash folder is always permanent regardless of the flag.

Inputs: folder (required), email_ids (required), permanent.

bulk_mark_flaggedC

Star or unstar multiple emails via the \Flagged flag.

Inputs: folder (required), email_ids (required), flagged.

bulk_mark_readB

Mark multiple emails as read (adds \Seen).

Inputs: folder (required), email_ids (required).

bulk_mark_unreadB

Mark multiple emails as unread (removes \Seen).

Inputs: folder (required), email_ids (required).

bulk_moveA

Move multiple messages to another folder in a single IMAP session.

Uses atomic UID MOVE (RFC 6851) in chunks when the server advertises it, falls back to COPY+STORE+EXPUNGE per chunk otherwise.

Inputs: folder (required), email_ids (required), destination (required).

bulk_set_flagsA

Set or clear IMAP flags on multiple messages in a single operation.

More efficient than looping set_flags: one UID STORE per chunk of ~500 UIDs, not one per message. Validates every flag the same way set_flags does (rejects flags with whitespace, parens, etc.).

Args: folder: Folder containing the messages email_ids: List of UIDs to update add: Flags to add (e.g. ["\Seen"]) remove: Flags to remove

Returns count of UIDs touched per add/remove operation.

Inputs: folder (required), email_ids (required), add, remove.

create_folderA

Create a new mail folder. Name can be human-readable (Cyrillic supported — auto-encoded to IMAP modified UTF-7).

Inputs: name (required).

delete_emailA

Delete an email (move to Trash).

Trash folder is discovered via the IMAP \Trash SPECIAL-USE attribute (RFC 6154) with fallbacks to common localized names. If no trash folder is found or copy fails, the email is permanently deleted.

Args: folder: Folder containing the email email_id: Email ID to delete

Returns confirmation of deletion.

Inputs: folder (required), email_id (required).

delete_folderA

Delete a mail folder.

WARNING: This is destructive. Behavior on non-empty folders is server-dependent (RFC 3501 §6.3.4 permits servers to return NO); some servers reject the operation, others delete the contents without moving them to Trash. The MCP client should surface this call for user approval.

Inputs: name (required).

download_attachmentA

Download an email attachment to disk.

Args: folder: Mailbox folder containing the email email_id: Email ID from search_emails() result filename: Attachment filename to download (from read_email attachments list) save_dir: Directory to save the file (default: ~/Downloads)

Returns dict with saved file path and size.

Inputs: folder (required), email_id (required), filename (required), save_dir.

empty_trashA

Empty the Trash folder.

Discovers Trash via \Trash SPECIAL-USE with localized fallbacks, selects it, marks all messages +FLAGS \Deleted, and EXPUNGEs. Returns the count of deleted messages.

Inputs: no named parameters.

fetch_partA

Fetch a specific MIME part of an email by part number.

Part numbers come from inspect_email's parts list (e.g. "1", "2.1"). For text parts with decode=True (default), returns the decoded string body. For binary parts or decode=False, returns base64-encoded bytes so the result is JSON-safe.

Args: folder: Folder containing the email email_id: UID of the email part_number: Part identifier from inspect_email (e.g. "1", "2.1") decode: If True, decode text parts to str; otherwise return base64

Returns dict with content (str or base64) + encoding marker.

Inputs: folder (required), email_id (required), part_number (required), decode.

forward_emailA

Forward an email to new recipients.

Unlike reply_email, this is a new thread: no In-Reply-To or References headers are set, and the subject gets a deduped "Fwd: " prefix.

Args: folder: Folder containing the original email email_id: UID of the email to forward to: Forward recipients (comma-separated) body: Optional introduction text prepended to the forwarded content cc: CC recipients (comma-separated) bcc: BCC recipients (comma-separated) html: If True, intro body is HTML (affects inline display only) attachments: Additional files to attach alongside the original as_attachment: If True (default), original message is attached as message/rfc822 (preserves all original headers and structure). If False, headers + body are inlined as quoted text in the body. save_to_sent: If True (default), save a copy to the Sent folder

Inputs: folder (required), email_id (required), to (required), body, +6 more.

get_folder_statusC

Get counts and state for a folder via IMAP STATUS (RFC 3501).

Returns dict with keys (when available):

  • folder: input folder name

  • messages: total messages

  • unseen: unread messages

  • recent: recent messages

  • uidnext: next UID to be assigned

  • uidvalidity: UID validity identifier (if this changes, stored UIDs are no longer valid and must be re-fetched)

Inputs: folder (required).

get_unread_summaryA

Get unread and total message counts across ALL selectable folders.

Iterates LIST, skips \Noselect folders, calls STATUS on each. Much more efficient than calling get_folder_status per folder from the client side because everything happens in one IMAP session.

Returns a dict keyed by human-readable folder name, each value containing {messages, unseen}. Also includes a _summary key with totals.

Inputs: no named parameters.

inspect_emailA

Inspect an email's headers and MIME structure WITHOUT downloading bodies.

Uses FETCH BODYSTRUCTURE + header subset — returns in milliseconds even for huge messages with attachments. Ideal for:

  • Previewing large emails without tying up bandwidth

  • Deciding which attachment to download (see fetch_part)

  • Bulk processing many messages efficiently

Returns subject/from/to/date/size plus a list of MIME parts, each with:

  • part: part number (e.g. "1", "2", "2.1") — pass to fetch_part

  • type: MIME type (e.g. "text/plain", "application/pdf")

  • size: part size in bytes (may be None)

  • charset: for text parts

  • filename: for attachments (RFC 2231 / MIME decoded)

  • disposition: "inline" or "attachment"

Inputs: folder (required), email_id (required).

list_foldersA

List all mail folders in the Yandex mailbox.

Returns list of folders with:

  • name: Human-readable folder name (decoded from IMAP UTF-7)

  • imap_name: Raw IMAP folder name (use this for other operations like search_emails)

  • attrs: IMAP folder attributes, e.g. ["\HasNoChildren", "\Trash"]

Inputs: no named parameters. Returns: result

mark_answeredC

Mark an email as answered (adds \Answered).

Inputs: folder (required), email_id (required).

mark_flaggedC

Star or unstar an email via the \Flagged IMAP flag.

Inputs: folder (required), email_id (required), flagged.

mark_readB

Mark an email as read (adds \Seen).

Inputs: folder (required), email_id (required).

mark_unreadB

Mark an email as unread (removes \Seen).

Inputs: folder (required), email_id (required).

move_emailA

Move an email to another folder.

Args: folder: Source folder containing the email email_id: Email ID to move destination: Destination folder name

Returns confirmation of move.

Inputs: folder (required), email_id (required), destination (required).

read_emailA

Read full email content by ID.

Args: folder: Mailbox folder containing the email email_id: Email ID from search_emails() result

Returns email with subject, from, to, date, body_text, body_html, attachments list.

Inputs: folder (required), email_id (required).

rename_folderC

Rename a mail folder. Both names are auto-encoded to UTF-7.

Inputs: old_name (required), new_name (required).

reply_emailA

Reply to an email with correct threading headers (RFC 5322).

Fetches the original message's Message-ID, References, Subject, From, Reply-To, To and Cc headers, and builds a reply with:

  • In-Reply-To pointing at the original Message-ID

  • References chaining the previous thread plus the original Message-ID

  • Subject with a deduped "Re: " prefix

  • Recipients: original Reply-To (or From); if reply_all, also original To + Cc with our own address removed

Args: folder: Folder containing the original email email_id: UID of the email to reply to body: Reply body text (plain or HTML) reply_all: If True, include original To + Cc recipients html: If True, body is HTML attachments: Optional list of file paths to attach save_to_sent: If True (default), save the reply to the Sent folder

Inputs: folder (required), email_id (required), body (required), reply_all, +3 more.

search_emailsA

Search emails in a folder.

IDs returned are IMAP UIDs (stable within a folder's UIDVALIDITY), not sequence numbers — they will not change after other messages are deleted.

Args: folder: Mailbox folder (default: INBOX). Use list_folders() to see available folders. Accepts either ASCII names, raw IMAP names from list_folders(), or human-readable non-ASCII names (e.g. "Корзина") — the latter are auto-encoded to IMAP modified UTF-7. query: IMAP search query. Examples: - "ALL" - all emails - "UNSEEN" - unread emails - "FROM sender@example.com" - from specific sender - "SUBJECT hello" - subject contains "hello" - "SINCE 01-Dec-2024" - emails since date - "BEFORE 31-Dec-2024" - emails before date - Can combine: "UNSEEN FROM boss@company.com" limit: Maximum number of emails to return (default: 20) offset: Number of newest-first results to skip, for pagination (default: 0)

Returns list of email summaries with id (UID), subject, from, date.

Inputs: folder, query, limit, offset. Returns: result

send_emailA

Send an email via Yandex SMTP.

Args: to: Recipient email address (comma-separated for multiple) subject: Email subject body: Email body (plain text or HTML based on html flag) cc: CC recipients (optional, comma-separated) bcc: BCC recipients (optional, comma-separated) html: If True, body is treated as HTML (default: False) attachments: Optional list of absolute file paths to attach. Each attachment is resolved and must be a regular file. SECURITY: this tool can read any file accessible to the MCP server process and exfiltrate it via email — the MCP client should surface every send_email call for user approval. All attached paths are logged to yandex_mail_mcp.log for audit. save_to_sent: If True (default), append a copy of the sent message to the Sent folder via IMAP APPEND. Yandex does not reliably auto-save SMTP-sent messages to Sent; this ensures a copy exists. Failure to save is non-fatal and logged as a warning.

Returns confirmation with recipients, attached file names, and saved_to_sent (decoded Sent folder name or None).

Inputs: to (required), subject (required), body (required), cc, +4 more.

set_flagsB

Set or clear IMAP flags on a message.

Common IMAP system flags (backslash-prefixed): \Seen, \Flagged, \Answered, \Draft, \Deleted. Custom user keywords have no backslash.

Args: folder: Folder containing the email email_id: UID of the email (from search_emails result) add: Flags to add (e.g. ["\Seen", "\Flagged"]) remove: Flags to remove

Returns confirmation with the flags added/removed.

Inputs: folder (required), email_id (required), add, remove.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 28 tools

    Disambiguation4/5

    Tools are mostly distinct with clear descriptions. There is some overlap between bulk and individual operations, but descriptions clarify when to use each. Overall, an agent can distinguish tools with minimal confusion.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern using snake_case, e.g., 'create_folder', 'delete_email', 'bulk_move'. No mixing of conventions.

    Tool Count4/5

    28 tools is slightly above the typical well-scoped range (3-15), but the email domain is complex and each tool serves a distinct purpose. The count is reasonable for comprehensive mail functionality.

    Completeness5/5

    The tool set covers the full email lifecycle: send, search, read (including inspection of MIME parts), manage folders, move/copy, mark status, delete with trash support, and bulk operations. No obvious gaps.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides a Model Context Protocol interface for Mozilla Thunderbird, allowing AI assistants to manage emails, filters, calendars, and contacts. It exposes 24 tools for tasks like searching messages, drafting replies, and organizing folders through a local bridge.
      MIT
    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      A Model Context Protocol server that provides email access via IMAP and SMTP, enabling AI agents to read, search, send, and manage emails. It features specialized tools for folder management, message retrieval, and replying to threads through a standardized HTTP/SSE interface.
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to read, search, reply to, and send emails from Yandex Mail directly in chat using natural language.
      MIT
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to read, search, send, reply to, forward, draft, schedule, manage, and analyze email across multiple IMAP/SMTP accounts through the Model Context Protocol. Includes provider-aware label management, real-time IMAP IDLE watching with AI-powered triage, verification-code capture, calendar (ICS) extraction, desktop/webhook alerts, and OAuth2 support for Gmail and Microsoft 365.
      31 npm
      ISC