AI-powered email archive viewer with native RAG pipeline, multi-format import, and semantic search.
MBox Explorer parses MBOX, EML, EMLX, MSG, and Gmail Takeout archives into a searchable, threaded interface with a built-in retrieval-augmented generation pipeline for natural language queries against your email history. All AI processing runs locally via Ollama or MLX -- no data leaves your machine unless you opt into a cloud provider.
Written by Jordan Koch.
graph TD
subgraph Import
A[MBOX / EML / EMLX / MSG / Gmail Takeout] --> B[MultiFormatImporter]
B --> C[MboxParser]
end
subgraph Core
C --> D[MboxViewModel]
D --> E[Email Model]
D --> F[Thread Detection]
D --> G[SmartFilters]
end
subgraph RAG["RAG Pipeline"]
H[User Query] --> I[Question Router]
I --> J{Search Strategy}
J -->|Semantic| K[EmbeddingManager]
J -->|Keyword| L[FTS5 Full-Text Search]
J -->|Fallback| M[Direct Text Match]
K --> N[VectorDatabase SQLite]
L --> N
M --> O[In-Memory Scan]
N --> P[Context Augmentation]
O --> P
P --> Q[LLM Generation]
Q --> R[Response + Source Citations]
end
subgraph Backends["AI Backends"]
Q --> S[Ollama]
Q --> T[MLX]
Q --> U[TinyChat / TinyLLM]
Q --> V[Cloud: OpenAI / Azure / AWS / GCP / IBM]
end
subgraph Export
D --> W[ExportEngine]
W --> X[CSV / JSON / Markdown / TXT]
end
subgraph Widget["macOS Widget"]
D --> Y[SharedDataManager]
Y --> Z[WidgetKit S/M/L]
end
| Capability | Details |
|---|---|
| Supported formats | MBOX, EML, EMLX, Outlook MSG, Gmail Takeout ZIP |
| Streaming parser | Reads the file line-by-line and emits one email per From boundary — peak memory ~one message, not the whole archive. Honors mbox >From quoting. |
| Persistent parse cache | Parsed mailboxes are cached (keyed by path + size + mtime); reopening an unchanged archive is near-instant instead of re-parsing the whole file. Editing/replacing the file invalidates the cache. |
| Thread detection | Groups emails by Message-ID / In-Reply-To / References |
| Smart filters | Filter by sender, domain, date range, size, attachments |
| Duplicate finder | Identifies duplicate messages across archives |
| Regex search | Pattern-based search across bodies and headers |
| Attachment browser | Browse, preview, and export attachments |
| PII redaction | Redact personal information before export |
| Mailbox merger | Combine multiple archives into one |
| Tags and collections | Organize emails with custom tags |
| Command palette | Quick access to all actions |
| Component | Implementation |
|---|---|
| Vector database | SQLite + FTS5 full-text search + float-array embeddings |
| Search strategy | Three-tier fallback: semantic, FTS5 keyword, direct text match |
| Question routing | Auto-detects query type (statistics, content, summary, follow-up) |
| Conversation memory | Maintains context across follow-ups (configurable history) |
| Source citations | Every response shows which emails were used |
| Temperature controls | Separate for Q&A (0.2), summary (0.3), creative (0.7) |
| Debug panel | Inspect the full prompt sent to the LLM |
| Export conversations | Save Q&A sessions as Markdown or JSON |
| Provider | Type | Setup |
|---|---|---|
| Ollama | Local, free | brew install ollama && ollama pull nomic-embed-text |
| MLX | Local, free | Built-in (Apple Silicon only) |
| OpenAI | Cloud, paid | API key in Settings |
| Sentence Transformers | Local, free | pip install sentence-transformers |
| TinyChat | Local, free | OpenAI-compatible API on localhost |
| OpenWebUI | Self-hosted | Web UI with embeddings |
- Email and thread summarization via Ollama/MLX
- Sentiment dashboard (NaturalLanguage framework)
- Smart reply suggestions with tone options
- Meeting/event extraction (EventKit integration)
- Topic clustering
- Communication relationship mapping
- Phishing/threat detection
- Action item extraction
- Person profile generation from email history
- Daily briefing engine
MBox Explorer can spread AI work across every model available on your machine at once instead of pinning everything to a single backend. Three independent toggles in AI Settings compose the balancer pool:
| Toggle | Pool contribution |
|---|---|
| All local models | Every Ollama model + locally-installed MLX models |
| All frontier models | OpenRouter (bring-your-own-key, stored in the Keychain) |
| Nova Gateway (optional) | One OpenAI-compatible backend at 127.0.0.1:18792 |
A pure, network-free LoadBalancer spreads requests across the healthy pool using a
round-robin or least-busy policy, and unhealthy backends are gated out automatically.
Nova is never required. With zero Nova the app still balances across local Ollama/MLX and (if a key is set) OpenRouter. A failed Nova health check simply drops the gateway from the pool and the toggle reads "unavailable" — everything else keeps working. There is no hard dependency on Nova, PostgreSQL, or the gateway.
graph TD
subgraph Toggles["AI Settings — three toggles"]
T1[All local models]
T2[All frontier models]
T3["Nova Gateway (optional)"]
end
subgraph Discovery["ModelRegistry (pure)"]
T1 --> O[Ollama /api/tags]
T1 --> X[MLX HF-cache scan]
T2 --> R[OpenRouter models]
T3 --> NG[Nova Gateway model]
O --> P[assemblePool -> DiscoveredModel pool]
X --> P
R --> P
NG --> P
end
subgraph Balance["LoadBalancer (pure, network-free)"]
P --> HG[Health-gate unhealthy backends]
HG --> LB{round-robin / least-busy}
end
LB --> S[Email Summarization]
LB --> IDX[Bulk semantic indexing]
S -.->|no backend| SF[Basic extractive summary]
IDX -.->|no backend| KW[Keyword-only, resume-safe]
A Summarize action in the email detail toolbar sends the selected email (or thread)
through the balanced model pool and shows a concise 2-3 sentence summary. The request
construction lives in a pure, unit-tested SummarizationRequest builder, and dispatch
degrades gracefully in three tiers:
- Balanced pool — when any load-balancing toggle is on and a model is reachable.
- Single active backend — the app's existing Ollama/MLX/etc. selection.
- Basic extraction — a network-free extractive summary with a clear reason banner, so the feature is never a crash and never a dead end.
Bulk semantic indexing can also route through the balancer: selecting the
"Balanced (All Local Models)" embedding provider fans indexing work out across every
local Ollama model via the same LoadBalancer. Resumability is untouched —
VectorDatabase.pendingEmails(...) still drives the resumable work set, so a cancelled or
partial index picks up exactly where it left off.
The pure balancer core (
ModelRegistry,LoadBalancer,OpenRouterProvider,OpenAICompatibleRequest,KeychainStore) is shared verbatim with the AIStudio app.
| Format | Options |
|---|---|
| File formats | TXT, CSV, JSON, Markdown |
| Export modes | Per-email, per-thread, or both |
| AI-optimized export | Chunked text with metadata for downstream pipelines |
| Contact exporter | vCard, CSV, or Address Book |
| Spotlight | Emails indexed in macOS system search |
| Quick Look | Space bar preview (native macOS) |
| Notifications | Follow-up reminders via Notification Center |
- Statistics dashboard (Swift Charts)
- Communication network graph
- Timeline view
- Activity heatmap
- Word cloud
- Email diff (side-by-side comparison)
| Size | Content |
|---|---|
| Small | Email count, loaded file name |
| Medium | Stats + top 3 senders |
| Large | Stats + senders + recent searches + quick search |
Data syncs via App Group group.com.jkoch.mboxexplorer.
Local HTTP API on port 37434 (loopback only).
curl http://127.0.0.1:37434/api/status # App status + uptime
curl http://127.0.0.1:37434/api/ping # Health check- macOS 13.0 (Ventura) or later
- For AI features: Ollama (
brew install ollama) or MLX on Apple Silicon - Cloud providers are optional -- fully functional with local backends
- Download the latest
.dmgfrom Releases. - Open it and drag MBox Explorer into your Applications folder.
- Launch it from Applications. That's it — no Xcode, no toolchains, nothing else to install.
See "MBox Explorer can't be opened because the developer cannot be verified"? That means you have a build that isn't yet Developer-ID-signed and notarized. To open it anyway:
- macOS 14 and earlier: Control-click (right-click) the app → Open → Open.
- macOS 15 (Sequoia) / 26 and later: double-click it, dismiss the dialog, then open System Settings → Privacy & Security, scroll down, and click Open Anyway.
- Or from Terminal:
xattr -dr com.apple.quarantine "/Applications/MBox Explorer.app"Notarized releases open with no prompt at all — maintainers, see RELEASE.md.
Requires Xcode 16 or later. Because the app bundles MLX for on-device LLM inference, the build compiles Metal GPU shaders, which needs Apple's Metal Toolchain — a component Xcode 16 no longer ships by default. Install it once:
xcodebuild -downloadComponent MetalToolchain
# (or in Xcode: Settings → Components → Metal Toolchain → Get)Then build:
git clone git@github.com:kochj23/MBox-Explorer.git
cd MBox-Explorer
open "MBox Explorer.xcodeproj" # Xcode resolves Swift packages on first open (MLX, swift-transformers, …)
# Build & run: Cmd+RSkipping the Metal Toolchain step produces a wall of
CompileMetalFile … cannot execute tool 'metal' due to missing Metal Toolchainerrors from themlx-swiftdependency. That's the missing component, not a problem with the project.
- Launch MBox Explorer
- Open an archive (File > Open -- supports MBOX, EML, EMLX, MSG, Gmail Takeout)
- Browse in list, timeline, heatmap, or network view
- Click "Ask AI" in the sidebar for natural language queries
- Optionally click "Index Emails" for semantic search via embeddings
106+ tests covering parsing, export, AI pipeline, view model logic, and security — including
MailboxCacheTests (7 categories: unit, integration, regression against the re-parse bug, performance,
edge cases, security, and a UI/smoke test of the reopen flow).
xcodebuild -scheme "MBox Explorer" -destination "platform=macOS" test- Local-first: Ollama and MLX run entirely on your Mac
- SQL injection prevention: all database queries use parameterized bindings
- Keychain storage: API keys stored in macOS Keychain via Security framework
- Ethical AI Guardian: monitors all AI input/output for policy compliance
- No telemetry: zero analytics, tracking, or phone-home behavior
MIT License -- Copyright 2026 Jordan Koch
See LICENSE for the full text.
Written by Jordan Koch (@kochj23)