Changelog
All notable changes to msgvault, grouped by release.
Unreleased¶
0.19.3¶
2026-08-09
Improvements
- Start the API immediately while the analytics cache builds in the background.
- Respect provider rate limits during Circleback syncs.
- Improve daemon job scheduling and meeting import reliability.
Bug fixes
- Repair dangling message recipients automatically during database upgrades.
- Prevent keyed-object Circleback insights from blocking sync.
- Treat cooperative embedding scheduler yields as normal instead of job failures.
Contributors
- Thanks to Rusty Shackleford for the non-blocking API startup, daemon job and meeting import reliability work, and cooperative embedding scheduler fix.
- Thanks to Matthew Sweeney for the Circleback insight decoding and provider rate-limit fixes.
- Thanks to Wes McKinney for repairing dangling message recipients during database upgrades.
0.19.2¶
2026-08-08
Improvements
- Shows cache-building progress during daemon startup.
- Bounds relationship index builds to improve resource usage and reliability.
Bug fixes
- Preserves checksum compatibility for automatic updates.
- Accepts Fastmail pod-scoped JMAP API URLs.
0.19.1¶
2026-08-07
Bug fixes
- Advance Slack
--limit 1sweeps beyond the certified overlap window. - Stop Windows daemons cleanly during releases.
- Recover interrupted releases from existing tags.
0.19.0¶
2026-08-07
New features
- A new relationships-focused Web UI explores a mixed archive as messages, conversations, files, people, and domains. It adds explicit full-text, semantic, and hybrid search states; Saved Views; source status; safe deletion staging; settings; keyboard navigation; and authenticated remote sessions.
- Slack workspace archiving imports the channels a user belongs to, group DMs,
direct messages, threads, reactions, mentions, and files through a read-only
user token. Incremental sync discovers late replies to threads of any age,
and
backfill-slack-mediaretries deferred downloads. - Discord guild archiving imports bot-visible channels, threads, forum posts,
edits, deletion state, reaction summaries, and attachments with resumable
per-container checkpoints.
sync-discord, bounded compatibility and generic exports, scheduled sync, andbackfill-discord-mediacover ongoing archive maintenance; personal DMs and user-token automation are intentionally out of scope. POST /api/v1/import/meetingaccepts one provider-neutral meeting at a time, stores it as a searchable meeting transcript, and updates repeated deliveries in place by source identifier and external meeting ID.list-foldersshows selectable IMAP folders and approximate counts. Repeatable--folderand--skip-folderflags onsync-fullandsyncsafely restrict a scan without removing messages or labels learned earlier.export-messagesstreams required, bounded time windows as deterministic, provider-neutralmsgvault-message-export/1JSON Lines. A completion trailer lets consumers reject interrupted output, and exact source and message-type filters keep large mixed archives bounded.GET /api/v1/messages/changesprovides current message snapshots ordered by a content-change watermark, with opaque archive-bound cursors and a safe completion bound. It is an invalidation feed, not an audit log: multiple edits may collapse into one row, and related-table-only changes are outside its contract.- Email sync now enriches already-confirmed source-scoped identities with
strong evidence from trusted Sent metadata; first-time aliases require
identity discover --apply.identity discoverpreviews archived and optional Fastmail alias evidence, whileidentity importpreviews or applies text and JSON lists with unambiguous numeric source selection. - Durable person profiles provide stable IDs, vCard UIDs, explicit participant bindings, display-name overrides, and optimistic concurrency. Typed, historized person attributes and portable metadata-defined fields are available through the CLI, HTTP API, and generated clients. Together with the meeting, change-feed, and source-identity additions, these changes advance the OpenAPI schema to 1.36.0.
- MCP Streamable HTTP can reuse
[server].api_keyfor bearer authentication. Authenticated listeners may bind beyond loopback without the insecure override, while keyless non-loopback listeners still require an explicit--http-allow-insecureopt-in. - The vCard codec now parses, validates, and deterministically renders vCard 2.1, 3.0, and 4.0 while preserving ordered properties, groups, parameters, unknown extensions, legacy encodings, and source spelling. Its IANA registry snapshot and coverage declarations are vendored and checkable.
[data].loose_attachments = truekeeps newly stored attachments as individual files, disables automatic and explicit pack/repack creation, and makes backup restore materialize loose files. Existing packs remain readable until the operator stops the daemon and runsunpack-attachmentsonce.
Improvements
- Relationship activity, people, domains, and daily signals now use compact Parquet indexes. The Relationships workspace and person/domain/file grouping stay within the daemon's interactive memory budget on multi-million-message archives; upgrading an existing SQLite cache triggers one full rebuild.
- Email ingestion rejects missing, malformed, and implausible canonical dates
outside 1990 through 30 days in the future, then falls back through the oldest
plausible
Receivedtimestamp and source metadata.repair-datespreviews the same rules and--applyrecords an audit ledger before refreshing the analytics cache. - The official Docker image now includes the SQLite vector extension, so SQLite-backed semantic and hybrid search can be enabled without rebuilding the container.
[microsoft].redirect_urican override the Microsoft 365 and Teams OAuth callback when the application registration requires a custom URI.- The repeatable IMAP sync flags are now singular:
--folderand--skip-folder. - Background lifecycle management is standardized under
msgvault daemonwithstart,status,stop, andrestart;msgvault serveis the foreground Web UI/API and scheduler. The oldservelifecycle forms remain hidden compatibility aliases. - Analytics cache builds stage and verify every dataset before publishing it
under one lock, with
_last_sync.jsonwritten last as the commit marker. Failed exports retain the previous committed cache, while interrupted publication is rejected and repaired instead of exposing mixed Parquet data. - Newly generated NAS Compose bundles use
pull_policy: alwaysfor the moving GHCRlatesttag. A restart still reuses the installed image; reconcile withdocker compose up -dor explicitly pull before restarting older bundles.
Bug fixes
add-beepernow registers networks Beeper Desktop serves natively rather than through a bridge, such as iMessage. Beeper omits those accounts from its accounts API, so they are found from chat data instead and then sync, resume, and filter like any other Beeper source. Re-runadd-beeperon an existing install to pick them up.- Daemon-backed CLI, TUI, MCP, statistics, and backup operations now wait for completion or caller cancellation instead of failing at fixed HTTP or server deadlines on slow storage. Local daemon authentication uses the lightweight authenticated health endpoint, while connection setup, browser traffic, and ordinary API clients retain protective timeouts.
- Daemon runtime-record cleanup now requires a probe-confirmed identity mismatch before deletion, tolerates small creation-time clock skew, and lets a live daemon republish a missing record. This prevents false local-writer conflicts during later operations such as backup.
- Full message detail, including MCP
get_message, restores chat senders frommessages.sender_idwhen a direct message has no explicitfromrecipient row. Explicit email sender rows remain authoritative. - MBOX imports recover dates whose header value gained a trailing continuation artifact and accept weekday plus US month-day ordering.
deduplicate --content-hashbatches RFC822 duplicate-group reads and uses a supporting index instead of issuing one unindexed query per group, avoiding planning timeouts on large archives.- Generic and Discord compatibility exports use stable keyset reads, the same sender precedence as message APIs, and outer source constraints when scanning conversations, avoiding rescans, skipped rows, and unrelated archive work.
- Repeated source-deletion observations preserve the original tombstone time and no longer bump a message's content-change watermark until its state actually changes.
- Canceled maintenance transactions preserve the caller's cancellation error
when
database/sqlhas already rolled the transaction back, without masking substantive commit failures. - Granola accepts exact date-only values for note, calendar, and transcript timestamps and normalizes them to midnight UTC instead of dropping the note.
Acknowledgements
- Thanks to Wes McKinney for the Web UI, bounded message export, transactional analytics cache, daemon lifecycle and slow-I/O work, Docker deployment freshness, and release documentation infrastructure.
- Thanks to Rusty Shackleford for source identity discovery, durable person profiles and typed attributes, generic meeting ingestion, MCP bearer authentication, the vCard codec, Beeper account discovery, and direct-message sender hydration.
- Thanks to Matt Richmond for Slack workspace archiving, reply discovery, media handling, and Granola test portability.
- Thanks to Matthew Farrellee for IMAP folder discovery and filtering, the singular sync flags, configurable Microsoft OAuth redirects, and error-handling cleanup.
- Thanks to Jesse Robbins for date recovery and repair, scalable duplicate planning, and the relationship-query fan-out work incorporated into the memory-bounded index.
- Thanks to danshapiro for the message change feed, idempotent source-deletion tombstones, daemon runtime-record safety, schema-copy robustness, and faster PostgreSQL tests.
- Thanks to Nicholas Wang for enabling SQLite vector search in the Docker image.
- Thanks to Martin Schürrer for the loose-files-only attachment storage mode.
- Thanks to Marius van Niekerk for accepting date-only Granola timestamps.
- Thanks to Matthew Jacobs for keeping PostgreSQL CI coverage on reliable hosted runners.
0.18.0¶
2026-07-14
New features
- Granola and Circleback meeting notes, summaries, action items, and
transcripts can be synced into the archive and browsed in a new read-only
Meetings mode in the TUI. Meeting records are searchable with
message_type:meeting_transcript, and scheduled sync is supported through[[granola]]and[[circleback]]configuration. - Beeper Desktop chat archiving registers each bridged network as a separate
source, incrementally syncs messages, reactions, edits, and deletions, and
downloads media into the attachment store. Interrupted history backfills
resume, and
backfill-beeper-mediaretries pending downloads. msgvault skills installinstalls bundled read-only agent skills for search, attachment, and analytics workflows into Claude Code and Codex;msgvault skills uninstallremoves generated copies.- MCP search now has explicit
search_metadata,search_message_bodies, andsemantic_search_messagestools.search_in_messagefinds literal matches with raw-body offsets inside one message. The former combinedsearch_messagestool remains as a deprecated compatibility wrapper. - MCP
list_messagesaccepts aconversation_idfilter for listing one conversation or thread. - The daemon HTTP API schema is now 1.3.0 and supports
scope=bodyon deep search so daemon-backed clients can require an exact body-only response; bounded excerpts are returned in an ID-keyedbody_contextscompanion. GET /api/v1/attachments/{hash}/contentstreams archived attachment bytes by SHA-256 content hash; message details expose the hash needed to call it.- Windows users can build natively with
scripts/build.ps1on AMD64 or ARM64. Releases now include a native Windows ARM64 package with DuckDB analytics and Parquet cache support.
Improvements
- Attachment storage now supports sealed, immutable content-addressed packs
while remaining compatible with loose files.
pack-attachmentsmigrates eligible loose content,repack-attachmentsreclaims dead pack space, andunpack-attachmentsrestores loose files for downgrade or recovery. - Backup snapshots now use Kit's pack-based backup engine. Restore installs
compatible attachment packs directly by default, still SHA-256 verifies
every selected attachment, and falls back to loose files for incompatible or
oversized content;
--loose-attachmentsforces loose restoration. - Attachment exports, backup capture, HTTP downloads, and other consumers stream packed or loose content instead of buffering whole attachments in memory.
- SQLite's full
PRAGMA integrity_checkis now opt-in during restore through--integrity-check; page hashes, content hashes, and manifest-statistics verification remain enabled for every restore. - Apple Mail import recognizes
.partial.emlxfiles whose bodies are present but attachments have not been cached. A completeN.emlxcopy takes precedence overN.partial.emlxwhen both exist. - PostgreSQL full-text indexes use a versioned field layout so stale indexes are detected and must be backfilled before body-only search.
Bug fixes
- IMAP folder
UIDVALIDITY/UIDNEXThigh water marks are now supported on servers that advertise an\Allmailbox and are persisted as each folder is safely ingested. Interrupted, limited, or partially failed folders do not advance, so later fast syncs can skip unchanged folders without missing mail. - Local daemon discovery works when the msgvault home or configured data directory is a symlink, restoring the path layouts supported before 0.17.0 while retaining ownership and permission checks on the resolved directory.
- Metadata-only and body-only search scopes are enforced consistently across SQLite, PostgreSQL, DuckDB, and daemon-backed MCP sessions. Counts and aggregate statistics use the same predicates, and body excerpts remain bounded and UTF-8-safe.
Acknowledgements
- Thanks to Wes McKinney for the Kit backup and packed-attachment storage work, agent skills, Apple Mail partial-message import, native Windows builds and ARM64 releases, and symlink-safe daemon discovery.
- Thanks to endolith for the MCP search tools, in-message search, and consistent metadata/body search scopes.
- Thanks to Rob Elkin for attachment retrieval by content hash through the HTTP API and generated Go client.
- Thanks to Matthew Sweeney for Beeper Desktop archiving and Granola/Circleback meeting sync and TUI browsing.
- Thanks to Jesse Vincent for correct IMAP folder
high water marks and fast sync on servers with an
\Allmailbox.
0.17.1¶
2026-07-06
New features
- Deletion staging endpoints on the HTTP API (schema 1.2.0):
POST /api/v1/deletionsstages messages by filter and/or message IDs with server-side Gmail-ID resolution and adry_runpreview,GET /api/v1/deletionslists staged manifests by status, andDELETE /api/v1/deletions/{id}cancels a pending or in-progress manifest. Execution still happens only throughdelete-staged. - The generated Go client includes deletion staging support through
StageDeletion, including both dry-run (200) and create (201) responses. msgvault searchnow reports full-text index readiness while the daemon is checking or rebuilding the CLI search index, with long-running searches showing the daemon activity they are waiting on.
Improvements
- CLI search no longer waits for the full-text index completeness probe or backfill before returning results. Index checks and backfills run in the background, and responses identify when results may be incomplete until the index catches up.
- SQLite archives now index deletion timestamps so daemon cold starts avoid full-table deletion checks while deciding whether the analytics cache is stale.
- Automated dependency updates now use Renovate, and project dependencies were refreshed.
Bug fixes
- IMAP UID enumeration now constrains searches to fetchable UID ranges and
raw fetches no longer depend on fragile
ENVELOPEparsing, improving robustness on servers such as iCloud IMAP. - API-staged deletion manifests now reject empty or unknown filter input, enforce single-account selections, record the raw staging request, and avoid same-second manifest ID collisions.
Acknowledgements
- Thanks to Wes McKinney for the deletion staging API and client support, non-blocking CLI search status reporting, deletion timestamp indexes, and dependency refresh.
- Thanks to Tim Kersten for the IMAP UID enumeration and raw-fetch robustness fixes.
- Thanks to Marius van Niekerk for migrating automated dependency updates to Renovate.
0.17.0¶
2026-07-04
New features
msgvault backupadds incremental, verifiable archive snapshots withinit,create,list,verify, andrestore. Snapshots capture the SQLite database, attachments, deletion audit files, and optional config/token extras into an append-only repository with byte-level verification.- Google Calendar archive support via
msgvault add-calendarandmsgvault sync-calendar, including read-only event sync, recurring series, cancellations, scheduled[[gcal]]sync, and search with--message-type calendar_event. - Microsoft Teams archive support via delegated Microsoft Graph sync.
msgvault add-teamsauthorizes Graph access,msgvault sync-teamsimports chats and channels, Teams messages are stored withmessage_type = teams, andbackfill-teams-mediacan re-fetch hosted inline media for already imported messages. - Search and query paths now understand message-type scoping. Local search
accepts
message_type:/message_type=query operators and the--message-typeflag; HTTP, MCP, aggregate, and SQL-backed query surfaces expose the storedmessage_typeso email, calendar events, text messages, Teams messages, and other imported records can be separated cleanly. - Scoped embedding builds can restrict a vector generation to selected message
types through
[vector.embed.scope].message_types, with vector/hybrid search rejecting incompatible unscoped queries instead of treating a partial index as complete. - The HTTP API is now generated through Huma with a checked-in OpenAPI contract
(
msgvault openapi,/openapi.json) and a generated Go client underpkg/client. - Archive-access CLI commands now route through a msgvault daemon (the
configured remote server, or a local background daemon that starts on
demand and idles out after
[server].daemon_idle_timeout). The daemon is the single archive writer: concurrent operations queue with a visibleWaiting:message, read-only commands run immediately, and scheduled syncs yield to interactive commands. See the Daemon Migration Guide. - Daemon lifecycle management via
msgvault serve start|status|stop|restart, with automatic restart of older local daemons on binary upgrade ([server].daemon_auto_restart).
Improvements
- IMAP resyncs skip unchanged folders using the mailbox
UIDVALIDITYandUIDNEXTvalues captured after the previous completed sync. msgvault serve stopnow explains long shutdown waits by reporting the daemon operation it is waiting for and periodically printing elapsed wait updates.- MCP
get_messagereturns large message bodies in windows instead of returning the whole body in one response. - Vector embedding maintenance no longer uses a separate pending queue.
Coverage is tracked per message with
embed_gen, so rebuilds, repairs, and daemon top-ups all share the same scan-and-fill path. - Full-sync batch errors are counted and persisted on the sync run, making source status and diagnostics more accurate after partial failures.
- The documentation site now lives in the repository, including CLI, API, setup, backup, calendar, daemon, PostgreSQL, and vector-search docs plus the docs build/check scripts.
- macOS users can install through Homebrew with
brew install msgvault. - The TUI migration to Bubble Tea v2 is complete.
Deprecations
tui --force-sql,tui --no-cache-build,tui --no-sqlite-scanner,mcp --force-sql, andmcp --no-sqlite-scannerare deprecated (removal planned for a later release); engine and cache selection moved to the[analytics]config section.
Bug fixes
- MCP list/search requests now reject Gmail-only
list:/List-IDsearch operators instead of treating them as local full-text terms. - DuckDB query engines re-probe Parquet schema columns when the cache is rebuilt or replaced underneath a running process.
- Empty
subject:and empty text search terms no longer match every message. - Facebook Messenger imports preserve multiple attachments on one message instead of collapsing them into a single row.
- Imported message and reaction timestamps are normalized to UTC.
- TUI startup avoids mixed SQLite access while the daemon owns archive writes.
- API server documentation no longer overflows its sidebar on narrow layouts.
- Release publishing and the Nix update flow were corrected for the new module and release packaging.
Acknowledgements
- Thanks to Wes McKinney for the backup repository commands, daemon-only CLI routing, daemon lifecycle/status improvements, IMAP folder-state skipping, the in-repo documentation site, OpenAPI/client generation, API docs polish, TUI startup fix, and release/Nix publishing fixes.
- Thanks to danshapiro for Google Calendar sync, message-type filters, scoped embedding builds, and persisted full-sync batch error counts.
- Thanks to Nat Torkington for Microsoft Teams ingestion and the Facebook Messenger multi-attachment fix.
- Thanks to Yuriy Grinberg for replacing the pending embedding queue with per-message embedding generations.
- Thanks to endolith for windowed MCP message body reads.
- Thanks to Lazare Rossillon for re-probing Parquet schemas when the analytics cache changes underneath a running query engine.
- Thanks to Matthew Sweeney for the Homebrew installation instructions.
- Thanks to Marius van Niekerk for finishing the Bubble Tea v2 TUI migration.
0.16.0¶
2026-06-18
New features
- PostgreSQL backend with pgvector support for semantic and hybrid search.
- Source sync status endpoint in the HTTP API.
- Pagination for MCP
search_messagesandlist_messages.
Improvements
- Record per-item sync errors so failed imports and fetch/ingest/delete failures are visible without treating an entire run as opaque.
- Upgrade DuckDB support to DuckDB 1.5.4 via
duckdb-go/v2. - Improve search/query behavior across MCP pagination, full-text query sanitization, and backend compatibility.
- Update packaging and release metadata for 0.16.0.
- Update stale project URLs to the
kenn-io/msgvaultlocation.
Bug fixes
- Prevent WAL corruption by isolating DuckDB's SQLite usage from the daemon.
- Fix Linux release builds by correcting the DuckDB link.
- Harden SyncTech SMS Backup & Restore Drive sync lifecycle handling.
- Tolerate null source import checksums.
Acknowledgements
- Thanks to Yuriy Grinberg for the PostgreSQL backend and pgvector semantic/hybrid search support.
- Thanks to danshapiro for source sync status, per-item sync diagnostics, SyncTech Drive lifecycle hardening, and null-checksum handling.
- Thanks to Matthew Sweeney for the DuckDB 1.5.4 /
duckdb-go/v2migration and stale URL cleanup. - Thanks to endolith for MCP pagination on
search_messagesandlist_messages. - Thanks to Jesse Robbins for improving the AFM vector-search docs and correcting the accounts, identities, collections, and deduplication documentation for the shipped 0.16.0 behavior.
- Thanks to Marius van Niekerk for isolating DuckDB's SQLite usage from the daemon to prevent WAL corruption.
- Thanks to Wes McKinney for the Linux release-build fix and 0.16.0 packaging/release metadata updates.
0.15.2¶
2026-06-10
New features
- Add
msgvault verify --jsonfor machine-readable verification results.
Bug fixes
- Escape FTS5 metacharacters in hybrid search queries to prevent search failures.
- Fix Windows installer redirects in PowerShell 5.x and improve arm64 fallback handling.
Improvements
- Update minor and patch dependencies.
Acknowledgements
- Thanks to Carlos de la Lama-Noriega for adding machine-readable
verifyoutput. - Thanks to Frederic Masi for fixing hybrid search failures with FTS5 metacharacters.
- Thanks to Wes McKinney for fixing Windows installer redirects and arm64 fallback handling.
0.15.0¶
2026-05-28
New features
- Microsoft Outlook PST archive import via
msgvault import-pst, including folder labels, attachments, resumable checkpoints, and automatic skipping of non-email PST items. - Facebook Messenger Download Your Information import via
msgvault import-messenger, with JSON and HTML export support. - SyncTech SMS Backup & Restore import via
msgvault import-synctech-sms, plus Google Drive source configuration and one-shot sync commands for scheduled Android backups. - Per-account identities, named collections, scoped search/stats, and reversible deduplication workflows across accounts and collections.
- Google service account support for Workspace domain-wide delegation, including per-app service account keys.
- Message detail API responses now expose
body_html, and inline image MIME parts can be fetched through a dedicated inline endpoint. - MCP StreamableHTTP transport with
msgvault mcp --http. - MCP
search_by_domainstool for finding messages where any participant belongs to one of several domains.
Improvements
- Vector embedding management is consolidated under a single
msgvault embeddingscommand, withbuild,resume,list,activate, andretiresubcommands covering the full index-generation lifecycle.msgvault build-embeddingsstill works as a deprecated alias formsgvault embeddings build. - Long messages are split into embedding chunks instead of being truncated to a single input.
- Embedding preprocessing now handles HTML bodies, base64/data blobs, URL tracking parameters, and whitespace cleanup more aggressively.
- Embedding progress reporting has steadier ETA handling, per-character timing, and better behavior when failed batches are downshifted.
- SQLite full-text search ranking better matches the weighting used by PostgreSQL-backed paths.
- iMessage imports can backfill participant display names from vCard contacts.
- Scheduled sync dispatch now resolves source type and supports IMAP sources as well as Gmail.
msgvault servecan also schedule SyncTech SMS Backup & Restore Drive sources. - SQLite sync paths are more durable and treat transient network failures as retryable scheduled-sync skips.
- Routine CLI command errors no longer print the full help output.
- Update checks avoid unnecessary GitHub API rate-limit pressure.
- Switch the Go module path to
go.kenn.io/msgvault.
Bug fixes
- Domain-based search results now hide locally deleted rows.
- SQL slow/error logging includes query arguments and reports accurate streaming query durations.
- Embedding skips rows that become empty after preprocessing and surfaces API 4xx response bodies for easier troubleshooting.
- PST imports namespace source message IDs per archive so messages from different PST files no longer collide.
Acknowledgements
- Thanks to Matthew C Roberts for the Microsoft Outlook PST importer, including attachment handling, folder labels, checkpoints, and PST item filtering.
- Thanks to Jesse Robbins for Facebook Messenger import support, the accounts/identities/collections/deduplication work, and several embedding progress and logging improvements.
- Thanks to danshapiro for the SyncTech SMS Backup & Restore importer and Google Drive source workflow.
- Thanks to hansn74 for Google service account support, MCP StreamableHTTP transport, multi-domain participant search, long-message embedding chunking, and expanded embedding preprocessing.
- Thanks to Yuriy Grinberg for the PostgreSQL dialect refactor work and SQLite FTS5 ranking improvements.
- Thanks to Rob Elkin for SQLite sync durability hardening and better handling of transient scheduled-sync network failures.
- Thanks to Franklin for scheduled-sync dispatch by source type, including IMAP support.
- Thanks to Boris Jabes for iMessage display-name backfill from vCard contacts.
- Thanks to sarcasticbird for exposing HTML email bodies and inline MIME parts through the API.
- Thanks to Phillip Cloud for the golangci-lint v2 migration, broad linter cleanup, command error-output polish, and Nix flake restructuring.
- Thanks to Marius van Niekerk for the
go.kenn.io/msgvaultmodule path migration and embedding-generation lifecycle command work. - Thanks to Wes McKinney for PST source-message ID namespacing, update-check rate-limit avoidance, Docker CI speedups, and the Go test-suite migration to testify.
0.14¶
2026-04-21
New features
- Vector search (semantic and hybrid). msgvault can now embed your archive using a configured OpenAI-compatible embedding endpoint (Ollama, llama.cpp
server, LM Studio, etc.) and search it by meaning, not just keywords.msgvault search --mode vectorruns pure semantic search;--mode hybridfuses BM25 and vector similarity via Reciprocal Rank Fusion. Exposed through local CLI search (msgvault search), the HTTP API (GET /api/v1/search?mode=vector|hybrid), and the MCP server (search_messagesmode argument plus a newfind_similar_messagestool). See Vector Search. msgvault build-embeddingscommand to generate and maintain the local vector index. Incremental by default;--full-rebuildcreates a new generation and atomically activates it once coverage reaches zero. Same-model rebuilds keep answering against the previous active generation while the new one is built, with active-generation top-ups frozen until activation; model or dimension changes returnindex_staleuntil activation.- Background embedding via the daemon scheduler. A new
[vector.embed.schedule]config block drives the embed worker on cron and/or after every successful scheduled sync, somsgvault servecan keep the vector index current without manual intervention. /api/v1/statsgains avector_searchsub-object reporting the active generation, any in-flight rebuild, and the actionable missing embedding count for the generation the worker will target next.msgvault rebuild-ftscommand to rebuild the SQLite FTS5 shadow table after corruption.
Improvements
searchcommand gains--mode fts|vector|hybridand--explainflags.--explainincludes per-signal scores (RRF, BM25, vector) in table and JSON output for ranking inspection.- Configuration gains a full
[vector]block with sub-tables for the embedding endpoint, message preprocessing, hybrid ranking, and the embed scheduler. See Configuration: vector. remove-accountdeletes attachment files from disk when they were unique to the removed account. Files shared across multiple accounts are preserved automatically, and an in-progress sync on any account skips file deletion to avoid racing new attachment writes.
Bug fixes
remove-accountno longer leaves orphaned attachment files on disk after an account's database rows are removed.
Acknowledgements
- Thanks to Yuriy Grinberg for the first PostgreSQL dialect refactor, which laid groundwork for alternative storage backends.
- Thanks to Matthew C Roberts for making
remove-accountclean up unshared attachment files safely. - Thanks to Wes McKinney for semantic and hybrid vector search, the embedding-generation workflow, background embedding scheduler, and the FTS5 rebuild recovery command.
0.13.1¶
2026-04-15
Bug fixes
- Fix importing older WhatsApp
msgstore.dbbackups.
0.13¶
2026-04-14
New features
- Structured file logging with per-run correlation IDs. Every CLI invocation gets a unique
run_idon every log line, making it easy to trace a single run across shared log files. Newmsgvault logscommand for viewing and tailing logs. File logging is opt-in; see Configuration: Log for setup.
Improvements
- The terminal UI inherits your terminal background colors instead of forcing its own, so custom terminal themes (Dracula, Solarized, Nord, etc.) work naturally.
Bug fixes
- Improve full-text search performance across local archives.
- Improve terminal UI stability during rapid interactions (fix race condition where switching views could briefly show stale data).
Acknowledgements
- Thanks to Jesse Robbins for structured file logging with per-run correlation IDs, plus the full-text search performance fix and TUI race-condition fix.
- Thanks to Wes McKinney for making the TUI inherit terminal background colors.
0.12.1¶
2026-04-10
New features
- Shell completion via
msgvault completionfor Bash, Zsh, Fish, and PowerShell. MSGVAULT_IMAP_PASSWORDenvironment variable and stdin piping for non-interactiveadd-imap(Docker, CI).- Advanced search: word-boundary regex matching replaces ILIKE substring matching across all search paths, and FTS5 prefix search for the SQLite full-text index.
- Expanded store API with structured query parsing for search (
SearchMessagesQuery).
Improvements
- Search result quality: text matching switched from ILIKE to word-boundary regex, reducing false positives from substring matches. SQLite aggregate sort ties are broken deterministically by key.
- Nix flake packaging metadata updated for 0.12.1.
- Docker image switched to
wolfi-basewithlibstdc++for CGO/DuckDB compatibility, non-root user, and health check.
Bug fixes
- IMAP label handling: standard folders (Sent, Drafts, Trash, Junk, etc.) are now classified as system labels via RFC 6154 attributes and fallback name matching.
import-mboxaccepts plain mbox files with any extension (ZIP entries still require.mbox/.mbx),--labelis repeatable/comma-separated, and re-imports update labels on existing messages instead of silently skipping.- API search now uses the full structured query parser (operators like
from:,subject:, date/size filters) instead of plain-text matching. completioncommand registered correctly in the CLI command tree.
Acknowledgements
- Thanks to Jesse Robbins for the advanced search work across regex matching, FTS5 prefix search, snippets, deterministic sorting, and related search-quality improvements.
- Thanks to Wes McKinney for the completion-command registration fix, IMAP label handling fixes, MBOX import fixes, API structured-query search fix, and Docker image update.
0.12¶
2026-04-09
New features
- SQL query interface via
msgvault query. Run arbitrary SQL against DuckDB over Parquet with--format json|csv|table. See SQL Queries. - Microsoft 365 OAuth2 support via
msgvault add-o365for Outlook.com and organizational accounts. Auto-detects personal vs. org IMAP hosts. - Text message import:
import-whatsapp,import-imessage, andimport-gvoicefor WhatsApp, iMessage, and Google Voice. See Text Messages. - TUI text mode: press
mto toggle between Email and Texts for browsing imported text conversations. --afterand--beforedate filters forsync-fullwith IMAP accounts.- CC and BCC recipients exposed in the message API responses.
- Claude Code skill for querying the archive via SQL views.
Improvements
delete-stagednow supports IMAP accounts (usesUID STORE \Deleted+UID EXPUNGE).- Analytics cache is automatically rebuilt after write operations (sync, import, delete-staged) so stats stay current.
msgvault queryauto-rebuilds a stale cache before executing SQL.- Improved archive query views and text-message search support.
Bug fixes
from:domain.comsearch now matches domain patterns automatically for common TLDs. Uncommon TLDs still require the explicit@prefix (from:@brand.pizza).- Wait for the IMAP server greeting before authenticating, fixing
unexpected EOFerrors with OAuth proxies. - Fix label name conflict handling when ensuring Gmail labels (use
ON CONFLICTupsert). - Open the MCP database in read-only mode to prevent concurrent session hangs when multiple AI sessions query the archive.
Acknowledgements
- Thanks to Matthew C Roberts for Microsoft 365 OAuth2 IMAP support.
- Thanks to dominic for adding IMAP support to
delete-staged. - Thanks to danshapiro for exposing CC and BCC recipients in message API responses.
- Thanks to arunim1 for adding
--afterand--beforedate filtering to IMAP sync. - Thanks to hansn74 for the
from:domain.comdomain-pattern search fix. - Thanks to Shantanu Singh for Nix dev-shell setup improvements.
- Thanks to Wes McKinney for the SQL query interface, Claude Code skill, text-message imports, cache rebuilds after writes, MCP read-only database mode, IMAP greeting handling, and label-conflict fix.
0.11¶
2026-03-24
New features
- Support multiple Google OAuth apps for Google Workspace organizations.
- Add
source_conversation_idtosearchandshow-messageJSON output.
Improvements
- Show masked IMAP passwords with
*while typing during account setup. - Better protect local data and cache handling when SQLite state is corrupted or analytics cache data is empty.
Bug fixes
- Fix IMAP host parsing for IPv6 addresses in
add-imap. - Improve IMAP compatibility by removing
ESEARCH RETURN (ALL)for IMAP4rev1 servers.
Acknowledgements
- Thanks to Rob Elkin for protecting local data paths when SQLite state is corrupted or analytics cache data is empty.
- Thanks to Jason Kuhrt for exposing
source_conversation_idin CLI JSON output. - Thanks to Alexander Mangel for improving IMAP4rev1 compatibility by removing
ESEARCH RETURN (ALL). - Thanks to endolith for fixing IPv6 host parsing in
add-imap. - Thanks to Wes McKinney for multiple Google OAuth app support and masked IMAP password entry.
0.10¶
2026-03-15
New features
- IMAP account support via
add-imapcommand for syncing mail from any standard IMAP server. - Remote TUI support:
msgvault tuican connect to a remote server when[remote]is configured. --accountflag onsearchto limit results to a specific account.
Improvements
- Auto-discover Apple Mail accounts during
import-emlxby reading macOSAccounts4.sqlite. - Shorten overly long MIME parse error messages to keep terminal output readable.
Bug fixes
- Fix Apple Mail V10 import to discover
.emlxfiles in partition subdirectories. - Prevent sync re-authentication from mixing tokens between accounts by adding
login_hintand post-auth email validation.
Acknowledgements
- Thanks to Ben Labaschin for TUI remote-server support.
- Thanks to David GG for adding the
--accountsearch flag. - Thanks to Wes McKinney for IMAP account support, Apple Mail V10 import fixes and account auto-discovery, MIME parse error truncation, and sync re-auth token isolation.
0.9¶
2026-02-26
New features
create-subsetcommand to generate smaller subset databases for testing or sharing.remove-accountcommand to delete an account and all its local data.
Improvements
- Support modern Apple Mail V10 directory layouts during
import-emlx. - Handle expired or revoked OAuth tokens with automatic re-authentication and a
--forceflag.
Bug fixes
- Fix a foreign key constraint failure during message ingest.
Acknowledgements
- Thanks to Hugh Brown for expired/revoked OAuth-token recovery with automatic re-authentication and
--force. - Thanks to Hugh Brown for query-layer refactoring that reduced duplication between DuckDB and SQLite paths.
- Thanks to Wes McKinney for
create-subset,remove-account, Apple Mail V10 layout support, and the ingest foreign-key fix.
0.8¶
2026-02-24
New features
import-mboxcommand to import local MBOX archives.import-emlxcommand to import Apple Mail.emlxexports.- MCP
stage_deletiontool for Claude-assisted staged email cleanup. - NAS/Docker deployment support with updated Compose templates.
Improvements
- Installation instructions for conda-forge and additional package managers.
Bug fixes
- Fix TUI label search and aggregate search behavior.
Acknowledgements
- Thanks to Riccardo Iaconelli for the local mail import commands,
import-mboxandimport-emlx. - Thanks to Rob Elkin for the
stage_deletionMCP tool. - Thanks to Ben Labaschin for NAS and Docker deployment support.
- Thanks to Pavel Zwerschke for additional package-manager installation instructions.
- Thanks to bchoor for store time-parsing unit tests.
- Thanks to Wes McKinney for TUI label and aggregate search fixes and Docker Compose template cleanup.
0.7¶
2026-02-09
New features
- HTTP API server with daemon mode and scheduled background syncs.
- Account filters for MCP
search,list, andaggregatetools. - Hide-deleted message filter with a revamped filter modal in the TUI.
- Gmail thread ID support in query results.
- Nix flake for reproducible builds.
Improvements
- Optimize incremental sync to reduce sync time.
- Harden cache validation and handling.
Bug fixes
- Fix CPU pinning behavior during batch deletion.
- Fix batch deletion terminal UI workflow issues.
Acknowledgements
- Thanks to Ben Labaschin for the HTTP API server, daemon mode, and scheduled sync foundation.
- Thanks to Rob Elkin for account filters on MCP search, list, and aggregate tools.
- Thanks to Ben Lovell for the initial Nix flake and automated vendor-hash maintenance.
- Thanks to Wes McKinney for optimizing incremental sync, hardening cache handling, adding Gmail thread IDs to query results, improving batch-deletion UX, and adding the TUI hide-deleted filter.
0.6¶
2026-02-05
New features
- Secure file permissions with Windows DACL support.
- Windows update support with
.ziparchives and.exebinaries. --homeCLI flag to set the base directory for archives.- FTS5 full-text search index built and updated during sync, with automatic backfill for existing databases.
Improvements
- Strip surrounding quotes from CLI paths for Windows CMD compatibility.
- Suggest running
repair-encodingwhen encoding errors are detected during sync.
Bug fixes
- Fix TUI search and navigation issues (pagination, scrolling, stats, zero-result handling).
- Fix silent error handling in encoding repair.
- Fix command-injection risk when launching OAuth browser.
- Fix Windows TOML parsing error hints for backslashes.
- Preserve cursor position when scrolling page up/down in the message list.
- Fix invalid UTF-8 handling during sync to prevent failures.
Acknowledgements
- Thanks to Hugh Brown for cross-platform secure file permissions with Windows DACL support.
- Thanks to Hugh Brown for several security and reliability fixes, including OAuth browser command-injection hardening, attachment path-traversal fixes, MCP bounds checks, panic handling, and encoding repair error handling.
- Thanks to Wes McKinney for FTS5 indexing and backfill, Windows update/build support,
--home, Windows path diagnostics, invalid UTF-8 handling, and TUI search/navigation fixes.
0.5¶
2026-02-04
New features
export-attachmentandexport-attachmentsCLI commands.- Windows support with installer, config path fixes, and
--configflag. - MCP attachment support with embedded resources and
export_attachmenttool. - Account management CLI with
add,list, andupdatecommands.
Improvements
- Improve Windows installer, remove
sqlite_scannerdependency, and harden test reliability.
Bug fixes
- Fix cache consistency after deletions.
- Fix incremental export losing junction table data.
- Fix SQL injection vulnerability in query handling.
- Fix MIME date parsing issues.
- Fix path traversal risk in attachment export, including symlink traversal.
- Fix non-functional
sync-fulllimit argument. - Fix DuckDB type handling errors.
- Prevent crash when rethrowing panics during export.
- Add missing bounds checks in MCP handlers.
Acknowledgements
- Thanks to Ethan Byrd for account CLI updates and the
sync-full --limitfix. - Thanks to Hugh Brown for security fixes across SQL query handling, attachment path traversal, symlink traversal, MIME date parsing, and panic handling.
- Thanks to Rob Elkin for fixing cache consistency after deletions.
- Thanks to Wes McKinney for Windows installer/config support, attachment export commands, MCP attachment resources,
export_attachment, DuckDB type fixes, MIME date fixes, and incremental export fixes.
0.4¶
2026-02-03
New features
--listflag ondelete-stagedto preview staged deletions before executing.
Improvements
- Replace broken
--headlessdevice flow with clearer setup instructions.
0.3¶
2026-02-02
New features
syncandsync-fullrun without arguments to sync all accounts.
Improvements
- Tighten private file permissions to
600for better local data security. - Improve deletion progress display and recovery behavior.
Bug fixes
- Fix deletion issues around scope escalation and checkpoint recovery.
- Fix missing
rows.Err()handling when batching participants.
Acknowledgements
- Thanks to Hugh Brown for tightening private-resource file permissions.
- Thanks to Ethan Byrd for fixing missing
rows.Err()handling in participant batching. - Thanks to Matt Galligan for fixing broken README documentation links.
- Thanks to Wes McKinney for making
syncandsync-fullrun across all accounts, and for deletion workflow fixes around scope escalation, checkpoint recovery, and progress reporting.
0.2¶
2026-02-02
Improvements
- Use MCP server for chat instead of the built-in chat command.
- Reduce memory use during string joins for better performance.
Acknowledgements
- Thanks to Hugh Brown for the memory-efficient string-join improvement.
- Thanks to Wes McKinney for replacing the built-in chat command with the MCP server.
0.1¶
2026-02-02
New features
- MCP server for AI-assisted email exploration.
Improvements
- Improve Linux compatibility by building against Ubuntu 20.04 (glibc 2.31).
- Rename
sync-incrementalcommand tosyncfor a simpler workflow. - Show full version tag in the TUI title bar.
- Show helpful OAuth setup instructions when
client_secretsis missing.
Bug fixes
- Fix TUI update notification to show commit and date info in release builds.
- Fix incorrect elapsed time reporting during sync.
- Fix recipient name filters to include BCC recipients.
Acknowledgements
- Thanks to Ethan Byrd for fixing recipient-name filters to include BCC recipients.
- Thanks to Wes McKinney for Linux build compatibility, the
syncrename, OAuth setup guidance, TUI release/update polish, and sync elapsed-time fixes.
0.0¶
2026-02-01
Initial public release.