francisco-perez-sorrosal/cv-writer-mcp
If you are the rightful owner of cv-writer-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The CV Writer MCP Server is a tool that converts markdown CV content to LaTeX and compiles it to PDF, leveraging AI for intelligent conversion and error fixing.
CV Writer MCP Server
An AI-powered Model Context Protocol (MCP) server that generates professional CVs from markdown with intelligent style optimization. Built with OpenAI Agents SDK and FastMCP framework.
๐ Features
Complete End-to-End Pipeline
- Markdown โ LaTeX โ PDF โ Style Optimization โ Final PDF
- Multi-variant style generation with AI quality judge
- Automatic LaTeX error fixing with retry logic
- Iterative quality improvement with feedback loops
- Organized file naming:
iter1_var2.tex
,iter1_var2_refined.pdf
(iteration 1, variant 2, refined)
AI-Powered Intelligence
- OpenAI Agents SDK: Multiple specialized agents for conversion, compilation, and styling
- Quality Judge: LLM-as-a-judge pattern for variant evaluation with scientific scoring
- Smart Defaults: Cost-aware configuration (fast by default, quality on demand)
- True Parallel Processing: Each variant progresses through ALL steps independently (generation โ compilation โ validation โ refinement)
- Enhanced Logging: Clear file identification in judge comparisons
MCP Integration
- Primary Tools:
md_to_latex
,compile_and_improve_style
- Debug Tools: Individual phase tools for testing
- Transport Flexibility: stdio (Claude Desktop) and HTTP support
- Resource Serving: PDFs and LaTeX files via MCP resources
MCPB Bundle Support
- Portable Distribution: Bundle server + dependencies into single .mcpb file
- Easy Installation: Drag-and-drop installation in Claude Desktop
- Self-Contained: All Python dependencies bundled in lib/ directory
- Automated Build: Makefile and pixi tasks with
uv
for fast bundling
๐ฆ Installation
Prerequisites
- Python 3.11+
- LaTeX distribution (TeX Live, MiKTeX, or MacTeX)
- OpenAI API key (for AI agents)
Quick Setup
# Clone repository
git clone https://github.com/francisco-perez-sorrosal/cv-writer-mcp.git
cd cv-writer-mcp
# Install with pixi (recommended)
pixi install
# Set OpenAI API key
export OPENAI_API_KEY="your-api-key-here"
# Verify installation
pixi run check-latex
๐ฆ MCPB Bundle Installation (Recommended)
For the easiest installation experience:
- Download
cv-writer-mcp.mcpb
from releases - Open Claude Desktop settings
- Go to "MCP Servers" tab
- Click "Install from file"
- Select
cv-writer-mcp.mcpb
- Set
OPENAI_API_KEY
in environment variables
That's it! The server is ready to use.
Building Your Own Bundle
Requires uv
to be installed (ultra-fast Python package manager):
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Build complete MCPB bundle
make build-mcpb
# Or use individual steps
pixi run python-bundle # Build wheel with uv
pixi run update-mcpb-deps # Export dependencies with uv
pixi run mcp-bundle # Install to lib/ with uv
pixi run pack # Create .mcpb file
Install LaTeX
macOS:
brew install --cask mactex
Ubuntu/Debian:
sudo apt-get install texlive-full
Windows: Download MiKTeX or TeX Live
๐ฏ Quick Start
End-to-End CV Generation
# FAST MODE (Default) - Quick & Cheap (~3-4 LLM calls)
pixi run generate-cv-fast
# QUALITY MODE - 2 variants, judge picks best (~6-8 LLM calls)
pixi run generate-cv-quality
# ITERATIVE MODE - Best quality with feedback loops (~15-25 LLM calls)
pixi run generate-cv-iterative
What Happens in Each Mode?
Mode | Variants | Iterations | Judge | Cost | Use Case |
---|---|---|---|---|---|
Fast | 1 | 1 | No | ~3-4 calls | Testing, quick iterations |
Quality | 2 | 1 | Yes | ~6-8 calls | Production CVs |
Iterative | 2 | 3 | Yes | ~15-25 calls | Highest quality needed |
๐๏ธ Architecture
Complete Pipeline
Phase 1: Markdown โ LaTeX
โโ MD2LaTeXAgent (OpenAI agent)
Phase 2: Initial Compilation (LOOP #1: compile-fix-compile)
โโ LaTeXExpert
FOR attempt in 1..max_attempts:
โโ CompilationAgent: compile LaTeX
โโ If errors: CompilationErrorAgent fixes them
โโ Retry until success or max attempts
Phase 3: Style Improvement (LOOP #2: true parallel processing)
โโ PDFStyleCoordinator
FOR iteration in 1..max_iterations:
โโ Step 1: Capture & Analyze PDF (VisualCriticAgent)
โโ Step 2: Generate N variants IN PARALLEL
โ FOR each variant (parallel execution):
โ โโ FormattingAgent: translate critiques โ LaTeX fixes
โ โโ LOOP #1: compile-fix-compile (nested!)
โ โโ Visual Validation: detect critical regressions
โ โโ Refinement: fix critical issues (Branch Judge)
โ โโ Final variant ready with validation metadata
โโ Step 3: Main Quality Judge evaluates all completed variants
โโ Decision: pass/needs_improvement/fail โ stop or continue
Smart Defaults
Auto-Enables Judge: When num_variants >= 2
(needed to pick best)
Auto-Disables Judge: When num_variants = 1
(nothing to compare)
Cost-Aware: Default is 1 variant, 1 iteration (fast & cheap)
Quality-Aware: Easy to enable quality mode with --variants 2
Key Architectural Improvements
๐ True Parallel Processing: Each variant now progresses through its complete lifecycle independently:
- Generation โ Compilation โ Validation โ Refinement (if needed)
- No sequential bottlenecks between processing phases
- Maximum resource utilization and speed
๐ Clear File Naming: Organized, descriptive naming convention:
iter1_var2.tex
instead ofi1v2.tex
iter1_var2_refined.pdf
instead ofi1v2r.pdf
- Easy to understand file relationships and versions
๐ง Enhanced Error Handling: Robust pipeline that continues processing even if individual variants fail:
- Graceful handling of compilation failures
- Null-safe PDF path processing
- Individual variant failures don't stop the entire pipeline
๐ Usage
MCP Server
Start the server for Claude Desktop or other MCP clients:
# Start with stdio transport (default for Claude Desktop)
export TRANSPORT="stdio"
pixi run serve
# Start with HTTP transport
export TRANSPORT="streamable-http"
pixi run serve
Primary MCP Tools
md_to_latex
โญ
Complete end-to-end pipeline: Markdown โ LaTeX โ PDF โ Style โ Final PDF
Parameters:
markdown_content
(required): Markdown CV contentoutput_filename
(optional): Custom output filenameenable_style_improvement
(default: true): Enable style phasemax_compile_attempts
(default: 3): Max compilation retriesmax_style_iterations
(default: 1): Max style iterationsnum_style_variants
(default: 1): Number of variants per iterationenable_quality_validation
(default: None): Judge enabled if variants >= 2
Example:
{
"markdown_content": "# John Doe\n## Experience...",
"num_style_variants": 2,
"max_style_iterations": 3
}
compile_and_improve_style
โญ
Compile existing LaTeX and improve styling: LaTeX โ PDF โ Style โ Final PDF
Parameters:
tex_filename
(required): Name of .tex fileoutput_filename
(optional): Custom output filenamemax_compile_attempts
(default: 3): Max compilation retriesmax_style_iterations
(default: 1): Max style iterationsnum_style_variants
(default: 1): Number of variantsenable_quality_validation
(default: None): Auto-enabled if variants >= 2
CLI Commands
Primary Workflows
# Fast mode (1 variant, 1 iteration, no judge)
pixi run generate-cv-fast
# Quality mode (2 variants, judge picks best)
pixi run generate-cv-quality
# Iterative mode (3 iterations, 2 variants, judge-driven)
pixi run generate-cv-iterative
# Compile and improve existing LaTeX
pixi run compile-and-improve
Debug/Test Workflows (Individual Phases)
# Check LaTeX installation
pixi run check-latex
# Phase 1: Markdown โ LaTeX only
pixi run convert-markdown
# Phase 2: LaTeX โ PDF only (with error fixing)
pixi run compile-latex
# Phase 3: PDF โ Styled LaTeX only
pixi run fix-style
Custom Commands
# Custom workflow with specific parameters
python -m cv_writer_mcp generate-cv-from-markdown input/cv.md \
--output my_cv.pdf \
--max-style-iter 3 \
--variants 2 \
--quality
# Disable style improvement (just convert and compile)
python -m cv_writer_mcp generate-cv-from-markdown input/cv.md \
--no-enable-style
# Force quality judge on single variant
python -m cv_writer_mcp generate-cv-from-markdown input/cv.md \
--variants 1 \
--quality
โ๏ธ Configuration
Create a .env
file:
# Required
OPENAI_API_KEY=your-api-key-here
# Optional
TRANSPORT=stdio # "stdio" or "streamable-http"
HOST=localhost
PORT=8000
OUTPUT_DIR=./output
TEMP_DIR=./temp
LATEX_TIMEOUT=180
LOG_LEVEL=INFO
๐งช Development
Setup
# Install development dependencies
pixi install
# Run all checks (format, lint, type-check, test)
pixi run ci
Development Commands
# Format code
pixi run format
# Lint code
pixi run lint
# Type checking
pixi run type-check
# Run tests
pixi run test
# Run tests with coverage
pixi run test-cov
Project Structure
cv-writer-mcp/
โโโ src/cv_writer_mcp/
โ โโโ orchestration/ # End-to-end pipeline orchestrator
โ โ โโโ pipeline_orchestrator.py
โ โ โโโ models.py
โ โโโ compilation/ # LaTeX compilation with error fixing
โ โ โโโ latex_expert.py
โ โ โโโ compiler_agent.py
โ โ โโโ error_agent.py
โ โ โโโ tools.py
โ โ โโโ models.py
โ โ โโโ configs/
โ โ โโโ compiler_agent.yaml
โ โ โโโ error_agent.yaml
โ โโโ conversion/ # Markdown to LaTeX conversion
โ โ โโโ md2latex_agent.py
โ โ โโโ models.py
โ โ โโโ configs/
โ โ โโโ md2latex_agent.yaml
โ โโโ style/ # PDF style improvement
โ โ โโโ pdf_style_coordinator.py
โ โ โโโ visual_critic_agent.py # Design quality critic
โ โ โโโ formatting_agent.py # LaTeX implementation
โ โ โโโ quality_agent.py # LLM-as-a-judge
โ โ โโโ pdf_computer.py # Screenshot capture
โ โ โโโ tools.py
โ โ โโโ models.py
โ โ โโโ configs/
โ โ โโโ formatting_agent.yaml
โ โ โโโ quality_agent.yaml
โ โ โโโ visual_critic_agent.yaml
โ โโโ main.py # MCP server and CLI entry point
โ โโโ models.py # Shared data models
โ โโโ utils.py # Utility functions
โ โโโ logger.py # Logging configuration
โโโ context/ # LaTeX templates
โโโ input/ # Sample input files
โโโ output/ # Generated files
โโโ tests/ # Test suite
๐ก How It Works
Multi-Variant Style Improvement
- Screenshot Capture: Utility function uses Playwright to convert PDF pages to PNG images
- Visual Critique: VisualCriticAgent analyzes screenshots and identifies design quality issues
- Evaluates spacing, consistency, readability, layout
- Describes problems in design language (not code)
- Suggests WHAT should improve (goals, not implementation)
- Generate Variants in Parallel: Each variant progresses through its complete lifecycle independently:
- Variant 1: Conservative approach (safe, minimal changes)
- Variant 2: Aggressive approach (bold formatting, space optimization)
- Variant 3+: Balanced approaches
- Parallel Processing Pipeline: Each variant simultaneously executes:
- FormattingAgent: translates critiques โ LaTeX fixes
- Compilation: compile-fix-compile loop until success
- Visual Validation: detect critical regressions
- Refinement: fix critical issues using Branch Judge (if needed)
- Main Judge Evaluation: StyleQualityAgent compares all completed variants and selects the best
- Iterate: If score is "needs_improvement", repeat with judge feedback
Quality Criteria & Scoring
The judge evaluates variants using a scientific scoring methodology:
Four Quality Dimensions (Weighted)
- Design Coherence (30%): Unified, intentional design system
- Spacing Efficiency (25%): Effective vertical space utilization
- Visual Consistency (25%): Uniform formatting across similar elements
- Readability (20%): Easy information scanning and navigation
Quality Thresholds
- "pass": Overall score โฅ 0.75 AND all metrics โฅ 0.65
- "needs_improvement": 0.55 โค score < 0.75 OR any metric < 0.65 but โฅ 0.45
- "fail": Score < 0.55 OR any metric < 0.45
Iteration Control
- Early Termination: System stops when judge returns "pass" score
- Maximum Iterations: Respects
max_iterations
parameter - Judge Feedback: Each iteration uses feedback from previous evaluation
File Naming System
The system uses clear, descriptive naming conventions:
Base variants: iter1_var1.tex, iter1_var2.pdf (iteration 1, variant 1/2)
Refined variants: iter1_var1_refined.tex, iter1_var2_refined.pdf (iteration 1, variant 1/2, refined)
Backup files: iter1_var1_backup_20251006_145832.tex (organized backups with timestamps)
Benefits of New Naming:
- Clear Structure: Easy to understand iteration and variant relationships
- Linear Progression: Files are organized in chronological order
- Version Tracking: Refined versions clearly distinguished from base variants
- Backup Organization: Timestamped backups with descriptive prefixes
Enhanced Judge Logging
The system provides clear visibility into judge decisions:
โ๏ธ MAIN JUDGE: Comparing 2 variants (Iteration 1)
๐ Original PDF: schwab_cv_iterative.pdf
๐ Variants to compare:
๐ Variant 1 (original): iter1_var1.pdf
๐ Variant 2 (refined): iter1_var2_refined.pdf
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ MAIN JUDGE RESULT: Selected Variant 2 (refined)
๐ Winning file: iter1_var2_refined.pdf
๐ Score: pass
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Troubleshooting
LaTeX Not Found
# Check installation
pixi run check-latex
# Verify LaTeX is in PATH
which pdflatex
# Install LaTeX (see Installation section)
Compilation Errors
The system automatically fixes most LaTeX errors through the compile-fix-compile loop. If issues persist:
- Check the error logs in console output
- Review the generated
.tex
file in./output/
- Try increasing
max_compile_attempts
Style Improvement Issues
If style improvement fails:
- Ensure Playwright browsers are installed:
pixi run playwright install
- Check that PDF was generated successfully in Phase 2
- Try with
--variants 1 --no-quality
to disable judge
Iteration Stopping Early
If iterations stop before reaching max_iterations
:
- Check Judge Scores: Look for "โ Quality criteria met! Stopping iterations."
- Judge is Too Lenient: The quality judge may be giving "pass" scores too easily
- Current Issue: Judge returns "pass" even when issues remain, causing early termination
- Workaround: Use
--variants 1
to disable judge, or modify quality thresholds
Cost Management
To reduce API costs:
# Use fast mode (default)
pixi run generate-cv-fast
# Disable style improvement entirely
python -m cv_writer_mcp generate-cv-from-markdown input/cv.md --no-enable-style
# Single variant, no judge
python -m cv_writer_mcp generate-cv-from-markdown input/cv.md --variants 1
๐ Performance
Parallel Processing Benefits
The new parallel architecture provides significant performance improvements:
Configuration | LLM Calls | Time | Quality | Parallel Benefits |
---|---|---|---|---|
Fast (default) | ~3-4 | ~30s | Good | Single variant processing |
Quality (2 variants) | ~6-8 | ~45s | Better | ~25% faster - variants process independently |
Iterative (3ร2) | ~15-25 | ~90s | Best | ~50% faster - true parallel pipeline |
Speed Improvements
Before (Sequential): Variants โ Wait for all โ Validation โ Refinement โ Judge After (Parallel): Each variant: Generation โ Compilation โ Validation โ Refinement โ Ready
Key Performance Gains:
- Parallel Validation: No waiting for all variants to complete
- Independent Refinement: Each variant refines independently
- Faster Iterations: Reduced overall pipeline latency
- Better Resource Utilization: CPU and I/O operations happen concurrently
Times are approximate and depend on CV complexity and API latency
๐ค Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name
- Make changes and add tests
- Run checks:
pixi run ci
- Commit:
git commit -m "Add feature"
- Push and submit a pull request
๐ License
MIT License - see LICENSE file for details.
๐ค Author
Francisco Perez-Sorrosal
- Email: fperezsorrosal@gmail.com
- GitHub: @francisco-perez-sorrosal
๐ Acknowledgments
Built with: