A semi-automated cold email outreach and follow-up agent with intelligent leads management, powered by multiple AI providers and deployed on Vercel.
Branch: vercel | Status: Production-ready MVP with Phase 3.5+ features
Midas is a full-stack TypeScript/Python application that automates the entire cold email outreach workflow:
- Lead Management β Upload and manage CSV/XLSX files with prospect data
- Campaign Orchestration β Create campaigns with customizable follow-up sequences
- Intelligent Email Drafting β AI-powered email generation based on tone, use case, and campaign context
- Automated Sending β Scheduled delivery via Mailgun with domain deliverability management
- Reply Intelligence β Automatic sentiment analysis and reply-to-reply generation
- Inbox Management β Centralized inbox for monitoring opens, clicks, bounces, and replies
- Domain Warmup β Built-in sender reputation management with daily send limits and bounce tracking
Key Stats:
- 84.5% TypeScript | 12.9% Python | 3.6% Other
- Tech Stack: Vite + React, Express.js, Prisma, PostgreSQL (Neon), Clerk Auth, Mailgun, Multiple AI Providers
- Deployment: Vercel (serverless) with scheduled cron jobs
- Node.js 18+
- PostgreSQL database (Neon recommended for serverless)
- Environment variables (see Configuration section)
# Clone the repository
git clone https://github.com/Pyrex611/Midas.git
cd Midas
git checkout vercel
# Install dependencies
npm install
# Generate Prisma client
npx prisma generate
# Setup database
npx prisma db push
# Start development server
npm run devFrontend: Accessible at http://localhost:5173
Backend API: Accessible at http://localhost:3000/api
# Build for production
npm run build
# Start production server
npm start
# Vercel deployment
npm run vercel-buildCreate a .env.local file in the project root with the following variables:
# Database
DATABASE_URL=postgresql://user:password@host/dbname
DATABASE_URL_POOLED=postgresql://user:password@host/dbname?sslmode=require
# Frontend
VITE_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
# Backend Authentication
CLERK_SECRET_KEY=your_clerk_secret_key
CLERK_WEBHOOK_SECRET=your_clerk_webhook_secret
# CORS & Deployment
CORS_ORIGIN=http://localhost:5173,https://midas-aem.vercel.app
NODE_ENV=development
PORT=3000
# Email Service (Mailgun)
EMAIL_SERVICE=mailgun
EMAIL_FROM=hello@yourdomain.com
MAILGUN_API_KEY=your_mailgun_api_key
MAILGUN_WEBHOOK_KEY=your_mailgun_webhook_key
# File Storage
BLOB_READ_WRITE_TOKEN=your_vercel_blob_token
MAX_FILE_SIZE_MB=10
# Cron Job Security
CRON_SECRET=your_32_char_minimum_secret
# AI Provider (choose one or multiple)
AI_PROVIDER=openrouter
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo-preview
GEMINI_API_KEY=your_gemini_key
GEMINI_MODEL=gemini-2.5-flash-lite
DEEPSEEK_API_KEY=your_deepseek_key
DEEPSEEK_MODEL=deepseek-chat
OPENROUTER_API_KEY=your_openrouter_key
OPENROUTER_MODEL=deepseek/deepseek-r1:free
# Optional: Local LLM (Ollama)
OLLAMA_URL=http://localhost:11434
OLLAMA_FAST_MODEL=llama3.2:1b
OLLAMA_POWERFUL_MODEL=llama3.1:8b
# Optional: Email Verification
BOUNCEBAN_API_KEY=your_bounceban_key
# Encryption (generate a 64-char hex key or use default for dev)
ENCRYPTION_KEY=your_64_char_hex_encryption_keyMidas/
βββ src/ # React Frontend (84.5% TypeScript)
β βββ main.tsx # Entry point with Clerk provider
β βββ App.tsx # Router & route definitions
β βββ pages/ # Route components (Home, Leads, Campaigns, etc.)
β βββ components/ # Reusable UI components
β βββ context/ # React context (AuthContext)
β βββ index.css # Tailwind CSS styles
β
βββ server/ # Express.js Backend
β βββ app.ts # Express app setup with CORS & routes
β βββ index.ts # Server entry point (port 3000)
β βββ config/ # Configuration modules
β β βββ env.ts # Environment validation (Zod)
β β βββ logger.ts # Winston logging
β βββ middleware/ # Auth & request handlers
β β βββ auth.middleware.ts # Clerk JWT verification + user sync
β βββ routes/ # API route handlers
β βββ lead.routes.ts # Lead CRUD & upload
β βββ campaign.routes.ts # Campaign management
β βββ domain.routes.ts # Domain verification & warmup
β βββ inbox.routes.ts # Email tracking & replies
β βββ ai.routes.ts # Draft generation & sentiment analysis
β βββ webhooks.routes.ts # Mailgun & Clerk webhooks
β βββ cron.routes.ts # Scheduled email sending
β βββ user.routes.ts # User profile
β βββ diagnostic.routes.ts # Health checks
β
βββ api/ # Vercel Serverless Functions
β βββ index.ts # Serverless HTTP wrapper (serverless-http)
β
βββ prisma/ # Database Schema
β βββ schema.prisma # 14+ models (User, Campaign, Lead, etc.)
β
βββ vite.config.ts # Vite build configuration
βββ tsconfig.json # TypeScript config (frontend)
βββ tsconfig.server.json # TypeScript config (backend)
βββ vercel.json # Vercel deployment & cron config
βββ package.json # Dependencies & build scripts
βββ .dockerfile # Docker image for Cloud Run deployment
Core Models:
- User β Clerk-integrated user accounts with UUID primary key
- Campaign β Email campaigns with follow-up steps, timezones, and status tracking
- Lead β Prospects with email verification status and outreach tracking
- Domain β Sender domains with DKIM/SPF/MX/tracking verification, warmup day, daily limits
- Draft β Email templates (subject + body) with version control and reusability
- OutboundEmail β Sent emails with delivery tracking (open, click, reply, bounce)
- PendingEmail β Scheduled emails awaiting dispatch
- FollowUpStep β Configured delays between campaign steps
- CampaignMember β Multi-user collaboration (OWNER/EDITOR/VIEWER roles)
- CampaignInvite β Email invitations with expiration tokens
- Blocklist β Regex patterns to filter leads
- UploadJob β Async lead upload progress tracking
- UserSettings β User preferences and configuration
- Frontend: React SDK with
@clerk/clerk-react - Backend: Node SDK with JWT verification via
@clerk/clerk-sdk-node - Middleware:
requireAuthmiddleware validates RS256 signatures and auto-syncs users to PostgreSQL - User Cache: In-memory cache maps Clerk IDs to local UUIDs for 0ms resolution
Allowed origins include:
- Configured
CORS_ORIGINlist - All
*.vercel.appdeployments localhost:*and127.0.0.1:*(development)- All origins in development mode
/api/leads,/api/campaigns,/api/domains,/api/inbox,/api/ai,/api/user,/api/diagnosticsβ Protected by Clerk auth/api/webhooksβ Public (Mailgun & Clerk webhooks)/api/cronβ Protected byCRON_SECRETbearer token/api/healthβ Public health check
- API Key: Validated during domain setup
- Webhook Key: Verifies webhook signatures
- Events Tracked: Delivered, opened, clicked, bounced, complained
- Sender Format:
{senderLocalPart}@{domainName}(default:hello@domain.com)
- DKIM, SPF, MX Verification β Status flags for each domain
- Tracking Enabled β Optional tracking domain for open/click events
- Warmup Protocol:
- Day 1 warmup start
- Configurable daily send limit (default: 20)
- Bounce/complaint rate tracking
- Automatic rate limiting based on reputation
- Draft Generation β AI creates email from campaign context
- Pending Queue β Email scheduled with optional domain preference
- Cron Dispatch β 09:00 UTC daily (
/api/cron/queue) - Mailgun Send β Domain selected via round-robin or preference
- Webhook Events β Real-time delivery status updates
- Reply Capture β Incoming replies parsed and stored
- Sentiment Analysis β AI analyzes reply tone
- Auto-Reply Draft β AI generates contextual response (user approval required)
- OpenAI β
gpt-4-turbo-preview(default for powerful tasks) - Google Gemini β
gemini-2.5-flash-lite - DeepSeek β
deepseek-chat - OpenRouter β
deepseek/deepseek-r1:free(free tier default) - Ollama β Local models for privacy (
llama3.2:1b,llama3.1:8b) - Mock β Development mode (returns static responses)
- Email Draft Generation β Contextual cold emails from tone, use case, and campaign objective
- Sentiment Analysis β Reply classification (positive, negative, neutral, interested, not-interested)
- Intent Recognition β Detect action items in replies
- Auto-Reply Drafting β Generate follow-ups based on sentiment and thread context
- Request Delay β Configurable delay between AI requests (default: 500ms) to respect rate limits
AI_PROVIDER=openrouter # Primary provider
PRIMARY_FALLBACK_PROVIDER=gemini # Fallback if primary fails
OPENROUTER_API_KEY=sk-...
OPENROUTER_MODEL=deepseek/deepseek-r1:free
GEMINI_API_KEY=...
GEMINI_MODEL=gemini-2.5-flash-lite
AI_REQUEST_DELAY_MS=500 # Delay between API callsQueue Processing: 0 9 * * * (09:00 UTC daily)
- Dispatches pending emails respecting domain daily limits
- Checks warmup status and adjusts send rates
- Handles retries for failed sends
Lead Processing: 0 10 * * * (10:00 UTC daily)
- Processes incoming replies
- Runs sentiment analysis
- Generates auto-reply drafts
{
"crons": [
{ "path": "/api/cron/queue", "schedule": "0 9 * * *" },
{ "path": "/api/cron/leads", "schedule": "0 10 * * *" }
]
}Secure cron requests with CRON_SECRET header:
curl -H "Authorization: Bearer $CRON_SECRET" https://midas-aem.vercel.app/api/cron/queue- Home β Dashboard overview
- Leads β Lead list with CSV/XLSX upload, status filters, verification tracking
- Campaigns β Campaign creation, editing, follow-up step configuration
- Campaign Detail β Per-campaign email tracking and member collaboration
- Domains β Domain verification, DNS record display, warmup status
- Inbox β Unified inbox for sent emails, replies, opens, clicks
- Profile β User settings and account management
- Responsive Design β Tailwind CSS v4 for modern styling
- Dropzone β
react-dropzonefor file uploads - CSV Parsing β
papaparsefor lead import - Routing β React Router v6 for SPA navigation
- Error Boundaries β Graceful error handling
npm run dev- Vite dev server on port 5173 (frontend)
- Express server on port 3000 (backend)
- Hot module replacement enabled
npm run buildExecutes:
prisma generateβ Generate Prisma clienttsc -p tsconfig.server.jsonβ Compile backend todist/servervite buildβ Bundle frontend todist/client
npm run vercel-buildExecutes:
prisma generateprisma db push --accept-data-lossβ Auto-migrate schematsc -p tsconfig.server.jsonvite build
Deployment Config (vercel.json):
- Rewrites
/api/*requests to/api/index.ts(serverless function) - Rewrites all other requests to
/index.html(SPA routing) - Cron jobs configured for background tasks
A multi-stage .dockerfile is included for Cloud Run:
FROM node:18-slim AS build
# Build backend and frontend
FROM node:18-slim
# Copy dist and node_modules, expose port 8080reactβ UI frameworkreact-router-domβ Client-side routing@clerk/clerk-reactβ Authentication UItailwindcssβ Stylingaxiosβ HTTP clientpapaparseβ CSV parsingreact-dropzoneβ File upload
expressβ Web frameworkprisma&@prisma/clientβ ORM & database client@neondatabase/serverlessβ Neon PostgreSQL driver@clerk/clerk-sdk-nodeβ Server-side authmailgun.jsβ Email APIsvixβ Webhook verificationbcryptjsβ Password hashingjsonwebtokenβ JWT handlingwinstonβ Loggingzodβ Schema validationserverless-httpβ HTTP wrapper for serverless
viteβ Build bundlertypescriptβ Type safety@vitejs/plugin-reactβ React plugin
curl https://midas-aem.vercel.app/api/health
# Returns: { "status": "ok", "timestamp": "2026-..." }- Winston Logger β Structured JSON logs
- Environment-aware β
debuglevel in development,infoin production - Console Transport β Logs to stdout (Vercel compatible)
- Clerk auth failures return
401 Unauthorized - Database errors return
500 Internal Server Errorwith logging - Input validation via Zod schemas
- Error boundary component on frontend
# Terminal 1: Backend (Express + Prisma)
npm run dev
# Terminal 2: Database (if running locally)
docker run -e POSTGRES_PASSWORD=password postgres:15
# Terminal 3: Sync database schema
npx prisma studio # Open Prisma GUI at http://localhost:5555# Create a new migration
npx prisma migrate dev --name migration_name
# Push schema changes (Vercel build)
npx prisma db push
# View database GUI
npx prisma studio- Branch:
vercelis the production branch - Main branch: Contains alternate implementations
- Commits: Descriptive messages with feature/phase numbers (Phase 3.5, etc.)
- Google Cloud ADK β Limited support due to API key acquisition challenges
- Reply Threading β Basic reply-to tracking; full thread reconstruction in progress
- Real-time Updates β Webhook events processed via cron; WebSocket support pending
- Advanced Analytics β Campaign performance metrics available via email tracking data
This project includes a LICENSE file. See LICENSE for details.
Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes with clear messages
- Push to your fork
- Open a pull request
For issues, questions, or feature requests:
- Open a GitHub issue: Midas Issues
- Contact the author: Pyrex611
Last Updated: February 2026 | Phase: 3.5+ (Reply Analysis & Automation)