A configuration layer and automation stack on top of ApplyPilot — an AI-powered job application pipeline that discovers listings, tailors resumes, writes cover letters, and submits applications autonomously.
This repo handles everything that's missing from the upstream package: install scripts, patches, n8n workflow for job discovery, and daemon configs for both macOS and Windows.
ApplyPilot is a genuinely impressive project — a full autonomous job application pipeline that handles everything from discovery to form submission. Credit where it's due.
This repo exists because upstream has a few gaps that matter a lot in practice, particularly for Canadian internship seekers.
Upstream's discovery stage pulls from hardcoded company career page directories — useful for general job hunting, but not calibrated to any specific region or hiring season. This setup replaces that with two of the most actively maintained and comprehensive Canadian internship repositories:
- Canadian Tech Internships — community-curated list of Canadian tech internship postings, updated continuously throughout hiring cycles
- Hanzili — focused CS internship tracker for Canada with strong coverage of co-op and fall/winter terms
An n8n workflow polls both repos on a 2-hour schedule, deduplicates against your local DB, prunes closed listings, and feeds new ones directly into the pipeline. The result is discovery that's actually calibrated to the Canadian market rather than a generic global directory.
The apply stage (launcher.py + prompt.py) is where most of the real work happened:
-
Email MCP for OTP/verification — upstream has no handling for sites that send a verification code or magic link before showing the application form. This adds IMAP-based email access via
@codefuturist/email-mcpso the agent can retrieve OTP codes and password reset links mid-session without human intervention. Works with any provider that supports IMAP — Gmail, iCloud Mail, Outlook, Fastmail, etc. -
Prompt rewrite — the upstream agent prompt is verbose and general-purpose. This version is stripped down and made prescriptive: explicit dropdown handling (open → read all options → fuzzy match → click, never type verbatim), forgot-password flow before sign-up fallback, React/SPA input event dispatch for Ashby/Greenhouse forms that don't register
browser_typeevents, and hard rules around education fields (never cancel mid-fill, never submit without one). -
Worker-local file paths — Playwright MCP sandboxes file access to the worker's own directory. Upstream passes resume paths from a shared
current/folder that the MCP can't reach. This copies resume and cover letter PDFs into each worker's directory before spawning Claude. -
Token efficiency — upstream defaults encourage long, expensive sessions. This sets
--limit 15 --max-turns 30and runs the apply daemon every 12 hours instead of more frequently, reducing baseline token consumption significantly. -
Live log streaming — upstream buffers worker log writes until the session ends, making real-time debugging impossible. This opens the log file with
buffering=1sotail -fworks during active sessions.
- Discovers internship listings from GitHub-curated repos (Canadian Tech Internships, Hanzili) via an n8n workflow running every 2 hours
- Enriches listings with full descriptions and application URLs
- Scores each job 1–10 against your profile using an LLM
- Tailors your resume per job, with role-type detection and locked bullet preservation
- Generates a cover letter per job
- Applies autonomously using Claude Code + Playwright (fills forms, solves CAPTCHAs, handles logins)
| Tool | Required | Install |
|---|---|---|
| Python 3.11+ | Yes | python.org |
| uv | Yes | curl -LsSf https://astral.sh/uv/install.sh | sh |
| Claude Code CLI | Yes (for apply stage) | npm install -g @anthropic-ai/claude-code |
| Google Chrome | Yes (for apply stage) | chrome |
| Node.js 18+ | Yes (for apply stage) | nodejs.org |
| n8n | Optional | npm install -g n8n |
| CapSolver account | Optional | Sign up — ~$2 buys hundreds of CAPTCHA solves |
API keys needed:
- Gemini API key (free tier works): aistudio.google.com
- Anthropic API key (for Claude Code): console.anthropic.com
git clone https://github.com/Retriever1693/applypilot-setup.git ~/.applypilot
cd ~/.applypilot
bash install.shgit clone https://github.com/Retriever1693/applypilot-setup.git "$env:USERPROFILE\.applypilot"
cd "$env:USERPROFILE\.applypilot"
.\install.ps1The install script:
- Installs
applypilotvia uv - Applies patches (optimized prompt, PDF renderer, validator tweaks)
- Copies config templates to
~/.applypilot/ - Installs a daemon (LaunchAgent on macOS, Scheduled Task on Windows) that runs the apply pipeline every 12 hours
After install, edit these three files:
GEMINI_API_KEY=your_key_here
CAPSOLVER_API_KEY=your_key_here # optional but recommended
AP_PASSWORD=a_unique_password # used for ATS account creationCopy from config/profile.example.json (already done by install script). Fill in:
personal— name, email, phone, address, LinkedIn, GitHubcompensation— salary floor and rangeskills_boundary— your actual skills (LLM never adds anything outside this list)resume_facts— locked bullet points, project descriptions, preserved company names
Copy from config/searches.example.yaml. Set your target city, role queries, and distance radius.
~/.applypilot/resume.txt # plain text — used for AI tailoring
~/.applypilot/resume.pdf # PDF — uploaded to application forms
# First-time setup
applypilot init
# Run the full pipeline (discover → score → tailor → cover → pdf → apply)
applypilot run
# Run specific stages only
applypilot run enrich score tailor cover pdf
# Apply to queued jobs manually
applypilot apply --limit 10 --model haiku
# Check pipeline status
applypilot status
applypilot dashboardn8n runs the discovery + ingestion workflow on a schedule, then triggers the pipeline automatically.
- Start n8n:
n8n(or it runs via the LaunchAgent on macOS) - Open http://localhost:5678
- Import
n8n/applypilot-github-ingestion.json - Activate the workflow
The workflow checks GitHub internship repos every 2 hours, prunes closed listings from your DB, inserts new ones, and calls run_pipeline.sh.
Re-apply patches any time you run uv tool upgrade applypilot:
# macOS
bash ~/.applypilot/patches/patch_applypilot.sh
# Windows
& "$env:USERPROFILE\.applypilot\patches\patch_applypilot.ps1"~/.applypilot/
├── install.sh / install.ps1 # One-command setup
├── apply_daemon.sh / .ps1 # Scheduled apply runner (every 12h)
├── run_pipeline.sh # Called by n8n: pipeline + apply
├── start_n8n.sh # macOS nvm-aware n8n launcher
├── patches/ # Overrides applied on top of upstream
│ ├── apply/prompt.py # Optimized agent prompt (~50% token reduction)
│ ├── scoring/tailor.py # Resume tailoring with profile-driven logic
│ ├── scoring/validator.py # Banned-word detection + LLM judge
│ ├── scoring/pdf.py # PDF generation via Playwright
│ └── cli.py # CLI entrypoint
├── n8n/
│ └── applypilot-github-ingestion.json # n8n workflow
├── launchagents/ # macOS LaunchAgent templates
├── config/ # Template configs (safe to commit)
│ ├── profile.example.json
│ └── searches.example.yaml
├── .env.example # API key template
└── .gitignore # Excludes .env, profile.json, resume, DB
Pipeline stages: discover → enrich → score → tailor → cover → pdf → apply
Each stage reads/writes to ~/.applypilot/applypilot.db (SQLite). Stages are fully decoupled — you can run any subset independently.
Apply stage: Spawns claude --model haiku -p per job with a Playwright MCP pointing at a dedicated Chrome instance. Claude fills the form, solves CAPTCHAs via CapSolver, handles logins, and outputs a result code. Max 30 turns per job, 15 jobs per run.