Turn raw email and mbox files into readable MIME messages, without a mail client.
Features · Installation · Quick start · Mailboxes and threads · Scope and safety
Ukdah is a dependency-free Ruby parser for RFC 5322 messages and MIME bodies. It exposes headers, decoded text, attachments, diagnostics, and conversation structure without connecting to IMAP, POP, or SMTP. The name comes from ι Cancri and the Arabic ʿuqdah, “knot.”
- Folded headers, encoded words, address groups, and RFC 2231 parameters
- Multipart MIME trees with base64 and quoted-printable transfer decoding
- Attachment and inline-part discovery, including
cid:identifiers - Tolerant parsing with diagnostics for damaged messages
- mbox splitting, Message-ID threading, and quote segmentation
- Injectable charset decoder; no runtime dependencies
Add gem "ukdah" to your Gemfile and run bundle install, or install directly:
gem install ukdahRequires Ruby 3.1 or newer.
require "ukdah"
raw = "From: Ada <ada@example.com>\r\n" \
"Subject: Hello\r\n" \
"Content-Type: text/plain; charset=UTF-8\r\n\r\n" \
"A short note."
message = Ukdah::Message.parse(raw)
puts message.from.first.email # => ada@example.com
puts message.subject # => Hello
puts message.decoded(message.text_part) # => A short note.
puts message.diagnosticsmessage.attachments returns MIME parts with decoded transfer bodies.
Treat their filenames as untrusted input; choose a safe destination name
before writing one to disk.
messages = Ukdah::Mbox.each(File.binread("archive.mbox")).to_a
threads = Ukdah::Thread_.build(messages)Mbox.each accepts bytes or an IO object and yields parsed messages.
Thread_.build groups messages using Message-ID, References, and In-Reply-To.
Pass a decoder when the application has its own charset strategy:
text = message.decoded(message.text_part, decoder: ->(bytes, charset) {
bytes.force_encoding(charset || "UTF-8").encode("UTF-8", invalid: :replace, undef: :replace)
})Without a custom decoder, Ukdah uses Ruby's Encoding support.
Ukdah parses messages only; it does not fetch, send, or sanitize HTML mail.
Sanitize message.html_part before display. For design rationale, see
parsing-only scope and
decoder injection.
bundle install
bundle exec rake
gem build --strict ukdah.gemspec