Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TempMail OTP — Self-Hosted Temporary Email Generator

Receive-only temp email server with automatic OTP extraction for security research, QA automation, and disposable identity workflows.

Features

  • SMTP catch-all — accepts all inbound email on your domain (port 25, no auth)
  • Real-time inbox — SSE stream pushes new emails instantly to the browser
  • OTP extraction — automatic detection of verification codes (4–8 digit, alphanumeric)
  • Link extraction — parse all URLs from plain-text and HTML email bodies
  • REST API — authenticated endpoints for email generation, reading, OTP, and link extraction
  • MCP integration — stdio-based Model Context Protocol server for AI agents (Hermes, Claude, etc.)
  • Docker — multi-stage build, SQLite persistence, health check included
  • Dark/light mode — built with Tailwind CSS + shadcn/ui
  • DNS verification — built-in /api/dns-check endpoint validates MX, SPF, DMARC records
  • Multi-key support — manage API keys via the web UI or /api/keys endpoint

Prerequisites

  • Node.js 20+ (with tsx for MCP; npm for package management)
  • Domain name — configured with MX, SPF, and DMARC records
  • Port 25 access — required for SMTP receiving; unavailable on most home ISPs. Use a VPS (Oracle Cloud Free Tier, AWS EC2, DigitalOcean) or port forwarding if supported

Quick Start

1. Clone and install

git clone <repo-url> website-email
cd website-email
npm install

2. Configure environment

cp .env.example .env

Edit .env with your domain and a strong API key:

DOMAIN=mail.yourdomain.com
API_KEY=your-generated-api-key

Generate a secure API key:

openssl rand -hex 32

3. Set up DNS records

Configure MX, SPF, and DMARC records for your domain. See the complete guide:

docs/dns-setup.md

Quick verification after DNS propagates:

dig MX yourdomain.com +short
dig TXT yourdomain.com +short | grep spf
dig TXT _dmarc.yourdomain.com +short

4. Start the servers

Terminal 1 — Next.js web UI + API:

npm run dev

Terminal 2 — SMTP server (receives mail):

npx tsx src/infrastructure/smtp/start.ts

5. Open the app

http://localhost:3000

Generate a temp email address, send a test email to it, and watch it appear in real-time.

Docker Deployment

1. Configure .env

Same as Quick Start — fill in DOMAIN and API_KEY.

2. Build and start

docker compose up -d

3. Verify

curl http://localhost:3000/api/config
# {"success":true,"data":{"domain":"mail.yourdomain.com"}}
# Note: never returns API_KEY — paste API_KEY from .env into the UI when prompted

Note: Docker Compose exposes port 3000 only (web UI + API). Run the SMTP server directly on the host for port 25:

npx tsx src/infrastructure/smtp/start.ts

For production, use a reverse proxy (nginx/Caddy) for TLS termination and run SMTP via a process manager (systemd, pm2).

Environment Variables

Variable Required Default Description
DOMAIN Yes Your domain for receiving email (e.g. thefreelancer.web.id)
API_KEY Yes Secret key for API, MCP, and Cloudflare Worker (must match Worker secret)
SMTP_PORT No 25 Port for inbound SMTP
SMTP_HOST No 0.0.0.0 Bind address for SMTP server
DB_PATH No ./data/emails.db SQLite database file path
NEXT_PUBLIC_APP_URL No http://localhost:3000 Public URL of the application
CLOUDFLARE_WORKER_URL No (empty) Cloudflare Worker base URL for cloud inbox fallback. Empty = local SQLite only. Example: https://freelancer-mail.<subdomain>.workers.dev

Do not use legacy URLs such as tempik.email1-f03.workers.dev. Current worker name is freelancer-mail. See cloudflare-email-worker/README.md and root AGENTS.md.

REST API

Most endpoints require an x-api-key header matching server API_KEY or an active key created via /api/keys.
GET /api/config is public and returns { domain } only (never the secret).
Response format: { "success": true, "data": ... } or { "success": false, "error": "..." }.

npm test          # unit tests (vitest)
npm run lint
npm run build

Email Addresses

Method Endpoint Description
GET /api/addresses List all addresses
POST /api/addresses Generate new address (optional body: { "address": "custom@domain" })
DELETE /api/addresses/:id Delete an address and its emails

Emails

Method Endpoint Description
POST /api/emails/generate Generate address (shorthand)
GET /api/emails/:address List emails for an address
GET /api/emails/:address/:id Read a specific email
DELETE /api/emails/:address/:id Delete a specific email
POST /api/emails/:address/:id/otp Extract OTP from email
GET /api/emails/:address/:id/links Extract links from email
GET /api/emails/:address/stream SSE stream for real-time email events

Misc

Method Endpoint Description
GET /api/config Get server domain only (no auth, no secrets)
GET /api/dns-check Verify DNS records (MX, SPF, DMARC; requires API key)
GET /api/keys List API keys
POST /api/keys Create new API key

Example: Full workflow

KEY="your-api-key"
DOMAIN="mail.example.com"

# Generate an address
curl -sH "x-api-key: $KEY" -X POST http://localhost:3000/api/emails/generate | jq

# List emails
curl -sH "x-api-key: $KEY" "http://localhost:3000/api/emails/temp-abc123@$DOMAIN" | jq

# Read email and extract OTP
curl -sH "x-api-key: $KEY" -X POST \
  "http://localhost:3000/api/emails/temp-abc123@$DOMAIN/eml_xxx/otp" | jq

MCP Integration

The MCP server exposes 5 tools for AI agents via stdio transport:

Tool Description
temp_email_generate Generate a new temporary email address
temp_email_list List emails for an address
temp_email_read Read a specific email by ID
temp_email_extract_otp Extract OTP/verification code from an email
temp_email_extract_links Extract all links from an email

Configuration and workflow documentation:

docs/hermes-integration.md — Hermes MCP configuration → docs/chrome-devtools-mcp.md — Browser automation with Chrome DevTools MCP → docs/workflow-examples.md — Copy-paste ready prompts

Quick test:

DOMAIN=mail.example.com API_KEY=your-key npx tsx src/infrastructure/mcp/start.ts

Architecture

Two independent inbound paths. App reads local SQLite first, then optionally pulls from the Worker.

                    Internet mail
                   /              \
                  v                v
     ┌──────────────────┐   ┌────────────────────────────┐
     │ Host SMTP :25    │   │ CF Email Routing (zone)    │
     │ smtp-server      │   │ → Worker freelancer-mail   │
     │ → local SQLite   │   │ → D1 freelancer-mail-db    │
     └────────┬─────────┘   └─────────────┬──────────────┘
              │                           │
              │              GET /emails/:addr (x-api-key)
              │                           │
              v                           v
     ┌────────────────────────────────────────────┐
     │ Next.js app (UI + REST + SSE)              │
     │ getEmailsByAddress: local first, then      │
     │ CLOUDFLARE_WORKER_URL if set               │
     │ OTP/link extraction happens HERE only      │
     └──────────────────┬─────────────────────────┘
                        │
                        v
              MCP stdio (npm run mcp)

Domain is configurable: set app DOMAIN + Cloudflare Email Routing on that zone. Worker name is not the email domain.

Stack: Next.js 14 + TypeScript + Tailwind CSS + shadcn/ui + better-sqlite3 + smtp-server + mailparser + Cloudflare Workers/D1

Cloudflare Worker (optional cloud ingest)

Separate package: cloudflare-email-worker/.

Piece Value
Worker freelancer-mail
D1 freelancer-mail-db
Deploy cd cloudflare-email-worker && npx wrangler deploy (or ./deploy-fresh.sh)
App wire CLOUDFLARE_WORKER_URL in .env + same API_KEY as Worker secret
Dashboard Email Routing catch-all → Send to Worker freelancer-mail

Details: cloudflare-email-worker/README.md, docs/deployment.md, AGENTS.md.

Additional Documentation

License

MIT

About

Self-hosted temporary email generator with automatic OTP extraction — SMTP catch-all, real-time inbox (SSE), REST API, and MCP server for AI agents.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages