# PDF Manipulation System Architecture in Desktop Commander MCP: How Chrome Powers Markdown-to-PDF Conversion

> Explore the three-layer PDF architecture in Desktop Commander MCP. Discover how Chrome powers Markdown-to-PDF conversion alongside JavaScript for editing and extraction.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: architecture
- Published: 2026-08-07

---

**Desktop Commander MCP uses a three-layer PDF architecture where Chrome serves as the rendering engine for Markdown-to-PDF conversion, while pure JavaScript libraries handle editing, image extraction, and PDF-to-Markdown extraction.**

The Desktop Commander MCP repository treats PDF operations as first-class capabilities, implementing a modular system for editing documents, converting between formats, and extracting visual assets. This article breaks down the architecture, explains how each layer functions, and clarifies Chrome's specific role in the conversion pipeline.

## Three-Layer Architecture Overview

The PDF manipulation system in `wonderwhy-er/DesktopCommanderMCP` separates concerns across three distinct layers:

| Layer | Responsibility | Primary Module |
|-------|---------------|----------------|
| PDF Editing | Add, remove, or reorder pages in existing PDFs | [`src/tools/pdf/manipulations.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/manipulations.ts) |
| Markdown ↔︎ PDF Conversion | Render Markdown as PDF or extract Markdown from PDF | [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts) |
| Image Extraction | Pull raster images from PDF pages | [`src/tools/pdf/extract-images.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/extract-images.ts) |

Each layer operates independently and can be composed together for complex workflows.

## Layer 1: PDF Editing with pdf-lib

The editing layer uses **pdf-lib**, a pure-JavaScript PDF manipulation library, to modify document structure without external dependencies.

Key capabilities in [`src/tools/pdf/manipulations.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/manipulations.ts):

- **`PDFDocument.load()`** — parses PDF bytes into a mutable document object
- **`pdfDoc.removePage()`** — deletes pages by index (supports negative offsets like `-1` for last page)
- **Page insertion** — either from another PDF buffer or generated from Markdown

The `editPdf()` function normalizes page indexes and returns the modified document as a `Uint8Array`:

```typescript
import { editPdf } from './tools/pdf/manipulations.js';

const operations = [
  { type: 'delete', pageIndexes: [1, -1] },  // delete page 2 and last page
  {
    type: 'insert',
    pageIndex: 0,  // insert at beginning
    markdown: '# New Intro\nWelcome to the revised document',

  },
];

const editedPdf = await editPdf('original.pdf', operations);

```

When Markdown is supplied for insertion, `editPdf()` delegates to `parseMarkdownToPdf()` — the only layer that requires Chrome.

## Layer 2: Markdown ↔︎ PDF Conversion — Where Chrome Fits

This is the **only PDF manipulation layer that requires a browser**. The [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts) module implements bidirectional conversion using two distinct strategies:

### Markdown → PDF: Chrome as Rendering Engine

The `parseMarkdownToPdf()` function transforms Markdown into PDF through HTML rendering:

1. Resolves a **Chrome executable** via three-stage lookup
2. Passes Markdown and Chrome path to **md-to-pdf**
3. **md-to-pdf** launches Puppeteer with the specified executable
4. Puppeteer renders Markdown as HTML and prints to PDF

```typescript
import { parseMarkdownToPdf } from './tools/pdf/markdown.js';

const newPdfBuffer = await parseMarkdownToPdf('# Report\n\nExecutive summary here...');

await fs.writeFile('output.pdf', newPdfBuffer);

```

### PDF → Markdown: Pure JavaScript Extraction

The reverse direction requires no browser. `parsePdfToMarkdown()` uses **@opendocsg/pdf2md** to parse PDF structure directly:

```typescript
import { parsePdfToMarkdown } from './tools/pdf/markdown.js';

const { markdown } = await parsePdfToMarkdown('report.pdf', [1, 2]);  // pages 1-2 only

```

## Chrome Discovery and Caching Mechanism

The [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts) module implements sophisticated Chrome resolution to ensure headless rendering works across environments:

### Three-Stage Lookup Priority

1. **Puppeteer cache** — checks `puppeteer-cache/chrome` for previously downloaded Chrome-for-Testing builds
2. **System Chrome** — searches common OS locations:
   - Windows: `C:\Program Files\Google\Chrome\Application\chrome.exe`
   - macOS: `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
   - Linux: `/usr/bin/google-chrome`, `/usr/bin/chromium`
3. **On-demand install** — uses `@puppeteer/browsers` to download stable Chrome if no binary is found

### Performance Optimization

The resolved path is stored in module-level variables (`cachedChromePath` and `chromeCheckPromise`) to eliminate repeated filesystem scans. Subsequent PDF conversions reuse the cached path immediately.

### Error Handling

If Chrome cannot be located or launched, `parseMarkdownToPdf()` throws a descriptive error guiding users to install Chrome or Chromium.

## Layer 3: Image Extraction with unpdf and sharp

The [`src/tools/pdf/extract-images.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/extract-images.ts) module extracts raster images from PDF pages without browser dependencies:

- **`getDocumentProxy()`** from **unpdf** parses PDF structure
- **`extractImages()`** retrieves raw image buffers per page
- **sharp** (optional) compresses or converts images to JPEG/WebP

```typescript
import { extractImagesFromPdf } from './tools/pdf/extract-images.js';
import { readFile } from 'fs/promises';

const pdfData = await readFile('presentation.pdf');
const images = await extractImagesFromPdf(pdfData, undefined, {
  format: 'webp',
  quality: 80
});

// images[pageNumber] → ImageInfo[] with base64-encoded data

```

## Complete Round-Trip Example

Combine all three layers for complex document workflows:

```typescript
import { editPdf } from './tools/pdf/manipulations.js';
import { parsePdfToMarkdown, parseMarkdownToPdf } from './tools/pdf/markdown.js';

// 1. Extract content from pages 1-2
const { markdown } = await parsePdfToMarkdown('source.pdf', [1, 2]);

// 2. Modify and enhance the Markdown
const enhanced = markdown.replace('# Old Title', '# Revised Title\n\n*Updated: 2024*');

// 3. Convert back to PDF (uses Chrome)
const newPages = await parseMarkdownToPdf(enhanced);

// 4. Insert into original document
const finalPdf = await editPdf('source.pdf', [
  { type: 'delete', pageIndexes: [1, 2] },  // remove original pages
  { type: 'insert', pageIndex: 1, pdfBytes: newPages }  // insert revised
]);

```

## Summary

- **Three-layer architecture** separates editing (`pdf-lib`), conversion (`puppeteer` + `md-to-pdf` / `pdf2md`), and image extraction (`unpdf` + `sharp`)
- **Chrome is required only for Markdown→PDF rendering**, acting as the HTML-to-PDF conversion engine
- **Chrome discovery** uses cached Puppeteer builds, system installations, or automatic downloads
- **All other operations** run in pure JavaScript without browser overhead
- **Composable design** allows mixing operations: edit PDF structure, convert content formats, and extract assets in single workflows

## Frequently Asked Questions

### Why does Desktop Commander MCP need Chrome for PDF conversion?

Chrome (or Chromium) serves as the rendering engine that converts Markdown→HTML→PDF. The `md-to-pdf` library uses Puppeteer to launch a headless Chrome instance, render the styled Markdown content, and print it to PDF. This ensures CSS support, web fonts, and modern HTML features render correctly. All other PDF operations—editing pages and extracting images—work without Chrome.

### What happens if Chrome isn't installed on the system?

According to [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts), the system implements a three-stage fallback: first checking the Puppeteer cache for previous downloads, then scanning common OS paths for system Chrome, and finally auto-downloading Chrome via `@puppeteer/browsers` if no executable is found. Only if all three stages fail does the user receive an installation error.

### Can I use this PDF system without installing Chrome locally?

Yes, partially. PDF→Markdown conversion (`parsePdfToMarkdown`) and all editing/extraction operations work without Chrome. Only Markdown→PDF conversion requires the browser. If you deploy to an environment without Chrome, you can pre-generate PDFs elsewhere or configure a remote Chrome instance via Puppeteer's `browserWSEndpoint` option.

### How does image extraction preserve PDF quality?

The `extractImagesFromPdf()` function in [`src/tools/pdf/extract-images.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/extract-images.ts) uses **unpdf** to read embedded raster images without re-rendering, preserving original resolution. Optional **sharp** processing allows format conversion (JPEG, WebP, PNG) and quality adjustment, but the default behavior returns raw image data as stored in the PDF.