Skip to main content

Yandex Mail

@magistr/yandex-mailv2026.10.25.10· MIT· 1d agoBEHAVIORS
01README

Yandex Mail over IMAP (read, search, organise) and SMTP (send). Yandex has no JMAP or public REST mail API, so this speaks the standard protocols with an app password of type Mail or an OAuth token (XOAUTH2).

Methods:

  • get-account-summary, list-mailboxes — folders with total/unread counts
  • create-mailbox, rename-mailbox, delete-mailbox — idempotent folder ops
  • query-emails — search a mailbox (date, from, to, subject, text, unread, flagged), newest first
  • get-email, get-thread, get-attachment — decoded body, conversation via Message-ID/References, save an attachment to disk
  • send-email, reply-email, forward-email, create-draft, send-draft — SMTP sending with optional idempotent messageId
  • archive-mailbox — incremental Maildir backup (raw .eml per message)
  • import-apple-mail — fill server-unavailable messages from Apple Mail's cache
  • set-email, archive-email, delete-email, bulk-email-action — flags, moves, trash/spam, permanent delete

Emails are addressed as <mailbox>:<uid> (e.g. INBOX:1234).

02Release Notes

2026.10.25.10

  • Repo-wide republish; no functional change.
03Behaviors1
@magistr/yandex-mailv2026.10.25.10extensions/models/yandex_mail.ts

Global Arguments

ArgumentTypeDescription
usernamestringYandex login or full address (e.g. user@yandex.ru). A bare login is
appPassword?stringApp password of type Mail (Yandex ID → Security → App passwords)
oauthToken?stringOAuth token with mail scope, used via XOAUTH2 instead of appPassword
fromName?stringDisplay name for sent mail
imapHost?stringIMAP host (imap.ya.ru is the alternative outside Russia)
smtpHost?stringSMTP host
smtpPort?numberSMTP port: 465 (implicit TLS) or 587 (STARTTLS)
fn get-account-summary()
Account overview with total/unread counts per mailbox
fn list-mailboxes()
List all mailboxes (folders) with message counts
fn create-mailbox()
Create a mailbox (folder). No-op if it already exists.
fn rename-mailbox()
Rename (move) a mailbox
fn delete-mailbox()
Delete a mailbox and ALL messages in it. No-op if it does not exist.
fn query-emails(after?: string, before?: string, from?: string, to?: string, subject?: string, text?: string, unseen?: boolean, flagged?: boolean, limit?: number)
Search a mailbox (default INBOX) and return newest-first summaries
ArgumentTypeDescription
after?stringOn/after date (ISO 8601)
before?stringBefore date (ISO 8601)
from?string
to?string
subject?string
text?stringSearch headers and body
unseen?booleantrue = only unread
flagged?boolean
limit?number
fn get-email(maxBodyChars?: number, markRead?: boolean)
Get one email with decoded text/HTML and attachment list
ArgumentTypeDescription
maxBodyChars?number
markRead?booleanSet \\Seen after reading (fetching never sets it by itself)
fn get-thread(mailboxes?: array)
Reconstruct a conversation from Message-ID/References across the
ArgumentTypeDescription
mailboxes?arrayMailboxes to search (default: the email's mailbox + Sent)
fn get-attachment(index?: number, filename?: string, outputDir: string)
Save one attachment of an email to a local directory
ArgumentTypeDescription
index?numberAttachment index from get-email
filename?stringOr match by filename
outputDirstringDirectory to write the file into
fn archive-mailbox(outputDir: string, mailboxes?: array, exclude?: array, maxMessages?: number, batchSize?: number, retryUnavailable?: boolean)
Incrementally back up folders to a local Maildir (raw .eml per
ArgumentTypeDescription
outputDirstringMaildir root, e.g. ./yandex-backup
mailboxes?arrayFolders to archive (default: every selectable folder)
exclude?arrayFolders to skip, e.g. ["Spam", "Trash"]
maxMessages?numberStop after this many fetch attempts in this run (0 = no limit);
batchSize?number
retryUnavailable?booleanFetch UIDs from unavailable.json again instead of skipping them
fn import-apple-mail(outputDir: string, accountDir: string, envelopeIndex?: string)
Fill the Maildir gaps listed in unavailable.json from Apple Mail's
ArgumentTypeDescription
outputDirstringMaildir root used by archive-mailbox
accountDirstringApple Mail account directory, e.g.
envelopeIndex?stringPath to Mail's Envelope Index (default: <accountDir>/../MailData/
fn send-email(subject: string, text?: string, html?: string, attachments?: array, inReplyTo?: string, references?: array, messageId?: string, saveToSent?: boolean)
Compose and send an email over SMTP
ArgumentTypeDescription
subjectstring
text?stringPlain-text body
html?stringHTML body
attachments?arrayLocal file paths to attach
inReplyTo?string
references?array
messageId?stringStable Message-ID. If set and already in Sent, the send is skipped
saveToSent?booleanAppend a copy to Sent. Leave false if Yandex already files SMTP mail
fn reply-email(text: string, html?: string, replyAll?: boolean, quote?: boolean, messageId?: string, saveToSent?: boolean)
Reply (or reply-all) to an email, quoting the original
ArgumentTypeDescription
textstringReply body (plain text)
html?string
replyAll?boolean
quote?booleanQuote the original text
messageId?stringStable Message-ID for idempotent retries
saveToSent?boolean
fn forward-email(text?: string, messageId?: string, saveToSent?: boolean)
Forward an email; the original is attached as message/rfc822
ArgumentTypeDescription
text?stringNote above the forward
messageId?string
saveToSent?boolean
fn create-draft(subject: string, text?: string, html?: string, attachments?: array, inReplyTo?: string, references?: array, messageId?: string, saveToSent?: boolean)
Save an email to Drafts without sending
ArgumentTypeDescription
subjectstring
text?stringPlain-text body
html?stringHTML body
attachments?arrayLocal file paths to attach
inReplyTo?string
references?array
messageId?stringStable Message-ID. If set and already in Sent, the send is skipped
saveToSent?booleanAppend a copy to Sent. Leave false if Yandex already files SMTP mail
fn send-draft(saveToSent?: boolean)
Send a saved draft, then remove it from Drafts
ArgumentTypeDescription
saveToSent?boolean
fn set-email(seen?: boolean, flagged?: boolean)
Set read/flagged state and/or move one email
ArgumentTypeDescription
seen?boolean
flagged?boolean
fn archive-email(emailIds: array)
Mark emails read and move them to Archive
ArgumentTypeDescription
emailIdsarray
fn delete-email(emailIds: array)
Permanently delete (expunge) one or more emails
ArgumentTypeDescription
emailIdsarray
fn bulk-email-action(emailIds: array, action: enum)
Batch action on many emails: mark-read, mark-unread, flag, unflag,
ArgumentTypeDescription
emailIdsarray
actionenum

Resources

mailboxes(30m)— Mailbox (folder) listing with message counts
mailboxResult(infinite)— Mailbox create/rename/delete result
summary(30m)— Account overview: totals and unread per mailbox
emails(15m)— Email query results / bulk action results
email(1h)— Single email with decoded body and attachment list
thread(1h)— Conversation reconstructed from Message-ID/References
attachment(infinite)— Attachment saved to local disk
sendResult(infinite)— Email send result
archive(infinite)— Maildir archive run: per-folder counts and UID watermarks
appleImport(infinite)— Apple Mail cache import: per-folder imported/partial/missing
draft(infinite)— Draft saved to the Drafts mailbox
04Previous Versions10
2026.10.25.1MIT

2026.10.25.1

Security

  • Update postal-mime 3.0.0 → 4.1.4 for GHSA-f2hq-32vh-53cc (HIGH): decoding a header with many RFC 2047 encoded words took quadratic CPU time, so one large message could stall the event loop.
  • Update nodemailer 10.0.10 → 10.2.1 for GHSA-85x2-q946-cp5h, GHSA-8c8m-p3m8-cjg8 and GHSA-m943-m63m-w62w (MEDIUM): address-parser bugs that could turn quoted text or comments into recipients.

No schema change.

2026.10.15.9MIT

2026.10.15.9

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.8MIT

2026.10.15.8

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.6MIT

2026.10.15.6

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.5MIT

2026.10.15.5

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.4MIT

2026.10.15.4

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.3MIT

2026.10.15.3

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.2MIT

2026.10.15.2

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.15.1MIT

2026.10.15.1

Changed

  • Repo-wide maintenance release: version bump to republish the current source. No schema change.
2026.10.11.1MIT

2026.10.11.1

First release.

  • Yandex Mail over IMAP (imap.yandex.com:993, TLS) and SMTP (465 implicit TLS or 587 STARTTLS), with an app password of type Mail or an OAuth token (XOAUTH2).
  • Mailboxes: get-account-summary, list-mailboxes, and idempotent create-mailbox, rename-mailbox, delete-mailbox (INBOX and special-use folders are never deleted).
  • Reading: query-emails, get-email, get-thread, get-attachment.
  • Sending: send-email, reply-email, forward-email, create-draft, send-draft. A messageId makes a send idempotent: if that Message-ID is already in Sent, the send is skipped.
  • Organising: set-email, archive-email, delete-email, bulk-email-action.
  • Backup: archive-mailbox writes an incremental Maildir and records messages the server cannot deliver in unavailable.json; import-apple-mail fills those gaps from Apple Mail's local cache.

Fixed before release

Found while writing the test suites:

  • archive-mailbox maxMessages subtracted every UID already listed as unavailable from the budget, so a folder with old unavailable messages used up the budget of the folders after it. The budget now counts only the fetch attempts made in the current run.
  • reply-email crashed with a TypeError when the original had a Reply-To but no From header and quoting was on.
  • A message with an unparseable Date header made query-emails and get-thread fail with RangeError: Invalid time value. The date now falls back to INTERNALDATE, then to "".
  • Email ids with a non-decimal UID (INBOX:1e3, INBOX:0x10, INBOX: 1) or a UID above 2^32-1 were accepted. They are now rejected.
  • get-thread, get-email, get-attachment and set-email on two folders with non-ASCII (for example Cyrillic) names and the same UID wrote the same resource name, so the second overwrote the first. Non-ASCII ids now get a short hash suffix; ASCII ids keep their names.
  • A messageId containing CR/LF or spaces was folded into a malformed Message-ID header and broke the idempotency lookup. It is now rejected, and a@b> no longer becomes <a@b>>.
  • An attachment named ., .., or an empty name made get-attachment write to the output directory path itself. Such names, and control characters, are now replaced.
  • Mailbox arguments and email ids with CR, LF or NUL are rejected before any IMAP connection is opened.
  • Error messages are scrubbed of the app password and OAuth token.

Internal

  • transport export: the factories that build the IMAP client and SMTP transport. Tests replace them with in-memory fakes.
05Stats
A
100 / 100
Downloads
16
Archive size
643.8 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Docs keep secrets in a vault1/1earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License2/2earned
  • Verified public repository2/2earned
06Platforms
07Labels