User Guide

JobScoutAI

AI-powered job hunting agent — setup, features, and day-to-day use.

Version 1.0  ·  Comprehensive Documentation
Stop scrolling job boards. Let AI find and rate the opportunities that match your skills.

1. What is JobScoutAI?

JobScoutAI is an AI-powered job hunting agent that scrapes job boards, rates each posting against your skills using AI, generates tailored resumes, drafts freelance proposals, tracks applications, and sends daily email briefings. It is built with Python, Flask, and SQLite, and runs locally on your machine — no accounts, no cloud, no shared data.

Instead of manually refreshing LinkedIn, Indeed, and Freelancer every morning, you point JobScoutAI at the keywords that matter, tune your skill profile once, and let the agent do the filtering. Jobs that survive the AI rating pass appear in your tracker with a score, a summary, and an Apply button. The ones that don't are learned from — the system remembers why you skipped a listing and scores similar ones lower next time.

2. Features Overview

FeatureDescriptionStatus
Multi-platform scrapingSearches LinkedIn, Indeed, ZipRecruiter, Freelancer.com, Upwork, Craigslist, Google JobsLinkedIn primary — others depend on ScraperAPI or may be blocked
AI job ratingClaude AI rates each job 1–10 against your skill profile with two tiers: Standard (7+) and Quick Win (5+)Working
Ollama supportFree local AI alternative — no API key needed for job ratingWorking
Resume builderGenerates tailored HTML resumes for specific job postings using your profile and work historyWorking
Proposal drafterDrafts freelance proposals using your past proposals as style referenceWorking
Application trackerFull CRM — tracks status, follow-ups, communications, deadlinesWorking
Skip tag learningLearns your preferences from skipped jobs and adjusts future AI ratingsWorking
Email notificationsDaily briefing email with new matches and follow-up remindersWorking — requires Gmail OAuth
Dashboard & analyticsFunnel chart, skills demand tracker, scraper activity, win rate trendsWorking
Mobile-responsive UICard-based layout on phones, bottom navigation, touch-friendlyWorking
Background scraperRuns in background thread — doesn't freeze the UI, survives phone disconnectWorking
Demo pageRead-only showcase at /demo for quick presentationsWorking
Search profilesMultiple keyword/filter configurations for different job categoriesWorking
API keys in SettingsManage all API keys from the web UI — no .env editing neededWorking

3. Requirements

Required

Optional but recommended

4. Quick Start — First-Time Setup

Follow these seven steps once. After that, running the app is a single command.

  1. Clone the repository
    git clone https://github.com/HrSYT420/JobScoutAI.git
    cd JobScoutAI
  2. Create a virtual environment
    # Windows
    python -m venv .venv
    .venv\Scripts\activate
    
    # macOS / Linux
    python -m venv .venv
    source .venv/bin/activate
  3. Install dependencies
    pip install -r requirements.txt
  4. Set up your API keys

    Copy .env.example to .env and add at least your Anthropic key:

    cp .env.example .env
    # then edit .env and set:
    ANTHROPIC_API_KEY=sk-ant-...
    SCRAPER_API_KEY=your_key   # optional

    Or skip the file and enter the keys in the web UI under Settings → API Keys once the app is running.

  5. Set up your profile

    Copy the example config files and fill them in:

    cp config/profile.example.json config/profile.json
    cp config/resume_content.example.txt config/resume_content.txt

    Edit config/profile.json with your skills, proof points, contact info, and job preferences. Edit config/resume_content.txt with your work history and bullet points. You can also edit both from Settings → Profile and Settings → Resume.

  6. Start the app
    python -m tracker.app

    Open http://localhost:5001 in your browser.

  7. Run your first scrape

    Go to the Control page and click Run Scraper. Or from the terminal:

    python -m job_hunter.scraper
Tip The first scrape is the slowest — subsequent runs skip URLs seen in the last 7 days and finish much faster.

5. Scraper Sources — What Works and What Doesn't

Job boards actively fight automated scraping. JobScoutAI supports many sources on paper, but in practice the reliability varies. This table is current and honest.

SourceMethodStatusNotes
LinkedIn JobSpy library Working (FREE) Primary source. 30–50+ jobs per keyword. No API key needed.
Indeed Selenium / ScraperAPI Blocked without ScraperAPI Cloudflare CAPTCHA blocks browser scraping. Works with ScraperAPI ($49/mo).
ZipRecruiter Selenium / ScraperAPI Blocked without ScraperAPI Same as Indeed — Cloudflare-protected.
Freelancer.com Direct HTML scraping Working (FREE) Parses search pages directly. Limited free bids on the platform itself.
Upwork RSS feed Dead Upwork removed their RSS feeds (410 Gone). Selenium also blocked.
Craigslist RSS feed Blocked Returns 403 on all requests.
Google Jobs ScraperAPI structured Requires ScraperAPI Up to 10 jobs per keyword.
Tip LinkedIn via JobSpy is the most reliable free source. If only one source works for you, make it LinkedIn.
Note ScraperAPI costs $49/month but unlocks Indeed, ZipRecruiter, and Google Jobs. If the app helps you land one freelance gig or full-time role, it pays for itself.

6. The Pipeline — How It Works

Every scraper run walks through eight phases:

  1. Scrape — searches enabled platforms for each keyword in your active profiles.
  2. Deduplicate — checks each URL against seen_urls.json with a 7-day rolling window.
  3. Keyword Filter — keeps only jobs matching at least one of your filter terms.
  4. AI Rating — Claude (or Ollama) scores each job 1–10 against your profile.
  5. Two-Tier Sort — Standard jobs (score 7+, budget $200+) and Quick Wins (score 5+, low budget or hourly).
  6. Save — results written to a dated JSON file: data/jobs_YYYY-MM-DD.json.
  7. Notify — email sent with new matches and follow-up reminders (if Gmail is configured).
  8. Display — jobs appear in the Available Jobs section of the tracker.

7. The Web UI — Page by Page

Tracker /
Main dashboard. Stat cards, Available Jobs with AI scores, In Progress applications, Skipped Jobs with learning data, Apply Later queue. Sorting, filtering, and pagination on Available Jobs.
Control /control
Run the scraper, watch live log output, stop a running scrape. Profile selector chooses which search profiles to run.
Dashboard /dashboard
Analytics charts: pipeline funnel, proposals over time, win rate trend, scraper daily activity, skills demand tracker, skip tag frequency, bid distribution, response times.
Rated Jobs /rated-jobs
Review AI-rated jobs by date with thumbs up / thumbs down feedback.
Resumes /resumes
Index of all generated resumes. View, download, or delete.
Settings /settings
Ten tabs: Scraper, AI Filter, Profile, Notifications, Statistics, Overrides, Proposal Rules, Profiles, Resume, API Keys.
Demo /demo
Read-only showcase page for presentations. Pipeline visualization, live stats, scraper control.
Application Detail /application/<id>
Individual application view with communication timeline, proposal text, and full job description.

8. Settings Reference

TabWhat you configure
ScraperKeywords, filter terms, budget range, hourly rate, platforms, location, browser preference.
AI FilterScore thresholds for Standard and Quick Win tiers, quick-win hour limit, feature toggles.
ProfilePrimary skills, secondary skills, topics to avoid, proof points.
NotificationsEmail address and per-event toggles (new jobs / follow-up due / nothing new).
StatisticsProposal stats, source performance breakdown, skip tag weights with sorting.
OverridesManual weight adjustments for skip tags, temporary or permanent.
Proposal RulesWriting guidelines for the AI proposal drafter.
ProfilesCreate, edit, and delete search profiles with their own keywords and filter terms.
ResumeContact info, resume content library, skills willing to learn.
API KeysAnthropic, ScraperAPI, Gmail OAuth, notification email — all manageable from UI.

9. AI Providers — Claude vs Ollama

JobScoutAI ships with two interchangeable AI backends. Swap between them in Settings → AI Filter or Settings → Scraper.

Claude (Anthropic API)

Ollama (Free, Local)

Note A common setup: use Ollama for the per-job rating pass and Claude only for proposal drafting and resume generation. That keeps API spend low while still producing polished output where it counts.

10. Resume Builder

The resume builder produces a tailored one-page HTML resume per job, using your profile and work history as the only sources of truth.

  1. Click Create Resume on any Available Job or In Progress application.
  2. The app looks up the job details from scraped data.
  3. Claude generates a tailored HTML resume matching the job requirements.
  4. The anti-fabrication checker highlights any skills Claude invented (red badges).
  5. The resume opens in a new tab — review, print, or save as PDF.
  6. All resumes are saved to data/resumes/ and accessible from the Resumes page.
Warning The AI may fabricate skills despite anti-fabrication rules. Always review generated resumes before submitting. Skills highlighted in red were not in your profile.

11. Proposal Drafter

The drafter uses your past proposals and your writing rules to keep new drafts consistent with your voice.

  1. Click Draft Proposal on any Available Job.
  2. The app loads your past proposals from the tracker as style examples.
  3. Proposal writing rules from config/proposal_rules.txt are applied.
  4. Claude drafts a proposal matching your tone and structure.
  5. The draft is saved as a new application with status draft — edit before submitting.
Tip Label every past application with its actual outcome (won / lost). The drafter weights winning proposals higher as style references, so labelled history improves future drafts.

12. Skip Tag Learning

The system learns from every job you skip and uses that knowledge to score future jobs.

13. Mobile Usage

Note Remote ngrok access exposes your tracker publicly. Only run it when you need it, and consider adding basic auth in front of the Flask app before sharing the URL.

14. Known Limitations

15. Roadmap — Room for Improvement

FeatureDescriptionDifficulty
Residential proxy supportUnlock Indeed / ZipRecruiter without ScraperAPIMedium
Scheduled scrapingCron-style automatic daily runsEasy
First-time setup wizardStep-by-step UI for new usersMedium
PyInstaller .exe buildStandalone executable for non-developersMedium
Multi-user supportUser accounts, separate profiles, shared serverHard
Browser extensionOne-click "rate this job" from any job board pageHard
More AI providersOpenAI, Google Gemini, local models beyond OllamaEasy
Email template systemCold outreach templates for freelance client acquisitionEasy
Advanced analyticsProfile comparison, ROI by source, weekly activity trendsMedium
Webhook integrationsSlack / Discord notifications instead of emailEasy

16. Project Structure

JobScoutAI/
├── config/
│   ├── settings.py              — keywords, budget, platforms, location
│   ├── profile.json             — your skills and contact info
│   ├── proposal_rules.txt       — AI writing guidelines
│   ├── resume_content.txt       — work history for resume builder
│   ├── filter_config.json       — AI score thresholds
│   ├── notification_config.json — email notification settings
│   ├── profiles/                — search profile configs
│   └── ...
├── job_hunter/
│   ├── scraper.py               — main pipeline orchestrator
│   ├── filter.py                — two-tier AI job rating
│   ├── ai_client.py             — unified Claude / Ollama interface
│   ├── notifier.py              — email notifications
│   ├── proposer.py              — proposal drafter
│   ├── resume_builder.py        — AI resume generator
│   ├── browser.py               — Selenium / undetected-chrome manager
│   ├── background.py            — background thread execution
│   └── *_scraper.py             — per-platform scrapers
├── tracker/
│   ├── app.py                   — Flask app entry point
│   ├── database.py              — SQLite queries
│   ├── helpers.py               — shared utilities
│   ├── routes/                  — Flask blueprint routes
│   └── templates/               — HTML templates
├── data/                        — job results, database, resumes (gitignored)
├── .env                         — API keys (gitignored)
├── requirements.txt
├── CLAUDE.md                    — developer guide
└── README.md

17. Troubleshooting

"No module named 'distutils'"
Run pip install setuptools. Required for undetected-chromedriver on Python 3.12+.
Indeed / ZipRecruiter return 0 jobs
These platforms block scraping without ScraperAPI. Check Settings → Scraper for your ScraperAPI key, or disable these platforms.
"Invalid grant" Gmail error
Delete gmail_token.json and restart the app to re-authenticate.
Dashboard shows Internal Server Error
Check for Jinja2 template errors in the terminal. Common cause: dict keys that clash with Python method names — use bracket notation d["values"], not d.values.
Resume builder fabricates skills
Review all generated resumes before submitting. Skills highlighted in red were not found in your profile.
Scraper runs for 40+ minutes
Normal with multiple profiles and polite delays. Use the background scraper (Control page) so the UI stays responsive.
App freezes during scraping
Use the background scraper (Control page's Run Scraper button) rather than running python -m job_hunter.scraper while the web UI is also running in the same shell.
Tip When anything unusual happens, check the terminal running python -m tracker.app — nearly every error prints a clear traceback or warning there.

18. Contributing

19. License

JobScoutAI is released under the MIT License. You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, provided the license notice is preserved.

The software is provided "as is", without warranty of any kind. See the LICENSE file in the repository for the full text.