JobHunter
An autonomous, modular agent that finds vacancies, matches them to a verified profile and prepares or sends applications, with a human-controlled safety net.
JobHunter, internally job-agent, is a modular monolith that runs on the server on its own. Its Celery workers and scheduler keep going whether or not an AI client, a phone or a browser is connected. The REST API, a mobile-friendly admin panel and a remote MCP endpoint are only ways to steer it.
Off until switched on
A real crawl of a job site and real email sending are disabled by default. The code base never runs a mass live scan or sends real mail during tests. Before a live crawl, the operator checks the site's terms and legal basis, then records that review.
How the pieces fit
source adapter ─▶ discovery / crawl ─▶ normalisation ─▶ SourceJob
─▶ reversible deduplication ─▶ CanonicalJob
─▶ deterministic filters ─▶ strict LLM evaluation
─▶ verified contact ─▶ verified resume ─▶ application generator
─▶ deterministic policy ─▶ Gmail sender
The main flow does not depend on any particular job board. A board plugs in as an adapter. Read the pipeline for each stage.
Modules
| Area | Responsibility |
|---|---|
| Crawlers | Registry of adapters, checkpoints, rechecks and a circuit breaker that stops a degrading source |
| Models and database | SQLAlchemy 2 on PostgreSQL, with Alembic migrations |
| Deduplication | Source postings are always kept; the canonical merge can be undone |
| Matching, contacts, applications, policies | Untrusted-data boundaries and a deterministic final decision |
| OAuth 2.0 with PKCE, encrypted refresh tokens, Gmail sending | |
| Scheduler | Celery Beat, queues, Redis locks and idempotency |
| API, admin, MCP | REST, the mobile panel and MCP over Streamable HTTP |
| Audit and observability | Audit events, JSON logs, health and readiness, Prometheus metrics |
How it runs here
The production stack is a Docker Compose project of seven application services, plus PostgreSQL and Redis:
apiserves the REST API, the panel and MCP.worker,matching-worker,proxy-workerandcontrol-workereach consume their own queue.beatschedules periodic work.call-agenthandles phone calls through PhoneGate.
Caddy on the host terminates TLS and proxies to the API on loopback. Crawler traffic that needs a clean mobile address leaves through the A14 egress tunnel.
A development checkout is kept separately from the production checkout. Production only ever takes fast-forward updates from the development main branch, and a script checks the two are in sync before a rollout.
Related pages
- Pipeline: every stage from discovery to sending.
- Safety and policy: what stops the agent from doing something it should not.
- Phone agent: answering employer calls and checking the facts afterwards.