Skip to main content
Glama
owieschon

contact-verifier-mcp

by owieschon

contact-verifier

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.

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.

Related MCP server: MailboxValidator Email Validation MCP Server

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.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/owieschon/contact-verifier'

If you have feedback or need assistance with the MCP directory API, please join our Discord server