Storm-triggered lead engine
StormLead
Four autonomous LangGraph pipelines that turn storms across 10 metros into outreach, replies and booked inspections, with a person approving every email before it sends.

Problem
After a storm, the roofing companies that reach affected customers first get the work. Doing that by hand means watching the weather in many cities, writing outreach to the right customers, keeping up with replies and booking inspections before the moment passes.
Constraints
What made it hard.
- Outreach goes to real customers in the company’s name, so no email can send without a person approving it.
- A pipeline paused for approval must survive a closed terminal or a restart and resume exactly where it stopped.
- Four stages run on their own schedules, so every handoff has to be unambiguous without any stage calling another.
- Only opted-in customers may ever be contacted.
- Operators need to see everything the agents do without being able to change it.
Solution
StormLead is four independent LangGraph pipelines that share one Postgres database as their coordination point, one scheduler that runs them unattended, and a read-only operations dashboard over the whole thing.
Autonomy stops where the company’s reputation starts. Every outreach email waits at a human-review gate built with LangGraph’s interrupt() and Postgres checkpointing. It is the one deliberate manual step in an otherwise automated pipeline.
Lead find, daily at 08:00
- System: Check storms per city
- Code: Find opted-in customers
- Model output: Draft personalised outreach
- Human decision: Approve, reject or rewrite
- System: Send email
Reply triage, every 30 min
- System: Read new Gmail replies
- Model output: Classify the reply
- Code: Send a Calendly link
Booking notify, hourly
- System: Check Calendly for bookings
- System: Alert the team in Slack
Close stale, daily at 08:30
- Code: Close leads silent for 7 days
Stages hand off only by writing a status to the tracking table in PostgreSQL. Simplified diagram.
The read-only operations dashboard shows the whole system from the same Postgres database the agents write to.





The dashboard has six views in all: overview, leads, pipeline, cities and weather, bookings, and the review queue. Light and dark themes are both built in.
Technology and why
- LangGraph
- interrupt() pauses a run at the human-review node, and the Postgres checkpointer lets it resume later from the same state.
- MCP
- A custom stdio MCP server wraps OpenWeather, and hosted Klavis MCP servers handle Gmail and Slack.
- Composio
- Calendly is reached through Composio’s Tool Router, driven by a small ReAct agent with a 90-second timeout and a 12-step limit so a stuck call fails fast.
- OpenAI
- Drafts and rewrites outreach, classifies replies and runs the Calendly tool-router agent.
- PostgreSQL
- Holds customers, the tracking table whose status column is the handoff between stages, and every LangGraph checkpoint.
- React and FastAPI
- The operations dashboard. Its connection pool sets default_transaction_read_only, so Postgres itself refuses any write.
- LangSmith
- Traces every graph run, so drafts and classifications can be inspected after the fact.
Hard problems
Human approval in an autonomous system
After drafting, the graph hits interrupt() and genuinely pauses, checkpointed to Postgres. A person approves, rejects or asks for a rewrite with feedback for every draft. Scheduled runs that pause are logged to a pending-review table and resolved later with one command.
Handoffs without tight coupling
Stages never call each other. Each writes a status (awaiting reply, interested, booked, no response) and the next stage polls for it, so each runs on its own cadence without holding state about the others.
A dashboard that cannot break anything
The dashboard is read-only by construction. Postgres refuses writes from its connection pool, so the safety does not depend on the UI behaving.
Long-running process, one set of connections
The scheduler builds the MCP client, every tool and the checkpointer once at startup and reuses them, rather than opening a new Calendly session and database connection on every 30-minute tick.
Results
- Autonomous LangGraph pipelines
- 4
- Metros monitored for storms
- 10
- Views in the read-only ops dashboard
- 6
- Seeded customers in end-to-end testing
- 400
Model and evaluation
- Model
- OpenAI models for drafting, rewriting, reply classification and the Calendly tool-router agent.
- Evaluation
- Tested end to end on 400 seeded customers, with every graph run traced in LangSmith.