Go to file
2026-09-15 00:11:42 +02:00
.cursor (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
.github/workflows (feature): init 2026-09-13 16:47:17 +02:00
.vscode (feature): init 2026-09-13 16:47:17 +02:00
data (feature): init 2026-09-13 16:47:17 +02:00
packaging/macos (feature): init 2026-09-13 16:47:17 +02:00
src (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
utils (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
.editorconfig (feature): init 2026-09-13 16:47:17 +02:00
.gitignore (feature): init 2026-09-13 16:47:17 +02:00
AGENTS.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
CHANGELOG.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
CONTRIBUTING.md (feature): init 2026-09-13 16:47:17 +02:00
LICENSE.md (feature): init 2026-09-13 16:47:17 +02:00
README.de.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
README.es.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
README.fr.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
README.it.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00
README.md (feature): indices, pst mailboxes, and rules 2026-09-15 00:11:42 +02:00

Postclient — desktop PEC, REM, and IMAP mail client

Line Coverage Branch Coverage Method Coverage .NET License Platform

Language: English · Italiano · Français · Deutsch · Español

The application UI is English, Italian, French, German, or Spanish. These documents describe the same open-source desktop email client for people who send and keep posta elettronica certificata (PEC), eIDAS registered electronic mail (REM), and ordinary IMAP / POP3 / SMTP mail on Windows, Linux, and macOS.

Postclient is a local mail client, not a web mailbox. It talks IMAP, POP3, and SMTP to accounts you already have: Gmail, Microsoft 365, Italian PEC at a qualified gestore (Aruba, InfoCert Legalmail, Namirial, Poste Italiane, Register.it, Libero, and custom-domain IMAP), and European REM when the operator publishes IMAP/SMTP. Receipts stay on this PC as .eml plus a searchable SQLite archive.

It is not a qualified trust service provider (QTSP), not a PEC operator, not a timestamp authority, and not hosted mail. The gestore / QTSP issues envelopes and ricevute. This client unwraps them, shows delivery evidence, and keeps the originals on the machine.

Kind Desktop mail client for PEC, REM, and IMAP
OS Windows, Linux, macOS (Apple Silicon and Intel)
Stack C#, .NET 10, Avalonia, MailKit
License Apache 2.0
Not A QTSP, a new PEC/REM address, cloud mail, or a scanner

Changes: CHANGELOG.md. Contributing: CONTRIBUTING.md.

Built for certified mail on the desktop

Typical desktop and web mail treats a PEC busta or an ETSI REM evidence part as just another attachment. Postclient is written around that evidence:

  • Unwrap PEC / REM envelopes — read the inner postacert.eml (the message the recipient was meant to see) instead of the gestore wrapper; Type column PEC, RIC, REM, or digitally signed SIG.
  • Delivery column from operator evidence — accettazione, avvenuta-consegna, ETSI SubmissionAcceptance / Delivery / Retrieval, LRE and AR24 avis, De-Mail Zustellung and Abholbestätigung, acuse de recibo. After SMTP send, Sent is matched to Inbox/Ricevute ricevute by Message-Id, daticert.xml, and subject prefixes. Italian PEC has no read receipt: avvenuta consegna is deposit in the certified mailbox.
  • FatturaPA preview — Italian e-invoice XML as a readable view (XML parser, not generative AI).
  • Fascicolo of original .eml — export selected messages as the files a notaio, PA desk, bank, or court can keep.
  • From is a mailbox picker — you cannot type a free From; send uses the SMTP identity of the connected account.
  • Practice labels on this PC — tag a condominium, a client file, an IMU notice. Labels are local, not a studio-wide database.
  • Full-folder local archive — Get Messages stores the whole IMAP folder in mail.db plus .eml on disk (not a last-N window). Keyword FTS on subject, body, PDF/XML/HTML/CSV/JSON attachment text, and labels.
  • On-device meaning search (RAG) — optional EmbeddingGemma 300M in Settings → Indices…. Vectors stay in mail.db. Mail never leaves the machine. Rebuild or repair keyword and meaning indices.
  • Rules across mailboxes — move, delete, flag, label; a destination folder can live on another account, including an attached .pst / .ost data file. Import JSON or a legacy .rwz file; export is JSON.
  • Open .pst / .ost as a mailbox — Unicode personal store is writable (folders, flags, move, delete). An offline store is copied to a Unicode .pst on first write. No extra mail program required to read the file.
  • Country packs — Settings → Features turns Italy (PEC, FatturaPA, fascicolo), Europe (eIDAS REM), France, Germany, Spain, and Switzerland evidence labels on or off. Ordinary IMAP stays available.

Who it is for

Private individuals

Daily client for one or more addresses: Gmail or Microsoft 365 next to a personal PEC (Italy) or an IMAP REM mailbox (EU). Search a condominium notice, a tax file, or a PA communication years later without leaving the originals on someone else’s server.

Typical use: certified and ordinary mail in one window; see whether the gestore accepted and deposited a PEC; print or save a PDF; export the original .eml if a municipality, bank, or court asks for it.

Practices and agencies

Use it when certified identities must not be mixed: personal PEC, studio PEC, ordinary mail. A commercialista, avvocato, notaio, CAF, condominium administrator, or EU practice that files with PA can keep each gestore mailbox separate (IMAP QUOTA in the status bar), group a send with its ricevute, and export a fascicolo without uploading the practice to a third-party archive.

The program does not replace the gestore, does not issue a qualified ricevuta, and does not share labels across office PCs.

Accounts and protocols

Incoming: IMAP (full folder tree), POP3 (Inbox only), or an attached .pst / .ost. Unicode .pst is writable. Outgoing: SMTP. Encryption: Auto, SSL/TLS, STARTTLS, STARTTLS if available, or none. MailKit uses the SASL methods the server advertises.

Several mailboxes at once. Presets fill hosts and ports:

Preset Role
Gmail IMAP/SMTP; Google sign-in (OAuth2 / XOAUTH2) or a Gmail app password
Microsoft 365 IMAP/SMTP; Microsoft sign-in. Most of these accounts reject a mailbox password
IT PEC — Aruba imaps.pec.aruba.it / smtps.pec.aruba.it (POP3: pop3s.pec.aruba.it)
IT PEC — InfoCert Legalmail mbox.cert.legalmail.it / sendm.cert.legalmail.it. Username is often the InfoCert User ID, not the address
IT/EU PEC — Namirial imaps.sicurezzapostale.it / smtps.sicurezzapostale.it
IT PEC — Poste Italiane mail.postecert.it
IT PEC — Register.it imap.pec-email.com / smtp.pec-email.com
IT PEC — Libero mail.postacert.it.net
EU — Intesi Group imap.ig-trustmail.com / smtp.ig-trustmail.com
IMAP / POP3 Any host the operator gave you. Set mailbox kind to Italian PEC or EU REM if that mailbox is certified (including a custom domain)
Data file (.pst / .ost) Local store opened as a mailbox. Unicode .pst is writable; .ost / ANSI .pst is copied to a Unicode .pst on first write. No password.

Certified IMAP mailboxes use the gestore password, or an app password if the gestore has 2FA. AR24 (France), De-Mail (Germany), IncaMail (Switzerland), and Lleida (Spain) are usually not IMAP. If that operator gave you IMAP/POP3 hosts, choose IMAP / POP3. Otherwise this client cannot open that mailbox; it can still display ETSI REM evidence on messages you import as .eml.

OAuth needs a Google client ID (ends with .apps.googleusercontent.com) and, for Web clients, the client secret — paste both in Account Settings (the secret is stored in secrets.bin, not as the mailbox password). Desktop public clients need no secret. Environment variables POSTCLIENT_GOOGLE_CLIENT_ID / POSTCLIENT_GOOGLE_CLIENT_SECRET are also accepted. Enable the Gmail API, add scope https://mail.google.com/ on the consent screen, allow loopback http://127.0.0.1, and enable IMAP in Gmail. Microsoft: Azure Application (client) ID (a GUID); public client; redirect http://localhost; IMAP/SMTP permissions.

Passwords and OAuth refresh tokens stay next to settings (DPAPI on Windows, file mode 600 on Linux/macOS), never in settings.json.

Italian PEC (posta elettronica certificata)

Italian certified mail is a busta produced by the gestore:

  • transport message with X-Trasporto: posta-certificata, daticert.xml, and the original as postacert.eml;
  • ricevute (X-Ricevuta) in Inbox and Ricevute: accettazione, presa-in-carico, avvenuta-consegna, non-accettazione, mancata-consegna, rilevazione-virus, preavviso-errore-consegna.

View → Unwrap PEC/REM envelope shows the inner postacert.eml. The Type column marks PEC (transport) or RIC (ricevuta).

Italian PEC has no read receipt. Avvenuta consegna means the message was deposited in the recipient’s certified mailbox, not that a person opened it.

European REM (eIDAS registered electronic mail)

When the message carries ETSI REM evidence (REMEvidence / urn:etsi:rem, or a part name such as remevidence / rem-md), the client treats it as REM. Event types map onto the same delivery column as PEC:

  • SubmissionAcceptance → accepted by the QTSP;
  • Delivery / LRE or AR24 avis de réception / De-Mail Zustellung / acuse de recibo → deposited;
  • ContentConsignment / Retrieval / De-Mail Abholbestätigung → the recipient retrieved the content (closest European equivalent of “read”);
  • rejection, virus, non-delivery, DeliveryExpiration → failed.

S/MIME (smime.p7s / smime.p7m) is shown as digitally signed; it is not PEC and not REM.

Delivery column after send

After SMTP send, Postclient stores the outbound Message-Id and, when you open Sent, reconciles gestore ricevute from Inbox and Ricevute. That wait applies only to accounts whose kind is PEC or REM (a PEC/REM preset, or IMAP/POP3 with that mailbox kind). Ordinary Gmail, Microsoft 365, and IMAP just report as sent. Matching uses, in order: daticert.xml <msgid>, X-Riferimento-Message-ID, In-Reply-To, PEC identificativo, then subject prefixes (ACCETTAZIONE:, CONSEGNA:, AVIS DE RECEPTION:, ACUSE DE RECIBO:, ZUSTELLBESTAETIGUNG:, ABHOLBESTAETIGUNG:, …).

Evidence Mark Meaning
PEC accettazione / presa-in-carico, ETSI SubmissionAcceptance Accepted The gestore took the message
PEC avvenuta-consegna, ETSI Delivery, LRE/AR24 avis, De-Mail Zustellung Delivered Deposited in the recipient certified mailbox — Italian PEC has no read receipt
ETSI ContentConsignment / Retrieval, De-Mail Abholbestätigung Retrieved Recipient picked up the content
non-accettazione, mancata-consegna, virus, ETSI rejection Failed Gestore reported non-acceptance or failed delivery

This client shows operator evidence. It does not issue a qualified ricevuta, PEC envelope, or timestamp.

Desktop notices fire for new PEC, ricevute, and REM (Windows toast, macOS notification, Linux notify-send).

Reading, folders, compose

  • Folder tree follows the server (Inbox, Ricevute/Receipts, Drafts, Sent, Archive, Junk, Trash, plus custom folders). System folders cannot be deleted. You can create a folder, empty one (to Trash, or permanently in Trash), mark all read/unread, delete a custom folder, and drag messages onto a folder.
  • List columns: unread, flag, attachments, delivery, type (PEC / RIC / REM / SIG), from, subject, date (local yyyy-MM-dd HH:mm), practice label.
  • View: HTML (OS web engine), plain text, raw source, or FatturaPA. Layout: list above reading, or three columns (folders, list, reading).
  • Group conversations indents replies in the folder list using Message-ID / In-Reply-To / References (depth up to 8). PEC ricevute that share the same original sit together. There is no separate conversation pane.
  • Message actions: reply, reply all, forward, open in a new window, read/unread, flag, priority, delete.
  • Compose is plain text. To, Cc, Bcc are address chips. Attachments are listed on the composer. Send attachments as ZIP packs dropped files (optional password). Send uses the selected mailbox’s SMTP identity only.

HTML uses the OS engine: WebView2 on Windows (profile under the data folder), WebKitGTK on Linux, WKWebView on macOS. If the engine is missing, the text body is shown instead.

Linux packages for the HTML view:

sudo apt install libgtk-3-0 libwebkit2gtk-4.1-0 libsoup-3.0-0

Fedora: gtk3 webkit2gtk4.1 libsoup3.

Local archive, keyword search, and meaning index

Get Messages indexes the whole IMAP folder into a local SQLite store (mail.db) plus .eml objects on disk. POP3 only fills Inbox. Indexing runs in the background; the status bar shows progress.

  • Settings → Indices…: keyword index (FTS) plus optional EmbeddingGemma 300M (~300 MB) meaning index. The ONNX package downloads from Hugging Face (onnx-community/embeddinggemma-300m-ONNX). Vectors stay in mail.db on this PC. Device: Auto / CPU / GPU (Windows DirectML). Rebuild or repair if search looks wrong. Weights use Google’s Gemma Terms.

Search (current folder) covers subject, body, attachment text (PDF and text/XML/HTML/CSV/JSON), practice labels, and meaning when the model is ready. Labels exist only on this PC.

The archive is only on this PC. File → Open archive folder / Export archive copies mail.db and the .eml files. Paths:

OS Config Data
Windows %AppData%\Postclient\ %LocalAppData%\Postclient\
Linux ~/.config/postclient/ ~/.local/share/postclient/
macOS ~/Library/Application Support/Postclient/ same

Override with POSTCLIENT_CONFIG / POSTCLIENT_DATA_DIR. A portable Windows zip that contains settings.json with installType: portable keeps config next to the executable.

IMAP QUOTA from the gestore (when the server supports it) is shown in the status bar. That is the operator mailbox, not cloud storage from this application.

Import, export, print

Action What you get
Import EML Originals into the current folder
Import mbox Local mbox stores from a desktop mail profile
Import .pst / .ost Copies mail from the data file into the selected IMAP/POP3 account. Nested stores inside the file are imported too. Close any program that has the file open.
Attach data file Opens a .pst / .ost as its own mailbox. Unicode .pst can be written. .ost cannot be written in place — the first change copies it to a Unicode .pst beside the original. File menu or account type data file.
New data file File menu: creates an empty Unicode .pst (Inbox, Drafts, Sent, Deleted) and attaches it as a mailbox.
Rules Settings → Rules: Import rules… reads this app’s JSON export or a legacy .rwz file. Export rules… writes JSON. Each rule is bound to an account; a move folder can live on another mailbox (including an attached data file). They run on Get Messages, on import, and from Run all rules.
Print Readable HTML of the (optionally unwrapped) message
Save PDF Same content as a PDF
Save attachments ZIP All attachments of the open message
Export selected EML (fascicolo) The original .eml files — what a notaio or PA can keep as the message

Opened messages are also stored as .eml under the data folder. The .eml files are the originals; PDF/print are a reading copy.

Interface language

View → Language: English, Italiano, Français, Deutsch, or Español. Folder names from the server (Posta in arrivo, Gesendet, Messages envoyés, Enviados, …) are mapped to Inbox/Sent/… in the UI language.

Country packs

Settings → Features is a checkbox matrix of certified-mail UI only. Ordinary IMAP/POP3, search, practice labels, mbox/.pst import, and attached data files stay on. Rows are certified-mail features; columns are Italy, Europe, France, Germany, Spain, Switzerland. The header checkbox turns every feature in that column on or off.

Pack What it unlocks Default
Italy PEC envelope / ricevute / delivery, Italian PEC presets, FatturaPA preview, fascicolo export On
Europe eIDAS REM evidence, Intesi REM preset On
France / Germany / Spain / Switzerland Operator evidence labels (AR24/LRE, De-Mail, Lleida, IncaMail). Those networks are usually not IMAP. Off

Turn off a pack to hide its menus, columns, and account presets. Existing mailboxes stay; only the extra UI goes away.

Downloads

When a GitHub Release exists: Windows portable zip and setup (postclient-{version}.exe, self-contained — no .NET SDK on the PC; default path C:\Program Files\MaksIT\Postclient), Linux Flatpak, macOS DMG (osx-arm64 and osx-x64). macOS builds are unsigned: first launch is Open from the context menu. WinGet listing comes later from the same setup exe.

Linux (Flatpak)

GitHub releases include postclient-{version}.flatpak when the Windows release run finds WSL Debian + Flatpak builder.

flatpak install --user ./postclient-{version}.flatpak
flatpak run eu.postclient.desktop

Run from source

dotnet run --project src/MaksIT.PostClient.UI

From src/ so global.json applies:

cd src
dotnet build MaksIT.PostClient.slnx

Tests

utils\Invoke-TestEngine.bat

Coverage shields at the top of this file are maintained by the test engine (CoverageBadges).

Release

  1. Update CHANGELOG.md and bump <Version> in src/Directory.Build.props.
  2. Tag v{version} on main when a remote exists.
  3. Run utils\Invoke-ReleasePackage.bat (self-contained Windows zip + setup exe, Linux Flatpak via WSL). Publishing the GitHub Release starts macOS release assets, which attaches unsigned osx-arm64 and osx-x64 DMGs.

License

Apache License 2.0. Copyright 2026 Maksym Sadovnychyy (MAKS-IT).