π― AI-Powered Job Search Outreach Agent
Automate your job search β find hiring managers, validate emails, and draft personalized outreach at scale.
π What Is This?
A fully automated cold-outreach pipeline designed for job seekers. Give it a company name and a job title, and it will:
- π Find real hiring managers on LinkedIn via Google Search (with DuckDuckGo fallback)
- π€ Verify candidates using LLM-based relevance filtering (NVIDIA Devstral)
- π§ Validate their corporate email addresses through DNS MX lookups & SMTP probing
- βοΈ Draft personalized cold emails powered by AI β tailored to the recipient's role
- π Export everything to a clean, structured CSV ready for your outreach workflow
No emails are ever sent. This tool only finds, validates, and prepares β you stay in full control of what gets sent.
ποΈ Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β main.py β
β (Orchestrator / CLI) β
β β
β Step 1 Step 2 Step 3 Step 4 β
β ββββββββββββ ββββββββββββββββββ ββββββββββββββ ββββββββββ β
β β Target ββββΆβ Email ββββΆβ Email βββΆβ Data β β
β β Finder β β Validator β β Drafter β β Export β β
β ββββββββββββ ββββββββββββββββββ ββββββββββββββ ββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β β
βΌ βΌ βΌ βΌ
Google Search DNS MX Lookup NVIDIA NIM API CSV File
+ DuckDuckGo SMTP RCPT TO (Devstral LLM)
+ LLM Verify Catch-All Check
| File | Purpose |
|---|---|
main.py |
CLI entry point & pipeline orchestrator |
config.py |
Environment variables, constants, and your tech profile |
target_finder.py |
LinkedIn profile discovery via web search + LLM verification |
email_validator.py |
Email permutation generator + DNS/SMTP validation |
email_drafter.py |
Personalized cold email drafting via NVIDIA Devstral |
data_export.py |
CSV writer with Excel-compatible encoding |
π¨ Web Dashboard
The project now includes a beautiful, modern web dashboard for running the pipeline interactively:

β‘ Quick Start
Prerequisites
- Python 3.10+
- NVIDIA API Key β Get one free from NVIDIA Build
1. Clone & Install
git clone <your-repo-url>
cd "Job Search Agent"
# Create virtual environment
python -m venv .venv
# Activate it
# Windows:
.venv\Scripts\activate
# macOS / Linux:
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
2. Configure Environment
cp .env.example .env
Open .env and add your API key:
NVIDIA_API_KEY=nvapi-your_key_here
π Full list of environment variables
| Variable | Required | Default | Description |
|---|:---:|---|---|
| `NVIDIA_API_KEY` | β
| β | Your NVIDIA NIM API key |
| `NVIDIA_MODEL` | | `mistralai/devstral-2-123b-instruct-2512` | LLM model for email drafting & verification |
| `NVIDIA_BASE_URL` | | `https://integrate.api.nvidia.com/v1` | NVIDIA NIM API endpoint |
| `NVIDIA_TEMPERATURE` | | `0.7` | LLM response creativity (0.0β1.0) |
| `NVIDIA_MAX_TOKENS` | | `1024` | Max tokens per LLM response |
| `SMTP_FROM_ADDRESS` | | `[email protected]` | Address used in `MAIL FROM` probe |
| `SMTP_TIMEOUT` | | `10` | Seconds before SMTP probe times out |
| `REQUEST_TIMEOUT` | | `15` | HTTP request timeout for web searches |
| `MAX_SEARCH_RESULTS` | | `10` | Maximum LinkedIn profiles to return |
| `OUTPUT_CSV` | | `outreach_results.csv` | Output file path |
3. Run the Pipeline
Option A: Web UI (Recommended)
python server.py
# Open http://localhost:8000 in your browser
The web interface provides a modern, dark-themed dashboard with a sleek violet/purple aesthetic:
- Real-time pipeline progress β watch each step complete with live status updates
- Results cards β browse discovered profiles, validated emails, and LinkedIn links in a responsive grid layout
- Email preview β click to view AI-drafted emails in a slide-over panel with copy-to-clipboard support
- CSV download β export results directly from the browser
Option B: CLI
# Interactive mode β you'll be prompted for company, title, and domain
python main.py
# CLI mode β pass arguments directly
python main.py --company "Google" --title "Engineering Manager" --domain "google.com"
# Short flags
python main.py -c Stripe -t "Head of Engineering" -d stripe.com
# Dry-run β test search only, skip validation & drafting
python main.py --company "Google" --title "Engineering Manager" --dry-run
# Verbose logging β see detailed debug output
python main.py -c Stripe -t "Head of Engineering" -d stripe.com -v
4. View Results
Results are saved to outreach_results.csv with the following columns:
| Column | Description |
|---|---|
full_name |
Target's full name |
first_name |
First name |
last_name |
Last name |
job_title |
Role/position at the company |
company |
Company name |
domain |
Corporate email domain |
profile_url |
LinkedIn profile URL |
validated_email |
Validated (or best-guess) email address |
email_body |
AI-drafted personalized cold outreach email |
π§ How Each Module Works
π Target Finder (target_finder.py)
Discovers LinkedIn profiles matching your search criteria using a dual-search strategy:
- Google Search (primary) β more accurate results via
googlesearch-python - DuckDuckGo (fallback) β used when Google is unavailable, via
duckduckgo_search - LLM Verification β sends candidate profiles to NVIDIA Devstral to verify they actually hold the specified job title at the target company
- Smart Filtering β deduplication, company-name matching, credential stripping, and name validation
π§ Email Validator (email_validator.py)
Generates and validates corporate email addresses without ever sending a message:
- Permutation Generation β creates 10 common corporate email formats (e.g.,
first.last@,flast@,first@, etc.) - DNS MX Lookup β resolves the domain's mail exchange servers
- SMTP
RCPT TOProbe β connects to the primary MX server, issuesHELO/MAIL FROM/RCPT TO, and reads the response code. No email is ever sent. - Catch-All Detection β probes a random fake address first; if accepted, marks all
250responses asCATCH_ALLto avoid false positives
βοΈ Email Drafter (email_drafter.py)
Generates personalized cold outreach emails via NVIDIA's Devstral LLM:
- Strict Formatting β exactly 3 paragraphs, under 180 words, with subject line on line 1
- Skills Mapping β maps your technical skills to the target company's likely pain points
- No Generic Fluff β the system prompt enforces specificity and relevance
- Retry Logic β exponential backoff with jitter on rate limits
π Data Export (data_export.py)
- Writes results to a UTF-8 BOM encoded CSV (opens correctly in Excel)
- Uses
csv.QUOTE_ALLto prevent delimiter-in-data issues - Overwrites on each run to keep results fresh
π¨ Customizing Your Tech Profile
The LLM uses your tech profile to craft personalized emails. Edit TECH_SKILLS in config.py, or override via .env:
TECH_SKILLS='{
"languages": ["Python", "Go", "Rust"],
"frameworks": ["Django", "gRPC", "FastAPI"],
"domains": ["distributed systems", "ML pipelines", "cloud infrastructure"],
"highlights": [
"Scaled API from 1k to 50k RPS",
"Led migration to Kubernetes across 200+ services",
"Built real-time fraud detection pipeline processing 10M events/day"
]
}'
π‘οΈ Error Handling
The pipeline is designed to be resilient β individual failures never crash the entire run:
| Scenario | What Happens |
|---|---|
| Google Search blocked / CAPTCHA | Falls back to DuckDuckGo automatically |
| HTTP 429 / 503 rate limit | Exponential backoff with jitter, retries up to N times |
| No matching LinkedIn profiles | Logs a warning; pipeline exits cleanly |
| Name looks like a job title | Profile is skipped to prevent false positives |
| No MX records for domain | Email candidates marked UNKNOWN; best-guess fallback used |
| SMTP timeout / connection refused | Individual candidate marked UNKNOWN; pipeline continues |
| NVIDIA API rate limit | Exponential backoff; raises RuntimeError after exhausting retries |
| Empty / invalid LLM response | Retried up to max_retries times |
π Project Structure
Job Search Agent/
βββ .env.example # Template for environment variables
βββ .env # Your local config (git-ignored)
βββ .gitignore
βββ requirements.txt # Python dependencies
βββ README.md
β
βββ main.py # CLI entry point & pipeline orchestrator
βββ server.py # FastAPI web server with SSE streaming
βββ config.py # Configuration & environment loader
βββ target_finder.py # LinkedIn profile discovery
βββ email_validator.py # Email permutation & SMTP validation
βββ email_drafter.py # AI-powered email drafting
βββ data_export.py # CSV export
β
βββ frontend/
β βββ index.html # Web UI β main page
β βββ app.js # Client-side logic (SSE, rendering)
β βββ styles.css # Dark theme with glassmorphism
β
βββ outreach_results.csv # Output (generated after first run)
π¦ Dependencies
| Package | Purpose |
|---|---|
googlesearch-python |
Google Search scraping for LinkedIn profile discovery |
ddgs |
DuckDuckGo search (fallback engine) |
dnspython |
DNS MX record resolution |
openai |
NVIDIA NIM API client (OpenAI-compatible) |
python-dotenv |
Environment variable loading from .env |
fastapi |
Web server framework for the browser-based UI |
uvicorn |
ASGI server to run the FastAPI application |
βοΈ Legal & Ethical Notes
[!IMPORTANT] This tool is intended for personal job-search assistance only.
- No emails are sent β the SMTP probe only issues
RCPT TOand disconnects immediately - Scraping LinkedIn search results via a search engine is subject to their Terms of Service β use responsibly and at low volume
- Comply with CAN-SPAM / GDPR when actually sending outreach emails through your own email client
- Rate limiting is built in β the tool includes delays and backoff to be respectful to external services
π€ Contributing
Contributions are welcome! Feel free to open an issue or submit a pull request. Some ideas:
- Add support for additional search engines
- Extend email validation with Hunter.io or similar API integrations
- Build a web UI for non-technical users
- Add support for bulk company lists
π License
This project is open source and available under the MIT License.
Log in or sign up for Devpost to join the conversation.