Sandbox
@jananthan30/Resume-Builder

Resume Builder plugin for Claude Code and Codex

ResumeHQ is a plugin bundle that plugs into Claude Code and Codex to help you search jobs, score fit, tailor a resume, and write a cover letter. It uses deterministic scoring and an audit pipeline before it generates final documents.

83 stars29 forksPythonUpdated 1mo ago
Who it's for

Builders who want Claude Code or Codex to help with resumes, cover letters, and job matching.

What it delivers

You can turn a job description into a tailored resume package with fit checks and scoring before you apply.

What it does

Job-fit gate

Checks a master resume against the job description before tailoring starts, and stops when the role is a genuine mismatch.

Resume and cover letter generation

Creates tailored resume drafts, cover letters, and DOCX output from the same job description.

Job discovery and scoring

Finds live jobs, ranks them against your resume, and shows ATS and HR-style scores.

Evidence-based auditing

Matches claims back to resume text and keeps a separate evidence record for review.

Claude Code and Codex surfaces

Ships as plugin manifests, slash commands, MCP tools, and local codex surfaces for both editors.

How to get it

  1. 1Claude Code
    /plugin marketplace add jananthan30/Resume-Builder
    /plugin install resume-builder
  2. 2Codex from a local checkout
    codex plugin marketplace add .
  3. 3Claude Code exposes the plugin setup command
    /resume-builder:setup
  4. 4Claude Code
    /resume-builder:resume [paste a job description here]
  5. 5Codex
    $resume-team [paste a job description here]
  6. 6Or find jobs first
    /resume-builder:find-jobs Senior Data Scientist in New York

README

ResumeHQ — the resume tool that refuses to lie for you

Every AI resume tool promises to "beat the ATS." This one has a harder rule: it never invents experience — and when a job is a genuine mismatch, it declines to tailor at all and tells you why. Finds jobs, scores your fit with deterministic engines (not LLM vibes), tailors through a fail-closed pipeline where an independent auditor can veto the writer, and publishes its own scoring failures. Works as a Claude Code plugin, Codex plugin, or standalone web app.

License: MIT Python 3.10+ Claude Code Codex

Upload a resume, paste a job description, get match scores and recruiter-style feedback with fixes in seconds

Upload a resume → paste the job posting → keyword-match and recruiter-style heuristic scores with concrete fixes, in under 30 seconds. Try it free.


Why ResumeHQ?

Most resume tools only score the resume you bring to them. ResumeHQ goes further:

FeatureJobscanReziTealResumeHQ
Keyword + semantic match scoring
Recruiter-style heuristic review
Discover matching jobs
Score jobs against your resume
Auto-tailor resume to JD
ATS-compliant DOCX output
Application tracker
Works in Claude Code / claude.ai / Codex
Open source
Publishes its scoring benchmarks — including the bugs
Refuses to fabricate — declines to tailor genuine mismatches, audits every claim against your real resume

What This Does

You paste a job description (or search for jobs). The system:

  1. Discovers matching jobs from live job boards — scored and ranked by fit with your resume
  2. Gates candidate fit — your master resume must clear the fit bar (default 50) against the exact JD with zero hard knockouts before resume work begins. If you don't fit, it says so and stops — no tool that invents experience to close the gap is working for you
  3. Analyzes passing JDs — extracts keywords, required skills, domain, seniority level
  4. Tailors your master resume — rewrites bullets, reorders sections, matches terminology
  5. Scores the result with two independent advisory heuristics (keyword/semantic match + recruiter-style review)
  6. Iterates automatically until the evidence match covers every must-have (75%+ evidence match) — an internal editorial target, not a prediction of any employer's screening
  7. Generates production-ready DOCX files (resume + cover letter)
  8. Tracks every application in an Excel spreadsheet

The candidate-fit gate always runs first and cannot be bypassed by ATS/HR scores. After it passes, safe read/scoring work may run concurrently while authorization, DOCX generation, and tracker mutation remain ordered.


Quick Start — 3 Steps

Works with Claude Code (CLI/IDE), Codex (CLI/app/IDE), and claude.ai (web/Projects).

Step 1: Install the plugin

Claude Code:

/plugin marketplace add jananthan30/Resume-Builder
/plugin install resume-builder

Codex from a local checkout:

codex plugin marketplace add .

Then restart Codex and install Resume Builder from the Resume Builder Local marketplace.

Step 2: Configure the runtime

Claude Code exposes the plugin setup command:

/resume-builder:setup

This walks you through everything:

  • Checks if Python is installed (tells you where to download it if not)
  • Installs all dependencies automatically (pip install -r requirements.txt)
  • Creates your config.json with your name, email, phone, LinkedIn
  • Optionally links a Pro account for unlimited cloud scoring
  • Optionally sets up the LLM scorer (Claude API key)

For Codex, install Python 3.10+, run python -m pip install -r requirements.txt, and create config.json with a valid master_resume_path. The installed Codex surface exposes the Resume Team as $resume-team; it does not expose the Claude-style /resume-builder:* command namespace.

Step 3: Start building resumes

Claude Code:

/resume-builder:resume [paste a job description here]

Codex:

$resume-team [paste a job description here]

$resume-team publishes an authorized, digest-verified resume.md draft. It does not by itself create a DOCX or complete an application package.

Or find jobs first:

/resume-builder:find-jobs Senior Data Scientist in New York

Claude Code Slash Commands (9)

CommandWhat It Does
/resume-builder:setupOne-time setup wizard (installs Python deps, creates config, links Pro account)
/resume-builder:job-fit [JD]Deterministic master-vs-JD gate (fit bar, default 50, and zero hard knockouts) before tailoring
/resume-builder:resume [JD]Full application: tailored resume + cover letter + scoring + DOCX + tracking
/resume-builder:tailor-resume [JD]Resume only (no cover letter)
/resume-builder:cover-letter [JD]Cover letter only
/resume-builder:find-jobs [title] [location]Discover and score matching jobs from live job boards
/resume-builder:batch-resumeProcess multiple job descriptions in parallel
/resume-builder:writing-coach [file]Audit and rewrite resume bullets using 10 writing rules
/resume-builder:resume-team [JD]Publish an authorized resume.md draft through the native Researcher → Writer → Auditor → Editor workflow

If running Claude Code locally from the cloned repo, use short names: /resume, /tailor-resume, /find-jobs, etc. In Codex, invoke $resume-team.

What Works Without Setup

Some Claude Code commands can provide prompt-only previews before setup. Production resume generation through /resume-builder:resume, /resume-builder:resume-team, or Codex $resume-team requires Python, config.json, the deterministic candidate-fit preflight, and the evidence, human-voice, and canonical-integrity audit helpers; those gates are never skipped.

CommandWorks immediately?With setup?
/resume-builder:job-fitNo — requires the configured master and deterministic preflightDigest-bound score, threshold, and hard-knockout decision
/resume-builder:resumeNo — the native team and deterministic audits require setupFull audited resume + automated ATS/HR scoring and DOCX output
/resume-builder:resume-team / $resume-teamNo — requires macOS/Linux, the configured master resume, and Python audit helpersAuthorized, digest-verified resume.md draft; DOCX/tracker finalization is still pending
/resume-builder:cover-letterYes — the assistant writes the letter+ DOCX output
/resume-builder:writing-coachYes — full writing auditSame
/resume-builder:find-jobsYes — shows results (no score)+ ATS/HR fit scoring per job
/resume-builder:setupYes — runs the setup wizardN/A
MCP scoring toolsNo — needs Pythonevidence_match, score_resume, score_ats, score_hr, score_with_llm, explain_score, extract_text, discover_jobs

MCP Tools (7 production-supported surfaces)

After running /resume-builder:setup, the MCP scorer auto-starts and provides these tools that Claude Code or Codex can call natively:

ToolWhat It Does
evidence_matchRequirement-by-requirement evidence matching, with the exact excerpt behind each conclusion (recommended)
score_resumeLegacy ATS + HR analysis in one call
score_atsKeyword + semantic match scoring (8 heuristic components)
score_hrRecruiter-style heuristic review (6 factors + F-pattern)
score_with_llmLLM-augmented rubric scoring (requires ANTHROPIC_API_KEY)
explain_scoreActionable improvement suggestions with missing keywords
extract_textExtract text from DOCX/PDF/MD/TXT files
discover_jobsSearch live job boards and score each job against your resume

All listed MCP tools support cloud-first scoring — they try the cloud API first and fall back to local scoring automatically. Legacy direct rewrite endpoints or functions are not production-authorized tailoring paths. The capability-isolated native Resume Team is the sole production rewrite and draft-publication path.


Job Discovery

The /find-jobs command and discover_jobs MCP tool search live job boards and rank results by how well each job matches your resume — answering "which jobs should I actually apply to?" with data.

/resume-builder:find-jobs Senior Product Manager in San Francisco
/resume-builder:find-jobs Data Scientist remote

How it works:

  1. Searches Adzuna (16 countries, salary data) + Remotive (remote jobs) + JSearch (aggregated boards incl. niche career centers; optional RapidAPI key)
  2. Pre-filters top 20 results by title relevance
  3. Lightweight scores all 20 candidates (keyword + phrase + BM25 — fast)
  4. Full ATS + HR scores top 10 finalists
  5. Returns ranked list with scores, salary range, and apply links

Sample output:

Rank  Title                        Company        ATS   HR    Salary
────  ───────────────────────────  ─────────────  ────  ────  ──────────────
#1    Senior Data Scientist        Pfizer          82%   74%  $120k–$150k
#2    Data Scientist II            Goldman Sachs   79%   71%  $110k–$140k
#3    ML Engineer – NLP            Microsoft       74%   68%  $130k–$160k

API keys required for job search:

  • Adzuna (free): Register at developer.adzuna.com — add ADZUNA_APP_ID and ADZUNA_APP_KEY to your .env
  • Remotive: No key needed (remote jobs only, included automatically)

Evidence Matching

A universal "ATS score" does not exist. Recruiting systems parse, search, filter, evaluate requirements and sometimes rank — using materially different mechanisms — so a single percentage cannot describe them all.

This tool answers a question that is answerable:

Your resume provides strong evidence for 17 of 21 important requirements. One must-have has no evidence found. Eligibility is UNVERIFIED.

Every conclusion cites the exact resume excerpt behind it, with character offsets you can verify.

python evidence_match.py --resume resume.docx --jd job.txt --verify

Three results stay separate and are never multiplied together:

OutputMeaning
EligibilityPASS / FAIL / UNVERIFIED on explicit hard requirements
Qualification Evidence FitHow strongly the resume supports the role's requirements
Evidence QualityHow explicit and traceable that evidence is

A missing licence is UNVERIFIED, not FAIL — the resume did not establish it, which is not proof the candidate lacks it. Only explicit contradictory evidence (an expired licence) produces FAIL.

Why this resists gaming. The model classifies evidence; Python computes every number. Repeating a phrase twenty times collapses to one piece of evidence, a parent skill never satisfies a child requirement (Python does not imply TensorFlow), and unapproved synonyms are downgraded rather than accepted. Scores replay exactly from stored judgments with no LLM call:

python evidence_match.py --replay match.json

Choosing a model

Because the model only classifies and Python computes every number, the model is configuration rather than policy — a weaker judge produces measurably wrong labels, never quietly drifting scores. Set either role with a provider:model spec; a bare name still means Anthropic.

# Careful extraction, cheap judging — the split that trades cost against risk
export EVIDENCE_EXTRACTOR_MODEL="anthropic:claude-sonnet-5"
export EVIDENCE_JUDGE_MODEL="deepseek:deepseek-chat"

# Or run entirely on self-hosted weights; nothing leaves the machine
export EVIDENCE_JUDGE_MODEL="local:qwen3"
export EVIDENCE_LOCAL_BASE_URL="http://localhost:11434/v1"

Providers: anthropic, xai, moonshot, deepseek, dashscope (Qwen, Singapore), dashscope-cn (Qwen, Beijing — cheaper, but candidate data leaves the region), openrouter, together, fireworks, groq, local (vLLM / Ollama / llama.cpp). Each reads its own key — DEEPSEEK_API_KEY, XAI_API_KEY, DASHSCOPE_API_KEY, and so on. Defaults are unchanged, so an existing install keeps behaving exactly as before.

A model that cannot stop reasoning is a poor fit for the judge role whatever its sticker price: judging is bounded classification, and reasoning tokens bill at the output rate, which is already ~80% of the cost here.

Using an aggregator? Pin the backend. One OpenRouter model slug can be served by several backends at different quantizations, so two runs can record the same judge_model and be materially different models — the same failure as recording a constant model name, one layer up.

export EVIDENCE_JUDGE_MODEL="openrouter:qwen/qwen3.8-max"
export EVIDENCE_OPENROUTER_PROVIDER="deepinfra"     # disables silent failover
export EVIDENCE_OPENROUTER_QUANTIZATIONS="fp8"      # optional, recorded too

A pin becomes part of the recorded identity (qwen/qwen3.8-max@deepinfra/fp8) and therefore part of the cache key. Without one the model id is recorded as …@unpinned, so a stored score never claims a reproducibility it does not have. Aggregators are well suited to comparing candidates; pin before you trust a number, and prefer a direct provider key once a model is chosen.

Extraction and judging are configured separately because they carry different risk. Extraction must quote the posting verbatim and classify hard gates, and runs once per match. Judging is bounded classification and runs once per requirement — roughly ten times the volume, and where the money goes.

The model is part of the result's identity. extractor_model and judge_model are written into the audit record and hashed into the cache key, so two models never share a cache entry and a cheap-model score can never be served as a frontier-model one. Changing either invalidates cached results by design.

Before switching, measure. Zero adversarial inversions is what makes this engine better than keyword matching, so re-run the ablations and compare against the current baseline rather than assuming a cheaper model holds:

RUN_LIVE_LLM=1 python -m benchmarks.evidence.runner --with-llm

Routing resumes to a third-party provider sends candidate data outside Anthropic. pii_redactor runs before every hosted call regardless of provider, and local: keeps everything on your own machine — but the choice of endpoint is a data-handling decision, not just a pricing one.


Legacy Scoring System (diagnostic only)

Retained for the comparison table and existing API integrations.

ATS Scorer — 8 Weighted Components

Heuristic keyword/semantic match scoring. It does not simulate any real ATS. There is no universal ATS algorithm — Workday, Greenhouse, Taleo, and other systems parse, search, filter, and rank differently, and modern products increasingly use requirement-based semantic matching rather than raw keyword counts. Treat this score as an advisory match diagnostic, never as a pass/fail prediction.

ComponentWeightWhat It Measures
Phrase Match25%Multi-word industry phrases present in both texts
Keyword Match20%Lemmatized keywords with synonym expansion
Weighted Industry Terms15%Domain-specific terminology with recency decay
Semantic Similarity10%SBERT vector cosine similarity between resume and JD
BM25 Score10%Probabilistic relevance ranking (BM25Plus)
Job Title Match10%Exact JD title in resume header/summary
Graph Centrality5%Infers missing skills from related skills via NetworkX
Skill Recency5%Exponential decay — recent experience weighted higher

Additional checks: Hidden text detection, readability analysis (Flesch-Kincaid Grade 10-12 optimal), format risk assessment.

HR Scorer — 6 Factors + Visual Analysis

Applies recruiter-inspired heuristics as an advisory review of experience and presentation signals. It does not predict how any actual recruiter will react — it is a structured checklist, not a behavioral model.

FactorWeightWhat It Measures
Job Fit15-30%Domain/therapeutic area, experience type, education, role level
Experience Fit10-20%Years of experience vs. JD requirements, Goldilocks zone
Skills Match10-30%Demonstrated skills (action verbs) vs. listed skills
Career Trajectory10-15%Title progression via linear regression slope
Impact Signals15-25%Metrics density + Bloom's Taxonomy verb power levels
Competitive Edge10%Company/university prestige signals
F-Pattern Visual+/-5ptsLayout heuristics (golden triangle, left-rail alignment)

Weights adapt to detected seniority (junior / mid / senior / executive / career-pivot); ranges shown. Risk penalties: Job hopping (-8 to -15 pts), unexplained gaps (-5 to -15 pts), recent instability.

LLM Scorer (Optional)

Claude-powered rubric evaluation that catches nuances the algorithmic scorers miss — tone, coherence, storytelling quality.


Pricing

TierPriceWhat You Get
Free$05 cloud scores (then automatic local scoring fallback for CLI/MCP users)
Pro$12/moUnlimited checks, full keyword gap + deep AI analysis, 10 AI rewrites/mo, 30 cover letters/mo
Ultra$29/moEverything in Pro + 100 AI rewrites/mo, 1,000 cover letters/mo

Note for Claude Code / claude.ai users: Your Anthropic subscription already handles resume writing via Claude. The scorer server only does ATS + HR scoring, so Pro is all you need — you do not need Ultra.

Sign up at getresumehq.com. After signing up, run /resume-builder:setup to link your Pro account in one step.


Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│             Claude Code / claude.ai                          │
│  /resume  /tailor-resume  /cover-letter  /find-jobs  /setup  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌───────────┐  │
│  │  ATS     │  │  HR      │  │  LLM     │  │  Writing  │  │
│  │  Scorer  │  │  Scorer  │  │  Scorer  │  │  Coach    │  │
│  │ (8-comp) │  │ (6-fact) │  │ (Claude) │  │ (10 rules)│  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └─────┬─────┘  │
│       └──────────────┴─────────────┘               │        │
│                      │                             │        │
│              ┌───────┴───────┐              ┌──────┴─────┐  │
│              │  MCP Server   │              │   DOCX     │  │
│              │  (FastMCP 3)  │              │ Generator  │  │
│              │  Cloud-first  │              │ (Workday)  │  │
│              └───────┬───────┘              └────────────┘  │
│                      │                                      │
│            ┌─────────┴──────────┐                           │
│            │  Cloud API         │                           │
│            │  resume-scorer     │                           │
│            │  .fly.dev          │                           │
│            │  (JWT + API key)   │                           │
│            └────────────────────┘                           │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│  Job Discovery: Adzuna + Remotive + JSearch → light score → │
│  full ATS+HR score → ranked results                         │
├─────────────────────────────────────────────────────────────┤
│  Orchestration State (state.json) — Multi-Agent DAG        │
│  Application Tracker (Excel) — Auto-updated per run        │
└─────────────────────────────────────────────────────────────┘

The MCP server operates in thin client mode: it tries the cloud API first for scoring, and falls back to local scoring if the cloud is unavailable or not configured. LLM scoring always runs locally using your own API key (BYOK).


Workflow

1. /resume-builder:setup            One-time setup (install deps, create config, link Pro)
2. Create your master resume         YOUR_MASTER_RESUME.md with full work history
3. /resume-builder:find-jobs [JD]   Optional — discover matching jobs scored by fit
4. /resume-builder:resume [JD]      Paste a job description — get a full application
5. /resume-builder:writing-coach    Optional — audit and improve writing quality

Each resume command follows a gated workflow:

  • Phase 0: Deterministic candidate-fit preflight against the configured master and exact JD (fit bar, default 50; zero hard knockouts). Rejected JDs create no output.
  • Phase 1: Read-only master/JD planning; prior tailored resumes are not inputs.
  • Phase 2: Native Researcher → Writer → Auditor → bounded Editor workflow.
  • Phase 3: Advisory ATS/HR scoring and cover-letter generation where requested.
  • Phase 4: Evidence, human-voice, and canonical-integrity authorization votes.
  • Phase 5: Ordered resume DOCX → cover-letter DOCX → tracker finalization.
  • Phase 6: Artifact verification, cleanup, and report.

Alternative: pip install

The scoring engine and MCP server are on PyPI:

pip install resumehq

# Serve the scorer to Claude/any MCP client over stdio:
resumehq-mcp

Alternative: Clone & Run Locally

If you prefer not to use the plugin system:

git clone https://github.com/jananthan30/Resume-Builder.git
cd Resume-Builder

pip install -r requirements.txt

# Download NLTK data (one-time)
python -c "import nltk; nltk.download('wordnet'); nltk.download('punkt_tab')"

cp .env.example .env
cp config.example.json config.json

Then edit .env (API keys) and config.json (your info), and use commands without the resume-builder: prefix (e.g., /resume instead of /resume-builder:resume).


Cloud Scoring API

The scoring API is hosted at https://resume-scorer.fly.dev. Free users get 5 scored resumes, then local scoring activates automatically. Sign up or upgrade at getresumehq.com.

The easiest way to link your account is via the setup wizard:

/resume-builder:setup

Or manually add to your .env:

SCORER_CLOUD_URL=https://resume-scorer.fly.dev
SCORER_CLOUD_API_KEY=rb_your_api_key_here

MCP Configuration

The .mcp.json file configures the MCP server to auto-start with Claude Code:

{
  "mcpServers": {
    "ai-resume-tuner": {
      "command": "python",
      "args": ["mcp_scorer.py"],
      "cwd": "/path/to/Resume-Builder",
      "env": {
        "SCORER_CLOUD_URL": "https://resume-scorer.fly.dev"
      }
    }
  }
}

Environment variables:

VariableRequiredDefaultDescription
SCORER_CLOUD_URLNohttps://resume-scorer.fly.devCloud scoring API URL
SCORER_CLOUD_API_KEYNoYour cloud API key (rb_...). Anonymous scoring (5 free) works without this.
ANTHROPIC_API_KEYNoFor LLM scoring (always runs locally with your key)
ADZUNA_APP_IDNoFor job discovery (free at developer.adzuna.com)
ADZUNA_APP_KEYNoFor job discovery
RAPIDAPI_KEYNoEnables the JSearch job source (aggregated boards)

Your Master Resume

Create a file with your complete work history. Supported formats: .docx, .pdf, .md, or .txt. This is the single source of truth — all tailored resumes are generated from it. DOCX is recommended since most people already have their resume in that format.

FULL NAME, CREDENTIALS
City, State ZIP | Phone | Email | LinkedIn

PROFESSIONAL SUMMARY
[Your comprehensive summary with all skills and experience]

PROFESSIONAL EXPERIENCE

JOB TITLE | COMPANY NAME | City, State
Month Year – Month Year

• Achievement with quantified impact
• Another achievement with metrics

EDUCATION

Degree Name
University Name, City, State | Year – Year

CERTIFICATIONS
• Certification Name – Issuing Body

Set the path to this file in your config.json as master_resume_path.


Scoring Reference

ATS Score

Heuristic keyword/semantic match diagnostic. It measures textual overlap with one job description — it does not predict whether any employer's system will advance your resume.

ScoreRatingMeaning
80-100%ExcellentVery high keyword/phrase overlap with this JD
65-79%GoodStrong textual match with this JD
50-64%FairModerate match — several JD terms missing
35-49%LowWeak textual match — many JD terms missing
0-34%PoorLittle keyword overlap with this JD

HR Score

Recruiter-inspired heuristic review. The recommendation labels describe heuristic factor strength only — not any recruiter's actual decision.

ScoreRecommendationMeaning
85%+STRONG INTERVIEWStrong across heuristic factors
70-84%INTERVIEWCompetitive across heuristic factors
55-69%MAYBEMarginal across heuristic factors
<55%PASSWeak across heuristic factors

API Reference

The scoring API runs locally (python scorer_server.py --port 8100) or is hosted at https://resume-scorer.fly.dev.

Scoring Endpoints

EndpointMethodAuthDescription
/healthGETNoServer health and version info
/api/matchPOSTYesEvidence match — requirement-level results with exact excerpts (recommended)
/score/atsPOSTYesLegacy keyword/semantic match scoring (8 weighted components)
/score/hrPOSTYesRecruiter-style heuristic scoring
/score/bothPOSTYesLegacy ATS + HR combined in one call (JSON by default, SSE with Accept: text/event-stream)
/score/llmPOSTYesLLM scoring via Claude
/score/combinedPOSTYesAll 3 blended (70% rules / 30% LLM)
/score/batchPOSTYesScore multiple resume/JD pairs
/explainPOSTYesDetailed score explanation
/jobs/discoverPOSTYesSearch jobs + score against resume

Auth & Billing Endpoints

EndpointMethodDescription
/auth/registerPOSTCreate account (email + password)
/auth/loginPOSTLogin and get JWT token
/auth/api-keyPOSTCreate an API key (requires JWT)
/auth/usageGETCheck usage stats and remaining scores
/billing/checkoutPOSTStart Stripe checkout for Pro upgrade
/billing/portalPOSTStripe customer portal

Authentication

  • JWT Bearer token: Authorization: Bearer <token> (from /auth/login)
  • API key: X-API-Key: rb_... (from /auth/api-key or web dashboard)

Example: Score a Resume

curl -X POST https://resume-scorer.fly.dev/score/ats \
  -H "X-API-Key: rb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"resume_text": "Your resume text...", "jd_text": "Job description text..."}'

Example: Discover Jobs

curl -X POST https://resume-scorer.fly.dev/jobs/discover \
  -H "X-API-Key: rb_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"resume_text": "Your resume...", "job_title": "Data Scientist", "location": "New York", "max_results": 10}'

Domain-Specific Scoring

The ATS scorer auto-detects the job domain and applies domain-specific adjustments:

DomainDetection MethodKey Adjustments
Clinical ResearchSBERT prototype embeddingsPublications bonus, transferable skills mapping
Pharma/BiotechKeyword + semantic hybridRegulatory terminology weighting, pipeline experience
TechnologyKeyword + semantic hybridPortfolio links bonus, 1.3x skill recency weight
FinanceKeyword + semantic hybridDeal artifacts required, 1.5x prestige weight
ConsultingKeyword + semantic hybridImpact metrics required, 1.4x prestige weight
HealthcareKeyword + semantic hybridCertifications required, quality improvement focus

Supported Professions

Works for any profession. The scorer auto-detects domain and applies appropriate weights:

DomainExample Roles
Clinical ResearchCRA, Medical Monitor, Study Director, Clinical Operations
Pharma/BiotechRegulatory Affairs, Medical Science Liaison, Drug Safety
TechnologySoftware Engineer, Product Manager, Data Scientist, ML Engineer
FinanceInvestment Analyst, Financial Controller, Risk Manager
ConsultingManagement Consultant, Strategy Analyst, Business Advisor
HealthcareNurse Manager, Quality Director, Health Administrator
GeneralAny role not matching a specific domain — uses universal scoring

ATS-Compliant DOCX Output

The DOCX generator produces files optimized for Applicant Tracking Systems (Workday, Taleo, Greenhouse, Lever):

  • No tables, text boxes, columns, or graphics (ATS parsers can't read these)
  • Heading styles for section detection (Workday XML parsing)
  • Safe fonts: Calibri, Arial, Times New Roman (10-12pt body)
  • Clean structure: Contact info in body (not headers/footers)
  • Bold metrics for visual impact during human review

Tech Stack

ComponentTechnology
AI Agent FrameworkClaude Code / claude.ai
LLMClaude (Anthropic)
MCP ServerFastMCP 3.0 (auto-starts with plugin, cloud-first thin client)
EmbeddingsSentence Transformers (all-MiniLM-L6-v2)
NLPNLTK (lemmatization), TextStat (readability)
SearchBM25Plus (rank-bm25), NetworkX (skill graphs)
Job DiscoveryAdzuna API + Remotive API + JSearch (RapidAPI)
API ServerFastAPI + Uvicorn
Cloud HostingFly.io (auto-stop/start, persistent volume)
AuthJWT (PyJWT) + SQLite-backed API keys
BillingStripe (subscription management)
Document Generationpython-docx
PDF Parsingpdfplumber
Trackingopenpyxl (Excel)

Project Structure

Resume-Builder/
├── agents/                     # Claude plugin-installed Researcher/Writer/Auditor/Editor definitions
├── .codex/agents/              # Native Codex Researcher/Writer/Auditor/Editor definitions
├── .claude/agents/             # Native Claude Code equivalents
├── .claude-plugin/             # Plugin manifest
│   └── plugin.json             # Plugin metadata (name, version, author)
├── .codex-plugin/              # Codex plugin manifest
│   └── plugin.json             # Codex metadata and install-surface copy
├── .agents/plugins/
│   └── marketplace.json        # Local Codex marketplace entry
├── skills/resume-team/         # Installable Codex Resume Team entrypoint
├── commands/                   # Slash commands (plugin format)
│   ├── setup.md                # One-time setup wizard
│   ├── job-fit.md              # Deterministic master-vs-JD candidate-fit gate
│   ├── resume.md               # Full application (native four-role team)
│   ├── resume-team.md          # Shared fail-closed coordinator protocol
│   ├── tailor-resume.md        # Resume only
│   ├── cover-letter.md         # Cover letter only
│   ├── find-jobs.md            # Job discovery + scoring
│   ├── batch-resume.md         # Batch processing
│   └── writing-coach.md        # Human Voice + Impact rules (0-16)
├── hooks/                      # Plugin hooks
│   └── hooks.json              # SessionStart: checks if scoring is ready
├── .mcp.json                   # MCP server config (auto-starts scorer)
├── .codex.mcp.json             # Codex MCP server config
├── mcp_scorer.py               # MCP scoring server (7 production-supported surfaces)
├── job_discovery.py            # Job search + two-tier scoring (Adzuna + Remotive + JSearch)
├── data/                       # Reference databases for scoring
│   ├── keywords_*.json         # Domain-specific keyword databases (6 domains)
│   ├── skill_taxonomy.json     # Skill categories with decay constants
│   ├── company_prestige.json   # Company prestige scoring
│   ├── university_rankings.json# University prestige scores
│   ├── acronyms.json           # Industry acronym expansion
│   └── action_verbs.json       # Verb power classifications
├── ats_scorer.py               # ATS scoring engine (2,800+ lines)
├── hr_scorer.py                # HR scoring engine (2,900+ lines)
├── llm_scorer.py               # LLM-powered rubric scorer
├── scorer_server.py            # FastAPI REST API (v3.0 — auth, usage, billing)
├── pii_redactor.py             # PII redaction via Presidio (pre-LLM API calls)
├── docx_generator.py           # ATS/Workday-compliant DOCX generator
├── orchestration_state.py      # Multi-agent state management (DAG)
├── multi_agent_team.py         # Vendor-neutral, offline, fail-closed team controller
├── candidate_fit_preflight.py  # Deterministic fit-bar/no-knockout first gate
├── native_resume_team.py       # Hardened Codex/Claude CLI adapter and draft publisher
├── schemas/
│   ├── resume-team-handoff.schema.json # Strict public role handoff contract
│   ├── resume-team-authorization.schema.json # Three-vote authorization contract
│   ├── resume-team-final-receipt.schema.json # Durable draft-authorization sidecar contract
│   └── resume-team-result.schema.json # Draft-stage runtime result contract
├── tracker_utils.py            # Excel application tracker utilities
├── resume_builder.py           # Retired direct-rewrite CLI; native-team migration guard
├── requirements.txt            # Python dependencies
├── config.example.json         # Config template
├── .env.example                # Environment variable template
├── AGENTS.md                   # Project context for Codex
├── CLAUDE.md                   # Project context for Claude Code
├── LICENSE                     # MIT License
└── README.md                   # You are here

Native Resume Team

Codex and Claude Code use the same resume-team/v2 control flow without API keys or a third-party orchestration framework. Project custom-agent role files omit model pins and follow their host's inheritance rules. The hardened runtime does not inherit transient parent-session or user configuration: by default its managed CLI model/reasoning selection is unknown and must not be described as a specific model, profile, or Ultra setting.

  • In an installed Claude Code plugin, run /resume-builder:resume-team [JD]; the four roles load from the plugin-root agents/ directory.
  • In Codex, run $resume-team [JD]. The skill uses python native_resume_team.py --host codex as the authoritative production path; each role runs from an empty temporary working directory with tool surfaces disabled. A project checkout also registers the four read-only custom roles from .codex/agents/ for interactive inspection, but those manual roles are not the capability-isolated publication path.
  • The hardened production runtime requires macOS or Linux, Python 3.10+, config.json, the configured master resume, candidate_fit_preflight.py, and the local deterministic audit helpers. Windows preflight fails closed with POSIX_RUNTIME_REQUIRED. No external model API key is required for the role agents.
  • Codex model selection is unpinned by default. Only when the user explicitly requests it may the runtime receive --model <exact-model> and/or --reasoning-effort ultra; it has no profile option. These Codex-only flags must not be passed to Claude.
  1. Before any role/team invocation or output creation, the coordinator runs candidate_fit_preflight.py against the exact JD and only the configured master resume—never a prior tailored resume. The canonical candidate-fit-policy-v3 report must clear the fit bar (default 50) with trustworthy extraction, zero hard knockouts, passed: true, and no codes. Scores below the bar (including 60–69) or hard knockouts return REJECTED:CANDIDATE_FIT; unavailable, malformed, stale, or mismatched reports return FAILED:CANDIDATE_FIT_PREFLIGHT. No automatic or manual workflow bypass exists.
  2. The coordinator sends the Researcher only the job description.
  3. The coordinator sends the Writer only the master resume and validated research artifact.
  4. The read-only Auditor checks the exact Writer draft and cannot edit it.
  5. The Editor is invoked only for named failures, with at most two corrections and a fresh audit after each edit.
  6. Draft-stage publication requires the final Auditor PASS plus independent evidence, human-voice, and canonical-integrity votes on the same draft digest.

Malformed, stale, replayed, ambiguous, timed-out, unavailable, side-effecting, or partially published runs fail closed. A runtime resume-team-result/v2 PUBLISHED result means only that an authorized, digest-verified resume.md draft was atomically written and read back. It does not mean DOCX generation, tracker update, cleanup, or package completion. /resume-builder:resume and /resume-builder:tailor-resume must complete their ordered DOCX, tracker, artifact-verification, cleanup, and report gates before claiming package success; a score cannot override an authenticity gate.

Every PUBLISHED result includes the independently reproducible candidate_fit_report and candidate_fit_report_digest, plus an inline resume-team-final-receipt/v2 authorization_receipt, its canonical authorization_receipt_digest, and a durable authorization_receipt_path. The sidecar conforms to schemas/resume-team-final-receipt.schema.json. Downstream finalization resolves the path against the output directory when relative, requires its resolved parent to be that directory, reads only a regular non-symlink JSON sidecar, and matches its canonical digest, run/case IDs, exact passing candidate-fit report/digest, and draft and verified-target digests against the result, configured master, exact JD, and independently hashed resume.md. It also recomputes the master source_digest from config.json, recomputes job_description_digest from the fixed sibling job_description.txt, and requires a SHA-256 Researcher artifact plus distinct same-host native Researcher/Auditor IDs. The receipt must also carry a same-draft PASS auditor_attestation and the complete passing authorization_report: no codes, exactly three ordered named PASS votes on the same draft with distinct IDs, canonical_digest(report) == authorization_digest, and an identical ordered vote_invocation_ids list. The same check is repeated immediately before DOCX generation. Cleanup preserves the receipt as durable audit evidence.

Finalization is code-bound: callers retain the captured runtime result, invoke final_receipt_verifier.py with its exact receipt path, digest, and config, and use only create_resume_from_md_authorized, create_cover_letter_from_md_authorized, and add_application_authorized. Each wrapper revalidates authorization at the side-effect boundary; tracker success requires a literal True return.

The constructive-provenance experiment established that a self-consistent model-supplied evidence ledger is not a trust root. Such a ledger is accepted only when its digest is independently attested. Production therefore anchors every changed line directly to coordinator-attested, same-role master-resume spans and applies the closed lexical verifier. constructive_provenance.py is a conditional checker and test artifact, not an alternative publication path.

Claude role definitions and the native runtime use an explicit zero-tool allowlist, so they cannot actively inspect workspace files; Claude Code may still supply its normal project startup instructions and basic environment context. Codex custom agents use a read-only sandbox, which prevents writes but is not a filesystem-read isolation boundary. In both cases, scoped payloads describe coordinator data flow rather than every byte of host-provided context. Codex currently has no documented per-custom-agent built-in-tool denylist, so manual Codex role instructions prohibit unrelated reads and must not be represented as capability isolation.

Writing Coach — Rules 0-16

The /writing-coach command applies human-voice and impact rules to every bullet point. Core rules include:

  1. Plain Verb Start — Use direct verbs such as Led, Built, Wrote, Cut, Reviewed, or Directed; AI-cliché openers are banned
  2. Quantified Impact — 40%+ of bullets must contain metrics (%, $, numbers)
  3. So-What Test — Every bullet answers "why does this matter?"
  4. Jargon Calibration — Match terminology level to the target role
  5. Tense Consistency — Past tense for past roles, present for current
  6. Parallel Structure — Consistent grammatical patterns within sections
  7. Length Optimization — 1-2 lines per bullet, no walls of text
  8. Keyword Integration — Natural placement, never forced
  9. Achievement vs. Duty — Frame responsibilities as accomplishments
  10. Readability — Flesch-Kincaid Grade 10-12 target

Contributing

Contributions are welcome! Some ideas:

  • New domain profiles — add keyword databases for law, marketing, academia, etc.
  • Additional job boards — integrate Indeed, LinkedIn, or regional boards
  • Additional ATS parsers — test against more ATS systems (Taleo, iCIMS, Greenhouse)
  • Resume templates — add more DOCX template styles
  • Internationalization — support for non-English resumes and job markets
git checkout -b feature/your-feature
# ... make changes ...
git commit -m "Add your feature"
git push origin feature/your-feature

License

MIT License — see the LICENSE file for details.


Acknowledgments

  • Built with Claude Code by Anthropic
  • Scoring heuristics informed by public research on how recruiting systems parse, search, and rank resumes (see docs/)
  • Domain keyword databases curated from thousands of real job descriptions
  • Job search powered by Adzuna and Remotive

If this project helps you land interviews, give it a star ⭐

Files in the repo

Repository payload76 top-level entries
  • .agents
  • .claude
  • .claude-plugin
  • .codex
  • .codex-plugin
  • .github
  • agent
  • agents
  • assets
  • benchmarks
  • cloud
  • commands
  • data
  • docs
  • evidence_engine
  • hooks
  • plugins
  • references
  • schemas
  • scripts
  • skills
  • skills_server
  • taxonomy
  • tests
  • .codex.mcp.json
  • .env.example
  • .gitignore
  • .mcp.json
  • AGENTS.md
  • ats_scorer.py
  • batch_job_search.py
  • BENCHMARKS.md
  • candidate_fit_judge.py
  • candidate_fit_override.py
  • candidate_fit_preflight.py
  • candidate_fit_review.py
  • CHANGELOG.md
  • claim_provenance_audit.py
  • CLAUDE.md
  • config.example.json
  • constructive_provenance.py
  • docx_generator.py
  • evidence_audit.py
  • evidence_match.py
  • final_receipt_verifier.py
  • generate_job_guide.py
  • hr_scorer.py
  • human_voice_audit.py
  • jd_fetcher.py
  • job_discovery.py
  • JOB_FIT_SCORER_PLAN.md
  • job_fit_scorer.py
  • legacy_rewrite_guard.py
  • LICENSE
  • llm_scorer.py
  • mcp_scorer.py
  • multi_agent_team.py
  • native_resume_team.py
  • orchestration_state.py
  • pii_redactor.py
  • pyproject.toml
  • README.md
  • requirements-dev.txt
  • requirements-plugin.txt
  • requirements.txt
  • restart_scorer.ps1
  • resume_builder.py
  • resume_integrity_audit.py
  • scorer_server.py
  • SECURITY.md
  • SUPPLEMENTAL_EXPERIENCE.md
  • test_domain_coverage.py
  • test_job_search.py
  • text_extractor.py
  • tracker_utils.py
  • uv.lock

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More plugins

Graphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.

82k
cbrock84/
headcount

An agent organization for Claude Code, structured as a company — 15+ departments, 125+ skills, each independently installable.

1.4k

Context window optimization for AI coding agents. Sandboxes tool output (98% reduction), persists session memory, and enforces routing across 17 platforms via MCP + hooks.

22k

Persistent file-based planning for AI coding agents and long-running tasks. Crash-proof markdown plans, session recovery after /clear and compaction, per-turn re-injection against context rot, deterministic completion gate. Manus-style. Install from npm, the Claude Code plugin marketplace, or npx skills. Codex, Cursor, OpenCode, 60+ agents.

27k

Self-organizing AI second brain for Obsidian + Claude Code. Drop any source and Claude reads, links, and files it into one connected knowledge graph of plain Markdown you own. AI note-taking, personal knowledge management (PKM), and an open-source Notion alternative. Based on Karpathy's LLM Wiki pattern.

15k

Universal SEO skill for Claude Code. 25 sub-skills + 18 sub-agents covering technical SEO, E-E-A-T, schema, GEO/AEO, backlinks, local SEO, maps intelligence, semantic clustering, e-commerce SEO, international SEO, Google APIs, and PDF/Excel reporting. Optional DataForSEO, Firecrawl, and Banana extensions.

17k