Skip to main content

cvloom

Manage your CV as one YAML dataset and generate any number of per-job-tailored PDFs from it — deterministically, with an agent-safe MCP layer and PII kept out of git.

Per-job overlays let you tailor a CV for each application by declarative config, not by copying files — so twenty variants stay consistent with one source of truth, and every variant is diffable and reviewable.

RenderCV renders one CV beautifully; cvloom manages twenty tailored variants of one dataset — with an agent-safe MCP layer.

PyPI Python 3.11+ License MIT


Every command below is runnable in examples/:

$ cvloom build --profile general          # your full CV, from one dataset
  ✓ HTML  → dist/cv.html
  ✓ PDF   → dist/Your_Name_Resume.pdf

$ cvloom build --profile example-job      # …same data, tailored for a specific role
  ✓ HTML  → dist/example-job-cv.html

$ cvloom diff general example-job         # tailoring is declarative + diffable
  Words: 195 vs 184 (-11)
  Highlights: 12 vs 12

$ cvloom check --profile example-job      # writing lint — no fake "ATS score"
  wl-002  writing  projects  cvloom  No quantification found  Add metrics.

$ cvloom match --jd stripe-infra-jd.txt --profile example-job
  Coverage: 41% (27 of 66 JD keywords found)

Change a fact once in data/ and every profile that uses it updates on the next build. See the worked one dataset, N applications example.


Features

Category Feature Command
Build YAML → HTML + PDF via WeasyPrint cvloom build
Named profiles with per-section content selection --profile NAME
Per-job overlays — patch highlights without duplicating data overlays: in profile
Per-section reordering and visibility section_order: / sections:
Rename any section heading, styling untouched section_titles: in profile
Build every profile in one run cvloom build --all
Public mode with placeholder contact data --public
Analyse Writing lint — 22 rules across writing / structure / ats-parse axes cvloom check
Per-axis lint breakdown inline after build (no fake "ATS score") --check / --strict N
Per-section word breakdown and trim guidance cvloom trim
Side-by-side profile comparison cvloom diff A B
Match Keyword gap analysis from job description cvloom match --jd FILE
AI Section scoring with strengths, weaknesses, priorities cvloom ai review
Tailored cover letter from CV + JD cvloom ai cover
Content improvement suggestions for a target role cvloom ai suggest
Qualitative JD alignment — tone, framing, repositioning cvloom ai align
Export JSON Resume, Markdown, plain text, DOCX cvloom export
Inspect List projects with tag filtering cvloom list-projects
List all build profiles cvloom list-profiles
List templates with their PDF text-extraction rating cvloom list-templates
Integrate Agent-safe MCP server — 16 tools over a schema-validated, PII-fenced data model cvloom-mcp
Publish to GitHub Pages — reusable, opt-in workflow scaffolded by init publish-cv.yml
Safety PII compartmentalisation + pre-commit scanner + --public builds private/ + hook

Quickstart

Install

# Install globally:
uv tool install cvloom

# Development setup:
git clone https://github.com/SWEStash/cvloom
cd cvloom
uv sync --all-extras

The repo root is the tool itself; a runnable demo CV lives in examples/ (cd examples && cvloom build --profile general --public).

Initialise a new CV project

mkdir my-cv && cd my-cv
cvloom init

Scaffolds the directory structure, creates sample YAML files, and installs the pre-commit PII scanner.

Upgrade

uv tool upgrade cvloom
cvloom sync   # refresh scaffolded files (hook, publish workflow); reports first, --force applies

See Keeping your instance updated; check the CHANGELOG for breaking changes before a major upgrade.

Edit your content

data/
├── basics.yaml          # headline, summary, public links
├── work.yaml            # work history
├── education.yaml       # education
├── skills.yaml          # skills by category
├── projects/            # one .yaml per project
└── (optional)           # publications, certifications, awards, languages

private/
└── contact.yaml         # name, email, phone, address — GITIGNORED

Build

cvloom build                          # default profile, HTML + PDF
cvloom build --profile backend-role   # specific profile
cvloom build --public --skip-pdf      # HTML only, placeholder contact
cvloom build --profile NAME --check   # build + writing-lint breakdown

Outputs land in dist/. See docs/user/cli-reference.md for the full command reference.


AI Features

Optional AI-powered analysis layered on top of the rules-based tools. Works with any OpenAI-compatible backend — local models via Ollama, cloud routing via LiteLLM, or OpenAI directly. All existing commands work unchanged when AI is not configured.

Setup

uv sync --extra ai

export CVLOOM_AI_BASE_URL=http://localhost:11434/v1   # Ollama, LiteLLM, OpenAI, etc.
export CVLOOM_AI_API_KEY=ollama                        # or your real key
export CVLOOM_AI_MODEL=gemma3:27b                      # or gpt-4o, claude-sonnet-4-6

cvloom ai config   # verify

Commands

ai review — score each CV section 1–10 with strengths, weaknesses, and the three highest-impact improvements across the whole CV.

cvloom ai review --profile general

ai cover — generate a tailored cover letter from your CV and a job description file.

cvloom ai cover --profile backend-role --jd stripe-infra.txt --output cover.md

ai suggest — get specific content improvements: new bullet points, skill additions, rewordings, and removals for a target role.

cvloom ai suggest --profile backend-role --role "Senior Platform Engineer"

ai align — qualitative analysis of how well your CV is positioned for a specific JD — tone, framing, narrative gaps — beyond keyword coverage.

cvloom ai align --profile backend-role --jd stripe-infra.txt

See docs/user/ai-features.md for backend quickstarts (Ollama, LiteLLM, OpenAI) and all configuration options.


Templates

Parses is how the rendered PDF survives text extraction — the step every ATS runs first. Ratings are measured with five independent extractors, from raw content-stream order through geometric reconstruction to the PDF structure tree; only what survives all five is rated safe. It is a property of the layout, not of your writing, so cvloom check does not cover it; cvloom list-templates prints this table, and build warns on anything not rated safe. See ATS-readiness for the measurements.

Template Cols Parses Font Use case
cv/ats-clean 1 ✅ safe Arial (system) Single column, no web fonts. The one to upload to a portal.
cv/academic 1 ✅ safe Georgia (system) Education-first serif CV. Runs long by convention; no page-count warning.
cv/modern-single 1 ✅ safe Lato Single column, slate rule system, aligned skills column.
cv/timeline-clean 1 ✅ safe Inter Swiss minimal, timeline rule down the experience section.
cv/executive-dark 1 ✅ safe Source Sans 3 Carbon header band, steel accent, title-first entries.
cv/sidebar-compact 2 ⚠️ caution Lato Two-column coloured sidebar. Best-looking for a human; pdftotext interleaves it, the other four engines do not.

The non-CV templates are unrated — they are not documents an ATS parses:

Template Use case
cover-letter/standard Professional cover letter driven by job_context
cover-letter/brief Compact cover letter, no boilerplate sign-off
project-summary/card Single-page project summary card

Profiles and Overlays

Each profile in profiles/ controls template, section visibility, content selection, section order, and heading text:

# profiles/backend-role.yaml
template: cv/ats-clean
output_filename: jane-smith-backend
sections:
  work: true
  education: true
  skills: true
  projects: true
select:
  work:
    tags: [python, kafka, aws]
section_titles:
  work: "Professional Experience"   # text only — styling stays in the template
job_context:
  company: Stripe
  role: Senior Platform Engineer

Overlays let you patch data per job application — override highlights, exclude entries, filter skills — without duplicating your base CV:

overlays:
  work:
    - match: {company: "Acme Corp"}
      highlights:
        mode: pick
        items: [perf-boost, api-redesign]

Choosing which content appears is a separate select block — per-section, so narrowing work leaves education alone:

select:
  work:
    tags: [python, kafka, aws]
  skills:
    categories: [Languages, Cloud]

Because tailoring is declarative config, two variants are diffable (cvloom diff A B) and always consistent — update a fact once in data/ and every profile that uses it updates on the next build. See the worked one dataset, N applications example, or the full overlay reference.


MCP Server

cvloom includes an MCP server exposing 16 tools for LLM-driven CV management. Data stays local — nothing leaves your machine.

uv sync --extra mcp
cvloom-mcp
Tool What it does
list_profiles List all build profiles
list_projects List projects, filter by tags
get_section Read raw YAML for any section
build_cv Build CV and return stats
create_profile Create a new profile
upsert_project Create or update a project
validate_data Run schema validation
export_json_resume Export as JSON Resume
check_cv Run writing lint, return categorized findings
trim_report Per-section word counts and trim recommendations
diff_profiles Compare two profiles side by side
match_jd Keyword gap analysis against a JD
ai_review_cv AI section scoring and feedback
ai_generate_cover AI cover letter from CV + JD text
ai_suggest_improvements AI content improvement suggestions
ai_align_to_jd AI qualitative JD alignment analysis

AI tools require the ai extra and CVLOOM_AI_BASE_URL to be set.

See docs/reference/mcp-server.md for setup with Claude Desktop, Claude Code, and example workflows.


Directory Structure

my-cv/
├── .gitignore          # private/ is LINE 1
├── data/               # CV content (committed, PII-free)
├── profiles/           # build configs (committed)
├── private/            # GITIGNORED — contact.yaml, cover letters
├── dist/               # GITIGNORED — build output
├── hooks/              # pre-commit PII scanner
└── templates/          # Jinja2 templates (or use built-in)

Documentation

User Guides

Guide What's covered
Getting Started Installation, init, and all features via step-by-step scenarios
CLI Reference Every command with flags, options, and examples
User Guide Complete config and features manual — data files, templates, exports, env vars
AI Features Setup, backends, and all AI commands
PII Safety Two-layer protection model
GitHub Pages Setup Automatic public CV deployment

Reference

Guide What's covered
Writing Lint Rules All 22 rules with categories, examples, and fix hints
ATS-readiness model The three honest axes, and why there is no single "ATS score"
MCP Server Setup, all 16 tools, and example workflows
Profiles and Overlays Full overlay system reference

Developer Guides

Guide What's covered
Architecture Build pipeline, module responsibilities, data flow
Custom Templates Writing Jinja2 templates, available blocks and filters
Contributing Dev setup, testing, adding linter rules, PR checklist

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cvloom-0.6.1.tar.gz (249.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cvloom-0.6.1-py3-none-any.whl (125.2 kB view details)

Uploaded Python 3

File details

Details for the file cvloom-0.6.1.tar.gz.

File metadata

  • Download URL: cvloom-0.6.1.tar.gz
  • Upload date:
  • Size: 249.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cvloom-0.6.1.tar.gz
Algorithm Hash digest
SHA256 9de09eab5059a3b22332d0cbc7eb15c24ce59d8793775159384336f2e7a29e08
MD5 4c9390ed90ff29a41b8f182fa170d7fc
BLAKE2b-256 1d103b8771fe3285262fa297c10d2f9554f0bdb249ea9879542805a639834176

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvloom-0.6.1.tar.gz:

Publisher: release-please.yml on SWEStash/cvloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cvloom-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: cvloom-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 125.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cvloom-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 712e9d14041c62d92b6817510ce6bce60d84b11dcd59fd4b957954b85940c1df
MD5 10e2b29ccbd5e6aa9cb915b6f791f5e5
BLAKE2b-256 b98148d6fab83b36d472dd9bd8a9949fe267591fcdff34fce1d2697fba111024

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvloom-0.6.1-py3-none-any.whl:

Publisher: release-please.yml on SWEStash/cvloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page