Local SQLite plus MCP means your bank CSVs land in a real database on your machine, and Claude Desktop or Cursor can import, categorize, query, and summarize that data through standard agent tools—without a bank link or a hosted finance vault.
If you have ever pasted a month of transactions into a chat window, you know the pattern: it works once, then the context vanishes. Spreadsheets are better for durability, but agents do not speak "cell range" fluently. The missing piece is a local database with a stable tool surface any MCP client can call.
This guide walks through that path end to end: install the es CLI, wire MCP into Claude or Cursor, import a CSV, run rules-based categorize, and ask your agent for monthly bookkeeping answers. Educational first—soft product links only where they help you finish the job.
What you will build
A monthly loop that looks like this:
- Export CSV from your bank or card portal (no bank login to a third party).
- Import into a local SQLite file via CLI or agent tools.
- Categorize with free rules (Local Pro optional for local NN + embeddings).
- Ask Claude or Cursor: spending by category, merchant outliers, month-over-month diffs.
- Export or summarize when you need a tax pack or a partner report.
Same engine whether you use the agent, the CLI, or the optional desktop shell. That is the point of Expense Sorted Local: one local DB, tools any agent can use.
Why not "just paste CSVs into Claude"?
Pasting works for a one-off "what did I spend on dining?" It fails as a system:
- No durable store. Chat history is not a ledger. Next month you re-paste and re-explain categories.
- No shared schema. Agents invent columns; your rules do not stick.
- No offline query path. You need the chat session every time you want a number.
- Privacy surface expands. Full statement text sits in the model provider's context window more often than necessary.
A local SQLite file plus MCP tools flips the default: the agent calls tools against your DB. You still choose what to ask; the system of record stays a file you can back up, inspect with sqlite3, or move between machines.
For the trust narrative behind local categorization, see Why we moved transaction categorization fully local. For Sheet vs Local trade-offs, see Local expense tracker vs Google Sheets template.
Prerequisites
| Requirement | Notes |
|---|
| macOS | Primary install path today: arm64 or x64 tarball. Match your chip. |
| Node.js 20 or 22 LTS | Required on PATH. Prefer the major used at tarball build time (releases target 22). |
| MCP client | Claude Desktop and/or Cursor. CLI works without either. |
| Bank CSV | Any standard export; multi-account is fine over time. |
Check Node:
node -v # expect v20.x or v22.x
Buyer-facing install hub: /local/get-started. Packaging and maintainer detail: the project's install runbook (macOS tarball, PATH, Gatekeeper notes).
Step 1 — Install the es CLI (macOS tarball)
Primary distribution is a platform tarball with prebuilt native modules—not a global npm install for everyday users.
- Download the matching asset from the latest GitHub Release, for example:
es-macos-arm64-<version>.tar.gz (Apple Silicon)
es-macos-x64-<version>.tar.gz (Intel)
- Extract to a permanent location:
mkdir -p ~/opt
tar -xzf ~/Downloads/es-macos-arm64-*.tar.gz -C ~/opt
# folder name looks like: es-macos-arm64-0.0.1
- Put
bin on your PATH (e.g. in ~/.zshrc):
export PATH="$HOME/opt/es-macos-arm64-0.0.1/bin:$PATH"
Or symlink a stable name:
ln -sfn "$HOME/opt/es-macos-arm64-0.0.1" "$HOME/opt/es"
export PATH="$HOME/opt/es/bin:$PATH"
- Reload the shell and verify:
hash -r
es help
If macOS quarantine blocks the extract (unsigned developer builds):
xattr -dr com.apple.quarantine ~/opt/es-macos-arm64-*
Expect es help to mention es mcp, es mcp --print-config, and license commands. Total primary path on a prepared Mac is usually under 15 minutes.
Step 2 — Print MCP config and paste into your client
es mcp --print-config
You get JSON shaped like:
{
"mcpServers": {
"expense-sorted": {
"command": "es",
"args": ["mcp"],
"env": {
"ES_DB": ""
}
}
}
}
Where to paste
| Client | Where |
|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json — merge under mcpServers |
| Cursor | Settings → MCP → add server from JSON |
Set ES_DB to an absolute SQLite path when you have one. Leaving it empty relies on discovery defaults; an explicit path is clearer for agents and multi-profile setups.
If es is not on the client process PATH, set "command" to the absolute path of bin/es:
"command": "/Users/YOU/opt/es/bin/es"
Restart Claude Desktop or Cursor after saving. Smoke from a terminal anytime:
es help
es mcp --print-config
--print-config should include "expense-sorted" under "mcpServers".
Step 3 — Point at a database
Resolution order (high level):
ES_DB environment variable (preferred)
- Desktop app profile under app data (
profiles.json)
- Fallback
~/.expensesorted/data.db
Example for a dedicated bookkeeping file:
export ES_DB="$HOME/Documents/expense-sorted/books.db"
MCP opens against the local engine and does not invent a missing DB for you in the MCP path—create or import data first via desktop, CLI import, or engine flows as documented on get-started.
Step 4 — Monthly bookkeeping with the agent
Once tools appear in Claude or Cursor, a practical first month looks like:
Import
Export last month's transactions from checking and cards. Ask the agent to import the CSV(s) into the local DB (or run the equivalent CLI import if you prefer terminal). Confirm row counts and date ranges before categorizing.
Categorize (free rules forever)
Run rules-based categorization on the new batch. Free Local includes rules forever. Fix a few misses; those corrections become durable rules over time.
Local Pro ($49 one-time lifetime) adds local NN categorize, embeddings, and semantic search—optional when rules are not enough. A 14-day Pro trial is available via email on /local (signed trial token; no card, no machine fingerprint).
Query and summarize
Useful prompts (word them as you like; the agent should use tools, not invent tables):
- "Summarize last month by category and top merchants."
- "What subscriptions charged more than $20?"
- "Compare dining this month vs last month."
- "List uncategorized transactions and suggest rules."
Export
When you need a tax folder or a shared report, export from the local store—still your file, still offline-capable for the data itself.
Free vs Local Pro (honest split)
| Tier | What you get |
|---|
| Free Local | Import, query, export, summarize, rules-based categorize, MCP install — forever free. No MiniLM / seed NN / personal vectors. |
| Local Pro | $49 one-time lifetime: local NN categorize, embeddings, semantic search. |
| Trial | 14-day Pro via email on /local. Not CLI self-mint. |
No monthly subscription is required for Local. Sheet add-ons, "$2/mo AI," and old bundle prices are not the Local hero path.
Privacy model in one paragraph
Transactions live in local SQLite on your hardware. Local product flows do not upload statements to Expense Sorted for storage or cloud AI categorize. You own the file: back it up, encrypt the volume, or keep it only on air-gapped machines if that is your bar. Your chat client may still send prompts to a model provider—keep statement dumps out of free-form chat when you can, and prefer tool-backed queries against the local DB.
For the longer privacy arc (CSV without bank linking → Local as end-state), read Expense tracker without bank linking.
Troubleshooting quick hits
Tools do not show in Claude/Cursor. Restart the client after config changes. Confirm JSON merges under mcpServers. Try absolute command path.
es not found. PATH only applies to shells that load your rc file; GUI apps often do not. Use the absolute path in MCP config.
Wrong or empty DB. Set absolute ES_DB in the MCP env block. Re-print config after you change defaults so you do not paste a stale snippet.
Gatekeeper warning. Clear quarantine with xattr as above; release tarballs may be unsigned developer builds until notarization lands.
Need a gentler start. Use the free Google Sheets template for a 3-minute lead path, then graduate to Local when you want a real DB and agent tools—see the Sheet vs Local comparison.
What success looks like after 30 days
- One SQLite file holds the months you care about.
- Claude or Cursor answers budget questions by querying, not by re-reading pasted CSVs.
- Category rules cover most merchants; you only touch exceptions.
- You can leave the network and still open the DB, run rules, and export.
That is private monthly bookkeeping with modern agents—without turning your bank login into someone else's product.
Next steps
- Install
es from the macOS tarball and run es mcp --print-config.
- Paste into Claude Desktop or Cursor; set absolute
ES_DB.
- Import one CSV, categorize with rules, ask for a monthly summary.
- When you want local NN and semantic search, start the 14-day Pro trial or buy Local Pro on Expense Sorted Local.
Related reading: Why local transaction categorization · Local vs Google Sheets template · Privacy-first tracking without bank linking.