Documentation · Setup Guide · Interactive TUI
> **Alpha software.** APIs, storage format, and CLI flags may change without notice. Back up your data. Archive a lifetime of email. Analytics and search in milliseconds, entirely offline. ## Why msgvault? Your messages are yours. Decades of correspondence, attachments, and history shouldn't be locked behind a web interface or an API. By default, msgvault downloads a complete local copy and then everything runs offline. Search, analytics, and the MCP server all work against your msgvault archive with no mailbox network access required. If you configure a remote deployment, the archive lives on your own server rather than a hosted msgvault service. Currently supports Gmail, Google Calendar, Microsoft Teams, Discord, Granola, Circleback, Beeper Desktop, and IMAP sync, plus offline imports from MBOX exports, Apple Mail (`.emlx`) directories, PST archives, and common chat/text export formats. ## Features - **Full Gmail backup**: raw MIME, attachments, labels, and metadata - **Google Calendar sync**: archive events, organizers, and attendees; searchable alongside email - **Microsoft Teams sync**: archive delegated Graph chats, channels, replies, and inline media with `message_type = teams` - **Discord sync**: archive guild channels, threads, forum posts, and attachments through a read-only bot with `message_type = discord` - **Meeting notes**: sync Granola and Circleback notes and transcripts, then browse them in the TUI - **Beeper Desktop sync**: archive chats and media from every network bridged through Beeper's local API - **IMAP sync**: archive mail from any standard IMAP server - **Incremental backup snapshots**: verifiable `msgvault backup` repositories for the SQLite archive and attachments - **MBOX / Apple Mail / PST import**: import email from local export formats - **First-party web UI**: dense, keyboard-driven search, grouping, people/domain, file, source, and deletion workspaces served directly by the daemon - **Interactive TUI**: drill-down analytics over your entire message history, powered by DuckDB over Parquet — connects to a remote `msgvault serve` instance or runs locally - **Full-text search**: FTS5 with Gmail-like query syntax (`from:`, `has:attachment`, date ranges) - **MCP server**: access your full archive at the speed of thought in Claude Desktop and other MCP-capable AI agents - **DuckDB analytics**: millisecond aggregate queries across hundreds of thousands of messages in the TUI, CLI, and MCP server - **Incremental sync**: History API picks up only new and changed messages - **Multi-account**: archive several Gmail and IMAP accounts in a single database - **Resumable**: interrupted syncs resume from the last checkpoint - **Content-addressed attachments**: deduplicated by SHA-256 - **Packed attachment storage**: sealed immutable packs reduce filesystem overhead, with pack, repack, and unpack maintenance commands - **Agent skills**: install bundled search, attachment, and analytics workflows for Claude Code and Codex ## Installation **macOS / Linux:** ```bash curl -fsSL https://msgvault.io/install.sh | bash ``` **macOS via Homebrew** ```bash brew install msgvault ``` **Windows (PowerShell):** ```powershell powershell -ExecutionPolicy ByPass -c "irm https://msgvault.io/install.ps1 | iex" ``` The installer detects your OS and architecture, downloads the latest release from [GitHub Releases](https://github.com/kenn-io/msgvault/releases), verifies the SHA-256 checksum, and installs the binary. You can review the script ([bash](https://msgvault.io/install.sh), [PowerShell](https://msgvault.io/install.ps1)) before running, or download a release binary directly from GitHub. To build from source instead (requires **Go 1.26+**, **Bun 1.3.14+**, and a C/C++ compiler for CGO and to statically link DuckDB): ```bash git clone https://github.com/kenn-io/msgvault.git cd msgvault make install ``` **Conda-Forge:** You can install msgvault [from conda-forge](https://prefix.dev/channels/conda-forge/packages/msgvault) using Pixi or Conda: ```bash pixi global install msgvault conda install -c conda-forge msgvault ``` ## Quick Start > **Prerequisites:** You need a Google Cloud OAuth credential before adding an account. > Follow the **[OAuth Setup Guide](https://msgvault.io/guides/oauth-setup/)** to create one (~5 minutes). ```bash msgvault init-db msgvault add-account you@gmail.com # opens browser for OAuth msgvault sync-full you@gmail.com --limit 100 msgvault serve ``` Open the `API server` URL printed by `msgvault serve`. The same release binary serves the complete browser application; Node, Bun, and a separate asset directory are not needed at runtime. See the [Web UI guide](docs/web-ui.md) for search modes, keyboard controls, and secure remote access. The TUI remains available with `msgvault tui`. ## Commands | Command | Description | |---------|-------------| | `init-db` | Create the database | | `add-account EMAIL` | Authorize a Gmail account (use `--headless` for servers) or add an IMAP account | | `sync-full EMAIL` | Full sync (`--limit N`, `--after`/`--before` for date ranges) | | `sync EMAIL` | Sync only new/changed messages | | `add-calendar EMAIL` | Authorize read-only Google Calendar access and register calendars | | `sync-calendar NAME\|EMAIL` | Sync Google Calendar events (full first run, then incremental) | | `add-teams EMAIL` | Authorize delegated Microsoft Graph access for Teams | | `sync-teams EMAIL` | Sync Microsoft Teams chats and channels | | `add-discord` / `sync-discord` | Register a read-only bot and sync Discord guild channels and threads | | `export-messages` | Stream a bounded, provider-neutral archive window as versioned JSONL | | `export-discord` | Temporary compatibility export for bounded Discord history | | `backfill-discord-media` | Retry incomplete Discord attachment downloads | | `add-granola` / `sync-granola` | Register and sync Granola meeting notes and transcripts | | `add-circleback` / `sync-circleback` | Authorize and sync Circleback meetings, notes, and transcripts | | `add-beeper` / `sync-beeper` | Register and sync Beeper Desktop chats and media | | `backup` | Initialize, create, list, verify, and restore backup snapshots | | `pack-attachments` | Migrate all eligible loose attachment files into immutable packs | | `repack-attachments` | Reclaim dead space from sparse attachment packs | | `unpack-attachments` | Restore packed attachments to loose files for downgrade or recovery | | `tui` | Launch the interactive TUI (`--account` to filter, `--local` to force the local daemon) | | `search QUERY` | Search messages (`--account` and `--message-type` to filter, `--json` for machine output) | | `show-message ID` | View full message details (`--json` for machine output) | | `mcp` | Start the MCP server for AI assistant integration | | `skills install` | Install bundled agent skills for search, attachments, and analytics | | `serve` | Run the API/scheduler or manage the background daemon (`start`, `status`, `stop`, `restart`) | | `stats` | Show archive statistics | | `list-accounts` | List synced email accounts | | `verify EMAIL` | Verify archive integrity against Gmail | | `export-eml` | Export a message as `.eml` | | `import-mbox` | Import email from an MBOX export or `.zip` of MBOX files | | `import-emlx` | Import email from an Apple Mail directory tree | | `build-cache` | Rebuild the Parquet analytics cache | | `update` | Update msgvault to the latest version | | `setup` | Interactive first-run configuration wizard | | `repair-encoding` | Fix UTF-8 encoding issues | | `repair-dates` | Report or repair missing and implausible email sent dates | | `list-senders` / `list-domains` / `list-labels` | Explore metadata | See the [CLI Reference](https://msgvault.io/cli-reference/) for full details. ## Vector Search msgvault can search your archive semantically using vector embeddings in addition to the default FTS5 keyword search. Point it at a self-hosted OpenAI-compatible embedding endpoint (Ollama, llama.cpp, LM Studio) and three surfaces accept either pure semantic search or BM25+vector fused via Reciprocal Rank Fusion: - **CLI:** `msgvault search "..." --mode vector` or `--mode hybrid` - **HTTP:** `GET /api/v1/search?q=...&mode=vector` or `mode=hybrid` - **MCP:** `semantic_search_messages` with `mode` set to `vector` or `hybrid` A separate MCP tool, `find_similar_messages`, returns nearest neighbors for a seed message. See the [Vector Search guide](https://msgvault.io/usage/vector-search/) for setup, backfill, and troubleshooting. > **Archive writes are daemon-owned.** CLI writer commands such as `msgvault sync-full`, `msgvault embeddings build`, `msgvault repair-dates --apply`, and `msgvault rebuild-fts` send their work to the configured remote server or local background daemon. The daemon serializes archive mutations and streams progress back to your terminal, so normal CLI ergonomics stay the same without opening a second SQLite writer process. Large archives can scope an embedding generation with `[vector.embed.scope] message_types = ["sms", "mms"]`. Scoped vector and hybrid searches must include a matching `message_type` filter so a partial index is never used as if it covered the whole archive. ## Importing from MBOX or Apple Mail Import email from providers that offer MBOX exports or from a local Apple Mail data directory: ```bash msgvault init-db msgvault import-mbox you@example.com /path/to/export.mbox msgvault import-mbox you@example.com /path/to/export.zip # zip of MBOX files msgvault import-emlx # auto-discover Apple Mail accounts msgvault import-emlx you@example.com ~/Library/Mail/V10 # explicit path ``` ### Import SMS Backup & Restore for Android (`synctech-sms`) Msgvault can import XML backups produced by **[SMS Backup & Restore](https://play.google.com/store/apps/details?id=com.riteshsahu.SMSBackupRestore)** by SyncTech Pty Ltd. The Android app is listed in Google Play as `SMS Backup & Restore` and uses package `com.riteshsahu.SMSBackupRestore`; the Pro app uses `com.riteshsahu.SMSBackupRestorePro`. Install the Android app on the phone that owns the messages, then configure a scheduled backup: 1. Open SMS Backup & Restore. 2. Choose **Set Up A Backup**. 3. Include **Messages**, **MMS media**, and **Call logs**. 4. Choose **Google Drive** as the backup location. 5. Use a dedicated Drive folder for Msgvault imports. 6. Choose **Incremental** backups for daily operation. Full and archive backups also import correctly, but incremental backups keep each daily upload smaller. 7. Schedule the Android backup for a quiet time such as `4:00 AM`. 8. Leave backup encryption off. Msgvault does not import encrypted Pro backups. Configure Msgvault to read that Drive folder: ```bash msgvault add-synctech-sms-drive pixel \ --owner-phone +15550000001 \ --folder-id 1exampleDriveFolderId \ --google-account you@gmail.com \ --schedule "30 4 * * *" ``` The folder ID is the final path segment in a Google Drive folder URL. For example, in `https://drive.google.com/drive/folders/1exampleDriveFolderId`, the folder ID is `1exampleDriveFolderId`. Run the source immediately: ```bash msgvault sync-synctech-sms pixel ``` You can also import local files, folders, or unencrypted ZIP backups: ```bash msgvault import-synctech-sms --owner-phone +15550000001 ~/Downloads/sms-backup.xml msgvault import-synctech-sms --owner-phone +15550000001 ~/Downloads/sms-backups/ msgvault import-synctech-sms --owner-phone +15550000001 ~/Downloads/sms-backup.zip ``` SMS and MMS messages appear in text-message search. Call logs are imported as searchable call records with `message_type = synctech_sms_call`, so missed and outgoing calls do not mix into normal text threads. ### Google Calendar Archive your calendars alongside email. Events become searchable (full-text and, when vector search is enabled, semantic) and join the same contact graph as your email, so organizers and attendees dedupe with the people you email. ```bash # Authorize read-only Calendar access and register your calendars. # If the account already has Gmail access, the consent screen asks for # Gmail + Calendar together — keep BOTH checked so Gmail access is kept. msgvault add-calendar you@gmail.com # First run does a full sync; later runs are incremental. msgvault sync-calendar you@gmail.com msgvault sync-calendar you@gmail.com --full # force a full re-sync msgvault sync-calendar you@gmail.com --all-calendars # include subscribed/holiday calendars # Find events msgvault search "standup" --message-type calendar_event ``` By default only calendars you own or can write to are synced (add `--all-calendars` for subscribed and holiday calendars). Calendar sync is read-only and never modifies your Google Calendar. Cancelled events are kept (marked cancelled), not deleted, so your archive preserves that a meeting once existed. The Calendar API must be enabled on your Google Cloud OAuth project. Msgvault stores Google OAuth refresh tokens under the Msgvault home directory with file permissions restricted to the current user. Tokens and client secrets are not written into `config.toml`, logs, README examples, or exported fixtures. ### Microsoft Teams Archive Microsoft Teams chats and channels through delegated Microsoft Graph sync. Teams uses the `[microsoft]` OAuth app config but stores a separate `teams_