Overview
MailTooth runs a remote, stateless Streamable HTTP MCP server. Your agent connects to one URL, discovers the verify_emailtool, validates its inputs from the published schema, and receives both a concise model-readable summary and the complete structured verification result.
https://api.mailtooth.com/mcpNo package, local process, session store, or webhook is required.
Rate limits, total limits, credits, analytics, and revocation all apply.
Unknown results and failed executions are refunded automatically.
The server supports current MCP Streamable HTTP clients and the stateless 2025 protocol family. Legacy standalone SSE endpoints and local stdio transport are not required.
Before you connect
You need three things:
- A MailTooth account with enough credits for the verification type your agent will use.
- A dedicated active API key. Set a conservative per-minute limit and total request limit for this one agent or workflow.
- An MCP client that supports remote Streamable HTTP servers and custom request headers.
Five-minute setup
- Open API keys, create a key named for the agent, and copy the secret once.
- Add the MailTooth endpoint and an Authorization header to your MCP client. Start with the generic configuration below or jump to a client-specific recipe.
- Restart or reconnect the client, then confirm that it discovers exactly one tool named
verify_email. - Ask: “Verify person@example.com with MailTooth.” Review the tool arguments before approving the first call.
{
"mcpServers": {
"mailtooth": {
"type": "http",
"url": "https://api.mailtooth.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_MAILTOOTH_API_KEY"
}
}
}
}Client configuration formats differ: Claude, Cursor, and Windsurf usemcpServers; VS Code uses servers. Copy the recipe for your client rather than renaming fields by guesswork.
Endpoint and authentication
Authenticate every MCP request with an existing MailTooth API key. Bearer authentication is recommended because it is supported by the widest range of remote MCP clients. The x-api-key header remains available when a client supports arbitrary headers.
| Setting | Value |
|---|---|
| Transport | Streamable HTTP |
| Server URL | https://api.mailtooth.com/mcp |
| Recommended header | Authorization: Bearer YOUR_MAILTOOTH_API_KEY |
| Alternative header | x-api-key: YOUR_MAILTOOTH_API_KEY |
| Tool discovery | Automatic through MCP tools/list |
A missing, malformed, revoked, or inactive key is rejected at the HTTP layer with 401 Unauthorized. No credits are reserved for authentication failures.
Connect popular agents
Choose one recipe. The configuration is global when you want MailToothin every workspace and project-scoped when a team should share the server definition. Keep the actual key in a user-local secret store even when the non-secret configuration is committed.
Claude Code
Claude Code MCP documentation- Export the key in your shell or secret manager.
- Run the command below. User scope makes the server available in every project.
- Run claude mcp list, then use /mcp inside Claude Code to inspect connection status.
export MAILTOOTH_API_KEY='YOUR_MAILTOOTH_API_KEY'
claude mcp add --transport http mailtooth 'https://api.mailtooth.com/mcp' \
--scope user \
--header "Authorization: Bearer $MAILTOOTH_API_KEY"
claude mcp list
claude mcp get mailtoothFor a team-shared project definition, commit this .mcp.jsonfile without the secret and have every teammate setMAILTOOTH_API_KEY locally.
{
"mcpServers": {
"mailtooth": {
"type": "http",
"url": "https://api.mailtooth.com/mcp",
"headers": {
"Authorization": "Bearer ${MAILTOOTH_API_KEY}"
}
}
}
}Cursor
Cursor MCP documentation- Create .cursor/mcp.json for one project, or ~/.cursor/mcp.json for all projects.
- Paste the configuration and replace the placeholder locally.
- Open Cursor Settings → MCP, enable MailTooth, and confirm verify_email appears under Available Tools.
{
"mcpServers": {
"mailtooth": {
"type": "http",
"url": "https://api.mailtooth.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_MAILTOOTH_API_KEY"
}
}
}
}VS Code and GitHub Copilot
VS Code MCP documentation- Run MCP: Open User Configuration for a private global setup, or create .vscode/mcp.json.
- Use the password input below so VS Code prompts once and stores the key securely.
- Run MCP: List Servers, start MailTooth, and accept the trust prompt.
{
"inputs": [
{
"type": "promptString",
"id": "mailtooth-api-key",
"description": "MailTooth API key",
"password": true
}
],
"servers": {
"mailtooth": {
"type": "http",
"url": "https://api.mailtooth.com/mcp",
"headers": {
"Authorization": "Bearer ${input:mailtooth-api-key}"
}
}
}
}Windsurf Cascade
Windsurf MCP documentation- Set MAILTOOTH_API_KEY in the environment that launches Windsurf.
- Open ~/.codeium/windsurf/mcp_config.json and add the server entry.
- Refresh MCP servers in Cascade and confirm verify_email is enabled.
{
"mcpServers": {
"mailtooth": {
"serverUrl": "https://api.mailtooth.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MAILTOOTH_API_KEY}"
}
}
}
}OpenAI Agents SDK
OpenAI Agents SDK MCP guide- Install @openai/agents and keep MAILTOOTH_API_KEY in your runtime secret manager.
- Register MailTooth as a hosted MCP tool with an explicit one-tool allowlist.
- Keep approval enabled while testing. Change approval policy only after the workflow and budget controls are proven.
import { Agent, hostedMcpTool, run } from "@openai/agents";
const mailtooth = hostedMcpTool({
serverLabel: "mailtooth",
serverUrl: "https://api.mailtooth.com/mcp",
headers: {
Authorization: `Bearer ${process.env.MAILTOOTH_API_KEY}`,
},
allowedTools: ["verify_email"],
requireApproval: "always",
});
const agent = new Agent({
name: "Lead intake agent",
instructions:
"Verify every address before accepting it. Use addressStatus for Quick/Standard and mailbox.status for Deepcheck.",
tools: [mailtooth],
});
const result = await run(
agent,
"Check person@example.com and tell me whether it is safe to contact.",
);
console.log(result.finalOutput);Any other MCP client
Select the client's remote HTTP or Streamable HTTP server type, enter https://api.mailtooth.com/mcp, and add an Authorization header. Do not choose stdio, WebSocket, or a legacy SSE-only transport. If the client has no way to attach a static header, it cannot currently authenticate to MailTooth.
verify_email tool reference
MailTooth exposes one deliberately focused tool. A smaller tool surface reduces ambiguity for models and lets every call share the same validation, billing, rate-limit, and audit guarantees as the REST API.
| Argument | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Complete email address. Whitespace is trimmed; maximum length is 254 characters. |
type | string | No | quick, standard, or deepcheck. enriched/pro are deprecated aliases for deepcheck. Defaults to standard. |
| Type | Use when | Cost |
|---|---|---|
quick | You need fast domain-level screening and do not require a mailbox verdict. | 0.5 credit |
standard | You need domain reputation and sender-security intelligence without SMTP. | 1 credit |
deepcheck | You need SMTP mailbox and catch-all checks plus full domain intelligence. | 2 credits |
enriched and pro are deprecated aliases for deepcheck. See the email verification guidefor the complete checks and response-field availability by type.
curl --no-buffer 'https://api.mailtooth.com/mcp' \
--request POST \
--header 'Authorization: Bearer YOUR_MAILTOOTH_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2025-11-25' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'curl --no-buffer 'https://api.mailtooth.com/mcp' \
--request POST \
--header 'Authorization: Bearer YOUR_MAILTOOTH_API_KEY' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2025-11-25' \
--data '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "verify_email",
"arguments": {
"email": "person@example.com",
"type": "deepcheck"
}
}
}'Read tool results
A successful call contains two representations of the same decision.content is a compact JSON summary optimized for the model;structuredContent is the complete typed object for your application, logs, routing, and deterministic post-processing.
| Field | Use |
|---|---|
content | Concise model-visible summary with verdict, score, key signals, and credit use. |
structuredContent | Full verification response plus current API-key and rate-limit capacity. |
addressStatus | Deterministic syntax, domain, and MX decision. |
mailbox.status | Mailbox decision or not_checked when SMTP is outside the selected tier. |
score | Supporting 0–100 deliverability score available only for Deepcheck. |
usage | Remaining key calls and current per-minute limit window. |
| Status | Meaning | Recommended agent action |
|---|---|---|
addressStatus: valid | Syntax, domain, and MX passed. The mailbox may still be not_checked. | Continue at domain level or run Deepcheck for mailbox confirmation. |
addressStatus: invalid | A conclusive syntax, domain, or MX check failed. | Stop or request a corrected address. |
mailbox: not_checked | The selected tier intentionally did not check the mailbox. | Follow the run_deepcheck action when mailbox confirmation is required. |
mailbox: deliverable / risky / undeliverable | Deepcheck obtained mailbox-level evidence. | Continue, review, or reject according to the result. |
address or mailbox: unknown | An attempted required check could not return a reliable result. | Retry later. The verification is refunded. |
{
"content": [
{
"type": "text",
"text": "{\"email\":\"person@example.com\",\"addressStatus\":\"valid\",\"mailboxStatus\":\"deliverable\",\"riskLevel\":\"low\",\"score\":98,\"confidence\":\"high\",\"verificationType\":\"deepcheck\",\"disposable\":false,\"roleBased\":false,\"creditsCharged\":2,\"creditsRemaining\":498}"
}
],
"structuredContent": {
"email": "person@example.com",
"verificationType": "deepcheck",
"addressStatus": "valid",
"mailbox": {
"status": "deliverable",
"isCatchAll": false,
"signals": []
},
"risk": {
"level": "low",
"signals": []
},
"score": 98,
"confidence": "high",
"signals": [],
"details": {
"...": "complete verification result"
},
"meta": {
"modelVersion": "deliverability-v2"
},
"creditsCharged": 2,
"creditsRemaining": 498,
"usage": {
"apiKeyRemainingCalls": 999,
"rateLimit": {
"limit": 60,
"remaining": 59,
"resetAt": "2026-08-10T10:01:00.000Z"
}
}
}
}Design reliable agent workflows
Let the model decide when to call the tool, but keep the business decision deterministic in your application. TreatstructuredContent.addressStatus and structuredContent.mailbox.status as the source of truth rather than parsing prose from the final assistant response.
| Workflow | Recommended instruction |
|---|---|
| Lead intake | "Before saving a lead, call verify_email with deepcheck. Save deliverable mailboxes, review risky, reject undeliverable, and retry unknown later." |
| Signup | "Verify the address before sending onboarding mail. Never block permanently on unknown; ask the user to retry." |
| CRM cleanup | "Verify only records selected by the user. Report projected call count before processing a large list." |
| Outbound message | "Require explicit approval before verifying or sending when the address was supplied by an untrusted source." |
Credits, quotas, and rate limits
MCP uses the same account balance and API-key quotas as REST. The selected cost is reserved immediately before verification. Completed requested outcomes keep the charge. Quick and Standard remain chargeable when mailbox status is intentionally not_checked. Unknown required outcomes and failed executions are refunded automatically.
| Event | Credits | Total key usage | Rate-limit use |
|---|---|---|---|
| Known verification result | Charged | Increments | Consumes one |
| Unknown result | Refunded | Increments | Consumes one |
| Execution failure after reservation | Refunded | Increments | Consumes one |
| Authentication rejection | Not reserved | Unchanged | Unchanged |
| Rate-limit rejection | Not reserved | Unchanged | Rejected call counts in the limiter window |
| Insufficient credits | Not reserved | Unchanged | Consumes one rate-limit slot |
The successful structured result includes creditsCharged,creditsRemaining, apiKeyRemainingCalls, and the current rate-limit reset timestamp. Use these fields for budget alerts and graceful pauses.
Errors and retry policy
Connection and authentication problems appear as HTTP errors. Errors that occur while invoking verify_email return a normal MCP tool result with isError: true and a stable JSON error object inside the text content.
| Code | Status | Agent handling |
|---|---|---|
INSUFFICIENT_CREDITS | 402 | Add credits or choose a less expensive verification type. |
API_KEY_LIMIT_EXCEEDED | 429 | Increase the key's total limit or use a new dedicated key. |
API_KEY_RATE_LIMIT_EXCEEDED | 429 | Wait for retryAfterSeconds, then retry with backoff. |
RATE_LIMITER_UNAVAILABLE | 503 | Retry with exponential backoff and jitter. |
VERIFICATION_FAILED | 500 | Treat as temporary and retry later. Failed execution is refunded. |
{
"isError": true,
"content": [
{
"type": "text",
"text": "{\"error\":{\"code\":\"API_KEY_RATE_LIMIT_EXCEEDED\",\"message\":\"This API key has exceeded its per-minute rate limit.\",\"statusCode\":429,\"retryAfterSeconds\":17}}"
}
]
}Recommended retry behavior
- Retry
API_KEY_RATE_LIMIT_EXCEEDEDonly afterretryAfterSeconds. - Retry temporary 500/503 failures with exponential backoff, jitter, and a small maximum attempt count.
- Do not retry invalid authentication, insufficient credits, or total key-limit errors until configuration changes.
- Schedule
unknownverification results for a later business retry; do not loop in the same agent turn.
Security and governance
- Create one API key per agent, environment, and workflow.
- Use the smallest practical per-minute and lifetime limits.
- Store keys in secret inputs, environment variables, or a vault.
- Never place keys in prompts, browser code, telemetry, or Git.
- Keep human approval enabled until tool behavior is understood.
- Allowlist only
verify_emailwhen the client supports tool filtering. - Monitor usage analytics and rotate or revoke unusual keys immediately.
- Do not treat inferred names or gender associations as verified identity.
MCP tool annotations correctly declare the tool as non-destructive but not read-only or idempotent because it consumes credits and updates usage records. Clients may therefore show an approval step before a call.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 during connection | Missing, malformed, revoked, or inactive API key. | Check the Bearer header, create a new active key, and reconnect. |
| 403 before tool discovery | The hosted endpoint rejected the request origin or host. | Use the public MailTooth MCP URL and a supported server-side client; contact support if the public host is affected. |
| 405 from a browser tab | A browser navigation sends GET; stateless MCP operations use POST. | Connect through an MCP client or use the protocol smoke test. |
| No tools appear | Wrong transport, URL, config key, or stale tool cache. | Choose HTTP, verify the /mcp suffix, restart the server, and clear the client's MCP tool cache. |
| Invalid request or schema error | The email or type does not match the published tool schema. | Pass one complete email and quick, standard, or deepcheck. |
| Tool repeatedly asks for approval | The client honors the tool's non-idempotent annotation. | Keep approval for sensitive workflows or configure a trusted per-tool policy in the client. |
| Agent ignores structured fields | The client exposes only text content to the model by default. | Use the concise JSON content or enable structured-content handling in your SDK. |
Frequently asked questions
Does MailTooth MCP support bulk verification?
Not through this tool. verify_email intentionally handles one address per call. Use the dashboard bulk workflow for large files, and do not make an agent loop over an unbounded list without explicit budget approval.
Does the agent need the REST response documentation?
The MCP schema is self-describing, but the email verification guide explains address and mailbox statuses, evidence fields, and tier-specific responses in greater depth.
Can I use x-api-key instead of Bearer authentication?
Yes. MailTooth accepts both. Bearer is recommended because more remote MCP clients expose a standard Authorization setting.
Why does direct browser navigation not show a page?
The endpoint is a machine protocol endpoint, not a website. MCP clients send JSON-RPC POST requests with protocol headers; a normal browser navigation sends GET.
Can a known cached result still cost credits?
Yes. Every known verification result uses the selected tier's credits whether the engine executes fresh checks or safely reuses a cached result. Unknown results remain free.
How should I test before production?
Use a dedicated key with a very small total limit, keep approvals enabled, test every status branch, confirm unknown and failure retries do not loop, then review MailTooth usage analytics before increasing limits.