email-fixture-lab
OfficialREADME.md
# Email Fixture Lab
Inspect an `.eml` file without uploading mail or opening its HTML. A small offline beta for people building email workflows, including Cloudflare Email Workers. Independent software by Valen Systems, not affiliated with Cloudflare.
## Try the ZIP
Install Node.js 22.13+, unzip, and run from the extracted directory:
```sh
node email-fixture-lab.mjs inspect examples/bounce.eml
```
To inspect your own file, run from the directory containing it:
```sh
node /path/to/email-fixture-lab.mjs inspect message.eml
```
The output describes body sizes, known MIME categories, attachments, nested messages and delivery-status fields. Email addresses become `address-1`, `address-2`, etc. Aliases preserve matching addresses within this inspection, including the nested original message; they reset for each file and are not cross-file identities. Exact address case is preserved internally when matching.
Subjects, display names, raw headers, message IDs, filenames, Content-IDs, diagnostic text and bodies are omitted. Unknown MIME types become `other`. Attachment bytes are never written or executed. Receipts contain input and attachment SHA-256 fingerprints, sizes, relationships and reported status codes: these can still be sensitive. Hashing is not encryption or anonymization. Review a receipt before sharing it.
## Local MCP
```json
{
"mcpServers": {
"email-fixture-lab": {
"command": "node",
"args": ["/path/to/email-fixture-lab.mjs", "mcp", "--root", "/path/to/fixtures"]
}
}
}
```
The only tool is `inspect_email_fixture`, with `{ "file": "bounce.eml" }`. Select a relative `.eml` path beneath the startup root. No directory discovery, URL input, network access, credentials, sending, account setup or file writes are exposed. Concurrent inspections return `BUSY` rather than queueing. CLI inspection uses the current directory as its root. Keep the root stable: this is not a sandbox against another local process replacing directories during a read.
## Beta limits
- Input: 1 MiB, regular files only, no symlinks in the selected relative path.
- MIME: 32 levels and 64 KiB aggregate headers per parsed message.
- Embedded `message/rfc822`: four levels below the outer message, 16 messages total.
- Across the inspection: 128 attachments and 256 address occurrences.
- Delivery-status part: at most 16 recipient blocks. Only standard action values and numeric enhanced-status codes are emitted. Duplicate/missing/unrecognized fields become null; `fieldsValid` checks only these extracted fields. `actionStatusConsistent` compares action and status class.
Exceeded limits fail with fixed error codes, without raw input in diagnostics. The parser is tolerant of malformed MIME; a successful inspection is not RFC conformance, a malware verdict, exhaustive MIME-tree validation or a claim that delivery occurred. Internationalized/global DSN extensions and arbitrary nested containers are outside v0.1. A DSN can be forged; this tool reports what a local fixture says. ZIP, PDF and image attachment contents are not recursively inspected. HTML is parsed as data, never rendered.
CLI exits: `0` inspected, `64` input/parse/limit error, `70` unexpected error. No runtime dependency installation is needed for the ZIP. Windows execution has not been tested.
## Source and build
```sh
npm ci --ignore-scripts
npm test
npm run build
```
The build uses the host's `zip`; package tests use `unzip`. Source CLI: `node src/cli.mjs inspect examples/bounce.eml`. Original adapter code is MIT licensed. Bundled dependencies retain their licenses, supplied in `licenses/` and `THIRD_PARTY_NOTICES.md`.
Parser: [PostalMime 3.0.0](https://github.com/postalsys/postal-mime), MIT-0. Its documented MIME/header limits are applied before extracting output. Delivery-status fields follow the core format in [RFC 3464](https://www.rfc-editor.org/rfc/rfc3464). All included messages are synthetic; no private mail code or messages were used.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues