Expense Sorted
Download · import CSV · categorize

Get started with the Expense Sorted app

Download the app. Drop in a bank CSV. Click Categorize. Your data stays on your computer.

If you paid for Sheets Pro or the Chrome extension, you already get Pro on the app. Check the email you bought with, or see /migrate.

Free forever for core tracking · Pro $49 lifetime for on-device AI

Data stays on your computerClassify on-devicemacOS & Windows

Prefer the product story first? Expense Sorted Local

1. Download the app

The Expense Sorted app is the default path — macOS and Windows. Open it, import a CSV, and categorize. Your data stays on your computer.

Expense Sorted app — desktop view on your computer

2. Import a bank CSV

Export a statement from your bank or broker. In the app, drag the file in (or choose Import). Map columns if asked. No bank login required.

CSV in, no bank link

  1. 1Download a statement CSV from your bank or broker portal.
  2. 2Drop it into the app. Map columns once if needed.
  3. 3Confirm the preview, then import.

3. Categorize

Click Categorize. Review suggestions and accept what looks right. Rules-based categorize is free forever. Pro adds on-device AI.

  • Click Categorize in the app.
  • Scan the suggestions — accept, edit, or skip.
  • Your transactions stay in a file on your computer.

4. Unlock Pro

Pro is on-device AI categorize — not a new product. Paste your key in the app under Settings → License.

Already paid for Sheets Pro?

If you paid for Sheets Pro or the Chrome extension, you already get Pro on the app. Check the email you bought with, or see /migrate.

Complimentary Pro details

New here? Trial or $49

Start a 14-day Pro trial (email, no card) or buy Pro for $49 lifetime.

Advanced

Command-line install and connecting an AI helper after the app works. Most people never need these steps.

Install es (macOS)

Primary CLI path is a macOS tarball from GitHub Releases with a prebuilt native SQLite binding. Put es on your PATH.

  1. Install Node.js 20 or 22 LTS (required on PATH). Prefer matching the Node major used when the tarball was built (releases target 22). nodejs.org
  2. Download the asset for your Mac from GitHub Releases: es-macos-arm64-*.tar.gz (Apple Silicon) or es-macos-x64-*.tar.gz (Intel).
  3. Extract and add bin to PATH, then verify:
mkdir -p ~/opt
tar -xzf ~/Downloads/es-macos-arm64-*.tar.gz -C ~/opt
# folder name looks like: es-macos-arm64-0.0.1
export PATH="$HOME/opt/es-macos-arm64-0.0.1/bin:$PATH"
# or symlink: ln -sfn "$HOME/opt/es-macos-arm64-0.0.1" "$HOME/opt/es"
#            export PATH="$HOME/opt/es/bin:$PATH"
hash -r
es help

Deep packaging, signing, monorepo build, and smoke helpers: docs/INSTALL_LOCAL.md on GitHub (maintainer SoT — not required for the app path above).

The desktop app is the default path — download from the product page. Windows CLI tarball is not the primary path yet.

Activate license / trial (CLI)

Prefer the app: Settings → License. Trial and purchase keys are emailed to you (signed tokens). There is no machine fingerprint and no phone-home for your transactions. CLI does not self-mint licenses.

  • Desktop: paste the key when prompted, or open Settings → License.
  • CLI: run es doctor first — it shows which database was discovered and your license tier. If you are on Free, es license activate applies Pro in one step: it reuses your Desktop sign-in when present, syncs entitled cloud accounts, or prints the next step.

Advanced: paste key / manual sync

Prefer es license activate. Use these only when you want to paste a key directly or sync manually — ES_DB is only needed to force a specific database.

export ES_DB="$HOME/Library/Application Support/com.fstrauf.expensedesktop/expensedesktop.db"   # advanced: only to force a specific DB
es license set 'YOUR_KEY_HERE'

# Existing Desktop / Sheets / AI customers (API key):
export ES_API_KEY='your-desktop-api-key'
es license sync

Already a cloud customer? es license activate auto-discovers your Desktop API key and syncs. Need a trial? Start 14-day free Pro trial on the product page (email mint). Buy Local Pro lifetime from pricing.

Prepare local AI (Pro)

Local Pro categorize and semantic search need a one-time MiniLM model on disk (~23MB under ~/.expensesorted/models/). Free skips this and stays rules-only. License alone does not download the model.

Skip the ES_DB line below unless you need to force a specific database — discovery finds the Desktop profile DB on its own.

export ES_DB="$HOME/Library/Application Support/com.fstrauf.expensedesktop/expensedesktop.db"   # only to force a specific DB
es doctor              # should say Next: es embed setup when Pro + model missing
es embed setup         # download/warm model once
es embed backfill      # optional: vectorize existing history for personal NN
es doctor              # green: Local Pro AI ready

After setup, restart MCP clients so long-lived es mcp processes see the model. Use es embed setup --backfill to warm and backfill in one step.

MCP config

Print a Claude Desktop / Cursor snippet and paste it into your client. Leave ES_DB empty and the engine discovers your Desktop profile database automatically. Set an absolute SQLite path only for multi-DB or non-Desktop setups.

es mcp --print-config

Example shape (discovery — ES_DB empty):

{
  "mcpServers": {
    "expense-sorted": {
      "command": "es",
      "args": ["mcp"],
      "env": {
        "ES_DB": ""
      }
    }
  }
}

Claude Desktop — merge under mcpServers in ~/Library/Application Support/Claude/claude_desktop_config.json

Cursor — Settings → MCP → add server from JSON

Desktop profile DB (macOS example): ~/Library/Application Support/com.fstrauf.expensedesktop/expensedesktop.db

If es is not on the client's PATH, set command to the absolute path of bin/es. Restart the client after saving.

Windows (Desktop installed): skip the CLI paste. Open Expense Sorted → Settings → Connect Claude. That writes Claude Desktop config against the app-bundled engine and your profile database.

First workflow (MCP tools)

Honest cold path against your local DB. Import and categorize default to dry-run (apply: false) until you confirm.

  1. 1

    es_status

    Confirm DB path, counts, and license tier.

  2. 2

    es_import_csv

    Import a bank CSV (path or text). Start with apply: false (dry-run), then apply: true when the mapping looks right.

  3. 3

    es_categorize

    Suggest categories. Start with apply: false; Free uses rules-only; Pro uses local NN after es embed setup (not rules fallback).

  4. 4

    es_accept_categories

    After review, write accepted category updates (clears needs_review).

  5. 5

    es_summarize / es_query

    Totals by category/month, or filter transactions — no free-form SQL.

Default: use the Desktop app for import and categorize on the same file — no MCP required.

Free vs Pro

Free Local

Import, query, export, summarize, rules-based categorize, MCP install — forever free. No MiniLM / seed NN / personal vectors.

Local Pro — $49 lifetime

One-time: local NN categorize, embeddings, semantic search after es embed setup. Trial = 14-day Pro via email mint on /local.

Privacy

Transactions live in local SQLite. Local product flows do not upload statements to Expense Sorted for cloud classify — categorization stays on-device.

Troubleshooting

  • Gatekeeper / quarantine blocks extract

    Unsigned builds may be quarantined. Clear with xattr -dr com.apple.quarantine ~/opt/es-macos-*

  • DB_NOT_FOUND / wrong database

    MCP and es license set do not create a missing DB — open Desktop once or import data first. Run es doctor to see which path was discovered. Set an absolute ES_DB only when you need to force a different DB. Discovery: ES_DB → desktop profile → ~/.expensesorted/data.db.

  • DB_BUSY

    Another process holds a write lock (Desktop, another es mcp, daemon). Close the other writer or retry shortly.

  • EMBEDDING_MODEL_MISSING / rules-only on Pro

    Pro is a license flag; local NN needs MiniLM on disk. Run es doctor then es embed setup. Restart MCP after setup. Free stays rules-only by design.

  • MCP client cannot find es

    Set command in MCP JSON to the absolute path of bin/es, not only the bare name.

  • Still Free after pasting a key

    The key is stored even when verify fails (typo, wrong product, expired trial). Check es license set output for tier/verify, confirm the same ES_DB, and re-copy the full token from email.

Still stuck? Support · packaging depth: INSTALL_LOCAL.md

Ready for Pro?

Free rules forever. Unlock on-device AI categorize with a one-time $49 license — or try Pro for 14 days.