Meredith's List

MVP Live Python / Flask / SQLite / Claude / Pandas claude ai real-estate https://app.meredithslist.click ↗

An AI-powered lead system for real estate — reads your contacts, ranks who’s worth calling today, drafts the message in your voice. You just approve.

Meredith’s List — landing page

The problem

A successful agent accumulates hundreds of contacts over a few good years. Buyers who asked about a house once, sellers who aren’t ready yet, referrals from three years ago who might be ready now. Knowing which 12 out of 247 are worth a call today stops being intuition and becomes arithmetic — and the arithmetic stopped being human-scale a long time ago.

The system I needed didn’t exist. Not a CRM with a dashboard. A system that does the prep — reads the export, scores the contacts, writes the message the way I’d write it — and then stops and waits for me to say yes.

Core feature: AI buyer matrix

Claude Opus 5, routed through OpenRouter with Anthropic native fallback, reads the listing details and buyer profile and drafts a personalized message in the agent’s voice. Tone controls — Brief Low Pressure, Casual, Professional, Warm. Channel selection between email and SMS. Property mentions pulled from active listings. The whole thing lands in about three to five seconds.

Nothing sends without the agent clicking confirm. That’s not a setting. There is no bulk-send toggle, no scheduled autopilot, no way to turn it off.

AI draft modal — tone, channel, and property controls with a generated message ready for review

Trust centre

Every message that has ever left this system is logged — intended recipient, actual recipient, send mode, message ID. The rows are append-only. Nothing in the interface can delete or rewrite them.

Three modes: DEV redirects everything to the operator, MIRROR sends to the real recipient and copies the operator, LIVE sends clean. The trust centre shows exactly which mode was active for every message, so the system can prove what it sent and to whom.

Trust centre — append-only audit log with intended vs actual recipients and send modes

Deal commission board

A kanban pipeline — Hot, Nurture, Long Hold, Annual, Protected — with estimated commission per column. The Protected column is for deliberate decisions the pipeline never overwrites: contacts you’ve moved there stay there regardless of what the scoring model thinks.

Commission board — kanban pipeline with estimated commission totals per stage

Dashboard

Scored lead cards with a “Why now” explanation in plain language. Each card shows the score, estimated commission, location, available channels, and three actions: Draft, Snooze, Done. The rest of the queue sits below, ranked, with one-line summaries.

Dashboard — scored lead cards with Why now explanations and Draft/Snooze/Done actions

Build context

Idea to MVP in roughly one to two sprints. The whole thing is specific enough that the architecture fell out of the problem: ingest a CSV, normalize it, score it, draft against it, log the send. The pipeline is DataFrame-in, DataFrame-out end to end — pandas does the heavy lifting, Claude does the language.

Technical details

BackendPython 3.11+, Flask, pandas
StorageSQLite (WAL mode), no ORM
LLMClaude Opus 5 via OpenRouter
FrontendVanilla ES modules + CSS, no bundler
DeployDocker Compose (4 services), Gunicorn + Caddy
CIGitea Actions → AWS SSM (no SSH keys)
EmailAmazon SES
Botdiscord.py

AI does the prep. The human holds the trigger.