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
| Tool | What it does |
|---|---|
| rate_email | Rates one address: verdict, score and reasons. Set deliverability: true for a live SMTP probe on paid tiers. |
| rate_domain | Rates a domain only, without a local part. Cheaper and coarser than rate_email. |
| explain_reason | Looks up one reason code and returns its severity, source, trigger and an example message. |
| list_reasons | Returns the full reason code catalogue. No arguments, no filtering. |
| check_usage | Returns 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.