An email MCP server for Claude Code, Codex, and Cursor

Give coding agents a real inbox over MCP: install the agent-temp-mail server with one command, learn its seven tools, and keep the key out of the model.

On this page
  1. What it does
  2. Claude Code
  3. Codex
  4. Cursor and others
  5. The seven tools
  6. A typical session
  7. Protect the key
  8. Local or hosted
  9. Troubleshooting

Coding agents keep running into email. You ask Claude Code to build a signup flow and test it, or Codex to create an account on a staging service, and the work stalls at “check your inbox.” An MCP server gives the agent an inbox it can check by itself.

Agent Temp Mail ships one in its npm package. It runs locally over stdio, needs no account or API key, and keeps the mailbox’s private key in a file the model never sees. Setup is one command.

What the server does

The server gives your agent a permanent, receive-only address tied to a key file on your machine. On first run it generates an Ed25519 keypair and saves it, readable only by you, at the path you choose. The public key becomes the address. The private key signs every request the server makes for the agent.

That split is the point. The tool calls the model makes contain ordinary arguments, like a message ID. The server adds the signature after the model is done, so nothing that grants access to the inbox passes through the conversation.

Install in Claude Code

mkdir -p "$HOME/.config/agent-temp-mail"
claude mcp add --transport stdio \
  --env MAIL_KEY_FILE="$HOME/.config/agent-temp-mail/identity.key.json" \
  agent-temp-mail -- npx --yes --package=agent-temp-mail@0.4.0 agent-temp-mail-mcp

Start a new session and ask, “What’s my agent-temp-mail address?” The agent calls inspect_inbox and tells you.

Install in Codex

mkdir -p "$HOME/.config/agent-temp-mail"
codex mcp add agent-temp-mail \
  --env MAIL_KEY_FILE="$HOME/.config/agent-temp-mail/identity.key.json" \
  -- npx --yes --package=agent-temp-mail@0.4.0 agent-temp-mail-mcp

Cursor, Claude Desktop, and other MCP clients

Any client that reads the standard mcpServers JSON works with the same block. In Cursor that’s ~/.cursor/mcp.json, or .cursor/mcp.json inside a project. In Claude Desktop it’s claude_desktop_config.json.

{
  "mcpServers": {
    "agent-temp-mail": {
      "command": "npx",
      "args": ["--yes", "--package=agent-temp-mail@0.4.0", "agent-temp-mail-mcp"],
      "env": { "MAIL_KEY_FILE": "/absolute/path/to/agent.key.json" }
    }
  }
}

Use an absolute path. Many clients don’t expand ~ or $HOME inside JSON.

The seven tools

ToolWhat it doesEffect
inspect_inboxShows the address, retention, and what’s stored. Works before any mail arrives.Read
list_messagesLists message summaries oldest first, with since, sender, after, and limit filters.Read
get_messageReturns one message as plain text, with candidate codes and links.Read
get_candidatesReturns only candidate codes and links, each with its source message ID.Read
configure_inboxSets retention for new messages, from one hour to seven days.Changes settings
delete_messageDeletes one message.Deletes
purge_inboxDeletes all stored messages and settings. The address keeps working.Deletes

If your client lets you auto-approve tools, approving the four read tools covers almost every task. Leave the others to ask first.

What a session looks like

Say you’re testing the signup flow on a staging deployment and you ask:

Sign up at https://staging.example.com/signup with my agent-temp-mail address,
finish email verification, and confirm the dashboard loads.

A well-behaved agent will:

  1. Call inspect_inbox to get the address.
  2. Note the current time, then submit the form with its browser or HTTP tool.
  3. Call list_messages with since set to that time, waiting between empty checks as the response’s poll_after_seconds suggests.
  4. Call get_candidates, choose the verification link on staging.example.com, and open it.
  5. Load the dashboard and report what it found.

If the agent skips the timestamp step, ask for it. It’s the difference between verifying today’s email and yesterday’s. How AI agents receive verification codes explains the rest of the loop.

Keep the key file safe

  • The key is the inbox. Anyone who copies the file can read the mail. Keep it outside your repository, and add the path to .gitignore if it has to live nearby.
  • Lose it and the address is gone. There’s no recovery and no way to move the address to a new key. Back the file up if the address matters.
  • Lock it in after setup. Once the file exists, add MAIL_REQUIRE_EXISTING_KEY=1 to the server’s environment. Without it, a mistyped path silently creates a new key, and with it a new address.
  • One key per agent. Give separate agents separate files unless you want them to share an inbox.

Local server or hosted endpoint?

There’s also a hosted Streamable HTTP endpoint at https://agent-temp-mail.com/mcp, meant for custom connectors in ChatGPT and Claude where you can’t run a local process. With no local process to hold the key, every protected tool call must carry an _auth proof: a signature over that exact tool name and those exact arguments, valid for 60 seconds and usable once. The SDK builds it for you:

import { loadIdentity, signedToolArguments } from "agent-temp-mail";

const identity = await loadIdentity("./agent.key.json");
const args = signedToolArguments(identity, "list_messages", {
  since: new Date().toISOString(),
});
// Pass args as the list_messages tool arguments in your connector.

That makes the hosted endpoint better for occasional, deliberate calls. For an agent that works on your machine, the local server is simpler and safer: it signs automatically and hides _auth from the tools the model sees.

Troubleshooting

  • The server exits immediately. Check that node --version reports 22.12 or later, that MAIL_KEY_FILE is set, and that its directory exists.
  • The address changed. The server started with a different key path. Point it back at the original file and set MAIL_REQUIRE_EXISTING_KEY=1.
  • HTTP 429 errors. Each key can make 30 signed calls a minute, and the service shares a daily budget. The error includes retry_after_seconds; wait that long. Agents that check in a tight loop hit this first.
  • A 409 replay error. A signed request was reused. The local server signs every call fresh, so this usually means a hosted-connector proof was retried. Sign again.

The full protocol lives in llms.txt, and every supported runtime is listed in integrations.md.