md_converter_mcp
by fifeek0
README.md
# md_converter_mcp
MCP server for converting Markdown files to **print-ready PDF** and **Word (DOCX)** with professional styling, page numbers, table of contents, and custom themes.
Built for local use with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — your Markdown files never leave your machine and never enter the LLM context window.
## Why MCP instead of a script?
When you ask an LLM to convert a Markdown file, it has to:
1. Read the entire file into the context window
2. Write conversion code
3. Execute and debug it
4. Return the result
With an MCP server, the LLM just calls a tool with a file path. The heavy lifting happens outside the context window.
### Token Usage Benchmark
Tested on a real 1,072-line Markdown file (37 KB, ~10,000 tokens):
| Approach | Input Tokens | Output Tokens | Total | Cost (Opus) |
|----------|-------------|---------------|-------|-------------|
| **MCP tool call** | ~100 | ~50 | **~150** | ~$0.003 |
| **LLM reads file + generates code** | ~12,000 | ~2,000 | **~14,000** | ~$0.27 |
**MCP is ~93x cheaper per conversion.**
For a batch of 10 similar files:
| Approach | Total Tokens | Cost (Opus) |
|----------|-------------|-------------|
| **MCP batch tool** | **~500** | ~$0.01 |
| **LLM manual approach** | **~100,000+** | ~$2.00+ |
**MCP is ~200x cheaper at batch scale** because file contents never enter the context window.
> Note: "LLM manual approach" estimates include reading files, writing/debugging conversion scripts, and processing output. Actual usage varies by model and conversation length.
## Features
- **PDF output** via WeasyPrint with full CSS3 print support
- **DOCX output** via pandoc with reference document templates
- **3 built-in themes**: default (professional sans-serif), academic (serif, formal), minimal (clean whitespace)
- **Print-ready**: page numbers, headers/footers, TOC generation, custom margins, page size selection
- **Syntax highlighting**: 500+ languages via Pygments
- **Batch conversion**: convert entire directories with glob patterns
- **Custom themes**: bring your own CSS or DOCX template
## Installation
### Prerequisites
```bash
# macOS
brew install pango pandoc
# Ubuntu/Debian
sudo apt install libpango-1.0-0 libpangocairo-1.0-0 pandoc
# Arch
sudo pacman -S pango pandoc
```
### Install the server
```bash
git clone https://github.com/YOUR_USERNAME/md_converter_mcp.git
cd md_converter_mcp
uv sync --python 3.12
```
Generate the default DOCX template:
```bash
uv run python -m md_converter_mcp.create_default_template
```
### Configure Claude Code
Add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"md_converter_mcp": {
"command": "/absolute/path/to/md_converter_mcp/.venv/bin/python",
"args": ["-m", "md_converter_mcp.server"]
}
}
}
```
Or with `uv`:
```json
{
"mcpServers": {
"md_converter_mcp": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/md_converter_mcp", "md-converter-mcp"]
}
}
}
```
## Usage
### In Claude Code (natural language)
```
Convert /path/to/notes.md to PDF with the academic theme
```
```
Batch convert all markdown files in /path/to/docs/ to both PDF and DOCX with TOC
```
```
Make a PDF from my-file.md with A4 pages, 25mm margins, and page numbers
```
### Available Tools
#### `md_converter_to_pdf`
Convert a single Markdown file to PDF.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `input_path` | string | *required* | Absolute path to .md file |
| `output_path` | string | input + .pdf | Output file path |
| `theme` | string | `"default"` | Theme name or path to .css |
| `page_size` | string | `"A4"` | `A4`, `Letter`, `A3`, `Legal` |
| `margin_mm` | int | `20` | Margins in mm (5-50) |
| `include_toc` | bool | `false` | Generate table of contents |
| `header_text` | string | `null` | Header with `{title}`, `{date}` placeholders |
| `footer_text` | string | `"{page} / {pages}"` | Footer with page numbering |
#### `md_converter_to_docx`
Convert a single Markdown file to Word.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `input_path` | string | *required* | Absolute path to .md file |
| `output_path` | string | input + .docx | Output file path |
| `template` | string | `"default"` | Template name or path to .docx |
| `include_toc` | bool | `false` | Generate table of contents |
#### `md_converter_batch`
Convert multiple files at once.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `input_dir` | string | *required* | Directory with .md files |
| `output_dir` | string | input_dir | Output directory |
| `glob_pattern` | string | `"**/*.md"` | File matching pattern |
| `output_format` | string | `"pdf"` | `pdf`, `docx`, or `both` |
| `theme` | string | `"default"` | CSS theme (PDF) |
| `template` | string | `"default"` | DOCX template |
| `page_size` | string | `"A4"` | Paper size (PDF) |
| `margin_mm` | int | `20` | Margins (PDF) |
| `include_toc` | bool | `false` | Table of contents |
| `footer_text` | string | `"{page} / {pages}"` | Footer (PDF) |
#### `md_converter_list_themes`
List all available CSS themes and DOCX templates. No parameters.
## Themes
### Built-in PDF themes
| Theme | Style | Best for |
|-------|-------|----------|
| `default` | Professional sans-serif (Inter), clean layout | Business docs, reports, notes |
| `academic` | Serif fonts (Georgia), justified text, formal | Papers, articles, theses |
| `minimal` | Light sans-serif, generous whitespace | Creative writing, simple docs |
### Custom themes
Create a CSS file with `@page` rules and body styling:
```css
@page {
size: {{ page_size }};
margin: {{ margin_mm }}mm;
@bottom-center {
content: {{ footer_content }};
}
}
body {
font-family: "Your Font", sans-serif;
font-size: 11pt;
}
```
Use it by passing the absolute path:
```
Convert my-file.md to PDF with theme /path/to/my-theme.css
```
Or place it in `~/.config/md_converter_mcp/themes/mytheme.css` and reference by name:
```
Convert my-file.md to PDF with theme mytheme
```
## Architecture
```
Markdown file
|
+---> [markdown-it-py] ---> HTML ---> [WeasyPrint + CSS theme] ---> PDF
|
+---> [pandoc + reference-doc template] ---> DOCX
```
- **PDF path**: markdown-it-py parses MD to HTML, Pygments highlights code blocks, WeasyPrint renders with CSS `@page` rules for print layout
- **DOCX path**: pandoc handles everything natively — better DOCX structure than any HTML-to-DOCX approach
- **Async**: synchronous rendering (WeasyPrint, pandoc) runs in `asyncio` executor to avoid blocking the MCP event loop
## Project Structure
```
md_converter_mcp/
├── pyproject.toml
├── uv.lock
├── src/
│ └── md_converter_mcp/
│ ├── server.py # FastMCP entry point, 4 tools
│ ├── models.py # Pydantic v2 input models
│ ├── create_default_template.py
│ ├── converter/
│ │ ├── markdown_parser.py # MD -> HTML + Pygments + TOC
│ │ ├── pdf_renderer.py # HTML -> PDF (WeasyPrint)
│ │ ├── docx_renderer.py # MD -> DOCX (pypandoc)
│ │ └── pipeline.py # Single + batch orchestration
│ └── styling/
│ ├── theme_manager.py # Theme/template resolution
│ └── themes/
│ ├── default.css
│ ├── academic.css
│ ├── minimal.css
│ └── default_ref.docx
└── tests/
└── fixtures/
└── sample.md
```
## Tech Stack
| Component | Library | Why |
|-----------|---------|-----|
| MCP framework | FastMCP (Python SDK) | Best DX, `@mcp.tool()` decorator |
| MD parser | markdown-it-py | Fast, CommonMark compliant |
| Syntax highlighting | Pygments | 500+ languages |
| PDF renderer | WeasyPrint | Full CSS3 print support, `@page` rules |
| DOCX converter | pypandoc (pandoc) | Native DOCX writer, reference-doc templates |
| Input validation | Pydantic v2 | Type-safe tool parameters |
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues