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 doesSchema
rate_emailRates one address: verdict, score and reasons. Set deliverability: true for a live SMTP probe on paid tiers.
View schema
{
  "type": "object",
  "required": [
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email"
    },
    "deliverability": {
      "type": "boolean",
      "default": false
    },
    "custom_list_id": {
      "type": "string"
    }
  }
}
rate_domainRates a domain only, without a local part. Cheaper and coarser than rate_email.
View schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "format": "hostname"
    }
  }
}
explain_reasonLooks up one reason code and returns its severity, source, trigger and an example message.
View schema
{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string"
    }
  }
}
list_reasonsReturns the full reason code catalogue. No arguments, no filtering.
View schema
{
  "type": "object",
  "properties": {}
}
check_usageReturns the calling API key's tier, quota, remaining quota and reset time.
View schema
{
  "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": "{"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."}]}"
    }
  ],
  "isError": false
}

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.