FinDash
A Claude Code plugin for turning personal finance documents into an accurate SQLite-backed dashboard.
FinDash is a Claude Code plugin (findash) bundling a set of skills plus a small deterministic toolchain:
- Skills reason over messy real-world records — bank statements, payslips, brokerage screenshots, deposits, transfers, card charges.
- Scripts do the mechanics — parse files, update SQLite, fetch prices, render HTML, send to Telegram.
The core loop: drop source documents in a Google Drive vault → ask Claude to sync them into SQLite → render a self-contained dashboard. Telegram delivery and automatic bank/card fetch are both optional; the dashboard is always written locally as HTML.
[!NOTE] Built for Israel. FinDash ships tuned for Israeli personal finance: automatic fetch covers Bank Hapoalim and Cal (via
israeli-bank-scrapers), money reports in ₪ (ILS), the dashboard applies the 25% Israeli capital-gains tax to securities profit, and the schema models Israeli payslips (income tax, Bituach Leumi) and retirement vehicles (pension + training fund / קרן השתלמות). Dates parse as DD/MM and Hebrew/RTL text is handled throughout. Many docs, prompts, and examples assume this locale.Living elsewhere? Nothing is locked in — fork it and swap the locale-specific pieces. See Adapting to another country.
What It Does
How It Works
+----------------------+ +----------------------+
| Google Drive vault | | fetch-bank-data |
| dump/ (human drops: | | Hapoalim + Cal via |
| statements/PDF/XLSX) | | israeli-bank-scrapers|
+----------+-----------+ +----------+-----------+
| best-effort pull | local write
v v
+---------------------------------------------------------+
| inbox/staging/ (local handoff) |
| drive/<driveId>__file fetched/pairs |
+----------------------------+----------------------------+
| +-----------------+
v | fetch-investments|
+----------------------+ | IBKR connector |
| sync-finance-data | | (best-effort) |
| AI interpretation | +--------+---------+
| audited inserts | |
+----------+-----------+ |
| +-------------------+
v v
+----------------------+
| SQLite (truth) |----> weekly backup
| deterministic math | to Drive (best-effort)
+----------+-----------+
|
v
+----------------------+
| render dashboard |
| HTML + Telegram |
| (+ ⚠️ warnings) |
+----------------------+
fetch-bank-data stages fresh bank data locally — it never writes to Drive; Drive is your territory (manual drops) plus the weekly database backup. sync-finance-data pulls new Drive drops into staging (best-effort — Drive being down just becomes a ⚠️ Telegram warning), reasons through everything staged, inserts rows with source links into SQLite, deletes staged files after commit, and files your dump/ drops into their vault folders. render-finance-dashboard reads SQLite, fetches live prices/FX, fills the template, and writes one portable HTML file.
The dashboard is self-contained: CSS, fonts, Chart.js, chart data, and markup are inlined into output/dashboard.html.
The Skills
FinDash is operated through the plugin's namespaced skills. The two new entry points wrap the rest, so most days you only run one:
| Skill | Required? | What it does |
|---|---|---|
/findash:daily-run |
Entry point | Runs the whole morning flow end-to-end: fetch → IBKR (best-effort) → sync → render → deliver to Telegram. This is what the cron wrapper invokes. |
/findash:setup |
Entry point | Guided first-time onboarding: auto-fixes the safe pieces and walks you through the rest. |
/findash:sync-finance-data |
Yes | Gathers new Drive drops into local staging (best-effort), applies Claude's judgment to everything staged, writes audited rows into SQLite, and backs the database up to Drive weekly. |
/findash:render-finance-dashboard |
Yes | Renders output/dashboard.html from SQLite and optionally sends it to Telegram. |
/findash:fetch-bank-data |
Optional | Uses israeli-bank-scrapers to pull fresh Hapoalim and Cal data into local staging for sync. |
/findash:fetch-investments |
Optional | Ingests your Interactive Brokers trade history (plus a reconcile snapshot) into SQLite via the official IBKR connector. Attempted best-effort in the daily run; the connector authenticates only in hands-on sessions, so unattended runs skip it with a warning. |
/findash:findash-doctor |
Recommended | Audits local setup and auto-fixes safe missing pieces. |
Skills live in skills/ and the plugin manifest in .claude-plugin/. Claude Code loads them when you run claude --plugin-dir . from the repo root.
Privacy Model
This repo is designed so the public code can be shared while private financial state stays local or in your Drive vault.
Secrets live in a single local INI file, .secrets/findash (chmod 600), with one section per integration. Omit any section you don't use:
# .secrets/findash — chmod 600. Omit any section you don't use.
[drive]
root_folder_id=<from your vault folder's Drive URL: drive.google.com/drive/folders/<ID>>
[hapoalim]
user_code=<your hapoalim user code>
password=<your hapoalim password>
[cal]
username=<your cal username>
password=<your cal password>
[telegram]
bot_token=<from @BotFather>
chat_id=<your numeric id, from @userinfobot>
[pdf-passwords]
<payslip-filename-pattern>=<password>
rclone.conf stays a separate file — it is rclone's own OAuth config, passed via --config ./rclone.conf.
The committed docs use placeholders for account suffixes, card suffixes, Drive IDs, balances, transaction IDs, and example amounts. Concrete mappings belong in the private SQLite DB or source documents, not in git.
When you run the Claude skills, Claude reads the documents needed for the task. That is the point of the system: Claude supplies the judgment layer, while SQLite and scripts provide the audit trail and repeatable math.
Repo Map
.claude-plugin/ plugin + marketplace manifests
skills/ plugin skills: daily-run, setup, fetch, sync, render, doctor
docs/ project docs: schema, Drive layout, source document types
scripts/ mechanical parsers, scrapers, renderers, daily runner
templates/ dashboard shell, CSS, and chart code
.secrets/findash single local INI of credentials, gitignored
data/ local SQLite database, gitignored
inbox/staging/ local fetch→sync handoff (deleted after ingest), gitignored
output/ rendered dashboard, gitignored
Quickstart
For the full setup, read docs/setup.md. The short version:
- Install and authenticate Claude Code and the local tools:
qpdf --version # payslip PDFs
rclone version # Drive sync
node --version # bank fetch, needs >=22.13.0
python3 --version
sqlite3 --version
- Clone this repo and load the plugin from its root:
git clone https://github.com/ya5huk/findash.git
cd findash
claude --plugin-dir .
- Run the guided onboarding — it auto-fixes the safe pieces and walks you through the rest:
/findash:setup
-
Create
.secrets/findash(chmod 600) from the single block in Privacy Model. Omit any section you don't use.rclone.confstays separate; see Drive + rclone setup and Drive layout. -
Run the whole flow with one command:
/findash:daily-run
This fetches, syncs, renders, and delivers to Telegram. To run pieces by hand, use /findash:fetch-bank-data, /findash:fetch-investments, /findash:sync-finance-data, and /findash:render-finance-dashboard.
For unattended (cron/launchd) daily runs, schedule the wrapper — it loads the plugin and runs /findash:daily-run:
CLAUDE_BIN="$(command -v claude)" scripts/run_daily.sh
If you want unattended runs to fetch from Hapoalim or Cal, seed the browser profiles once before scheduling:
node scripts/fetch_bank.js --company=hapoalim --setup
node scripts/fetch_bank.js --company=visaCal --setup
In each browser window, log in, complete OTP/CAPTCHA, trust the device if
offered, wait for the account page, then press Enter in the terminal. If a bank
sends an OTP during a later unattended run, rerun the matching --setup
command; the run will continue with stale fetched data until the profile is
refreshed.
Install as a plugin (for others)
You don't have to clone to use FinDash. From any Claude Code session:
/plugin marketplace add ya5huk/findash
/plugin install findash@findash
Optional Integrations
- Telegram: sends
output/dashboard.htmlas a bot attachment. Without Telegram, rendering still writes the local dashboard. See Telegram setup. - Automatic bank/card fetch: pulls Hapoalim and Cal data through
israeli-bank-scrapers. Unattended fetch requires a one-time interactive--setupper source to seed trusted-device cookies. Without it, manually upload statements or exports into Drivedump/. See Bank fetch setup. - Password-protected payslips: requires
qpdfand a[pdf-passwords]section in.secrets/findash. Without it, skip payslip PDFs or add the passwords later. - Interactive Brokers: ingests your IBKR trade history onto a mapped account (so you stop screenshotting trades), plus a reconciliation snapshot, via Anthropic's official IBKR connector — added through Claude's connector directory, not findash config. The daily run attempts it best-effort; the connector authenticates only in hands-on sessions, so unattended runs skip it with a warning — run
/findash:fetch-investmentsby hand (then re-render) for fresh holdings any time. See IBKR setup.
Adapting to another country
FinDash is Israel-first, not Israel-only. The data model, scripts, and dashboard are generic; the locale-specific assumptions are concentrated in a handful of places, so a fork can re-point them without rewriting the core:
| Area | Where it's assumed | Swap it for |
|---|---|---|
| Banks / card fetch | scripts/fetch_bank.js, the [hapoalim]/[cal] secrets, and fetch-bank-data |
Your country's banks — israeli-bank-scrapers covers many Israeli institutions, or wire in another scraper/aggregator. |
| Capital-gains tax | ISRAELI_CAPGAINS_TAX = 0.25 in scripts/render_dashboard.py; the 25% dividend withholding in sync-finance-data |
Your jurisdiction's rate(s). |
| Base currency | BASE_CCY = "ILS" in scripts/render_dashboard.py; the USD/ILS & GBP/ILS FX pairs; en-IL number formatting |
Your reporting currency and FX pairs. |
| Payslips & retirement | docs/doc-types/payslips.md, long-term-savings.md, and the pension / training-fund columns in scripts/init-db.sql |
Your payroll deductions and retirement products (401(k)/IRA, ISA, etc.). |
| Dates & language | DD/MM ambiguity handling in scripts/xlsx_to_rows.py; Hebrew/RTL handling in the templates and renderer |
Your locale's date format and language. |
Most interpretation lives in the skills' prompts rather than hard-coded rules, so re-pointing those plus the constants above gets you most of the way. PRs that generalize these are welcome — see Contributing.
Docs
- Setup — Claude, rclone, Drive vault, Telegram, bank fetch, daily runs.
- Drive layout — vault folders and filename conventions.
- Document types — what each source document contains and how Claude should interpret it.
- SQLite schema — tables, money conventions, and audit rules.
- Design system — dashboard visual rules.
License
No open-source license is currently granted. All rights are reserved by the repository owner.
No comments yet
Be the first to share your take.