Johannes Kaindl307 downloadsMail as vault notes: a server-side folder decides what becomes a note. Sends iMIP invitations for calendar-notes.
🇬🇧 English · 🇩🇪 Deutsch
Mailstone turns a mail folder on your server into notes in your vault — the server decides what becomes a note, and reading never marks a message as read.
Triage stays where your mail already lives: move a message into one designated IMAP folder — from your phone, from webmail, from a mail rule — and the next sync writes it into the vault as a Markdown note, with the original .eml beside it. Sending uses the same account over SMTP, and the plugin delivers iMIP calendar invitations on behalf of the sister plugin calendar-notes.

.eml stays next to the note, so everything derived from it can be rebuilt..eml, relink threads, extract an attachment, reply in your external mail client, create a TaskNotes task. Each shows a preview before it writes..eml files you already have into notes — no account needed.calendar-notes. Other plugins can send through Mailstone too, after you confirm each one once.EXAMINE and BODY.PEEK; moving a message carries its flags along. Another tool that keys off "unread" is not disturbed.Vault), and a second one for the archive. Anything you file in the allowlist folder becomes a note; nothing else is touched.Listing in the Community Plugins directory is pending review. Once it is through: Settings → Community plugins → Browse → "Mailstone". Until then use one of the ways below.
AnySource Sideloader installs and updates plugins from any git forge. Subscribe to this catalog once:
https://git.jkaindl.de/jkaindl/obsidian-catalog/raw/branch/main/catalog.json
Mailstone then appears in the sideloader's plugin list and updates like any other plugin, every download checksum-verified.
Download main.js, manifest.json and styles.css from the latest release into <vault>/.obsidian/plugins/mailstone/, then enable the plugin in Settings → Community plugins. Updates then have to be repeated by hand.
Add johannes-kaindl/mailstone in BRAT.
git clone https://git.jkaindl.de/jkaindl/mailstone
cd mailstone && npm install && npm run build
# main.js manifest.json styles.css → <vault>/.obsidian/plugins/mailstone/
npm run gate runs the full check suite (lint, type checks, unit and integration tests, purity check, build). npm run smoke:e2e is a maintainer-only check against a running Obsidian with TaskNotes installed; it is deliberately not part of gate.
2. **Decide on the server which mail matters.** Move it into your allowlist folder. The next sync — every few minutes, or *Synchronise now* in the sidebar — writes a note under `Mail//` and the `.eml` under `Mail//_eml/`.
3. **Or work from the inbox tab.** Open the sidebar with the ribbon icon or the command *Mailstone: Open the sidebar panel*, switch to **Inbox**, and use *Move to vault* on anything worth keeping. The message moves into the allowlist folder on the server, and the following sync writes the note.
4. **On a mail note**, the command palette offers *Re-render mail note from its .eml*, *Relink mail threads*, *Extract an attachment from a mail note*, *Reply to a mail in the external mail client* and *Create a TaskNotes task*. Only the ones that apply to the open note appear. Each one shows what it would change before it writes:
<img src="https://raw.githubusercontent.com/johannes-kaindl/mailstone/main/docs/images/relink-preview.png" width="820" alt="The "Review before writing" dialog of the Relink mail threads command: one note gets a wikilink in in_reply_to, shown as Before and After, with Cancel and Apply.">
![]()
Click the preview for the full-size image
Settings → Mailstone. Per account (Add account / Edit):
| Setting | What it does | Default |
|---|---|---|
| IMAP / SMTP: Host, Port, TLS | Implicit (usually 993/465) or STARTTLS (143/587) |
— |
| Username, Password | The password lives in Obsidian's secret storage, never in data.json or the vault |
— |
| Identities | Addresses you may send from; one is the default | — |
| Folders: Inbox | The folder the inbox tab lists | INBOX |
| Folders: Allowlist | The folder that decides what becomes a note | Vault |
| Folders: Archive | Where Archive moves a message | Archive |
| Folders: Sent | Where a sent copy is filed; empty turns the copy off | Sent |
| Sync enabled / Sync interval (minutes) | Automatic sync per account | on / 5 |
Global settings:
| Setting | What it does | Default |
|---|---|---|
| Notes folder | Where mail notes are created, in a subfolder per year | Mail |
| Subfolder per year | Turns the year subfolders off | on |
| Filename template | Placeholders {date}, {time}, {slug}, {year} |
{date}-{time}-{slug} |
| Extra fields for new mail notes | Fields written once into a note's front matter when it is first created, for example status: open |
none |
| Allowed note-creation values | Values accepted for the fields written at creation | mail |
| Plugins allowed to send | Plugins that send through Mailstone without asking; revoke one to be asked again | none |
| Open the panel at startup | Opens the sidebar panel when Obsidian starts | off |
| Debug log | Writes the IMAP/SMTP dialogue to the developer console, passwords masked | off |
| Language | Interface language | Automatic |
The server decides, not the plugin. A folder on the mail server is the allowlist. Sync reads it, and every message in it becomes a note — no rules engine, no filters in the plugin.
The Message-ID is the identity. It survives re-downloads, folder moves and renamed files. The .eml next to each note is the fidelity surface: front matter, rendered body and attachments can be rebuilt from it, so a formatting change never costs you data.
Notes are merged, not overwritten. Your own text lives outside a marked zone (%% mailstone:begin %% … %% mailstone:end %%) and is compared by hash before any write. If you edited the managed zone, the write is refused rather than silently applied. Mailstone never deletes a note: a message that leaves the folder is marked detached, and putting it back reattaches it.
Two kinds of IMAP session, enforced by the compiler. The read path cannot call SELECT or UID MOVE; those live on a separate session used only by the inbox actions. That is why "reading never marks as read" is a property of the type system, not a rule someone has to remember. Architecture and conventions are in AGENTS.md.
Issues and pull requests on GitHub; the canonical repository is on git.jkaindl.de. Test-driven (npm test, full check with npm run gate); larger features go through brainstorm → spec → plan → TDD. See AGENTS.md.
LICENSE; dual-license option in LICENSING.md).LICENSE-DOCS).Copyright © 2026 Johannes Kaindl.