Skip to content
Agentmart
Submit a tool

verify-email

Verify whether email addresses are reachable without sending an email.

Skill by press-pass

IndexedMIT★ 2
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/press-pass-verify-email

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Verify whether email addresses are reachable without sending an email. Checks syntax, DNS/MX records, disposable domains, and SMTP mailbox existence.

Use cases: productivity

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/verify-email

What's inside

Skill name
verify-email
Description
Verify whether email addresses are reachable without sending an email. Checks syntax, DNS/MX records, disposable domains, and SMTP mailbox existence.
License
MIT
Instructions
179 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Agent Skills spec issues

  • name: missing

Files (1)

  • SKILL.md

SKILL.md (first lines)

You will be given one or more email addresses (comma-separated). For each email address, run the verification pipeline
below. Report results in a summary table at the end.

## Step 1: Syntax check

Verify the email matches a valid format: one `@`, valid local part (no leading/trailing dots, no consecutive dots),
and a valid domain (valid hostname characters, at least one dot).

If the syntax is invalid, mark the email as **Invalid (bad syntax)** and skip remaining steps.

## Step 2: DNS/MX record check

Run `dig +short <domain> MX` via Bash. Inspect the results:

- If no MX records are returned, try `dig +short <domain> A` as a fallback (some domains accept mail on their A record).
- If neither returns results, mark as **Invalid (no mail server)** and skip remaining steps.
- If MX records exist, note the lowest-preference (primary) MX server for Step 4.

## Step 3: Disposable email check

Check whether the domain is a known disposable/temporary email provider. Search the web for
"is <domain> a disposable email" or check against well-known disposable domains (mailinator.com, guerrillamail.com,
tempmail.com, throwaway.email, yopmail.com, sharklasers.com, 10minutemail.com, trashmail.com, etc.).

If disposable, flag it as **Warning: disposable email provider** but continue to Step 4.

## Step 4: SMTP RCPT TO verification

This step connects to the mail server and asks if the mailbox exists without sending an email.

Run this Bash script, substituting the email and MX server:

```bash
{
  exec 3<>/dev/tcp/<mx_server>/25
  timeout=5

  # Read greeting
  read -t $timeout -u 3 greeting
  echo "GREETING: $greeting"

  # HELO
  echo -e "HELO verify.local\r" >&3
  read -t $timeout -u 3 helo_resp
  echo "HELO: $helo_resp"

  # MAIL FROM
  echo -e "MAIL FROM:<verify@verify.local>\r" >&3
  read -t $timeout -u 3 mail_resp
  echo "MAIL FROM: $mail_resp"

  # RCPT TO - the actual verification
  echo -e "RCPT TO:<EMAIL_ADDRESS>\r" >&3
  read -t $timeout -u 3 rcpt_resp
  echo "RCPT TO: $rcpt_resp"

  # QUIT
  echo -e "QUIT\r" >&3

  exec 3<&-
  exec 3>&-
} 2>&1
```

Interpret the RCPT TO response — match the response text as well as the code:

- **250**: Mailbox exists (or domain is catch-all — see below)
- **Text mentions "full", "quota", "blocks limit", or "inode limit"** (any code, typically 452/552): the mailbox
  exists but is over quota — mark as **Risky (mailbox full)**
- **Text mentions "relay", "relaying", "not local", or "authentication required"** (any code, e.g.
  `551 User not local: authentication required for relaying`): the server rejected the probe, not the mailbox —
  this says nothing about whether the address exists — mark as **Indeterminate (relay denied)**
- **550/551/553** (no relay/quota wording): Mailbox does not exist — mark as **Invalid (mailbox not found)**
- **450/451/452** (no quota wording): Temporary rejection (greylisting) — mark as **Indeterminate (greylisted)**
- **Connection refused/timeout**: check (once per run) whether outbound port 25 works at all:
  `timeout 8 bash -c 'exec 3<>/dev/tcp/gmail-smtp-in.l.google.com/25 && read -t 5 -u 3 greeting && echo "$greeting"'`.
  If that fails, mark as **Indeterminate (port 25 blocked locally)**. If it succeeds and the domain was
  A-record-only (no MX — the A record usually points to a web server, not a mail server), mark as
  **Invalid (no mail server)**; otherwise mark as **Indeterminate (server unreachable)**
- **Any other error**: Note the code and mark as **Indeterminate**

### Catch-all detection

After the RCPT TO check, if the result was 250, test whether the domain is catch-all by checking a clearly fake
address: `does-not-exist-xyz-99@<domain>`. If that also returns 250, the domain accepts all addresses and the result
is **Indeterminate (catch-all domain)**.

## Step 5: Provider-specific headless browser verification

For providers that defeat SMTP verification, use Playwright to check account existence via their password recovery
flows. Skip the SMTP check (Step 4) for these providers and use this step instead.

### Microsoft (outlook.com, hotmail.com, live.com, msn.com)

1. Call `browser_navigate` to `https://account.live.com/password/reset`
2. Call `browser_snapshot` to find the email input field.
3. Call `browser_fill_form` to enter the email address into the email input.
4. Call `browser_click` on the "Next" button.
5. Wait 3 seconds, then call `browser_snapshot` and check:
   - If the page contains text like "that Microsoft account doesn't exist" or "No account found with that email" → **Unreachable (account not found)**
   - If the page shows identity verification options ("verify your identity", "send a code", "authenticator app") → **Reachable (account exists)**
   - If a CAPTCHA appears, note it and mark as **Indeterminate (CAPTCHA blocked)**

### Yahoo (yahoo.com, ymail.com, aol.com, yahoo.co.uk, yahoo.ca, etc.)

1. Call `browser_navigate` to `https://login.yahoo.com/forgot`
2. Call `browser_snapshot` to find the email/phone input field.
3. Call `browser_fill_form` to enter the email address.
4. Call `browser_click` on "Continue".
5. Wait 3 seconds, then call `browser_snapshot` and check:
   - If the page shows an error message like "Sorry, we don't recognize that email" → **Unreachable (account not found)**
   - If the page shows verification options (send a code, security key, etc.) → **Reachable (account exists)**
   - If a CAPTCHA appears, note it and mark as **Indeterminate (CAPTCHA blocked)**

### Microsoft 365 (business domains with MX pointing to outlook.com or *.mail.protection.outlook.com)

Before using the headless browser, try the faster API check:

Run via Bash:

From press-pass/journalism-skills, MIT.

More from press-pass/journalism-skills

Signals

Stars
2
Forks
0
Open issues
0
Last commit (this folder)
Jun 12, 2026 (4 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from press-pass

Cite this page

verify-email skill. Agent Mart. https://agentmart.dev/skills/press-pass-verify-email (last updated 2026-10-24)