Skip to content

Legoless/spark-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spark-cli

A read-only command-line reader for Spark Desktop's local mail cache on macOS. Lists, reads, and searches the mail that Spark has already synced to your machine — without touching the Spark app, IMAP, or the network.

Read-only. Every database handle is opened with readonly: true. This tool never writes to Spark's data.

Why

Spark Desktop stores your mail unencrypted in a handful of SQLite databases under ~/Library/Application Support/Spark Desktop/core-data/. When Spark is already running and has synced your inbox, you don't need IMAP credentials or OAuth to read that mail — you just need to query those databases. This CLI does exactly that.

Requirements

  • macOS with Spark Desktop installed and signed in at least once (so the local cache exists).
  • Node.js 20+ (developed against Node 24).

Install

git clone https://github.com/Legoless/spark-cli.git
cd spark-cli
npm install
npm run build

# Optional: put `spark` on your PATH
npm link

Usage

spark list     [-n <count>] [-u] [-a <accountPk>]
spark read     <pk> [--html | --raw | -H]
spark search   <query> [-n <count>]
spark accounts

List recent inbox mail

spark list -n 10
#   pk    date              from                               subject
# ● 6238  2026-04-19 12:55  App Store Connect <no_reply@ema…   Version 1.0 (2) …
#   6230  2026-04-19 11:02  Google Search Console Team <sc-…   Congrats on 90K …

marks unread. -u filters to unread only, -a <pk> filters by account (see spark accounts for pks).

Read a message

spark read 6238            # rendered plain text (HTML → text)
spark read 6238 --html     # raw HTML body
spark read 6238 --raw      # raw RFC822 source, if cached
spark read 6238 -H         # headers only

Search

Simple LIKE search across subject, sender, and the short-body preview:

spark search "iOS Dev Weekly"
spark search invoice -n 5

Accounts

spark accounts
# 1    Personal       Dal
# 2    Work           Dal Rupnik

How it works

Spark's local cache is a handful of SQLite files:

File Tables used What's in it
messages.sqlite messages, accounts Per-message metadata: from/to/subject/date/flags/shortBody
cache.sqlite messageBodyHtml, messageImapData HTML body (plain BLOB) and raw RFC822 source

Join key: messages.pk = messageBodyHtml.messagePk = messageImapData.messagePk.

No decryption, decompression, or reverse engineering — the BLOBs are plain UTF-8. All queries go through better-sqlite3 with readonly: true, and the CLI never calls writefile, PRAGMA writable_schema, or any statement that could mutate state.

Caveats

  • Only the mail Spark has synced locally is readable. Messages beyond Spark's sync window still live on your IMAP server.
  • cache.sqlite is LRU — old bodies can be evicted even while metadata in messages.sqlite remains. In that case spark read <pk> will say (no body cached locally).
  • Schema names come from Spark's own code and may change in future versions. If a Spark update breaks this tool, the fix is usually a one-liner.
  • macOS-only. Spark stores data in the same shape on other platforms, but the default paths differ and aren't hardcoded here.

Development

npm install
npm run build     # tsc → dist/
node dist/index.js list

Single-file CLI in src/index.ts. Keep it that way.

License

MIT

About

Read-only CLI for Spark Desktop's local mail cache on macOS — list, read, and search already-synced mail without IMAP or OAuth.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors