Mailstone

approvedunreviewed

by Johannes Kaindl

Mail as vault notes: a server-side folder decides what becomes a note. Sends iMIP invitations for calendar-notes.

โ†“ 291 downloadsUpdated 15d agoAGPL-3.0

Mailstone

๐Ÿ‡ฌ๐Ÿ‡ง 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.

License: AGPL-3.0 Docs: CC BY-SA 4.0 Release Platform

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.

The Mailstone sidebar panel next to an imported mail note: two accounts with last run, next run and a

Features

  • Mail as notes. A server-side folder decides what becomes a note. The Message-ID is the identity, and the original .eml stays next to the note, so everything derived from it can be rebuilt.
  • A panel in the right sidebar. Per account: what the last run did, when the next one is due, the counters that are not zero, the error in plain words โ€” and a button to synchronise now, for one account or all of them. The last run survives a restart.
  • An inbox tab. The last 100 messages of your inbox, with a tick for everything that is already a note. Three actions per row: Move to vault and Archive (both server-side, both after a confirmation) and โ€” once TaskNotes is installed โ€” Create task.
  • Commands on a mail note. Re-render from the .eml, relink threads, extract an attachment, reply in your external mail client, create a TaskNotes task. Each shows a preview before it writes.
  • Import without a server. Import .eml files from a vault folder turns .eml files you already have into notes โ€” no account needed.
  • Sending. SMTP through the same account, including iMIP invitations for calendar-notes. Other plugins can send through Mailstone too, after you confirm each one once.
  • Reading never marks anything as read. Listing, previewing and syncing use EXAMINE and BODY.PEEK; moving a message carries its flags along. Another tool that keys off "unread" is not disturbed.
  • Mobile: read what is already synced. Synchronised notes are ordinary Markdown notes on mobile. Sync, sending and the inbox tab need a network layer mobile Obsidian does not provide and stay off there.

Requirements

  • Obsidian 1.13.0 or newer. Desktop for everything; mobile only reads notes that a desktop already synchronised.
  • An IMAP/SMTP account you can reach with an app password. Providers that require OAuth (Gmail with 2FA, Microsoft 365) are not supported โ€” there is no OAuth flow.
  • A folder on the mail server that acts as the allowlist (default name Vault), and a second one for the archive. Anything you file in the allowlist folder becomes a note; nothing else is touched.
  • TLS is not optional. Certificate checking cannot be turned off, and plaintext authentication without TLS is refused.

Install

Community Plugins

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

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.

Manual

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.

BRAT (beta)

Add johannes-kaindl/mailstone in BRAT.

From source

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.

Usage

  1. Set up an account. Settings โ†’ Mailstone โ†’ Add account: IMAP and SMTP host, port and TLS mode, username, an app-specific password, at least one identity, and the folder names as your IMAP server shows them. Test SMTP connection checks host, TLS and login without sending anything.
The account dialog: IMAP and SMTP host, port and TLS mode, username and a password linked to Obsidian's secret storage. 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/`. A mail note: front matter with sender, recipients, date and Message-ID, in_reply_to and references as wikilinks to the earlier mail, and the message text below. 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.">

Configuration

The Mailstone settings tab: language, notes folder, subfolder per year, filename template and the list of accounts with Edit buttons.
Click the preview for the full-size image

Settings โ†’ Mailstone. Per account (Add account / Edit):

SettingWhat it doesDefault
IMAP / SMTP: Host, Port, TLSImplicit (usually 993/465) or STARTTLS (143/587)โ€”
Username, PasswordThe password lives in Obsidian's secret storage, never in data.json or the vaultโ€”
IdentitiesAddresses you may send from; one is the defaultโ€”
Folders: InboxThe folder the inbox tab listsINBOX
Folders: AllowlistThe folder that decides what becomes a noteVault
Folders: ArchiveWhere Archive moves a messageArchive
Folders: SentWhere a sent copy is filed; empty turns the copy offSent
Sync enabled / Sync interval (minutes)Automatic sync per accounton / 5

Global settings:

SettingWhat it doesDefault
Notes folderWhere mail notes are created, in a subfolder per yearMail
Subfolder per yearTurns the year subfolders offon
Filename templatePlaceholders {date}, {time}, {slug}, {year}{date}-{time}-{slug}
Extra fields for new mail notesFields written once into a note's front matter when it is first created, for example status: opennone
Allowed note-creation valuesValues accepted for the fields written at creationmail
Plugins allowed to sendPlugins that send through Mailstone without asking; revoke one to be asked againnone
Open the panel at startupOpens the sidebar panel when Obsidian startsoff
Debug logWrites the IMAP/SMTP dialogue to the developer console, passwords maskedoff
LanguageInterface languageAutomatic

Documentation

How it works

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.

Contributing

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

Copyright ยฉ 2026 Johannes Kaindl.

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.