Model Context Protocol

Email verification for AI agents

Give an agent one governed tool for checking email deliverability inside lead intake, CRM, signup, support, and outreach workflows—without writing a custom REST integration.

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.

MCP
https://api.mailtooth.com/mcp
Remote and stateless

No package, local process, session store, or webhook is required.

Same API-key controls

Rate limits, total limits, credits, analytics, and revocation all apply.

Safe failure semantics

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:

  1. A MailTooth account with enough credits for the verification type your agent will use.
  2. A dedicated active API key. Set a conservative per-minute limit and total request limit for this one agent or workflow.
  3. An MCP client that supports remote Streamable HTTP servers and custom request headers.
Keep the key out of promptsStore it in your client's secret input, environment variable, or secret manager. Never paste it into a chat message, source file, browser bundle, or committed configuration.

Five-minute setup

  1. Open API keys, create a key named for the agent, and copy the secret once.
  2. 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.
  3. Restart or reconnect the client, then confirm that it discovers exactly one tool named verify_email.
  4. Ask: “Verify person@example.com with MailTooth.” Review the tool arguments before approving the first call.
Generic remote MCP configuration
{
  "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.

SettingValue
TransportStreamable HTTP
Server URLhttps://api.mailtooth.com/mcp
Recommended headerAuthorization: Bearer YOUR_MAILTOOTH_API_KEY
Alternative headerx-api-key: YOUR_MAILTOOTH_API_KEY
Tool discoveryAutomatic 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.

  1. Export the key in your shell or secret manager.
  2. Run the command below. User scope makes the server available in every project.
  3. Run claude mcp list, then use /mcp inside Claude Code to inspect connection status.
Claude Code CLI
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 mailtooth

For a team-shared project definition, commit this .mcp.jsonfile without the secret and have every teammate setMAILTOOTH_API_KEY locally.

Claude Code · .mcp.json
{
  "mcpServers": {
    "mailtooth": {
      "type": "http",
      "url": "https://api.mailtooth.com/mcp",
      "headers": {
        "Authorization": "Bearer ${MAILTOOTH_API_KEY}"
      }
    }
  }
}
  1. Create .cursor/mcp.json for one project, or ~/.cursor/mcp.json for all projects.
  2. Paste the configuration and replace the placeholder locally.
  3. Open Cursor Settings → MCP, enable MailTooth, and confirm verify_email appears under Available Tools.
Cursor · mcp.json
{
  "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
  1. Run MCP: Open User Configuration for a private global setup, or create .vscode/mcp.json.
  2. Use the password input below so VS Code prompts once and stores the key securely.
  3. Run MCP: List Servers, start MailTooth, and accept the trust prompt.
VS Code · mcp.json
{
  "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}"
      }
    }
  }
}
  1. Set MAILTOOTH_API_KEY in the environment that launches Windsurf.
  2. Open ~/.codeium/windsurf/mcp_config.json and add the server entry.
  3. Refresh MCP servers in Cascade and confirm verify_email is enabled.
Windsurf · mcp_config.json
{
  "mcpServers": {
    "mailtooth": {
      "serverUrl": "https://api.mailtooth.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:MAILTOOTH_API_KEY}"
      }
    }
  }
}
  1. Install @openai/agents and keep MAILTOOTH_API_KEY in your runtime secret manager.
  2. Register MailTooth as a hosted MCP tool with an explicit one-tool allowlist.
  3. Keep approval enabled while testing. Change approval policy only after the workflow and budget controls are proven.
OpenAI Agents SDK · TypeScript
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.

ChatGPT and consumer connector UIsSome hosted connector UIs require an interactive OAuth flow and do not accept a user-supplied static header. The current MailTooth MCP endpoint uses API-key authentication, so use an agent SDK or client that supports custom headers. Do not paste a key into a connector description or prompt.

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.

ArgumentTypeRequiredDescription
emailstringYesComplete email address. Whitespace is trimmed; maximum length is 254 characters.
typestringNoquick, standard, or deepcheck. enriched/pro are deprecated aliases for deepcheck. Defaults to standard.
TypeUse whenCost
quickYou need fast domain-level screening and do not require a mailbox verdict.0.5 credit
standardYou need domain reputation and sender-security intelligence without SMTP.1 credit
deepcheckYou 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.

Protocol smoke test · list tools
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"}'
Protocol smoke test · call verify_email
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.

FieldUse
contentConcise model-visible summary with verdict, score, key signals, and credit use.
structuredContentFull verification response plus current API-key and rate-limit capacity.
addressStatusDeterministic syntax, domain, and MX decision.
mailbox.statusMailbox decision or not_checked when SMTP is outside the selected tier.
scoreSupporting 0–100 deliverability score available only for Deepcheck.
usageRemaining key calls and current per-minute limit window.
StatusMeaningRecommended agent action
addressStatus: validSyntax, domain, and MX passed. The mailbox may still be not_checked.Continue at domain level or run Deepcheck for mailbox confirmation.
addressStatus: invalidA conclusive syntax, domain, or MX check failed.Stop or request a corrected address.
mailbox: not_checkedThe selected tier intentionally did not check the mailbox.Follow the run_deepcheck action when mailbox confirmation is required.
mailbox: deliverable / risky / undeliverableDeepcheck obtained mailbox-level evidence.Continue, review, or reject according to the result.
address or mailbox: unknownAn attempted required check could not return a reliable result.Retry later. The verification is refunded.
Successful MCP tool result
{
  "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.

WorkflowRecommended 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."
Avoid accidental repeat chargesTool calls are not idempotent from a billing perspective: each known result uses credits, including cached verification results. Persist the verdict and its timestamp in your workflow when reuse is acceptable instead of asking the agent to verify repeatedly.

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.

EventCreditsTotal key usageRate-limit use
Known verification resultChargedIncrementsConsumes one
Unknown resultRefundedIncrementsConsumes one
Execution failure after reservationRefundedIncrementsConsumes one
Authentication rejectionNot reservedUnchangedUnchanged
Rate-limit rejectionNot reservedUnchangedRejected call counts in the limiter window
Insufficient creditsNot reservedUnchangedConsumes 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.

CodeStatusAgent handling
INSUFFICIENT_CREDITS402Add credits or choose a less expensive verification type.
API_KEY_LIMIT_EXCEEDED429Increase the key's total limit or use a new dedicated key.
API_KEY_RATE_LIMIT_EXCEEDED429Wait for retryAfterSeconds, then retry with backoff.
RATE_LIMITER_UNAVAILABLE503Retry with exponential backoff and jitter.
VERIFICATION_FAILED500Treat as temporary and retry later. Failed execution is refunded.
MCP tool error result
{
  "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

  1. Retry API_KEY_RATE_LIMIT_EXCEEDED only afterretryAfterSeconds.
  2. Retry temporary 500/503 failures with exponential backoff, jitter, and a small maximum attempt count.
  3. Do not retry invalid authentication, insufficient credits, or total key-limit errors until configuration changes.
  4. Schedule unknown verification 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_email when 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

SymptomLikely causeFix
401 during connectionMissing, malformed, revoked, or inactive API key.Check the Bearer header, create a new active key, and reconnect.
403 before tool discoveryThe 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 tabA browser navigation sends GET; stateless MCP operations use POST.Connect through an MCP client or use the protocol smoke test.
No tools appearWrong 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 errorThe email or type does not match the published tool schema.Pass one complete email and quick, standard, or deepcheck.
Tool repeatedly asks for approvalThe 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 fieldsThe 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.

Ready to connect?

Create a governed key for your agent.

Open API keys