2 pointsby Iammnhamza2 hours ago1 comment
  • Iammnhamza2 hours ago
    Hi HN. I run AgentiSend, an email API for applications and AI agents. This is the part we pulled out and open-sourced (MIT).

    The failure it's for: an agent's send tool times out, the model retries, and each retry changes a word, so idempotency keys never match. In the demo, 400 attempts to send one customer the same receipt: 5 go out, 395 are refused. (The demo raises the threshold so you can see it; the default refuses the 4th.)

    It's blast-radius control, not a filter. Whatever the model decides: at most N emails per hour/day/month, M per minute, no near-repeats to the same inbox, a kill switch, and a hold for recipients you mark (e.g. anyone the agent hasn't emailed before) until a person approves.

    Three forms, strongest first:

    - a Claude Code PreToolUse hook (npx agent-email-guard hook install) that checks every email-sending tool call, whichever MCP server it goes to

    - an MCP proxy (npx agent-email-guard mcp --wrap ...) for Cursor, Codex, Claude Desktop

    - a library for Node, Python, PHP and Go that wraps nodemailer, SES, Resend, Postmark or SMTP

    The four libraries are one spec plus 49 shared test vectors, so they print the same decisions. npx agent-email-guard test runs 12 runaway scenarios (a prompt-injected forward, the 400-receipt loop, a recipient sweep, a reply-all storm) against a reference policy and shows what got through.

    Limits, stated up front: the library runs in the agent's process, so an agent that edits its own tools can route around it. The hook and proxy sit outside the agent's code but guard one machine. None of them stops someone who holds your provider API key from calling the provider directly. Our paid API enforces the same policy server-side, which is the only place that last gap closes. That's the line between free and paid.

    I'd like to hear about loops it misses and sends it blocks that it shouldn't.