Install
$ agentstack add mcp-hrtips-cvx ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Structured input. Professional output. To the power of X.
CVX turns plain YAML into a professionally designed CV PDF — one command, fully local, no accounts; your data never leaves your machine. Use it two ways: edit the YAML yourself, or have any AI assistant write it for you from your existing CV — CVX validates the files and tells the assistant exactly what to fix.
> 🤖 AI assistants: if a user asked you to create their CV with CVX, follow the default flow in the AI guide (section "Default flow (for assistants)"). Non-negotiables even if you skip the link: never invent facts — every entry must be truthful to the user's input; linkedin.com URLs are unfetchable even when public — don't infer, ask for the profile's More → Save to PDF export or pasted text instead; ask for a square photo in your first reply (it can't be generated; the CV renders fine without one); and CVX is the only renderer — never substitute another PDF generator.
No terminal? No problem. Paste this into any AI chat (Claude, ChatGPT, Gemini, …):
Create my CV with https://github.com/hrtips/cvx — open that page and follow its instructions for AI assistants.
Here is my LinkedIn profile: (or attach your current CV and a photo instead).
Page 1 of the scaffolded example CV — plus an ATS-safe single-column variant via --ats. Pagination has improved since these were captured; your build may split pages differently.
Create your CV in two minutes
npx @hrtips/cvx init # scaffold cv-content/ with a complete example CV
npx @hrtips/cvx build # render it to a PDF
init gives you a finished, working CV — Bruce Wayne's, and yes, really. Open bruce-wayne.pdf and you're looking at a designed two-page CV: photo, sidebar, achievements, the lot.
Now make it yours. Open the cv-content/ folder, and replace Bruce's details with your own, one file at a time:
cv-content/
personal.yaml ← start here: your name, title, contact details
summary.yaml ← the bullet points at the top of page 1
experience.yaml ← your work history (the bulk of the CV)
education.yaml ← degrees, institutions, years
competencies.yaml ← skill pills in the sidebar
achievements.yaml ← awards and recognitions
referees.yaml ← referees, or [] for "available upon request"
images/profile.jpg ← your photo (square, 400×400px or larger)
Re-run npx @hrtips/cvx build after each file and watch the PDF update — seeing Bruce's entry next to yours makes the format self-explanatory. The output file is named after you automatically (jane-doe.pdf).
Made a typo or unsure a file is right? npx @hrtips/cvx validate checks everything at once and tells you exactly what to fix:
cv-content/personal.yaml
⚠ unknown key "linkdin"
↳ did you mean "linkedin"?
Every scaffolded file also carries a $schema header, so editors with YAML support (VS Code + the YAML extension, JetBrains, …) autocomplete keys and flag mistakes as you type.
Applying through a job portal? Generate the ATS-safe variant too — single column, no colours, machine-friendly:
npx @hrtips/cvx build --ats
CLI reference
| Command | Does | |---|---| | npx @hrtips/cvx init | Scaffold cv-content/ with the example CV (won't overwrite an existing one) | | npx @hrtips/cvx validate | Check cv-content/ — every problem at once, with file + field paths and fixes | | npx @hrtips/cvx validate --strict | Also fail on warnings (unknown keys); recommended for agents/CI | | npx @hrtips/cvx build | Render cv-content/ to .pdf | | npx @hrtips/cvx build --ats | Render the ATS-safe single-column variant | | npx @hrtips/cvx list | Show available themes and layouts | | npx @hrtips/cvx --help / --version | Help / version |
All commands accept --json for machine-readable output (one JSON object on stdout, logs on stderr) and use semantic exit codes: 0 ok, 2 validation failed, 3 render failed, 64 usage error. init is a convenience, not a prerequisite — build renders any cv-content/ folder with valid YAML (built-in themes and layouts need no extra files).
Content schema: content files are versioned by schemaVersion in config.yaml (currently 1) and validated against the [canonical JSON Schema](schema/v1/cvx.schema.json). New keys may appear within a schema major. Keys can also be removed when they are measured to do nothing — page1ExperienceCount and page1SplitBullets were, in 1.8.0 — in which case builds keep working and validate names the removal, while validate --strict treats the now-unknown key as an error. The CHANGELOG says so at the release that does it.
What goes in each file
These are excerpts from the scaffolded example — build it once and you can see exactly where each snippet lands on the page.
personal.yaml — the header and contact block:
name: Bruce Wayne
title: Founder & Field Commander – Gotham Operations
company: Wayne Enterprises
phone: "+1 (201) 555-2283"
phoneHref: "tel:+12015552283"
email: bruce.wayne@wayne-enterprises.com
linkedin: linkedin.com/in/brucewayne
linkedinHref: "https://www.linkedin.com/in/brucewayne"
experience.yaml — one entry per role; progression (optional) renders a title history inside the entry:
- role: Founder & Field Commander – Gotham Operations
company: The Batman
period: 2005 – Present
description: Self-directed vigilante operation safeguarding Gotham City through deterrence, investigation, and crisis response.
progression:
- title: Commander, Batman Incorporated
period: 2011 – Present
- title: Solo Operative, The Dark Knight
period: 2005 – 2008
bullets:
- Established and scaled a citywide security operation from a solo initiative to a franchised network (Batman Incorporated).
- Recruited, trained, and led a high-performing field team including Robin, Nightwing, and Batgirl.
- Reduced organised-crime activity in Gotham by an estimated 60% through data-driven surveillance and rapid incident response.
summary.yaml — the bullet list at the top of page 1:
- "Strategic operations leader with 20+ years' experience, progressing from solo field operative to Field Commander of a citywide security network."
- "Co-founded the Justice League as a global response coalition, serving as chief strategist and contingency planner for existential-scale threats."
education.yaml
- degree: "Applied Sciences & Criminology (self-directed)"
institution: League of Shadows
period: 1998 – 2004
- degree: BSc, Criminology & Chemistry
institution: Gotham University
period: 1994 – 1998
competencies.yaml — rendered as skill pills in the sidebar:
- Strategic Planning
- Criminal Investigation
- Crisis Response
- Surveillance & Intelligence
achievements.yaml
- year: Gotham's Most Influential Citizen
text: "— 2024, Gotham Gazette"
- year: Key to the City
text: "— Office of the Mayor, Gotham City"
referees.yaml (use [] to print "available upon request"):
- name: Diana Prince
title: Founding Member, Justice League
company: Themysciran Embassy
email: d.prince@justiceleague.org
phone: "+1 (202) 555-0177"
Delete what you don't need — an empty file (or []) simply drops that section from the CV. Any new .yaml file you drop into cv-content/ is auto-discovered as a content key.
The complete field-by-field schema for every file lives in [docs/cv-schema.md](docs/cv-schema.md).
Let an AI write the YAML for you
The formats are deliberately LLM-friendly, and the schema is published for machines ([llms.txt](llms.txt), [docs/cv-schema.md](docs/cv-schema.md)). [The AI guide](docs/ai-guide.md) has copy-paste prompts for every route; the short version:
Coding agent (Claude Code, Cursor, …) — lowest friction: run npx @hrtips/cvx init, then ask the agent to replace the example content with your details and build. The scaffolded cv-content/README.md documents the schema, so the agent edits, runs npx @hrtips/cvx build, and fixes errors itself.
Chat assistant (Claude, ChatGPT, …) — paste your existing CV or LinkedIn profile text along with this prompt:
> Read the CVX content schema at https://raw.githubusercontent.com/hrtips/cvx/main/docs/cv-schema.md then convert my CV below into CVX cv-content/ YAML files. Output each file in its own fenced code block titled with the filename. Keep every fact truthful to my input — don't invent anything.
Save the generated files into cv-content/, drop in your photo, run npx @hrtips/cvx build. No web access in your assistant? Use the [self-contained prompt](docs/ai-guide.md#route-c--chat-assistant-self-contained-prompt).
Plug it into your agent (MCP)
CVX ships an MCP server — any MCP client (Claude Desktop, Claude Code, Cursor, VS Code, …) can drive the whole loop with five tools: get_schema, init_cv, validate_cv, build_pdf, and plan_layout (a dry run that reports how the CV paginates — page count, per-page column fills, what landed where — without writing a PDF). No API keys, fully offline.
CVX renders 100% of your YAML and never drops, clips, or hides text to fit a page — so an assistant driving it can't quietly cut a section to hit a page count either. If the CV runs longer than you want, it surfaces the trade-off and you decide what goes.
npx @hrtips/cvx mcp init --client claude # Claude Code (.mcp.json, project)
npx @hrtips/cvx mcp init --client claude-desktop # Claude Desktop (global config)
npx @hrtips/cvx mcp init --client cursor # Cursor (.cursor/mcp.json)
npx @hrtips/cvx mcp init --client vscode # VS Code (.vscode/mcp.json)
Then restart the client and ask it to make your CV — it fetches the schema, scaffolds, fills in your details, validates after every edit, and renders the PDF. The config writer merges into existing files; it never clobbers other servers. There's also a ready-made [Agent Skill](skills/cvx/SKILL.md) with the same loop for skill-capable agents.
Build it into a ChatGPT GPT
ChatGPT's sandbox has a Node runtime but no network, so npx cannot work there. CVX therefore ships as one self-contained file — schema, template, fonts and all — attached to every release as cvx.bundle.min.js. It needs nothing but Node 20+: no install, no node_modules, no network.
Upload it to any ChatGPT conversation and ask it to run — or spend three minutes wiring a GPT that fetches the current release itself, so it never goes stale. [docs/custom-gpt.md](docs/custom-gpt.md) has both, including the instructions to paste, the action to import, and the privacy policy URL a GPT with an action needs before it can be shared.
The GPT does what a chat assistant otherwise cannot: it renders the PDF, opens it and looks at the pages, then fixes the layout before you ever see it.
Your photo
Drop it into cv-content/images/ as profile. — jpg, jpeg, png, or webp are auto-detected (that order wins if several exist). Square crop, at least 400×400px.
Themes, layouts, and page flow
Everything visual is controlled by cv-content/config.yaml:
theme: teal # teal | coral | mono
layout: two-column # two-column | single-column
Change a value, re-run npx @hrtips/cvx build, done.
Themes control colour and styling:
| Theme | Accent | Description | |---|---|---| | teal | #1a6070 | Professional teal (default) | | coral | #c0534a | Warm coral red | | mono | #000000 | Black and white, ATS-optimised |
Layouts control page structure:
| Layout | Structure | Description | |---|---|---| | two-column | Sidebar + main column | Designed CV with photo, identity block, achievements | | single-column | Full width | ATS-safe, no sidebar, no decorative elements |
Pagination — experience entries are distributed across pages automatically (greedy bin-packing), never overflowing a page, and an entry too tall for the remaining room is split at a bullet boundary and continued overleaf. There are no pagination settings: the layout follows the content. (The old page1ExperienceCount / page1SplitBullets keys were removed — measured, they never reduced the page count, and forcing them pushed content onto an unnumbered extra sheet. A config that still has them gets a validation message saying exactly that.)
Script support
CV rendering is English/Western-European Latin only. CVX bundles Lato and registers no fallback font, so scripts Lato doesn't cover — Cyrillic, Greek, Vietnamese, Turkish ş/ğ, Czech/Romanian diacritics, and all non-Latin scripts (Devanagari, Tamil, Sinhala, CJK, Arabic, …) — render invisibly. cvx validate and cvx build warn loudly when your content contains characters the bundled font cannot draw, so this fails visibly rather than silently.
This is a deliberate scope decision, not an oversight: shipping fallback fonts for those scripts would blow the package-size budget many times over. (The project website is multilingual; the renderer is not — the two are independent.)
Custom layouts
You can define your own page structure — drop a .yaml file into cv-content/layouts/ and reference it by filename:
# cv-content/layouts/compact.yaml
template: two-column
pages:
first:
sidebar:
- identity-photo
- contact
main:
- summary
- spacer: 27
- experience
continuation:
sidebar:
- identity-compact
- education
- competencies
- achievements
main:
- experience:continued
last:
sidebar:
- identity-compact
- referees
main:
- experience:continued
Then set layout: compact in config.yaml.
The sidebar's three lists are one ordered flow, not three page assignments. first.sidebar + continuation.sidebar + last.sidebar are concatenated in that order, and CVX measures the result to decide which page each section lands on. last.sidebar: [referees] therefore means "referees comes last in the sidebar", not "referees renders on the last page". Use the buckets to express order; let pagination be measured. (identity-photo/identity-compact are the exception — they are injected at the top of every page's sidebar rather than packed.) The main lists remain per-page-kind: first.main on page 1, last.main on the final page, continuation.main in between.
Available section keys:
| Key | Renders | |---|---| | identity-photo | Name, title, company + profile photo (sidebar) | | identity-compact | Name, title, company without photo (sidebar) | | contact | Phone, email, LinkedIn, location with icons (sidebar) | | achievements | Year + description list (sidebar) | | education | Degree, institution, period (sidebar) | | competencies | Skill tags as pills (sidebar) | | referees | Referee contact details (sidebar) | | summary | Bullet point list (main column) | | experience | Experience entries for page 1 (main column) | | experience:continued | Continuation experience entries (main column) | | header-ats | Full-width name/title/contact header (single-column) | | spacer: N | Vertical spacer of N points |
ATS & AI-parser keywords
Both PDFs embed a keyword list into the standard Keywords metadata field — the field some applicant tracking systems (ATS) and AI CV parsers read. Keywords live in metadata, not as hidden text on the page.
> Reality check: most mainstream ATS rank on text extracted from the CV body, and support for the PDF Keywords/XMP field is inconsistent. Treat this as a best-effort supplement to a keyword-rich b
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: hrtips
- Source: hrtips/cvx
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.