echo.email MCP server

The MCP server gives AI agents the echo.email test: create an address, send one email to the address, wait for the report. The server is free, with no key and no signup. The registry lists the server as email.echo/deliverability.

Connect

Server URL, Streamable HTTP transport:

https://mcp.echo.email/mcp

Claude Code:

claude mcp add --transport http echo-email https://mcp.echo.email/mcp

Clients with a JSON configuration:

{
  "mcpServers": {
    "echo-email": { "type": "http", "url": "https://mcp.echo.email/mcp" }
  }
}

Tools

ToolArgumentsResult
create_test_addressnone address, token, key, idle_timeout_s, status_url
wait_for_reporttoken, key, timeout_s (1 to 50, default 45) status waiting or received (call again), or done with report_id, report_url and a digest
get_reportreport_id the digest plus the full report as JSON

The digest holds the score, SPF, DKIM, DMARC, TLS, IPv6 readiness and the failing sender requirements. Every result carries the data twice: as JSON text in content and as structuredContent.

Typical run

  1. The agent calls create_test_address.
  2. The agent sends one email to the address, through the application or mail server under test.
  3. The agent calls wait_for_report until the status is done.
  4. For details, the agent calls get_report.

The address stays alive while wait_for_report runs and for 10 minutes after the last call. Each address accepts one message, and reports are deleted after 24 hours.

Protocol

The server follows MCP 2026-07-28 and answers every request statelessly with a single JSON response. There is no handshake and no session. Each request carries the protocol version and the client details in _meta, and the HTTP headers repeat the version, the method and, for tools/call, the tool name. A tool name outside plain ASCII goes in Mcp-Name as =?base64?…?=.

POST /mcp HTTP/1.1
Host: mcp.echo.email
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: wait_for_report

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "wait_for_report",
    "arguments": {
      "token": "lake.mother.column",
      "key": "q3k7…",
      "timeout_s": 45
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "my-agent",
        "version": "1.0"
      },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

Every result carries resultType and the server details in _meta:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "{ \"status\": \"done\", … }"
      }
    ],
    "structuredContent": {
      "status": "done",
      "report_id": "…",
      "report_url": "https://echo.email/r/…",
      "digest": {
        "score": "8/9"
      }
    },
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "echo.email",
        "version": "1.1.0"
      }
    }
  }
}

server/discover returns the supported versions, the capabilities and the instructions. server/discover and tools/list results add ttlMs (one hour) and cacheScope, because the tool list only changes on a release.

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "supportedVersions": [
      "2026-07-28",
      "2025-11-25",
      "2025-06-18",
      "2025-03-26",
      "2024-11-05"
    ],
    "capabilities": {
      "tools": {
        "listChanged": false
      }
    },
    "instructions": "Create a test address, send one email to it, then wait for the report.",
    "ttlMs": 3600000,
    "cacheScope": "public",
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "echo.email",
        "version": "1.1.0"
      }
    }
  }
}

Errors

HTTPCodeCause
400-32020A required header is missing or differs from the body
400-32022Unsupported protocol version. The error data lists supported and requested
404-32601Unknown method
200-32602Unknown tool
403An Origin header from another site
405GET or DELETE on the endpoint
202A notification, accepted with an empty body

Rate limits and dead addresses come back as tool results with isError: true and a message the agent acts on. Each IP address gets 30 new addresses and 120 status or report requests per minute, and every poll inside wait_for_report counts as one request.

Older clients

Clients built for earlier MCP versions connect through the initialize handshake, with versions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05. A request without the version header counts as 2025-03-26. These clients also get ping. The tools and the results are the same in both cases.

API

Scripts and CI jobs use the same flow through the echo.email API.