uChecker
Email validation for AI agents: check addresses via SMTP/MX, detect disposable, catch-all and role emails, track tasks and export clean lists.
Hosted MCP Server
npx add-mcp 'https://api.uchecker.net/mcp'Installs into Claude Code, Codex, Cursor and more
Documentation
UChecker MCP Server
An MCP server for the UChecker email validation API. It lets an AI assistant validate email addresses, track validation tasks, read per-address results and account analytics, and export cleaned lists — without you writing any API glue.
Ten tools, three resources and two guided prompts, over either stdio (local) or Streamable HTTP (remote).
Quick start
Local (stdio)
You need a UChecker API key from app.uchecker.net.
// Claude Desktop: claude_desktop_config.json
// Claude Code: .mcp.json
{
"mcpServers": {
"uchecker": {
"command": "node",
"args": ["/path/to/mcp/build/stdio.js"],
"env": { "UCHECKER_API_KEY": "uk_..." }
}
}
}
The key can also be passed as --api-key=uk_.... Build first with npm ci && npm run build.
Remote (Streamable HTTP)
A hosted instance runs at https://api.uchecker.net/mcp. It is stateless: the
API key travels on every request, and no session is kept between calls.
curl -X POST https://api.uchecker.net/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'x-api-key: uk_...' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"get_account_balance","arguments":{}}}'
Authorization: Bearer uk_... works as well. Health check: GET /mcp/health.
To run your own instance, see docs/DEPLOYMENT.md.
The remote endpoint authenticates with an API key header, not OAuth, so clients that can only do OAuth or cannot set custom headers need the stdio build instead.
Configuration
| Variable | Mode | Default | Purpose |
|---|---|---|---|
UCHECKER_API_KEY | stdio | — | Required. Also settable via --api-key=. |
UCHECKER_API_URL | both | https://api.uchecker.net | Upstream API. Also --api-url= in stdio. |
UCHECKER_PUBLIC_API_URL | http | https://api.uchecker.net | URL shown to users in download hints, when the server reaches the API over an internal network. |
MCP_PORT | http | 3009 | Listen port. |
In HTTP mode the key is never configured server-side — it comes from the
x-api-key or Authorization: Bearer header of each request, so one instance
serves many accounts.
Tools
| Tool | What it does | Costs credits |
|---|---|---|
validate_email | Queue one address for validation | 1 |
validate_emails | Queue a batch (max 10 000 per call) | 1 per address |
get_task_status | Status and progress of a task | — |
wait_for_task | Poll until completed/failed, with progress notifications | — |
get_task_results | Per-address results, paged and filterable | — |
get_task_analytics | Counts, deliverability %, rejection reasons | — |
export_results | Save the full result list to a file (stdio) or return a curl command (http) | — |
list_tasks | Paginated task history | — |
get_account_balance | Remaining credits | — |
get_account_stats | Account-wide totals and averages | — |
Full parameter and output reference: docs/TOOLS.md.
Resources
uchecker://account/balance— remaining creditsuchecker://tasks— 20 most recent tasksuchecker://tasks/{taskId}/analytics— analytics for one task
Prompts
clean_email_list(source?)— end-to-end workflow: check balance, validate in chunks, wait, export cleaned good/bad lists, report deliverabilitydeliverability_report()— deliverability trend across recent tasks
How validation works
Addresses are queued, not checked synchronously. validate_email and
validate_emails return a task_id immediately; the task moves through
pending → processing → completed. A five-address list typically finishes
in well under a minute, but larger lists take proportionally longer, so:
- prefer
wait_for_taskover a manualget_task_statusloop — it emits MCP progress notifications while it waits and returnstimed_out: trueinstead of hanging forever; - for long lists pass
webhook_urland let the API call you back; - use
get_task_analyticswhen you only need aggregates — it is far cheaper than pulling every row.
Each address ends up good, bad, or unknown. unknown means the check could
not reach a verdict (unreachable MX, greylisting, catch-all ambiguity) — it is
not a synonym for invalid.
Development
The server runs on Node 20+; the test toolchain needs Node 22.12+.
npm ci
npm run build # tsc -> build/
npm test # vitest, no network
A live smoke test drives the built stdio server against a real API:
UCHECKER_API_KEY=uk_... UCHECKER_API_URL=https://api.staging.uchecker.net \
node tests/live-staging.mjs [completedTaskId]
It spends one credit on a real validate_email call, so point it at staging
unless you are deliberately verifying production.
Architecture: src/core/ holds the transport-independent server (API client,
tools, resources, prompts); src/stdio.ts and src/http.ts are the two entry
points. Adding a tool means touching src/core/tools.ts only.
Further reading:
- docs/TOOLS.md — tool reference
- docs/DEPLOYMENT.md — self-hosting with Docker behind a reverse proxy
- docs/API-NOTES.md — upstream API quirks this server absorbs
- CHANGELOG.md