# How PDF Support Works in Desktop Commander MCP: Extraction, Creation, and Modification

> Discover how Desktop Commander MCP handles PDF extraction to Markdown, PDF creation from Markdown, and PDF modification with pdf-lib. Learn about its integrated PDF support.

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

---

**Desktop Commander MCP provides comprehensive PDF support through a dedicated file handler that extracts text to Markdown using @opendocsg/pdf2md, creates PDFs from Markdown via md-to-pdf and Puppeteer, and modifies documents with pdf-lib page manipulations.**

Desktop Commander MCP treats PDF documents as first-class content through its specialized **PDF file handler** architecture. The implementation, found in the `wonderwhy-er/DesktopCommanderMCP` repository, abstracts complex PDF operations into three core capabilities: text extraction, document creation, and page-level modification. This design allows the Model Context Protocol (MCP) server to read, write, and edit PDF files using standard Markdown as an intermediate format.

## PDF Text Extraction (PDF to Markdown)

### The parsePdfToMarkdown Pipeline

When reading a PDF file, the [`PdfFileHandler`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/pdf.ts) class invokes [`parsePdfToMarkdown()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L74-L80) from [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts). This function streams the PDF content into a `Uint8Array` buffer and processes it through **@opendocsg/pdf2md**:

```typescript
// src/tools/pdf/markdown.ts
const pdfResult = await parsePdfToMarkdown(path, range);
// Internally uses: pdf2md(buffer) from @opendocsg/pdf2md

```

The conversion produces a `PdfParseResult` object containing the document's text content structured as Markdown, with each PDF page represented as a separate string in the pages array.

### Metadata and Page Structure

The extraction process captures rich metadata including **author**, **title**, and **total page count**. The [`FileResult`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/pdf.ts#L74-L80) returned by the handler includes:

- `mimeType`: `application/pdf`
- `pages`: Array of Markdown strings (one per page)
- `metadata`: Document properties extracted during parsing

For image extraction, the system leverages [[`src/tools/pdf/extract-images.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/extract-images.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/extract-images.ts), which uses **unpdf** to extract embedded images for downstream processing.

## PDF Creation (Markdown to PDF)

### The parseMarkdownToPdf Workflow

Creating PDF documents is handled by the **`write_pdf`** tool, which orchestrates the [`parseMarkdownToPdf()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L87-L105) function. This utility converts Markdown content into formatted PDFs using **md-to-pdf**:

```typescript
// src/tools/pdf/markdown.ts
const pdf = await mdToPdf({ content: markdown }, options);
return pdf.content; // Buffer containing the PDF

```

The `md-to-pdf` library renders the Markdown through **Puppeteer**, providing full CSS support and configurable page layouts via the options parameter.

### Chrome/Chromium Resolution

Before rendering, [`parseMarkdownToPdf()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L87-L105) ensures a Chrome binary is available through [`getChromePath()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L87-L105). The resolution strategy checks:

1. Puppeteer's cached Chrome installation
2. System-installed Chrome/Chromium binaries
3. Automatic download via **@puppeteer/browsers** (fallback)

If no Chrome installation is found, the function throws a descriptive error directing users to install Chrome manually, preventing silent failures during PDF generation.

## PDF Modification (Page Editing)

### Page Deletion and Insertion

Desktop Commander MCP supports surgical page-level modifications through [`editPdf()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/manipulations.ts), implemented in [`src/tools/pdf/manipulations.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/manipulations.ts). This function exposes two primary operations via **pdf-lib**:

- **`deletePages(pdfDoc, pageIndexes)`**: Removes specific pages by their zero-based indices
- **`insertPages(pdfDoc, pageIndex, sourcePdfDocument)`**: Inserts pages from a source PDF at a specified position

### The editPdf Implementation

The [`PdfFileHandler.editRange()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/pdf.ts#L98-L105) method delegates modification requests to `editPdf()`, which loads the target document into a `PDFDocument` instance, applies the requested transformations, and serializes the result:

```typescript
// src/utils/files/pdf.ts
const editedBuffer = await editPdf(buffer, operations);
await fs.writeFile(targetPath, editedBuffer);

```

This workflow supports complex reordering scenarios, such as deleting cover pages, inserting chapters from external files, or rearranging existing content without re-rendering the entire document from Markdown.

## Supporting Utilities and Architecture

The PDF subsystem relies on several specialized modules that provide low-level functionality:

- **[[`src/tools/pdf/lib/pdf2md.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/lib/pdf2md.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/lib/pdf2md.ts)**: Wraps the `@opendocsg/pdf2md` library to normalize PDF parsing results and handle edge cases in document structure.
- **[[`src/utils/files/factory.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts)](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/factory.ts#L14-L22)**: Registers `PdfFileHandler` for the `.pdf` extension, enabling automatic handler selection when the server encounters PDF file operations.
- **Error Handling**: All PDF operations include validation for file existence, format compatibility, and dependency availability (particularly Chrome for creation workflows).

## Summary

- **Text Extraction**: Uses `parsePdfToMarkdown()` with **@opendocsg/pdf2md** to convert PDF pages to Markdown while preserving metadata.
- **Document Creation**: Leverages `parseMarkdownToPdf()` with **md-to-pdf** and **Puppeteer** to render Markdown into formatted PDFs, with automatic Chrome binary resolution.
- **Page Modification**: Implements `editPdf()` using **pdf-lib** for deletion and insertion operations without full document re-creation.
- **Handler Architecture**: Centralizes PDF logic in `PdfFileHandler`, registered via the file factory pattern for seamless integration with the MCP server.

## Frequently Asked Questions

### How does Desktop Commander MCP extract text from PDFs?

The system uses the **`parsePdfToMarkdown()`** function in [`src/tools/pdf/markdown.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts), which internally calls **@opendocsg/pdf2md** to parse PDF buffers into Markdown text. This preserves document structure by returning each page as a separate Markdown string within a result object that includes metadata like author and title.

### What library does Desktop Commander MCP use to create PDFs from Markdown?

PDF creation relies on **md-to-pdf**, a Node.js library that uses **Puppeteer** to render Markdown content with CSS styling. The [`parseMarkdownToPdf()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L87-L105) function handles the conversion and manages Chrome binary detection to ensure the rendering engine is available.

### Can Desktop Commander MCP edit existing PDF files?

Yes, the tool supports page-level modifications through the **`editPdf()`** function in [`src/tools/pdf/manipulations.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/manipulations.ts). Using **pdf-lib**, it can delete specific page indexes or insert pages from other PDF documents, allowing for surgical edits without converting the entire file to Markdown and back.

### How does the tool handle Chrome dependencies for PDF generation?

The [`getChromePath()`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/tools/pdf/markdown.ts#L87-L105) utility implements a three-tier resolution strategy: it first checks Puppeteer's cache, then searches system installations, and finally attempts to download Chrome via **@puppeteer/browsers**. If all methods fail, it provides clear error messaging instructing users to install Chrome manually.