Rafters Mail

IMAP Command Reference

All commands supported by @rafters/mail-imap. Each command references the RFC section it implements.


Any State (RFC 3501 Section 6.1)

CAPABILITY

Returns the server’s supported extensions.

C: a001 CAPABILITY
S: * CAPABILITY IMAP4rev1 IDLE LITERAL+ UIDPLUS NAMESPACE ID
S: a001 OK CAPABILITY completed

NOOP

Keepalive. Returns any pending notifications.

C: a001 NOOP
S: a001 OK NOOP completed

LOGOUT

Cleanly disconnects. Server sends BYE before tagged OK.

C: a001 LOGOUT
S: * BYE LOGOUT requested
S: a001 OK LOGOUT completed

Not Authenticated State (RFC 3501 Section 6.2)

LOGIN

Authenticate with email address and app-specific password.

C: a001 LOGIN user@example.com myapppassword
S: a001 OK LOGIN completed

Security:

  • Generic “LOGIN failed” on bad credentials (no information leakage)
  • 3-attempt rate limit per session
  • Disconnect after max attempts

Authenticated State (RFC 3501 Section 6.3)

SELECT

Open a folder for read-write access.

C: a001 SELECT INBOX
S: * 47 EXISTS
S: * 3 RECENT
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)]
S: * OK [UIDVALIDITY 1]
S: * OK [UIDNEXT 48]
S: * OK [UNSEEN 12]
S: * OK [READ-WRITE]
S: a001 OK [READ-WRITE] SELECT completed

EXAMINE

Open a folder read-only. Same response as SELECT but with [READ-ONLY].

LIST

List available folders.

C: a001 LIST "" *
S: * LIST (\HasNoChildren \Inbox) "/" INBOX
S: * LIST (\HasNoChildren \Sent) "/" Sent
S: * LIST (\HasNoChildren \Drafts) "/" Drafts
S: * LIST (\HasNoChildren \Trash) "/" Trash
S: a001 OK LIST completed

Pattern wildcards: * matches everything, % matches within one hierarchy level.

LSUB

List subscribed folders. MVP: same as LIST (all folders subscribed).

STATUS

Get folder stats without selecting.

C: a001 STATUS INBOX (MESSAGES RECENT UNSEEN UIDNEXT UIDVALIDITY)
S: * STATUS INBOX (MESSAGES 47 RECENT 3 UNSEEN 12 UIDNEXT 48 UIDVALIDITY 1)
S: a001 OK STATUS completed

APPEND (RFC 3501 Section 6.3.6 + RFC 4315)

Upload a message to a folder.

C: a001 APPEND Sent (\Seen) {310}
S: + Ready for literal data
C: <message content>
S: a001 OK [APPENDUID 1 305] APPEND completed

Selected State (RFC 3501 Section 6.4)

FETCH

Retrieve message data. Supports individual items and macros.

C: a001 FETCH 1:* (FLAGS UID ENVELOPE)
S: * 1 FETCH (FLAGS (\Seen) UID 101 ENVELOPE (...))
S: * 2 FETCH (FLAGS () UID 102 ENVELOPE (...))
S: a001 OK FETCH completed

Data items: FLAGS, UID, ENVELOPE, RFC822.SIZE, INTERNALDATE, BODYSTRUCTURE, BODY[section].

Macros: ALL, FAST, FULL.

BODY.PEEK[section] fetches without setting \Seen flag.

STORE

Update message flags.

C: a001 STORE 1 +FLAGS (\Seen)
S: * 1 FETCH (FLAGS (\Seen))
S: a001 OK STORE completed

Modes: FLAGS (replace), +FLAGS (add), -FLAGS (remove). Add .SILENT to suppress response.

Find messages by criteria.

C: a001 SEARCH UNSEEN SINCE 1-Mar-2026
S: * SEARCH 3 7 12
S: a001 OK SEARCH completed

Supported criteria (parsed by parseSearchCriteria in packages/imap/src/protocol/parser.ts and passed through to your MessageAdapter.searchMessages implementation):

  • ALL
  • NEW
  • Flag-based: ANSWERED, UNANSWERED, DELETED, UNDELETED, DRAFT, UNDRAFT, FLAGGED, UNFLAGGED, SEEN, UNSEEN, RECENT, OLD
  • Header: FROM, TO, CC, BCC, SUBJECT
  • Date: BEFORE <date>, ON <date>, SINCE <date>
  • Size: LARGER <n>, SMALLER <n>
  • Text: TEXT <string>, BODY <string>
  • UID <sequence-set>
  • NOT <criterion>
  • OR <criterion> <criterion>
  • Bare sequence set (e.g., 1:10)

The parser dispatches flag tokens through a FLAG_CRITERIA lookup table before the main switch, so all 13 flag variants resolve to { type: "flag", flag: "\\<Name>", negated: boolean } criteria. The UN* variants set negated: true. Your searchMessages implementation receives the parsed criterion tree and is responsible for evaluating it against your message store (typically a WHERE clause over isRead, isStarred, deletedAt, and the derived \Answered / \Draft checks from thread state and folder slug).

Not yet supported (would need parser cases added): KEYWORD <keyword>, UNKEYWORD <keyword>, HEADER <field> <value>, SENTBEFORE <date>, SENTON <date>, SENTSINCE <date>. Sending one of these returns BAD Unknown search criterion: <name>.

EXPUNGE

Permanently remove messages marked \Deleted.

C: a001 EXPUNGE
S: * 3 EXPUNGE
S: a001 OK EXPUNGE completed

CLOSE

Close folder and silently expunge deleted messages (no EXPUNGE responses).

COPY (RFC 3501 Section 6.4.7 + RFC 4315)

Copy messages to another folder.

C: a001 COPY 1:3 Sent
S: a001 OK [COPYUID 1 10,20,30 200,201,202] COPY completed

MOVE (RFC 6851)

Atomically move messages to another folder.

C: a001 MOVE 1 Archive
S: * 1 EXPUNGE
S: a001 OK [COPYUID 1 10 300] MOVE completed

UNSELECT (RFC 3691)

Close folder without expunging.


Extensions

IDLE (RFC 2177)

Wait for server push notifications.

C: a001 IDLE
S: + idling
... (time passes, new mail arrives)
S: * 48 EXISTS
C: DONE
S: a001 OK IDLE completed

UID prefix

Any of FETCH, STORE, SEARCH, COPY, MOVE can be prefixed with UID to operate on UIDs instead of sequence numbers.

C: a001 UID FETCH 101 FLAGS
S: * 1 FETCH (FLAGS (\Seen) UID 101)
S: a001 OK FETCH completed

Flag Mapping

IMAP Flag@rafters/mail FieldNotes
\SeenisReadSettable
\FlaggedisStarredSettable
\DeleteddeletedAt (soft delete)Settable
\Answeredthread has outbound replyDerived, read-only
\Draftfolder slug = “drafts”Derived, read-only
Custom keywordslabels (inboxMessageLabel)Settable