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.

Most CV tools render one document well. cvloom manages twenty tailored variants of one dataset — deterministically, with an agent-safe MCP layer and PII kept out of git.

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
Localise Write and grade the CV in your own language — English and Spanish locale: in cvloom.yaml
Scaffold a project in a language cvloom init --locale es
Analyse Writing lint — 25 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
List locales with their document and lint-rule coverage cvloom list-locales
Integrate Agent-safe MCP server — 17 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). examples-es/ is the same project in Spanish — a separate directory because a cvloom project operates in one language. See Locales.

Initialise a new CV project

mkdir my-cv && cd my-cv
cvloom init                # or: cvloom init --locale es

Scaffolds the directory structure, creates sample YAML files, writes cvloom.yaml, and installs the pre-commit PII scanner. cvloom list-locales shows the languages available and how completely each is supported.

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

cvloom.yaml              # project settings — `locale:` is the language it operates in

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 tool install 'cvloom[ai]'   # see docs/user/ai-features.md#installation for pipx/pip/dev-checkout

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 — prints where each value came from

The endpoint and model can live in the project's cvloom.yaml instead, under an ai: block, so the repo records which backend analyses it; the environment overrides that. The API key stays in the environment either way — cvloom.yaml is committed.

Commands

ai review — band each CV section strong / adequate / needs work against written criteria, 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
cvloom ai cover --profile cover-letter --jd stripe-infra.txt --body-only

--body-only writes the body paragraphs alone, as a pasteable job_context.notes block — a cover-letter/* template supplies the greeting, closing and signature from the locale pack, so the finished letter has exactly one of each.

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 17 tools for LLM-driven CV management. Data stays local — nothing leaves your machine.

uv tool install 'cvloom[mcp]'   # see docs/reference/mcp-server.md#installation for pipx/pip/dev-checkout
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 a provider — CVLOOM_AI_BASE_URL, or an ai.base_url in the project's cvloom.yaml.

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
├── cvloom.yaml         # project settings — the language it operates in
├── data/               # CV content (committed, PII-free)
├── profiles/           # build configs (committed)
├── private/            # GITIGNORED — contact.yaml, cover letters
├── dist/               # GITIGNORED — build output
├── templates/          # Jinja2 templates (or use built-in)
├── .github/workflows/  # publish-cv.yml, scaffolded by `init`
└── .git/hooks/         # pre-commit PII scanner, installed by `init`

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 25 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 17 tools, and example workflows
Profiles and Overlays Full overlay system reference
Locales Running a project in your own language — pack keys, coverage, adding a locale

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
Releasing The per-release task list: version, gates, upgrade path, publish

License

MIT

Metadata

Release files for cvloom 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cvloom 0.10.1
File Size Uploaded
cvloom-0.10.1.tar.gz 413.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cvloom 0.10.1
File Interpreter ABI Platform
cvloom-0.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 606.1 kB

Release files / cvloom-0.10.1.tar.gz

Download URL cvloom-0.10.1.tar.gz
Size 413.9 kB
Tags Source
SHA-256 checksum
How to use checksums
639f5f8e2f47ab4dac064caec55c7ee277be5856862ba16c2dc75261c78c3d2a
BLAKE2b-256 checksum
How to use checksums
db1a0b342bd621d330cf0b871712ae29e7d21e8bd60e532945e67da147495e1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / cvloom-0.10.1-py3-none-any.whl

Download URL cvloom-0.10.1-py3-none-any.whl
Size 192.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d55215262a2f0f7ffb8c4427f06884fff5275167525efbd5482bb8e973b90c2
BLAKE2b-256 checksum
How to use checksums
726b6f33cbae3e91ff8e7b76da1d0c4e3d67b7360e3674aa9225b310fe0f2545
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

0.11.0

2 release files

This release

0.10.1 This release

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page