What we ran
We tested Claude for lead generation end to end. The job: find 20 heads of sales at London SaaS companies, check their emails, find a reason to write to each of them, and draft a sequence we would be happy to send. Claude, running in Claude Code, made every call itself against live data on 1 October 2026. We logged each call and what it cost.
❯ Find 20 heads of sales at SaaS companies in London with 20 to 200 staff. Verify every email, find a recent reason to reach out to each one, and draft a three-step sequence that opens with it. Stop before sending.What does Claude need to do lead generation?
Claude, Anthropic's AI assistant, needs live data and a way to act on it. On its own it can write a good email and reason about who to target, but it cannot look up who works where today or whether an address will bounce.
An MCP (Model Context Protocol) server gives it those tools. We used Layrcake, which puts company search, people search, email verification, social posts and campaign drafting behind one connection, so Claude could run the loop without switching tools.
Step 1: Connect the data layer
In Claude Code it is one command and a sign-in. Run the command, then type /mcp, choose layrcake and choose Authenticate. Your browser opens to sign in and approve access. There is no key to paste.
$ claude mcp add --transport http --scope user layrcake https://mcp.layrcake.dev/mcpIn the Claude app on the web or desktop, open Settings, then Connectors, choose Add custom connector and paste https://mcp.layrcake.dev/mcp. The Claude Code setup page walks through the first run, and the connect page has the steps for other apps.
Step 2: Describe who you want
Claude turned the sentence into one people search: the title, the city, the industry and the company size, with a limit of 20. The search matched 91 people and returned the first 20 in 1.8 seconds, for 4 credits.
❯ {
"audience": "Heads of sales at SaaS companies in London with 20 to 200 staff",
"titles": ["Head of Sales"],
"locations": ["London, United Kingdom"],
"industries": ["Software Development"],
"company_headcount": { "min": 20, "max": 200 },
"limit": 20,
"budget_credits": 10
}Search results carry a name, a title, a company and a LinkedIn profile. They do not carry email addresses, so Claude's next call was enrich, once per person, asking only for a work email. Enrich found 16 of the 20. The four it could not find cost nothing; each hit cost 5 credits.
Three of the 20 were heads of sales development, who run the SDR team. We kept them for this run. If you only want the person who owns the number, that is the filter to tighten.
find_leadsHead of Sales · London · Software Development · 20 to 200 staff · limit 2020 of 91 matches · 4 crenrich × 20want: work_email16 found · 4 misses free · 80 crverify_email × 16one call per address10 valid · 5 catch-all · 1 invalid · 16 crfind_postsleads: 15 · latest activity per person15 with a signal · 45 crcreate_campaign3 steps · 15 leadsdraft · 0 cr
Every tool's arguments and result fields are in the API reference.
Step 3: Verify before you draft
We asked Claude to verify every address before writing a word. Our view: a bounced first email spends sending reputation you need for the rest of the campaign, so the check comes first.
Enrich had labelled all 16 addresses valid. The second check disagreed on six of them. One address was invalid. Five sat on catch-all domains, which accept mail for any address, so a check can't confirm the mailbox exists. Claude dropped the invalid address and kept the catch-all ones, a judgement call we were comfortable with for a first send. That left 15.
One more thing the run turned up: one address enrich found was at a different company from the one the search listed. Search data can lag a job move, which is why we check the address we are about to use.
| Step | Asked | Hits | Credits |
|---|---|---|---|
| Find leads | 20 | 20 | 4 |
| Find work emails | 20 | 16 | 80 |
| Verify emails | 16 | 15 kept | 16 |
| Recent activity | 15 | 15 | 45 |
| Draft campaign | 15 | 15 | 0 |
Searches and lookups that found nothing were free. Every verification cost 1 credit, the failed one included. Every call reported its charge in the response.
Step 4: Draft the sequence and stop at approval
Before writing, Claude looked for a recent reason to contact each person. One find_posts call took the whole list of 15 and returned, for each person, the best recent activity it could find: their own post, a comment, a reaction to someone else's post, or failing those, a post from their company. Lists over 10 run in the background, so Claude polled for the result. It took 38 seconds.
All 15 came back with something: 9 of their own posts, 5 reactions and 1 company post. The newest was from that morning and the oldest was 23 days old, with a median of 7 days. Each lead with a signal cost 3 credits. A lead with nothing would have cost nothing.
Claude wrote one opening line per person from that activity and passed it to the campaign as a custom field, so the first email opens with it. Own posts made the strongest openers. Reactions are weaker, because liking a post says less than writing one, so those lines say "saw you liked" and stop there.
❯ Subject: Sales calls at [company_name]
Hi [first_name],
[opener]
Most heads of sales I speak to can say how many calls the team made last week, but not which ones moved a deal forward.
We built a call-recording tool that pulls the moments that matter out of every call (objections, pricing questions, next steps) and puts them in one weekly summary for you.
Would a look at last week's summary for a team your size be useful?
Thanks,
Sam❯ Saw your post about hiring two more AEs for the EMEA team. Sounds like a big quarter.Then create_campaign built the draft: three emails over seven days and 15 leads accepted, with none removed by the opt-out and suppression checks. It cost 0 credits. Creating a campaign never sends anything. Sending takes a second call, launch_campaign, which answers with a preview, a fresh check of the recipients and an approval link.
launch_campaign returns a preview and an approval link. A signed-in person approves before a single email leaves. We stopped at the draft, and so does this guide.
What did it cost?
The whole run cost 145 credits, about $1.45 at $0.01 per credit (prices as of October 2026). That is a little under 10 credits for each of the 15 people who ended up in the draft with a checked address and a reason to write.
Finding emails was most of the bill: 80 of the 145 credits. The tool calls took about 90 seconds between them. The run took under ten minutes end to end, most of it spent writing and reading the openers.
Where it falls short
Search data ages. One of the 16 people had moved company, and three of the 20 titles were adjacent roles. Read the list before you spend on it.
Catch-all addresses are a judgement call. We kept five. On a new sending domain you may want to drop them.
The openers need a human read. Claude's lines matched their sources, but a line about a webinar someone is hosting lands differently from a line about a post they liked. We would edit two or three before sending.
And the send is yours. Layrcake does not launch a campaign until a signed-in person approves it, which is the default we want for anything that emails real people.
Questions people ask
Can Claude generate leads on its own?
Not from its training data. Claude needs tools that search live company and people data and check email addresses. Connected over MCP, it calls those tools and works with what they return.
Is it safe to let Claude send cold email?
Only with an approval step. In our run the campaign was created as a draft. Launching it returns a preview and an approval link, and nothing sends until a signed-in person approves.
What does a run like this cost?
Our run cost 145 credits (about $1.45) for 20 leads, which left 15 ready to send. Searches and email lookups that find nothing are free; an email check that returns an answer costs 1 credit.
Does this work in the Claude app as well as Claude Code?
Yes. Claude on the web and desktop connects to the same MCP server as a custom connector; Claude Code adds it with one command.