DevPik Logo
open sourceai agentsjob searchclaude coderesume

Career-Ops: The Open-Source AI Job Search Agent That Tells You Where Not to Apply

Career-Ops is a free, open-source AI job search agent that runs inside Claude Code, Codex and other AI coding CLIs. It checks that a posting is real, scores it 1 to 5 against your actual CV, tells you to skip anything below 4.0, and drafts a tailored CV and cover letter for the rest. It never presses Submit.

ByMuhammad Tayyab12 min read
All open source picks
career-ops-hq/career-ops
The official repository — this write-up is not affiliated with the project.
73.6kJavaScriptMIT

What Career-Ops Is: An AI Job Search Agent That Lives in Your Coding CLI

Career-Ops is an open-source AI job search agent that runs inside the AI coding CLI you already use: Claude Code, Codex, OpenCode, Antigravity, Qwen, Grok Build and several others. You paste a job posting. It checks that the posting is still live, scores the role from 1 to 5 against your real CV, and then either tells you to skip it or drafts a tailored CV, a cover letter and answers for the application form. Then it stops. You press Submit.

It was built by Santiago Fernández de Valderrama Aparicio (santifer) for his own job search, and the README states the result in one line: 740 listings evaluated, 68 applied, 12 interviews, 1 offer. The offer was a Head of Applied AI role. Six months later he left it to work on career-ops full time.

Two things are worth knowing before you read anything else about it:

  • The repository moved. It started as santifer/career-ops and now lives at career-ops-hq/career-ops. The old URL redirects, but a lot of what ranks for "career-ops" still describes the early version, which graded every job from A to F. The current system writes a structured A-H report with a single 1-5 global score. This page covers that version, v1.35.0, released on 1 October 2026.
  • It is not a hosted service. There is no account, no backend and no telemetry. It is a folder of markdown modes, Node.js scripts and a Go terminal dashboard on your own machine, released under the MIT license.

The Filter Is the Product: Only 68 of 740 Jobs Got an Application

The README opens with the line that explains the whole design: "Companies use AI to filter candidates. I just gave candidates AI to choose companies."

Most AI job tools compete on volume: more applications, sent faster, ideally automatically. Career-ops goes the other way. Look at the funnel again. Of 740 listings evaluated, 68 received an application, about 9%. The other 91% were turned down by the candidate before anyone spent an evening on a cover letter. Of the 68 applications, 12 became interviews, roughly 18%.

The mechanism is a single line in the scoring rules:

Global scoreWhat career-ops tells you
4.5 and aboveStrong match, apply immediately
4.0 to 4.4Good match, worth applying
3.5 to 3.9Decent but not ideal, apply only with a specific reason
Below 3.5Recommends against applying

Below 4.0, it will tell you not to apply. You can override it, and it records that you did. The human stays in charge of the decision that matters most: whether this job deserves your night at all. The README puts it better than any feature list: "If it comes back do not apply, you just got the night back."

How Career-Ops Scores a Job: Five Dimensions, One Number, Eight Report Blocks

Before scoring, the agent classifies the role into an archetype. The defaults reflect the author's own search (LLMOps, Agentic, PM, Solutions Architect, Forward Deployed Engineer, Transformation), and the target roles you define in your own profile take precedence.

The 1-5 global score then integrates five dimensions:

DimensionWhat it measures
Match with CVSkills, experience and proof points
North Star alignmentFit with the target roles you defined
CompSalary against the market, 5 being top quartile
Cultural signalsCulture, growth, stability, remote policy
Red flagsBlockers and warnings, applied as negative adjustments

There is deliberately no arithmetic formula. The global score is one holistic judgement across the five, and once decided, the same value goes into the report header, a machine-readable summary and your tracker.

Around that number sits the A-H evaluation report:

  • A. Role summary, including geo-mismatch and work-authorization checks. A posting that explicitly rules out visa sponsorship is flagged as a hard blocker.
  • B. Match with CV, one row per significant requirement, each mapped to an exact line of evidence.
  • C. Level and strategy.
  • D. Comp and demand, backed by salary research.
  • E. Customization plan for the CV.
  • F. Interview plan, built on STAR+R stories (STAR plus a Reflection).
  • G. Posting legitimacy: is this a real opening at all?
  • H. Draft application answers.

Two of those signals are kept out of the score on purpose: the requirement importance in Block B and the legitimacy tier in Block G. The reason is comparability. The 4.0 line has to mean the same thing across your entire history, so that analyze-patterns.mjs and stats.mjs can later tell you something true about where your applications stall.

It Reads the Job Description Before Your CV, to Avoid Flattering You

This is the most interesting engineering decision in the repository. It lives in modes/oferta.md as the "two-pass rule".

When the agent fills in the CV match table, it works in two strict passes:

  1. Pass 1, job description only. Write down each requirement and how much it matters in this posting, before reading your CV.
  2. Pass 2, the CV. Only then read cv.md and mark each row Strong, Partial or Missing, quoting the evidence.

Importance is never revised in pass two. The reason is anchoring. A model that has just written "Strong" next to a requirement tends to rate that requirement as important, and to quietly discount the ones you lack. Doing it in the natural order would make the table flatter you exactly where it should warn you. Here the safeguard is the order of generation itself, not an instruction to "be objective".

Importance uses five named bands (critical, high, meaningful, preferred, low_signal) rather than a 0-100 number, because "87 versus 84" would not reproduce across two runs on the same posting. Every row also carries an evidence tier:

  • stated: the posting itself says "required" or "must have", backed by a verbatim quote.
  • structural: the posting's layout carries the weight, for example which section the requirement sits under.
  • inferred: market knowledge about how such roles are actually screened.

Then comes a gate: an inferred requirement can never be rated critical or high. The file explains the asymmetry. Inflating a requirement you are missing reads as "don't bother applying", which costs you an application you should have sent. Under-weighting a real one costs a less-prepared interview, which you can recover from. The cap sits on the side where being wrong is expensive.

One more detail worth copying into any LLM pipeline: job descriptions are treated as untrusted input. If a posting contains text aimed at the reviewer ("rank this requirement highest"), it is quoted as an anomaly in Block G and not obeyed. That is prompt-injection defence built into a job search tool.

Ghost Job Detection: It Checks the Posting Is Real Before You Write a Word

Ghost jobs, listings that stay up long after a role is filled or that were never really open, are one of the most common complaints about job hunting right now. Career-ops deals with them twice.

First, a liveness gate. When you paste a URL, the agent loads the page with Playwright before any evaluation starts. A 404, an "applications closed" banner or a redirect to a generic careers page stops the run before Block A, so a dead link never burns a full report and PDF. It also knows that many careers pages embed an Ashby or other ATS board inside an iframe, where the outer page looks empty while the listing is perfectly fine, and it refuses to call that closed.

Second, Block G rates every live posting as High Confidence, Proceed with Caution or Suspicious. The signals are weighted by how reliable they actually are:

SignalReliability
Posting age (under 30 days good, 60+ concerning)High
Apply button activeHigh
Tech specificity in the descriptionMedium
Requirements realismMedium
Recent layoff newsMedium
Same role reposted 2+ times in 90 daysMedium
Salary transparencyLow

The framing rules are strict: never present the findings as an accusation, always note the legitimate explanations, and let you decide. Outside the evaluation, detect-reposts.mjs tracks reposting across your scan history, and node scan.mjs --verify runs a Playwright liveness check on newly discovered listings before they ever reach your pipeline.

Tailored ATS-Friendly CVs and Cover Letters, With a Fact Check

When a role clears the bar, career-ops generates an ATS-readable PDF CV tailored to that job description. It is rendered from an HTML template through Playwright, set in Space Grotesk and DM Sans. If you live in LaTeX, it can export a .tex file for Overleaf or tailor your own resume.tex in place, and there is a plain markdown version too.

Cover letters use the same pipeline: keyword mirroring, four angle prompts (why, problems, approach, tone), a draft you approve in chat, then an A4 PDF. One is drafted automatically with every evaluation. If you want the idea without setting up a CLI, our free AI cover letter generator does a browser-only version for a single posting.

The rule that matters most here is "reformulate, never fabricate", and the README is unusually candid about how far it is enforced:

  • generate-pdf blocks a CV whose numbers or facts appear in neither your CV nor your article digest, unless you pass --skip-fact-check.
  • It does not yet check job titles or judge rewording. Two open issues track that gap: #2677 (titles must match cv.md) and #1411 (a fail-closed faithfulness check).

Until those merge, read every CV before it goes out. An AI proofreader will catch the grammar, but only you can catch a claim you never made.

What Career-Ops Will Not Do: No Auto-Submit, No Email, No Telemetry

The README gives its refusals their own section, and each one is backed by something concrete:

  • Auto-submit an application. It drafts an answer for every field. The script that prepares applications, prepare-application.mjs, documents that it never POSTs anything; you open the apply URL and submit yourself.
  • Send an email. Drafts only. There is no mail transport anywhere in the codebase.
  • Phone home. No telemetry and no backend. Your CV goes from your machine to the AI provider you chose, and nowhere else.
  • Push you to apply below 4.0. It recommends against it, and notes your override.

Outreach follows the same rule. The contacto mode identifies the hiring manager, recruiter or peer worth messaging and drafts a LinkedIn note of 300 characters or fewer, but it never sends it. If you edit that draft, a word and character counter keeps it under the limit.

"Draft, never decide" is becoming the standard posture for serious agent tooling. Anthropic's financial services agents take exactly the same line: they prepare analyst work and stage every output for human sign-off.

The disclaimer adds the necessary caveat. The prompts instruct the model never to submit, but models can behave unpredictably, especially if you edit the prompts or switch models. Treat the guarantee as the project's design, and your own review as the backstop.

How to Install Career-Ops in One Command

The fastest path needs Node.js and an AI coding CLI:

bash
npx @santifer/career-ops init
cd career-ops
claude   # or codex, opencode, qwen, agy, grok

init clones the latest release into ./career-ops and installs the dependencies. On first launch the agent asks for your CV, what you want and what you refuse, all in chat, with nothing to configure by hand. The README is frank about the start: "The first runs are rough. It does not know you yet." Treat it like a recruiter's first week.

If you prefer manual setup, clone the repository, run npm install, then npx playwright install chromium (only needed for PDFs) and npm run doctor to validate the prerequisites. Configuration is plain files: cv.md holds your CV, config/profile.yml your profile, and portals.yml the companies to scan. YAML is strict about indentation, so a YAML formatter saves a confusing error when the scanner reads a broken file.

From there, paste a job URL or description and the auto-pipeline runs: evaluation, report, PDF and tracker entry. In CLIs that register slash commands, /career-ops lists around forty modes, including scan, pipeline, pdf, cover, tracker, interview-prep, apply and patterns. Codex does not guarantee slash commands, so there you ask for a mode in plain language: "Run the career-ops scan mode."

Two options worth knowing:

  • npm i -g @santifer/career-ops installs a global career-ops command once you have a project folder.
  • Setting CAREER_OPS_ROOT moves your personal data (CV, reports, tracker, PDFs) out of the code checkout, so updating or switching branches never touches it.

Running Career-Ops for Free, and the API Key That Quietly Bills You

Career-ops is free; the AI model behind it is where the cost lives, and you have several ways to control it.

A spend_tier setting in config/profile.yml picks the model that evaluates offers. In Claude Code, economy maps to Haiku 4.5, standard to Sonnet 5.5 and premium to Opus 5.5. Every tier produces the same A-H report format. For zero spend, the project documents OpenRouter's free models, Ollama or any OpenAI-compatible endpoint, a guide to running on Antigravity CLI's free tier, and a standalone gemini-eval.mjs script that works with a free Gemini API key and no CLI at all.

Discovery is cheap by design. node scan.mjs finds new listings across the configured portals without spending any tokens. The tokens go into evaluating them, which is exactly where you want the model's attention.

Now the trap, which the FAQ answers because so many people hit it. If you pay for Claude Pro or Max and still see API charges, an ANTHROPIC_API_KEY in your environment is taking precedence over your logged-in subscription, so the CLI bills per token instead. Run echo $ANTHROPIC_API_KEY; if it prints anything, remove it from your shell profile, restart the terminal and run /login. Batch mode is the exception: its headless claude -p workers do not use the interactive login, so run claude setup-token once and export the result as CLAUDE_CODE_OAUTH_TOKEN.

The Rest of the Pipeline: Scanner, Tracker, Dashboard and Interview Prep

Evaluation is the core, but the repository covers the whole search from discovery to offer:

  • Portal scanner. More than 100 companies are pre-configured (Anthropic, OpenAI, ElevenLabs, Retool, n8n and more) with 35+ search queries, across 55+ provider modules covering Ashby, Greenhouse, Lever, Wellfound and board-wide feeds.
  • Job application tracker. Every evaluated offer is registered automatically, with merging, de-duplication and status normalization handled by scripts rather than by hand.
  • Dashboard. A terminal UI written in Go with Bubble Tea, with six filter tabs, four sort modes and inline status changes. An experimental web UI exists but only runs if you start it.
  • Batch processing. Parallel evaluation through headless workers (claude -p or opencode run).
  • Interview suite. A STAR+R story bank built up across evaluations, time-blocked prep plans, practice sessions with feedback, post-interview debriefs and an employer red-flag detector.
  • Offer stage. A contract reading companion that walks the clauses and lists questions for a lawyer (explicitly not legal advice), plus a salary-gap analyzer and negotiation scripts.
  • Learning from outcomes. patterns analyzes where rejections cluster, and calibrate checks whether your scores actually predicted your results. It reports; it never changes the scoring.

Integrations such as Gmail, Notion and Apify exist as opt-in plugins, disabled by default.

Repo Health: 73,583 Stars in Six Months, and Who It Is For

The repository was created on 4 April 2026 and had 73,583 stars and 13,820 forks at the time of writing. The latest release, v1.35.0, shipped on 1 October 2026. The README is translated into 17 languages, the project has been covered by Business Insider and WIRED's Greek edition, and it reached number one on Trendshift's repository of the day.

The community signals are unusually concrete. A public HIRED.md wall had 13 hiring stories on the record, each one an issue you can open and read, and the CareerOps Manifesto ("Apply better to fewer. Signal over volume. Evidence over keywords. A human decides.") had 144 signatures, each one an auditable commit. The author says the repository is maintained by a fleet of AI agents with a human deciding every merge. SerpApi sponsors it, under a stated rule that sponsorship buys labelled visibility and never influences evaluations or rankings. The code is MIT; the career-ops name is covered by a separate trademark policy that reserves it for commercial product naming.

Good fit if you are applying to more roles than you can evaluate properly, you already use an AI coding CLI, and you want a second opinion that is willing to tell you no. It is strongest for tech roles, since that is where the default archetypes and pre-configured portals point, though the archetypes are fully customizable.

Poor fit if you want a tool that applies for you while you sleep. Career-ops is a filter, not a spray-and-pray auto-applier, and that is the entire point of it. It is also not for anyone unwilling to read every CV it produces before sending, because the fact check does not yet cover everything.

Frequently Asked Questions

What is career-ops?

Career-ops is a free, open-source AI job search agent that runs locally inside an AI coding CLI such as Claude Code, Codex or OpenCode. It checks that a job posting is live, scores it 1 to 5 against your CV, generates a tailored ATS-friendly CV and cover letter, and tracks every application. You make every decision and press Submit yourself.

Is career-ops free?

Yes. The code is MIT licensed and free for candidates. You pay only for the AI model you run it on, and it supports free and local options including OpenRouter free models, Ollama, any OpenAI-compatible endpoint and a free Gemini API key.

Does career-ops auto-apply to jobs?

No. It drafts answers for every field of the application, but the script that prepares applications never submits anything and there is no email sending anywhere in the code. It is designed as a filter, not an auto-applier.

What score should a job get before I apply?

Career-ops recommends applying at 4.0 out of 5 or higher. 4.5 and above is a strong match, 3.5 to 3.9 is worth applying only with a specific reason, and below 3.5 it recommends against applying. You can always override it.

Which AI CLIs does career-ops work with?

Claude Code, Codex, OpenCode, Antigravity CLI, Qwen, Kimi, GitHub Copilot, Grok Build CLI and Pi, through the open Agent Skill Standard. It is not locked to one vendor.

Does career-ops upload my CV anywhere?

No. There is no backend and no telemetry. Your CV and application data stay on your machine and are only sent to the AI provider you chose to run the agent.

Why is career-ops using API credits when I pay for Claude Pro or Max?

An ANTHROPIC_API_KEY set in your environment takes precedence over your logged-in subscription. Remove it from your shell profile, restart the terminal and run /login. For batch mode, run claude setup-token and export the result as CLAUDE_CODE_OAUTH_TOKEN.

Is career-ops-hq/career-ops the same project as santifer/career-ops?

Yes. The repository moved from santifer/career-ops to the career-ops-hq organization, and the old GitHub URL redirects to the new one. The npm package is still published as @santifer/career-ops.

Related DevPik tools

Muhammad Tayyab

Written by

Muhammad Tayyab

CEO & Founder at Mergemain

Muhammad Tayyab builds free, privacy-first developer tools at DevPik. He writes about AI trends, developer tools, and web technologies.

More open source picks