Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

MCP server for verifying B2B contact records via email syntax and DNS/MX checks, serving verified data with per-tenant isolation.

README.md

contact-verifier

<!-- sourcebound:purpose --> contact-verifier is a local, multi-tenant contact-assessment service for teams that need explainable email syntax and domain mail-routing evidence without turning those signals into mailbox or identity claims. It stores each result under one tenant and serves the same record through REST, stdio MCP tools, and local Parquet or CSV exports. <!-- sourcebound:end purpose -->

All committed fixtures use synthetic contacts. Local operator data stays outside version control. Verification means syntax plus DNS evidence. It does not prove that a mailbox exists, accepts mail, belongs to a person, or may be contacted. An MX record is a clue, not a person.

What each result means

Stored contacts begin as unknown, which means not yet assessed. The verifier then assigns one of three compatibility wire values and keeps the underlying routing state alongside it:

| Status | Evidence represented | heuristic_score | | --- | --- | ---: | | valid | Syntax passed and DNS exposed explicit MX or an implicit A/AAAA mail route. | 0.9 | | invalid | Syntax failed, the domain did not exist, the domain published null MX, or no MX/A/AAAA route existed. | 0.0 or 0.1 | | risky | Syntax passed, but bounded DNS retries ended in a transient failure. | 0.5 | | unknown | The stored contact has not been assessed yet. | 0.0 |

These scores are ordinal rule constants, not calibrated probabilities. The API field is named heuristic_score; mail_routing_state preserves the narrower DNS outcome.

How a contact moves through the service

  1. REST or the CLI ingests contacts for the tenant resolved from an API key.
  2. The verifier normalizes each address, checks syntax, and classifies domain routing evidence.
  3. The service stores the result under the same tenant and flags later duplicate addresses.
  4. REST, stdio MCP tools, and tenant-partitioned local exports read that stored record.

The DNS client retries only transient failures. It returns definitive answers such as nxdomain and null_mx immediately, paces bulk calls, and bounds its cache. Tests inject the resolver, clock, and sleep function, so the retry, rate-limit, and cache paths run without network access or waiting.

Run the local flow

Install the application and its development and MCP extras, then run the hermetic checks:

pip install -e ".[dev,mcp]"
pytest
ruff check src tests

Provision a tenant and carry its one-time API key through the CLI flow:

KEY=$(contact-verifier provision --name "Acme" | awk '/API key/{print $NF}')
contact-verifier seed --key "$KEY"
contact-verifier verify --key "$KEY"
contact-verifier export --key "$KEY"

The verify command performs live DNS queries. The export command writes a local object under warehouse/tenant=<id>/; it does not upload to a remote warehouse.

To use the HTTP interface, start the service and send the same tenant key with each request:

contact-verifier serve

curl -s -X POST localhost:8000/v1/contacts \
  -H "X-API-Key: $KEY" \
  -H 'content-type: application/json' \
  -d '{"contacts":[{"email":"jane@example.com"},{"email":"bad-syntax"}]}'
curl -s -X POST localhost:8000/v1/contacts/verify -H "X-API-Key: $KEY"
curl -s "localhost:8000/v1/contacts?status=valid" -H "X-API-Key: $KEY"

OpenAPI is available at http://127.0.0.1:8000/docs. SQLite is the default. To use Postgres, install the postgres extra, set CV_DATABASE_URL, and run alembic upgrade head.

To expose the stored records to an MCP client, start the stdio server:

contact-verifier-mcp

The server registers search_contacts, get_contact, contact_stats, and verify_contacts. Each tool accepts an API key because stdio MCP calls do not carry the REST header.

Tenant and side-effect boundaries

Every repository method that reads or writes a contact requires a tenant ID. REST and MCP resolve the tenant from the supplied API key before calling that layer. Negative tests prove that a second tenant can neither list nor fetch another tenant's contact. REST returns 404 for a cross-tenant ID, so it does not confirm that the record exists.

Only verify_contacts changes state through MCP, and repeated calls skip contacts that already have an assessment. API keys are stored as SHA-256 hashes; plaintext appears once at creation. Sentry is off unless a DSN is configured. Verification itself is the only external call in the assessment path.

Read Architecture for the data path, DNS failure model, storage boundary, and declared limits.

License

Apache License 2.0.

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Communication servers.