From leads to inbox: LeadPuppet + the Resend MCP

The missing half

LeadPuppet is a small open-source tool I built for B2B lead discovery. You give it business categories and cities, it finds companies through the Google Places API, then visits each website to pull out a contact — name, role, email — with regex first and GPT-4o-mini as a fallback.

The output is a JSON file full of leads. And then… nothing. A file doesn't send emails. The second half of the job — actually reaching out — was always a separate script, a separate tool, a separate afternoon.

This week I closed that gap without writing a single line of sending code.


MCP: tools the agent can hold

The Model Context Protocol lets an AI agent use external services as tools. Resend ships an MCP server, so once it's connected to Claude Code, the agent can send emails, list domains, check delivery status — all through the same conversation where I'm working on the code.

The first test was the obvious one: "send me a test email with subject 'Test MCP'." Before sending, the agent checked which domains were verified on my Resend account, found auth.leadpuppet.com, and asked me which sender address to use. One answer later, the email was in my inbox.

That question matters. The agent didn't invent a sender. Resend's MCP marks the from field as something the model must ask the user for — a small design decision that says a lot about how these tools should behave.


From a JSON file to personalized emails

Then the real test. LeadPuppet's enrich step produces leads with contactName and contactEmail. I made a small file in that shape, pointing to aliases of my own address:

[
  {
    "name": "Test Company 1",
    "contactEmail": "me+lead1@gmail.com",
    "contactName": "Juan"
  },
  {
    "name": "Test Company 2",
    "contactEmail": "me+lead2@gmail.com",
    "contactName": "Maria"
  }
]

And the prompt:

Read test-mcp-leads.json. For each lead, use the Resend MCP to send a personalized email (greet them by contactName, mention their company name), from test@auth.leadpuppet.com, with a 30-second delay between sends.

The agent read the file, drafted both emails — subject and body, with the name and company swapped in — and showed them to me before sending anything. I said "perfect". It sent the first one, waited 30 seconds, sent the second. Both landed.

No SDK, no template engine, no queue. The "code" was a paragraph of Spanish.


What I actually learned

1. The confirmation step is the feature.

An agent that can send email on your behalf is only useful if you trust it. Seeing the exact drafts before they go out is what makes it safe to hand over a list. Sending is irreversible; a preview costs one message.

2. The boundary between tools got thinner.

LeadPuppet stays focused on discovery and enrichment. Outreach doesn't need to live inside it — the agent composes the two. That's a better architecture than bolting an email module onto every tool.

3. Small details still need a human.

Rate limiting, sender choice, the copy itself. The agent handled the mechanics; the decisions stayed mine.


What this actually costs

For context: generating ~150 leads (discovery + enrichment) costs about $0.10 in OpenAI usage — Google Places' free tier covers the search itself. Sending is separate and provider-dependent, but most transactional email services offer a free tier in the 100-300 emails/day range, enough to start reaching out without spending anything.

Cost to reach 150 leads in your first month

Estimated cost to reach 150 leads in the first month
ToolCostBasis
LeadPuppet (self-hosted)~$0.10OpenAI usage per 150 leads generated · scales with use, no fixed fee
Explee AutoGTM~$4.50$0.03/email × 150 · pay as you go
Hunter Starter$34Per month, billed annually
Apollo.io Basic$49Per user/month, billed annually

Public list prices, Sep 2026. LeadPuppet sending assumes a free transactional tier (e.g. Resend: 100 emails/day).

Compare that to the all-in-one tools in this space, which typically charge per-lead or bundle sending infrastructure you may not need — often $30-50/month minimum before you've validated the channel works for your product.


A word on responsibility

Every test in this post went to my own inbox. Going from "it works" to cold outreach at scale is a different conversation: CAN-SPAM, GDPR, unsubscribe links, sending reputation. Making sending easier makes it more important to send well — few, relevant, and with a clear way out.


Are you wiring MCPs into your own workflow? I'd love to hear what you're connecting. contact@gino.run