Looking for a job has two slow parts. Reading 30 new postings a day to find the 3 that fit. Then changing your resume for each one.
Both parts are reading and matching text. An LLM is good at that. So I wrote a Claude Code skill that does this every morning:
1. get new jobs ──> 2. score vs. resume ──> 3. Gmail: applied already? │ no ▼ 6. you click Apply <── 5. cover letter <── 4. resume points to put first (next post) Steps 1 to 4 are in this post. Step 6 stays with you. More on that below.
What you get
One Markdown file per day. This is part of a real one (2026-11-12, Seattle, backend roles, with a sample resume):
# Job hunt: 2026-11-12 28 new jobs. 8 to apply (score 7+), 0 already applied, 20 below 7. ### 1. Senior Backend Engineer, FinTech Lending Platforms at Coinbase, Inc. (9/10) - Why it fits: - Senior backend; requires Go or Java and cloud-native tools; resume has Go on AWS - Lending and real-time tracking in distributed systems; resume has payments platform - Gaps: - Lending and risk domain - Put first in your resume: - Go services on AWS (Example Payments) - Kafka pipeline for payment events, 2M events per second - On-call lead for the payments platform - Apply: https://... The 20 jobs below 7 go into one table with a single reason each ("Graduate role for 2025 CS graduates", "Requires a Master's degree; resume has a B.S."). You can see what was dropped and why.
How it works
The skill is a SKILL.md and two small Python scripts. Code and LLM each do what they are good at:
| Step | Who does it | Why |
|---|---|---|
| Get jobs, drop the ones you saw | fetch_jobs.py | Same input, same output. No reason to ask a model. |
| Score 0-10, reasons, gaps | Claude | Needs reading and judgment. |
| Check Gmail | Claude + Gmail tool | Needs judgment: a job alert is not an application. |
| Resume points | Claude | Only points that are already in the resume. |
| Check the scores, write the list | report.py | Catches a missing score or an unchecked top job, then Claude fixes it. |
The scoring rubric is in the skill, so scores mean the same thing every day:
0-3 wrong role or a hard blocker (seniority off by 2+ levels, location, missing skill family) 4-6 same role family, 1-2 core requirements missing 7-8 meets the core requirements, at most 1 nice-to-have missing 9-10 meets core and most nice-to-haves, and the level fits report.py is the part I like most. Claude writes the scores to a JSON file. The script refuses it if a job has no score, a score is not 0-10, a top job was not checked in Gmail, or a top job has no resume points. It prints the problems, Claude fixes them, and it runs again. The jobs go into seen.json only after the list is written, so a failed run loses nothing.
The jobs come from Google Jobs (the job panel in Google Search). Google has no API for it, so step 1 uses my Google Jobs Scraper on Apify. The first post shows that part.
Why it does not click Apply
I thought about it. I decided no, for three reasons:
- Your accounts. LinkedIn and Indeed do not allow bots to apply. You can lose the account you need most right now.
- Every form is different. Workday, Greenhouse, Lever and company forms all ask different questions. That is more work than steps 1 to 5 together, and it breaks often.
- It does not help. Sending 200 weak applications is worse than sending 5 good ones. The slow part was never clicking the button.
So the skill picks and prepares. You read the list over coffee and apply to the 2 or 3 that are worth it.
Things I learned from real data
Use datePosted: 7d, not 24h. I started with "jobs from the last 24 hours". Google returned 30 results per search, but only 1 was from the last 24 hours. The date filter runs on the results Google returns, so you pay for the same pages and keep much less. With 7d and seen.json you get the same "only new jobs" effect and many more jobs.
The company name is sometimes a reposting site. One job said "MeeBoss", but the text said TestSprite. Another said "Nubeero Limited" for a Stripe job. So the skill tells Claude to search Gmail for the employer named in the description, not the company field.
Many apply links are reposting sites. In this run, 7 of the 8 jobs to apply to had only reposting links. The script ranks links (company page or ATS first, big job boards next, reposts last) and marks a job when it found only reposts, so you know to look for it on the company careers page.
Search Gmail by subject. My first query matched newsletters and LinkedIn salary reports. "<employer>" subject:(application OR applying OR applied) works much better.
Try it
git clone https://github.com/krammer0/google-jobs-scraper-examples.git cd google-jobs-scraper-examples cp -r job-hunt ~/.claude/skills/job-hunt mkdir -p ~/job-hunt && cp job-hunt/job-hunt.example.json ~/job-hunt/job-hunt.json cp my-resume.md ~/job-hunt/resume.md pip install apify-client export APIFY_TOKEN=<your token> claude "/job-hunt" Edit queries, locations and notes in job-hunt.json first. No Gmail tool in Claude Code? Set "maxGmailChecks": 0.
Cost: one search of 30 jobs is about 3 to 4 result pages, $0.028 to $0.09 per page on Apify. Claude runs in your own Claude Code, so there is no extra API key.
Next post: step 5, a cover letter and form answers for the top jobs. Tell me in the comments what you want it to do.
