An insights engine for your Robinhood account that runs on your machine. It unifies everything Robinhood scatters — live positions, trade & options history, and monthly statements — into one report you can actually read and ask questions of: concentration, cost basis, holding period, realized long/short-term gains, premium income, wash-sale flags, and opportunities.
Robinhood keeps your data on three surfaces that never talk to each other — the UI (now), history (the past), statements (the record) — and none of them synthesize. So the insights you actually need are impossible to get without exporting CSVs and hand-stitching spreadsheets. Cairn does the stitching, on your machine.
Built in the open. Runs local-first — your credentials live only on your device, the connection is strictly read-only, and every line is auditable. MIT licensed.
⭐ If Cairn shows you something Robinhood couldn't, give it a star — it's the only way I know it's useful to someone.
git clone https://github.com/arunash/cairn.git && cd cairn
cp .env.example .env # add your Robinhood login — stays on this machine
pip install -r requirements.txt
python -m cairn report # builds web/report.html from your live account
open web/report.html # your insights, on one pageThen open the folder in Claude Code and just ask: "what should I do about my concentration?", "what's my tax situation?", "how much premium did I collect?"
You need nothing but a Robinhood login for the report. For the chat you need Claude Code (it's the brain). Everything runs locally.
Where does it open?
web/report.htmlis a plain file on your machine —openit (file://), or runpython -m cairn serveto build it and open it athttp://localhost:8787(bound to localhost only; add--port Nto change). There is no hosted portal — your data never leaves your machine.
Status — built in the open. The report spans all your accounts and is a full read: value, cash, every position with cost basis / unrealized P&L / holding period (LT vs ST), concentration (Herfindahl index), realized long- and short-term gains, options premium, dividends, and wash-sale candidates. Cost basis comes straight from Robinhood (already split- and transfer-adjusted); realized gains use a small bundled, local split table — no network.
python -m cairn taxesprints the tax view, and--account <id>limits any command to one account. Read-only throughout. Issues and PRs welcome.
| Layer | What it does | Runs on |
|---|---|---|
| 1 · Insights | The report — deterministic compute + render | Python, no LLM |
| 2 · Ask Cairn | Chat & advice, in the context of your whole account | Claude Code, read-only |
| 3 · Act & Steward | Places trades, runs the wheel, rolls, trims, watches | Claude Code + write tools, human-in-loop |
The safety line is structural: layers 1–2 only ever have read tools, so they physically cannot trade. Layer 3 unlocks the write tools and still approves every single order with you.
CLAUDE CODE (the brain, local) YOUR ROBINHOOD (your account)
┌───────────────────────────┐ read ┌────────────────────────────┐
│ CLAUDE.md = rules+guards │ ───────────► │ positions · quotes │
│ config/ledger.json = YOU │ ◄─────────── │ trade & options history │
│ broker/mcp.py = the gate │ write* │ monthly statements (PDF) │
└───────────────────────────┘ *Act only └────────────────────────────┘
│ runs
▼
cairn/ report ──► web/report.html python -m cairn report
compute/* · act/* · watch/* gains · premium · wheel · roll · trim · alerts
- Report (
python -m cairn report) pulls your live holdings read-only and renders the page — account value, unrealized P&L, concentration, and per-position cost basis & weight. - Compute holds the deterministic engines in
cairn/compute/: a FIFO lot engine (realized LT/ST gains, holding periods, wash-sale flags), positions & concentration, premium, cashflow (deposits + dividends), and the intent ledger (pool split, day-over-day). - Claude Code reads the report, answers questions in plain language, and — only in Act mode — executes with your approval.
- Local-first. Your Robinhood login sits in
.envon your machine. There is no Cairn server. - Read-only by default. Insights & chat never have trading permission.
- No outbound calls except to your Robinhood account and (for chat) your Claude.
- Disconnect anytime — delete the local session token and it's cut off instantly.
- Auditable — it's all here, MIT, nothing obfuscated.
cairn/
├── CLAUDE.md # the agent's behavior, YOUR rules, the hard guardrails
├── SECURITY.md # read-only-by-default model + secret handling
├── .mcp.json # Robinhood MCP wiring (read tools always; write gated to Act)
├── config/
│ └── ledger.example.json # intent-based pools + your rules (copy → ledger.json)
├── cairn/
│ ├── broker/mcp.py # the MCP gate — write tools registered only when CAIRN_ACT_ENABLED=1
│ ├── report/build.py # builds web/report.html (the insights page)
│ ├── compute/ # lots · realized · washsale · positions · premium · cashflow · ledger
│ ├── ingest/statements.py # monthly statement PDF → ACH cash-flow parse
│ ├── act/ # wheel · roll · reinvest · trim (human-in-loop)
│ └── watch/ # trim watcher · reminders (email alerts)
└── web/report.html # generated locally — your insights page (git-ignored)
Your personal data never belongs in the repo. Account IDs, cost basis, credentials, and generated output all live in git-ignored files only:
| File | What | Where it comes from |
|---|---|---|
.env |
your Robinhood login | copy .env.example |
config/ledger.json |
your accounts & pools | copy config/ledger.example.json |
web/report.html, config/daily-ledger.* |
generated output | created at runtime |
The tracked cairn/ modules ship with placeholders only — MARGIN_ACCT, IRA_ACCT,
<ticker>, BASIS = 0.0. Put your real values into config/ledger.json, never into the code.
Before you push, confirm git status shows none of the files above. See SECURITY.md.
MIT — do anything, no warranty. This is software, not financial advice. You run it, you own the decisions.