Work

Case study

Job Search Agent in Claude Cowork

A scheduled Cowork agent that finds, scores, and tracks job postings across three applicant tracking system (ATS) platforms and Gmail, and the debugging that made its output trustworthy.

Built for my own job search. I designed what it should do, directed the build in Claude Cowork, and debugged its output until I could trust it.

Key facts

  • 3 APIs Greenhouse, Lever, and Ashby, plus Gmail alerts
  • 2× a week scheduled runs Tuesdays and Sundays
  • 3 failure modes found and fixed
  • v6 of the versioned skill file

Problem

Job boards resurface stale listings and miss roles posted only on company career pages. Checking dozens of companies by hand twice a week wasn’t sustainable.

Who it was for

Me.

What I built

A scheduled task in Claude Cowork that runs on Tuesdays and Sundays. It pulls open roles from the Greenhouse, Lever, and Ashby job-board APIs for a target company list, parses LinkedIn alert emails from Gmail, scores each role against a fit profile, de-duplicates, and writes to a Supabase-backed dashboard.

A versioned skill file, now on v6, defines the sources, the scoring rubric, the output schema, and the validation gates.

How one run moves from sources to the dashboard.

Built with

Claude Cowork (a scheduled task and a versioned skill file), the Greenhouse, Lever, and Ashby job-board APIs, Gmail, and Supabase.

My role: deciding what it should do, directing the build, reviewing its output, and running it.

Demo

  • 90-second screen recording of a run and the dashboardComing
  • The skill file and LESSONS.md, with the company list removedComing

Recording of a real run. My target-company list and personal details are removed.

What happened

What went wrong, and the fix

Early runs looked fine and were wrong in ways that mattered.

Failures in early runs, their causes, and the fixes
FailureCauseFix
Invented titles like “best of 37 open”The model summarized where it should have copiedTitle must be the exact API value
Stale listings resurfacingNothing checked whether a role was still openRe-check every URL before writing a row
Generic career-page URLsThe model fell back to what it knewURL must come from the API; no URL, no row

The lesson: an agent that produces plausible output is more dangerous than one that fails loudly.

Moves through code

Anything that must be exact: titles, URLs, dates.

Left to the model

Judgment only: fit and summary.

Results

Results coming: companies monitored, roles surfaced, applications.

What I’d change

  • Move exact data out of the model from day one. Titles, URLs and dates should have gone through code from the first version, with the model only judging fit and writing summaries. I learned that across six versions instead of designing it in.