DEV Community

james-sib
james-sib

Posted on • Originally published at verifly.email

Give your AI agent email verification via MCP

An AI agent that handles signups, outreach, or CRM hygiene keeps hitting the same wall: it has no idea whether an email address is real. It will cheerfully email gmial.com, accept a mailinator.com throwaway as a new user, or import a dead domain into your database. The agent is not wrong to try; it just has no sense for deliverability.

MCP (the Model Context Protocol) is the clean way to close that gap. Instead of hardcoding an HTTP client into every agent, you point the agent at a server and it gets the tools. This post connects Verifly over MCP so any MCP-capable client (Claude Desktop, Cursor, your own agent runtime) can verify and clean email addresses inside its loop.

The use case

You are building an agent that onboards users or works a lead list. You want it to:

  • reject fake or disposable signups before they land in your database, and
  • clean a list before a campaign so you are not emailing dead addresses.

Both are decisions the agent should make mid-task, which means verification has to be a tool it can call, not a script you run afterward.

Two ways to connect

Verifly runs a hosted MCP server at https://verifly.email/mcp (Streamable HTTP, Bearer auth). There is also an npm package that runs the same server locally over stdio. Use whichever your client supports.

Get a key first

Verifly is built for agents, so onboarding is a single call, no dashboard:

curl -s -X POST https://verifly.email/api/v1/autonomous/register \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"a-strong-password"}'
Enter fullscreen mode Exit fullscreen mode

You get back an api_key.key starting with vf_ and 100 free credits.

Option A: hosted server (Claude Desktop / Cursor)

Add it to your MCP config. For Claude Desktop, claude_desktop_config.json:

{
  "mcpServers": {
    "verifly": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://verifly.email/mcp"],
      "env": { "VERIFLY_API_KEY": "vf_your_key_here" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Option B: local stdio server

npx verifly-mcp-server
Enter fullscreen mode Exit fullscreen mode
{
  "mcpServers": {
    "verifly": {
      "command": "npx",
      "args": ["-y", "verifly-mcp-server"],
      "env": { "VERIFLY_API_KEY": "vf_your_key_here" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart the client and the Verifly tools appear.

What the agent actually gets

After connecting, a tools/list against the server returns a real toolset. These are the verification-focused ones:

  • verify_email — verify one address, returns the verdict, reason, flags, and a send/reject recommendation.
  • verify_batch — verify a list synchronously (good up to a few hundred).
  • clean_email_list — dedupe, drop invalid syntax, optionally strip disposable and role accounts.
  • extract_emails — pull addresses out of free-form text (signatures, pasted notes).
  • check_domain_health — MX / SPF / DMARC and an overall health score for a domain.
  • submit_bulk / get_job_status / get_job_results — async jobs for large lists.
  • get_credits / get_account / get_usage — balance and usage, no credits charged.

The agent picks the right one from the descriptions. "Clean this list" pulls clean_email_list; "is this signup real?" pulls verify_email.

What a verdict looks like

When the agent calls verify_email on a typo, the live server returns this (shown via the underlying REST call the tool wraps):

{
  "email": "jane.doe@gmial.com",
  "result": "undeliverable",
  "reason": "Invalid email: bad_domain",
  "confidence": 90,
  "recommendation": "do_not_send",
  "did_you_mean": "jane.doe@gmail.com",
  "details": { "domain_exists": true, "mx_records": true, "smtp_valid": false,
               "is_disposable": false, "is_catch_all": false }
}
Enter fullscreen mode Exit fullscreen mode

A disposable address is caught outright:

{
  "email": "test@mailinator.com",
  "result": "undeliverable",
  "reason": "Disposable/temporary email address",
  "recommendation": "do_not_send",
  "details": { "is_disposable": true }
}
Enter fullscreen mode Exit fullscreen mode

And a real mailbox passes:

{
  "email": "james@sibscientific.com",
  "result": "deliverable",
  "reason": "Email exists and accepts mail",
  "confidence": 95,
  "recommendation": "safe_to_send"
}
Enter fullscreen mode Exit fullscreen mode

Two fields make this agent-friendly. recommendation is a flat verb (do_not_send / safe_to_send) the model can branch on with no parsing, and did_you_mean lets the agent offer a correction instead of just rejecting.

Wiring it into the agent loop

The pattern is the same regardless of framework. In your system prompt, tell the agent the policy and let the tool descriptions do the rest:

Before accepting a new signup, call verify_email. Reject anything with recommendation: do_not_send. If did_you_mean is set, ask the user to confirm the corrected address. Before sending a campaign, run the list through clean_email_list and only send to what survives.

Now the agent has a deliverability sense built into its decisions: fake signups bounce off at the door, typos get corrected, and lists get cleaned before send, all without you bolting on a separate validation step.

Notes

  • Verdicts are deliverable, undeliverable, risky, or unknown. risky usually means a catch-all domain (confidence around 40) where no provider can confirm the individual mailbox; treat it as "send with caution."
  • Read-only tools like get_credits and get_account cost nothing, so an agent can check its own balance before a big batch.
  • The free tier is 100 verifications, enough to wire the whole thing up end to end.

Point your agent at https://verifly.email/mcp, give it a key, and it can verify email the same way it calls any other tool. Full API and tool docs at verifly.email.

Top comments (0)