MCP server

rate.email exposes a Model Context Protocol server so an agent can rate an address itself, mid-conversation, instead of asking a person to run a curl command.

Transport

The primary transport is Streamable HTTP at POST /mcp on the same Worker as the REST API, no separate deployment. @rate-email/mcp is a thin stdio wrapper for clients that only speak stdio: it carries no rating logic of its own and proxies every call to the HTTP endpoint.

Install

Claude Desktop

Add to your claude_desktop_config.json, using the stdio wrapper:

{
  "mcpServers": {
    "rate-email": {
      "command": "npx",
      "args": [
        "-y",
        "@rate-email/mcp"
      ],
      "env": {
        "RATE_EMAIL_API_KEY": "your_api_key"
      }
    }
  }
}

Claude Code

Point Claude Code straight at the Streamable HTTP endpoint:

{
  "mcpServers": {
    "rate-email": {
      "type": "http",
      "url": "https://api.rate.email/mcp",
      "headers": {
        "Authorization": "Bearer your_api_key"
      }
    }
  }
}

Cursor

Cursor's MCP config also works with the stdio wrapper:

{
  "mcpServers": {
    "rate-email": {
      "command": "npx",
      "args": [
        "-y",
        "@rate-email/mcp"
      ],
      "env": {
        "RATE_EMAIL_API_KEY": "your_api_key"
      }
    }
  }
}

Never put the API key in a tool argument. Both configs above read it from an environment variable or a header, so a model never needs to see or repeat it.

Tools

MCP tools exposed by the rate.email server
ToolWhat it does
rate_emailRates one address: verdict, score and reasons. Set deliverability: true for a live SMTP probe on paid tiers.
rate_domainRates a domain only, without a local part. Cheaper and coarser than rate_email.
explain_reasonLooks up one reason code and returns its severity, source, trigger and an example message.
list_reasonsReturns the full reason code catalogue. No arguments, no filtering.
check_usageReturns the calling API key's tier, quota, remaining quota and reset time.

rate_email

{
  "type": "object",
  "required": [
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    },
    "deliverability": {
      "type": "boolean",
      "default": false
    },
    "custom_list_id": {
      "type": "string"
    }
  }
}

rate_domain

{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "format": "hostname"
    }
  }
}

explain_reason

{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string"
    }
  }
}

list_reasons

{
  "type": "object",
  "properties": {}
}

check_usage

{
  "type": "object",
  "properties": {}
}

Example call and result

Calling rate_email on a known disposable address:

Tool call

{
  "name": "rate_email",
  "arguments": {
    "email": "throwaway@mailinator.com"
  }
}

Tool result

{
  "content": [
    {
      "type": "text",
      "text": "(JSON string, parsed below)"
    }
  ],
  "isError": false
}
content[0].text, parsed
{
  "email": "throwaway@mailinator.com",
  "normalized": "throwaway@mailinator.com",
  "verdict": "reject",
  "score": 0,
  "reasons": [
    {
      "code": "DISPOSABLE_DOMAIN",
      "severity": "high",
      "source": "allowlist:disposable",
      "message": "mailinator.com is a known disposable email domain."
    }
  ]
}

Prompt: triage-signups

Given a CSV of addresses, rates each one and groups the results by verdict, with the top reason codes per group. Built for a human reviewing a batch of signups or an import file before deciding what to do with the review and reject buckets.

{
  "name": "triage-signups",
  "arguments": {
    "csv": "email
jane@example.com
bob@mailinator.com
sales@customer-domain.com"
  }
}

The rendered prompt asks the agent to call list_reasons first for any unfamiliar code, rate every address, and report addresses that fail to rate separately as "could not rate" rather than inventing a verdict for them.