Skip to content

Repository files navigation

Cairn

license: MIT Python local-first PRs welcome

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.


Quick start

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 page

Then 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.html is a plain file on your machine — open it (file://), or run python -m cairn serve to build it and open it at http://localhost:8787 (bound to localhost only; add --port N to 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 taxes prints the tax view, and --account <id> limits any command to one account. Read-only throughout. Issues and PRs welcome.


The three layers — all free, all local

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.

How it works

   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.

Security

  • Local-first. Your Robinhood login sits in .env on 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.

Repo structure

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)

Keeping your fork clean

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 onlyMARGIN_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.

License

MIT — do anything, no warranty. This is software, not financial advice. You run it, you own the decisions.

About

A local, read-only-by-default insights engine for your own Robinhood account — a shell on the Robinhood agent (MCP), run locally via Claude Code. Open source, MIT.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages