MCP Hub
Back to servers

@encryptioner/html-to-pdf-generator

Validation Failed

An MCP server that enables AI models to generate professional, multi-page PDFs from HTML content or URLs with support for pagination, watermarks, and security settings.

Stars
4
Tools
3
Updated
Nov 19, 2025
Validated
Jan 9, 2026

Validation Error:

Process exited with code 1. stderr: node:internal/modules/esm/resolve:873 throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null); ^ Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@modelcontextprotocol/sdk' imported from /home/runner/.npm/_npx/755478cd525f4f62/node_modules/@encryptioner/html-to-pdf-generator/mcp/dist/index.js at packageResolve (node:internal/modules/esm/resolve:873:9) at moduleResolve (node:internal/modules/esm/resolve:946:18) at defaultResolve (node:internal/modules/esm/r

Quick Install

npx -y @encryptioner/html-to-pdf-generator

HTML to PDF Generator

A modern, framework-agnostic library for converting HTML content to professional multi-page PDFs with smart pagination and rich features.

npm version License: MIT

📦 NPM Package: https://www.npmjs.com/package/@encryptioner/html-to-pdf-generator


📚 Documentation

Complete documentation is available in the documentation folder:

Framework Guides

Feature Documentation


✨ Features

Core Features

  • Multi-page support with smart pagination
  • Framework adapters for React, Vue, Svelte, and vanilla JS
  • OKLCH color support with automatic Tailwind CSS compatibility
  • Image optimization with SVG conversion and DPI control
  • Table pagination with automatic header repetition
  • Smart page breaks with orphan prevention
  • HTML string support for generating PDFs from HTML markup
  • TypeScript support with full type definitions
  • Progress tracking with real-time callbacks

Advanced Features

  • Watermarks - Add text or image watermarks with opacity control
  • Headers/Footers - Dynamic templates with variables ({{pageNumber}}, {{totalPages}}, {{date}}, {{title}})
  • PDF Metadata - Set title, author, subject, keywords, and creation date
  • PDF Security - Password protection and permission controls (printing, copying, modifying)
  • PDF Preview - Real-time PDF preview with live updates and debouncing
  • Batch generation - Combine multiple HTML sections into one PDF
  • Media type emulation - Apply @media print styles automatically
  • External CSS - Automatic loading and processing of stylesheets
  • Background images - Proper handling of CSS background images
  • Custom CSS injection - Add custom styles before rendering

📦 Installation

npm install @encryptioner/html-to-pdf-generator
pnpm add @encryptioner/html-to-pdf-generator
yarn add @encryptioner/html-to-pdf-generator

🚀 Quick Start

Vanilla JavaScript/TypeScript

import { generatePDF } from '@encryptioner/html-to-pdf-generator';

const element = document.getElementById('my-content');
await generatePDF(element, 'my-document.pdf', {
  format: 'a4',
  orientation: 'portrait',
  margins: [10, 10, 10, 10], // [top, right, bottom, left] in mm
  showPageNumbers: true,
  watermark: {
    text: 'CONFIDENTIAL',
    opacity: 0.1,
    position: 'diagonal'
  }
});

From HTML String

import { generatePDFFromHTML } from '@encryptioner/html-to-pdf-generator';

const html = `
<!DOCTYPE html>
<html>
  <head>
    <style>
      body { font-family: Arial, sans-serif; }
      .header { color: #333; font-size: 24px; }
    </style>
  </head>
  <body>
    <h1 class="header">My Document</h1>
    <p>This is a paragraph with some content.</p>
  </body>
</html>
`;

await generatePDFFromHTML(html, 'document.pdf', {
  format: 'a4',
  metadata: {
    title: 'My Document',
    author: 'John Doe'
  }
});

React

import { usePDFGenerator } from '@encryptioner/html-to-pdf-generator/react';

function MyComponent() {
  const { targetRef, generatePDF, isGenerating, progress } = usePDFGenerator({
    filename: 'my-document.pdf',
    format: 'a4',
    showPageNumbers: true,
  });

  return (
    <div>
      <div ref={targetRef}>
        <h1>Content to convert to PDF</h1>
        <p>This will be in your PDF document</p>
      </div>

      <button onClick={generatePDF} disabled={isGenerating}>
        {isGenerating ? `Generating... ${progress}%` : 'Download PDF'}
      </button>
    </div>
  );
}

Vue 3

<script setup>
import { usePDFGenerator } from '@encryptioner/html-to-pdf-generator/vue';

const { targetRef, generatePDF, isGenerating, progress } = usePDFGenerator({
  filename: 'my-document.pdf',
  format: 'a4',
  showPageNumbers: true,
});
</script>

<template>
  <div>
    <div ref="targetRef">
      <h1>Content to convert to PDF</h1>
      <p>This will be in your PDF document</p>
    </div>

    <button @click="generatePDF" :disabled="isGenerating">
      {{ isGenerating ? `Generating... ${progress}%` : 'Download PDF' }}
    </button>
  </div>
</template>

Svelte

<script>
  import { createPDFGenerator } from '@encryptioner/html-to-pdf-generator/svelte';

  let targetElement;
  const { generatePDF, isGenerating, progress } = createPDFGenerator({
    filename: 'my-document.pdf',
    format: 'a4',
    showPageNumbers: true,
  });

  const handleDownload = () => {
    if (targetElement) {
      generatePDF(targetElement);
    }
  };
</script>

<div bind:this={targetElement}>
  <h1>Content to convert to PDF</h1>
  <p>This will be in your PDF document</p>
</div>

<button on:click={handleDownload} disabled={$isGenerating}>
  {$isGenerating ? `Generating... ${$progress}%` : 'Download PDF'}
</button>

🔧 Advanced Usage

Watermarks

await generatePDF(element, 'document.pdf', {
  watermark: {
    text: 'CONFIDENTIAL',
    opacity: 0.1,
    position: 'diagonal', // 'center' | 'diagonal' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
    fontSize: 48,
    color: '#999999',
    rotation: 45
  }
});

Headers & Footers

await generatePDF(element, 'document.pdf', {
  metadata: {
    title: 'Annual Report 2024'
  },
  headerTemplate: {
    template: '<div style="text-align: center;">{{title}} - {{date}}</div>',
    height: 15,
    css: 'font-size: 11px; border-bottom: 1px solid #ccc;'
  },
  footerTemplate: {
    template: '<div style="text-align: center;">Page {{pageNumber}} of {{totalPages}}</div>',
    height: 12
  }
});

Available template variables:

  • {{pageNumber}} - Current page number
  • {{totalPages}} - Total number of pages
  • {{date}} - Current date
  • {{title}} - Document title from metadata

PDF Security

Password protect your PDFs and control permissions:

await generatePDF(element, 'secure.pdf', {
  securityOptions: {
    enabled: true,
    userPassword: 'secret123',      // Password to open PDF
    ownerPassword: 'admin456',      // Password to change permissions
    permissions: {
      printing: 'highResolution',   // 'none' | 'lowResolution' | 'highResolution'
      modifying: false,             // Disable modifications
      copying: false,               // Disable text copying
      annotating: false,            // Disable annotations
      fillingForms: false           // Disable form filling
    }
  }
});

Note: jsPDF uses RC4 40-bit encryption, which provides basic protection but is not suitable for highly sensitive documents. For stronger encryption, consider server-side solutions.

Full security documentation: documentation/advanced/security.md

PDF Preview

Display a real-time preview of your PDF with automatic updates as content changes:

import { PDFGenerator } from '@encryptioner/html-to-pdf-generator';

const generator = new PDFGenerator({
  format: 'a4',
  previewOptions: {
    containerId: 'pdf-preview',   // ID of container element (required)
    liveUpdate: true,             // Auto-update when content changes
    debounce: 500,                // Wait 500ms after changes before updating
    scale: 1,                     // Lower scale for faster preview
    quality: 0.7                  // Lower quality for faster preview
  }
});

// Start preview
const contentElement = document.getElementById('content');
await generator.startPreview(contentElement);

// Preview automatically updates as content changes
// Manually update if needed: await generator.updatePreview();

// Stop preview and download final high-quality PDF
generator.stopPreview();
await generator.generatePDF(contentElement, 'final.pdf');

HTML Structure:

<div id="content">
  <!-- Your content to preview -->
</div>

<div id="pdf-preview" style="width: 100%; height: 600px; border: 1px solid #ccc;"></div>

Full preview documentation: documentation/advanced/preview.md

Batch Generation

import { generateBatchPDF } from '@encryptioner/html-to-pdf-generator';

const items = [
  {
    content: document.getElementById('section-1'),
    pageCount: 2,
    title: 'Introduction',
    newPage: true // Start on a new page
  },
  {
    content: document.getElementById('section-2'),
    pageCount: 3,
    title: 'Content',
    newPage: true
  }
];

const result = await generateBatchPDF(items, 'combined.pdf', {
  showPageNumbers: true
});

console.log(`Generated ${result.totalPages} pages`);

Using the PDFGenerator Class

import { PDFGenerator } from '@encryptioner/html-to-pdf-generator';

const generator = new PDFGenerator({
  format: 'a4',
  orientation: 'portrait',
  margins: [15, 15, 15, 15],
  showPageNumbers: true,
  pageNumberPosition: 'footer',
  compress: true,
  onProgress: (progress) => {
    console.log(`Generating PDF: ${progress}%`);
  },
  onComplete: (blob) => {
    console.log(`PDF generated! Size: ${blob.size} bytes`);
  },
  onError: (error) => {
    console.error('PDF generation failed:', error);
  },
});

// Generate PDF
await generator.generatePDF(element, 'document.pdf');

// Or get blob without downloading
const blob = await generator.generateBlob(element);

🖥️ MCP Server (Model Context Protocol)

The package includes an MCP server for server-side PDF generation, enabling Claude Desktop and other MCP clients to generate PDFs.

Quick Setup for Claude Desktop

  1. Build the package:

    pnpm install && pnpm run build
    
  2. Add to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

    {
      "mcpServers": {
        "html-to-pdf": {
          "command": "node",
          "args": ["/absolute/path/to/html-to-pdf-generator/mcp/dist/index.js"]
        }
      }
    }
    
  3. Restart Claude Desktop and use PDF generation in your conversations:

    You: Generate a PDF invoice with these items and save to /tmp/invoice.pdf
    Claude: [Uses generate_pdf tool to create PDF]
    

MCP Tools Available

  • generate_pdf - Generate PDF from HTML with full feature support
  • generate_batch_pdf - Combine multiple HTML sections into one PDF
  • generate_pdf_from_url - Convert web pages to PDF (CORS-aware)

📖 Full MCP Documentation: See mcp/README.md for complete setup, API reference, and examples.


📖 API Options

PDFGeneratorOptions

OptionTypeDefaultDescription
format'a4' | 'letter' | 'a3' | 'legal''a4'Paper format
orientation'portrait' | 'landscape''portrait'Page orientation
margins[number, number, number, number][10, 10, 10, 10]Margins [top, right, bottom, left] in mm
compressbooleantrueEnable PDF compression
scalenumber2HTML2Canvas scale factor (1-4)
imageQualitynumber0.85JPEG quality (0-1)
showPageNumbersbooleanfalseShow page numbers
pageNumberPosition'header' | 'footer''footer'Page number position
customCSSstring''Custom CSS to inject
watermarkWatermarkOptionsundefinedWatermark configuration
headerTemplateHeaderFooterTemplateundefinedHeader template
footerTemplateHeaderFooterTemplateundefinedFooter template
metadataPDFMetadataundefinedPDF metadata
securityOptionsPDFSecurityOptionsundefinedSecurity & encryption settings
emulateMediaType'screen' | 'print''screen'Media type to emulate
onProgress(progress: number) => void-Progress callback (0-100)
onComplete(blob: Blob) => void-Completion callback
onError(error: Error) => void-Error callback

Full API documentation: documentation/api/options.md


🔍 Browser Compatibility

  • ✅ Chrome/Edge 90+
  • ✅ Firefox 88+
  • ✅ Safari 14+
  • ✅ Modern mobile browsers

Note: Requires browser support for html2canvas and jsPDF.


🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📝 License

MIT License - see LICENSE.md for details.


🐛 Issues & Support


🙏 Acknowledgments

Built with:


📊 Package Stats

  • Bundle Size: ~400KB (minified)
  • Dependencies: 3 core dependencies
  • TypeScript: Full type definitions included
  • Tree-shakeable: ESM and CJS builds
  • Framework Support: React, Vue, Svelte, Vanilla JS
  • Server-Side: Node.js with Puppeteer

Ready to get started?Quick Start Guide

Reviews

No reviews yet

Sign in to write a review