I used to hate cold email. Not the receiving of it — I could filter that with Gmail rules. I hated sending it. The whole process felt like assembly line work with zero feedback loop.
You'd spend hours crafting the perfect template, find a list of prospects, send 200 emails, and then... wait. For weeks. With no idea if anyone even opened them.
So I built something better.
What It Does
The cold-email-agent-system (running at posti.arvobitti.fi) is a full-stack B2B outreach machine. It does four things:
- Discovers your client — Give it a website and the AI analyzes the business, identifies their ideal customer profile (ICP), figures out their pain points and messaging.
- Finds leads — Uses Google Maps, Firecrawl, and Perplexity to find prospects that match the ICP. Companies in the right industry, right location, right size.
- Generates personalized email sequences — Not just "Hi {{first_name}}" personalization. Real personalization. References their specific business, recent news, their actual pain points.
- Tracks everything in real-time — Sends WebSocket updates when replies come in. Shows you exactly which emails got responses, which bounced, who's engaged.
The whole thing runs on a monorepo with a React frontend, Express backend, and an AI agent layer using Vercel AI SDK + DeepSeek. Data lives in Turso (SQLite-backed distributed database). Email goes through either Resend or plain SMTP.
Why I Built It
Here's the thing about cold email tools: they're all either:
- Too simple — You write the emails, you pick the list, you send. The tool just handles the plumbing.
- Too black box — AI writes everything, you have no idea what's happening, and the results are mediocre.
I wanted something where the AI does the heavy lifting but you still have control. The ICP isn't generated by magic — you see it, you can refine it. The email sequences aren't auto-generated garbage — they're based on actual analysis of the prospect's website and business context.
Also, I was tired of the feedback loop being weeks long. With real-time IMAP monitoring, you know within minutes when someone replies. That changes how you iterate.
The Tech Stack (For Fellow Devs)
- Frontend: React 18 + Vite + Tailwind + Zustand + TanStack Query. Socket.io client for real-time updates.
- Backend: Express + TypeScript. WebSocket server via Socket.io.
- AI Layer: Vercel AI SDK orchestrating DeepSeek calls. Python scripts for Google Maps scraping, Firecrawl crawling, Perplexity research.
- Database: Turso (libSQL). One database per client for isolation.
- Email: Resend for sending, IMAP for response monitoring.
- Deployment: Docker containers on Dokploy. GitHub Actions for CI/CD — push to main, images build and deploy automatically.
- Auth: Stack Auth for user management with role-based access (Admin, Editor, Viewer).
The whole thing is a pnpm monorepo with workspace packages for @cold-outreach/agent, @cold-outreach/shared, apps/backend, and apps/frontend.
What I Learned
Building a production AI pipeline is different from building a prototype. A few things that bit me:
Rate limits are real. Google Maps throttles hard. Perplexity costs money per query. DeepSeek has context windows. The system needs queue management and retry logic from day one, not as an afterthought.
IMAP monitoring is janky. Gmail in particular is its own beast with app passwords and IMAP IDLE being... optimistic. The monitor needs to handle disconnections gracefully.
User control vs. automation tension. Every "smart" feature needs a manual override. The ICP editor lets you tweak every parameter. The email sequences show you exactly what the AI generated before they go out.
Who's It For
Right now it's being used by a couple of B2B service companies in Finland. One does industrial cleaning, the other does marketing services. Both are using it to reach small-to-medium businesses in their vertical.
The workflow is: sign in, paste your website URL, wait 5 minutes while the AI analyzes your business and builds an ICP, approve or refine it, let the system find leads, review the email sequences, hit send.
It's not for everyone. If you want to blast 10,000 emails to a bought list, this isn't your tool. If you want to actually understand your ICP and send targeted, personalized outreach at scale — it works.
What's Next
The core system is done. Next up: better analytics, A/B testing for email variants, and possibly multi-channel (LinkedIn DMs alongside email). Also need to write better documentation — right now the README is 80% deployment instructions because that's where everyone gets stuck.
The code is on GitHub. If you want to poke around or contribute: github.com/jaakjuu1/cold-email-agent-system.
Juuso Jaakkola is a Finnish developer who keeps building tools to automate the boring parts of business. This post was written because someone asked "why did you build that thing" and he realized he hadn't actually explained it anywhere.