The email layer for AI agents

  • Every email, cleaned up
  • Ready for your model
  • The same result, every time

Your agent shouldn't have to fight MIME headers, quoted-printable, and tangled reply chains. MVRX turns every email into clean JSON it can actually read — in a single call.

inbox — support@acmeco.ioraw → normalizedawait parse(message)

Inbox 142

raw · RFC 5322

Received: from mail-sor-f41.google.com ([209.85.220.41])
  by mx.acmeco.io with ESMTPS id q9-20020a17090a
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
Message-ID: <c9f1a2@mail.acmeco.io>
From: Priya Nair <priya@acmeco.io>
Subject: Re: Webhook signature verification failing
Date: Tue, 14 Jan 2026 09:12:44 +0000
References: <a1b2c3@mail.runbot.dev> <b7e0d1@mail.runbot.dev>
In-Reply-To: <b7e0d1@mail.runbot.dev>
Content-Type: multipart/alternative; boundary="0000b616f2"
--0000b616f2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64
PGRpdiBkaXI9Imx0ciI+SGV5IHRlYW0sPGJyPjxicj5U
aGFua3MgZm9yIHRoZSBmaXgg4oCUIHNpZ25hdHVyZXM=

NormalizedEmail

{
  "messageId": "c9f1a2@mail.acmeco.io",
  "threadId": "a1b2c3@mail.runbot.dev",
  "metadata": {
    "from": {
      "name": "Priya Nair",
      "email": "priya@acmeco.io"
    },
    "subject": "Re: Webhook signature verification failing",
    "date": "2026-01-14T09:12:44Z",
    "timestamp": 1768381964
  },
  "content": {
    "forAI": "Hey team,\n\nThanks for the fix — signatures are verifying correctly now on staging. Can you confirm the same patch ships to production today?\n\nPriya",
    "html": "<div dir="ltr">Hey team,<br><br>Thanks for the fix — signatures are verifying correctly now on staging. Can you confirm the same patch ships to production today?<br><br>Priya</div>"
  },
  "thread": {
    "inReplyTo": "b7e0d1@mail.runbot.dev",
    "references": ["a1b2c3@mail.runbot.dev", "b7e0d1@mail.runbot.dev"]
  }
}

8/8
reference emails, all passing
6
levels of detail per email
0
runtime dependencies
100%
reproducible results

See the difference

The same email, twice

On the left, what an email actually looks like on the wire. On the right, what your agent gets back from MVRX — the same message, in a shape your model can read, every single time.

before — raw RFC 532218,412 bytes
Received: from mail-sor-f41.google.com ([209.85.220.41])
        by mx.acmeco.io with ESMTPS id q9-20020a17090a…
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=acmeco.io; s=google; h=mime-version:references…
References: <a1b2c3@mail.runbot.dev> <b7e0d1@mail.runbot.dev>
In-Reply-To: <b7e0d1@mail.runbot.dev>
Content-Type: multipart/alternative; boundary="0000b616f2"

--0000b616f2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hey team,
Thanks for the fix =E2=80=94 signatures are verifying correc=
tly now on staging. Can you confirm the same patch ships to=
 production today?
Priya
--=20
Priya Nair
Platform Lead, Acme Co.
On Mon, Jan 13, 2026 at 4:02=E2=80=AFPM Runbot Support wrot=
e:
> Hi Priya, we found the bug in our HMAC digest step and
--0000b616f2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

PGRpdiBkaXI9Imx0ciI+SGV5IHRlYW0sPGJyPjxicj5UaGFua3MgZm9yIHRo
ZSBmaXgg4oCUIHNpZ25hdHVyZXMgYXJlIHZlcmlmeWluZyBjb3JyZWN0bHkg
bm93IG9uIHN0YWdpbmcuIENhbiB5b3UgY29uZmlybSB0aGUgc2FtZSBwYXRj
aCBzaGlwcyB0byBwcm9kdWN0aW9uIHRvZGF5Pzxicj48YnI+UHJpeWE8YnI+
after — email.content.forAI178 chars

Hey team, Thanks for the fix — signatures are verifying correctly now on staging. Can you confirm the same patch ships to production today? Priya

quoted chain, signature & markup removed · threading resolved to a1b2c3@mail.runbot.dev

178 chars
payload your agent reads · from 18.4 KB raw
~41 tokens
tokens per message
1 of 6
content levels — the rest stay available

See it in code

One call, and you're done

Drop parse() into a Cloudflare Email Worker and you're forwarding clean, agent-ready JSON. No config, no setup, no pipeline to maintain.

What it handles for you

  • Cleans up the raw email
  • Strips quotes & signatures
  • Sorts it into a thread
  • Guards against prompt injection

From the @mvrx/mail README — implemented code, not pseudocode.

src/worker.tsnpm install @mvrx/mail
import { parse, wrappers } from "@mvrx/mail";

export default {
  async email(message: ForwardableEmailMessage) {
    const email = await parse(message, {
      wrapper: wrappers.xml("email"),
    });

    await fetch("https://agent.example.com/inbox", {
      method: "POST",
      body: JSON.stringify({
        messageId: email.messageId,
        threadId: email.threadId,
        from: email.metadata.from,
        subject: email.metadata.subject,
        input: email.content.forAI,
      }),
    });
  },
};

Open source

Built on an open standard, not a walled garden

AECS-1 is public domain — free forever, in any language. Everything MVRX ships is built on top of it, so nothing you write is locked to us: implement the spec yourself, swap in another SDK, or use ours.

AECS-1 specification

CC0 1.0

The NormalizedEmail schema and threading algorithm are public domain — implement them in any language, no license required.

@mvrx/aecs

MIT

The spec's reference implementation. Framework-agnostic, zero infrastructure dependencies — fork it, embed it, or write your own from the spec.

@mvrx/mail

AGPL-3.0-only

The Cloudflare Email Routing SDK, built on @mvrx/aecs. Commercial licensing (no AGPL obligations) is available from MVRX for closed-source embedding.

@mvrx/wbxml

MIT

Standalone WBXML codec with no product logic — licensed permissively so it's freely embeddable anywhere.

Full breakdown: /docs/licensing


Managed hosting

Open-source today.
Hosted when you're ready.

Point your domain at MVRX and get clean, agent-ready email delivered as JSON — no servers, no parsing, nothing to run. Join the waitlist and we'll tell you the moment it's live.