How tarunlnmiit/autopilot-jobhunt works
1. Overall shape
This is a local-first Python 3.11+ job-hunting automation package. It has two main entry surfaces: a CLI (job_hunt.main) and an optional MCP server (job_hunt.mcp_server) for Claude Code/Desktop. Most logic lives in a shared internal package so both interfaces drive the same backend.
2. Runtime boundary: packaged code vs user workspace
The repo ships templates and defaults in job_hunt/data/ and at the root (config.example.json, companies.json, .env.example). Real runtime data lives in a user-owned workspace:
- config.json / .env for secrets and preferences
- resume/YOUR_RESUME.md for the candidate profile
- state/ for scan state / deduplication
- output/ for exported or drafted artifacts
This is a file-based system, not a database-backed app.
3. Company discovery input
companies.json is the main catalog of target employers and careers pages. The scanner reads this list to decide which sites to query. The README indicates 130+ preconfigured companies, and users can customize this list to change the search universe.
4. Job scanning subsystem
job_hunt.scanner orchestrates the nightly scan flow:
- iterates through company careers pages
- discovers new job URLs
- fetches job details
- deduplicates against prior state
- hands jobs off for scoring
The README says this uses TinyFish API as the discovery/fetch layer, so external scraping/discovery is an architectural dependency, not an implementation detail.
5. LLM scoring boundary
job_hunt.llm_utils abstracts the LLM backend. The scanner uses it to score jobs against the full resume and job description, producing a 0–100 fit score plus a short rationale. The architecture supports multiple providers:
- OpenRouter with fallback models
- Claude CLI
- Anthropic API
This backend abstraction matters because scoring is the main intelligence layer and is designed to degrade gracefully if one model is unavailable.
6. Filtering and prioritization
Scored jobs are filtered by a configurable min_score. Only top matches are surfaced. This is the point where “all discovered jobs” become “actionable matches,” and it’s the main decision boundary between ingestion and notification/drafting.
7. Notification path
job_hunt.notifier sends the best matches to Telegram. The README shows a top-N summary with scores, locations, and job URLs. This is an outbound-only notification channel: scan results are pushed to the user without requiring a browser UI or server-hosted dashboard.
8. Drafting subsystem
job_hunt.drafter handles the on-demand workflow for a specific job:
- reads the selected job and the user resume
- generates tailored resume bullets
- generates a cover letter
- writes generated application materials to output/
This is distinct from scanning: scanning is broad and periodic; drafting is narrow and user-triggered.
9. Shared tool layer
job_hunt.tools appears to be the protocol-agnostic service layer used by both the CLI and MCP server. This is the boundary that keeps business logic reusable regardless of whether the caller is a shell user or an AI assistant session.
10. MCP integration
job_hunt.mcp_server exposes the same core actions through the Model Context Protocol, enabling natural-language control from Claude Code/Desktop. Architecturally, this is a thin adapter over the shared tool layer rather than a separate application.
11. Operational automation
setup_cron.sh and the README’s nightly-scan flow show the system is meant to run unattended on a schedule. The repo also includes a Dockerfile and GitHub Actions CI, which support reproducible execution and validation, but the application itself remains a local workflow.
12. Demo and test surface
demo/ contains scripted fixtures for a deterministic product demo, separate from the real scan pipeline. The tests cover configuration precedence, scan output, and export smoke behavior, which signals that configuration loading and file outputs are key architectural contracts.
13. External service dependencies that materially shape the design
The system depends on three external service classes:
- TinyFish for careers-page discovery/fetching
- LLM providers for scoring and drafting
- Telegram for alert delivery
Because the app is orchestrating these services, the main architecture is an automation pipeline with service adapters, not a monolith with local-only logic.
14. Data flow summary
The core flow is:
companies catalog + resume + config → scan careers pages → fetch jobs → score with LLM → persist/filter → Telegram notify → optional draft application artifacts.
That is the central architecture diagram to draw: a local orchestrator coordinating external fetch, inference, and messaging services, with file-based state and outputs on disk.
Main entry points: scanner.py Scanner · drafter.py Drafter · tools.py Shared tools · demo_run.py Demo harness
Components 20
Packaged app
Reusable Python package and entrypoints shipped with the repo.
- CLI · Command-line entry surface for running scans and drafting.
job_hunt/main.py - MCP server · Model Context Protocol adapter for Claude Code/Desktop.
job_hunt/mcp_server.py - Shared tools · Protocol-agnostic actions used by both CLI and MCP.
job_hunt/tools.py - Scanner · Discovers jobs, fetches details, deduplicates, and scores matches.
job_hunt/scanner.py - Drafter · Generates tailored resume bullets and cover letters for a selected job.
job_hunt/drafter.py - Notifier · Formats and sends top matches to Telegram.
job_hunt/notifier.py - LLM utils · Abstraction over model providers for scoring and drafting.
job_hunt/llm_utils.py - Logging · Shared logging setup for the runtime.
job_hunt/log.py
User workspace
Files and directories that hold runtime config, state, inputs, and outputs.
- Company catalog · Target employer and careers-page list used by the scanner.
companies.json - Runtime config · User-owned configuration and secrets that override package defaults.
config.example.json - Env vars · Environment-based secrets and overrides for local execution.
.env.example - Resume · User resume used for scoring and drafting.
resume/YOUR_RESUME.md - Scan state · Persistent deduplication and prior-scan state.
state - Output files · Generated application materials and exported artifacts.
output
External services
Third-party services the automation orchestrates.
- TinyFish · External discovery and fetch layer for careers pages and job details.
- LLM providers · OpenRouter, Claude CLI, and Anthropic backends used for scoring and drafting.
- Telegram · Outbound notification channel for top job matches.
Automation
Packaging, scheduling, demo, and validation surfaces.
- Cron setup · Unattended nightly execution path for the automation.
setup_cron.sh - Demo harness · Deterministic demo flow using canned companies, jobs, and resume data.
demo/demo_run.py - CI workflow · GitHub Actions validation for the package and tests.
.github/workflows/ci.yml
Connections 22
- CLI → Shared tools: uses · CLI invokes shared actions.
- MCP server → Shared tools: uses · MCP server exposes the same shared actions.
- Shared tools → Scanner: drives · Shared layer triggers the scan workflow.
- Shared tools → Drafter: drives · Shared layer triggers drafting workflow.
- Scanner → Company catalog: reads · Uses target company catalog to decide what to scan.
- Scanner → Runtime config: reads · Loads runtime preferences such as thresholds and providers.
- Scanner → Env vars: reads · Consumes secrets and environment overrides.
- Scanner → TinyFish: fetches · Discovers and retrieves job data from careers pages.
- Scanner → LLM utils: scores · Scores jobs against the resume and job description.
- Scanner → Scan state: persists · Stores deduplication and prior-scan state.
- Scanner → Notifier: sends matches · Passes top matches to outbound notification.
- Notifier → Telegram: delivers · Pushes summaries and links to the user.
- Drafter → Resume: reads · Uses the candidate profile as drafting input.
- Drafter → LLM utils: generates · Creates tailored bullets and cover letters.
- Drafter → Output files: writes · Exports generated application materials.
- LLM utils → LLM providers: routes to · Abstracts over multiple model backends and fallbacks.
- Cron setup → CLI: schedules · Runs the local automation unattended.
- Demo harness → Company catalog: uses fixtures · Drives deterministic demo inputs.
- Demo harness → Resume: uses fixtures · Drives deterministic demo inputs.
- Demo harness → Scanner: simulates · Exercises the scan pipeline with canned data.
- CI workflow → CLI: validates · Checks runtime and packaging behavior.
- CI workflow → Scanner: tests · Covers scan output and core workflow behavior.