Building an AI Lead Gen System That Doesn't Spam People
Notes on building an AI-powered lead generation system using MCP, Claude, and Apollo. How we automated startup discovery across YC, Vestbee, and ProductHunt, and why we deliberately kept a human in the loop.

Most AI outreach tools are built to send more messages. More volume, more templates, more automation. The pitch is always the same: "reach 1,000 prospects a day." The result is always the same too: founders drowning in identical LinkedIn messages from people who clearly haven't looked at their product.
When we set out to build our own lead identification and outreach tool
for internal use, we built the opposite. An AI-powered lead generation system designed around quality, not volume. It finds startups that genuinely fit our services, researches them properly, drafts outreach in our tone-of-voice, and puts a human in the loop before anything gets sent. The entire daily workflow takes about 15 minutes. On a good day it surfaces 1-2 leads worth pursuing, rather than spray-and-pray
tactics that generate noise. That's the point.
This post covers the architecture, the tools, and what we learned. There's enough technical detail for developers thinking about building similar systems, and enough context for founders wondering what "agentic AI" looks like when it's solving a real business problem rather than powering a demo.
Why we built it
We're a small studio. Most work comes through referrals, but referrals are unpredictable. When the pipeline gets quiet, the usual options are either to spend hours manually researching companies on LinkedIn, or send generic templates and hope. Neither works well.
The companies we want to work with are early-stage startups, founders who need a technical partner to help build and ship their product. These people get bombarded with outreach. If a message doesn't reference something specific about their company, written in a tone that sounds like an actual person, it gets ignored. Rightly so.
We wanted a system that could surface relevant startups automatically, do the initial research, and draft messages we'd be comfortable sending under our own name. Crucially, it needed to give us the space to actually look at each product before deciding whether to reach out. Download the app, try the site, understand what they're building. Not a spam tool. A research assistant that does the legwork so we can focus on the part that matters: deciding if there's a genuine fit.
The stack
MCP Server - a Next.js API deployed on Vercel that exposes tools Claude can call. MCP (Model Context Protocol) is an open standard that lets AI models interact with external services. Instead of copy-pasting data into prompts, Claude can directly search for companies, enrich contact data, scrape websites, and log leads to our CRM.
Apollo.io - for lead discovery and enrichment. The People Search API is free, and enrichment costs 1 credit per person. We use it to find founders at early-stage companies and get their LinkedIn URLs.
Jina Reader - free website scraping. Pass it any URL and it returns clean markdown. No API key needed.
Airtable - two tables. A "Launches" table where new startups land automatically, and a "Leads" table where qualified leads go with outreach messages attached.
n8n - automation workflows that scrape startup sources on a schedule, deduplicate against existing data, and trigger the AI agent when we approve a lead. We'll write up the n8n implementation in detail in a follow-up post.
Claude API - the brain. Claude decides which tools to call, in what order, and writes the outreach messages. One API call with tool use replaces what would otherwise be 7+ workflow nodes.
Architecture
The system has two layers: discovery and processing.
Discovery runs automatically. Scrapers check YC Launches, Vestbee (European startup funding news), and ProductHunt twice daily. New startups get filtered by relevance - SaaS, platforms, marketplaces, things we can actually help build - deduplicated against existing records, and added to the Launches table with a status of "New."
Processing is triggered by a human. We review the Launches table each morning. It takes about 5 minutes to scan. If something looks promising, we'll open their website, try the product, maybe download the app. That's where the real qualification happens, not in the data, but in spending a few minutes understanding what they've actually built. Anything that passes gets marked as "Process." That triggers the agentic workflow: Claude scrapes the company's website, enriches the founder via Apollo, writes a LinkedIn connection request and follow-up message, and logs everything to the Leads table. We review the messages, adjust where needed, and send.
The human stays in the loop at two deliberate points: choosing which leads to pursue, and reviewing the messages before they go out. This isn't a limitation of the system. It's a design choice. We've seen what happens when AI outreach runs without human oversight, and we don't want to be on the sending end of that.
The MCP server
The server exposes 10 tools: Companies House search and company lookup for UK company data, Apollo people search for lead discovery, Apollo company and person enrichment for LinkedIn URLs and verified emails, news search, website scraping via Jina Reader, outreach formatting, and lead logging with built-in deduplication.
Each tool has a description that tells Claude when and how to use it. The outreach tool is where things get interesting, because it contains the voice guide.
The voice guide
This was the hardest part to get right, and the most valuable.
The first version of the automated outreach read like every other LinkedIn sales message. VC jargon. Forced parallels to past work. Enrichment data parroted back at the founder as if we knew their business inside out. It took several rounds of testing on real leads to understand what was wrong.
The problem wasn't the AI's writing ability. It was the instructions. When you tell an AI to "reference the company's challenges," it invents challenges. When you say "draw a parallel to past work," it forces one even when none exists. When you feed it enrichment data, it dutifully repeats it back, even when that data is wrong.
We found that the enrichment data from APIs isn't always accurate, especially for very new companies. Funding amounts, round types, company descriptions, all of it should be treated as "probably right". Spending few minutes finding one real news article or LinkedIn post makes the outreach significantly better than anything built purely on automated data.
The voice guide we ended up with is specific. It includes concrete examples of good and bad messages, both based on real outreach we've sent. Claude reads it every time it writes outreach, whether we're using it interactively or through the automated workflow.
The rules are simple: show genuine interest in their product (mention you tried their app, looked at their site), describe skills generally rather than listing services, never use VC jargon, never pretend to know their challenges, and never force parallels to past work. Default to linking the portfolio and let the work speak for itself.
Getting the voice right matters more than any other part of the system. A perfectly researched lead with a bad message is worse than no message at all.
Apollo.io - the economics
Apollo was a deliberate choice over other enrichment APIs. The People Search endpoint is completely free. We can search for "Founders at UK SaaS companies with 5-20 employees" without spending anything. When we find someone worth contacting, one credit gets their LinkedIn URL through Person Enrichment. Company Enrichment costs one credit and returns industry, size, funding, and tech stack.
At roughly $49-79/month for a basic plan, the economics work out to about £0.10-0.15 per qualified lead. The key word is "qualified", credits only get spent on leads we've already reviewed and approved. The free search is the filter, human judgment is the qualifier, credits only flow to companies that passed both.
The agentic part
There's a lot of hype around "agentic AI" right now. Here's what it means in the context of what we built.
The non-agentic version would be a linear pipeline: scrape the website, then enrich the person, then write the message, then log the lead. Each step is hardcoded. If the website is down, the pipeline breaks. If Apollo doesn't find the person, everything after that fails.
The agentic version gives Claude a goal and lets it figure out the steps. It receives the startup data, a system prompt with the voice guide, and access to the MCP tools. It decides to scrape the website first, reads the content, decides to enrich the founder, gets their LinkedIn URL, writes the messages based on what it learned, then logs the lead. If the website is unreachable, it works with what it has. If Apollo doesn't find the person, it still writes the outreach and logs the lead without a LinkedIn URL.
One Claude API call with tool use replaces 7+ separate workflow nodes. The quality of the output is directly proportional to the quality of the tool descriptions and the system prompt. Vague tools and sloppy instructions produce vague, sloppy results.
We evaluated Mastra.ai, LangChain and LangGraph early on. They're powerful frameworks for multi-agent systems, but for a single agent doing one job, Claude's native tool use with MCP handles everything. We'll reach for Mastra.ai or LangGraph when building more complex multi-agent systems for clients.
What we learned
Quality over volume is a genuine competitive advantage. Most AI outreach tools optimise for reach. We optimise for relevance. The system surfaces 10-15 new startups per day across three sources. We pursue 1-2. That's not a bug in the automation, it's the whole point. Every message that goes out has been reviewed by a human who has actually looked at the product, adjusted if needed, and sent because we genuinely think there's a fit.
Automated data is a starting point, not the truth. Every piece of enrichment data should be treated as "probably right." We've had leads where the funding amount, round type, and company description were all wrong. The system is designed so we always review before sending.
Voice guides need real examples. Abstract rules like "be casual" or "be professional" don't produce good output. Concrete examples of good and bad messages, based on real outreach, are what make the difference between AI-generated content and content that sounds like it came from a real person.
The MCP server is the real asset. The automation workflows are replaceable. The voice guide will evolve. But the MCP server, the tools, the API integrations, the business logic is the foundation everything else is built on. It works with Claude in conversation, with automation workflows, and with any other MCP-compatible client.
What's next
More sources. TechCrunch, AngelList, and LinkedIn job postings, companies hiring engineers often need external help too.
Follow-up automation. A workflow that flags leads we've contacted but haven't heard back from, so nothing falls through the cracks.
A detailed n8n post. The automation layer has its own set of lessons around deduplication patterns, trigger reliability, and building agentic workflows with native AI Agent nodes. That'll be its own write-up.
And client-facing agent work. Everything we built here - MCP servers, tool use, agentic workflows is directly applicable to what we build for clients. The lead gen system is also a portfolio piece and a proof of concept for anyone thinking about what AI agents can do for their business.
We help early-stage founders build and ship products. If you're looking for a technical partner who understands the full stack - UI, APIs, infrastructure, automation and AI, have a look at some of the work we've done at ham.studio/work.
Related Post
Let's build something together
Feel free to contact us

