MCP Hub
Back to servers

pretext-pdf-mcp

MCP server: generate professional PDFs from JSON in Claude, Cursor, Windsurf, or any AI agent. Serverless, no Chromium. Invoices, reports, resumes.

npm238/wk
Updated
May 3, 2026

Quick Install

npx -y pretext-pdf-mcp

pretext-pdf-mcp

npm version npm downloads license CI

MCP server for pretext-pdf — generate professional PDFs from structured JSON in Claude, Cursor, or any AI agent.

No headless browser. No puppeteer. Pure Node.js with embedded fonts and precision text layout.

Live Demo

▶ Open Live Demo — edit JSON, click Generate, see a real PDF in seconds. No install.

▶ Open in StackBlitz — fork and edit the playground code.

4 templates included: GST Invoice · Market Report · Resume/CV · Custom


Connect via Smithery

The fastest way — no install, works instantly in any MCP-compatible agent:

https://pretext-pdf.run.tools

Or add via CLI:

smithery mcp add himaan4149-kv55/pretext-pdf

Local Install (Claude Desktop / Cursor / Windsurf)

Option 1: npx (no global install needed)

npx pretext-pdf-mcp

Option 2: Global install

npm install -g pretext-pdf-mcp
pretext-pdf-mcp

Claude Desktop Configuration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "pretext-pdf": {
      "command": "npx",
      "args": ["-y", "pretext-pdf-mcp"]
    }
  }
}

Config file location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Using with Claude Code CLI

claude mcp add pretext-pdf-mcp -- npx -y pretext-pdf-mcp

After running this command, all 6 MCP tools are available in your Claude Code session (4 generation tools + validate + list reference).

HTTP Transport Mode (advanced)

By default the server runs over stdio (MCP standard transport). For HTTP transport:

MCP_TRANSPORT=http MCP_PORT=3000 npx pretext-pdf-mcp

Environment variables:

  • MCP_TRANSPORT — Set to http to enable HTTP transport (default: stdio)
  • MCP_PORT — HTTP listen port when MCP_TRANSPORT=http (default: 3000)
  • MCP_HOST — HTTP listen host (default: 127.0.0.1)

Security note: HTTP transport is intended for trusted local networks only. Do not expose the HTTP port to the public internet without adding an authentication layer.

Known Limitations

  • Italic fonts — Italic markdown (*text*) requires an italic font variant. Inter italic is supported via @fontsource/inter (installed automatically). For other fonts, provide { family, weight, style: 'italic', src } in doc.fonts.
  • QR codes, barcodes, charts — Require optional peer dependencies: qrcode, bwip-js, vega/vega-lite. Install the ones you need.
  • SVG and images — Image URLs must be HTTPS. Private/local IP addresses are blocked (SSRF prevention). File paths require absolute paths.
  • Large documents — No hard page limit, but generation time scales with page count. Documents over 10,000 content elements trigger a performance advisory.
  • CJS consumers — pretext-pdf is ESM-only. If your project uses CommonJS, use dynamic import().

Tools

ToolInputOutput
generate_pdfPdfDocument JSON descriptorBase64 PDF + filename + size
generate_invoiceInvoice data (parties, items, GST, currency)Base64 PDF
generate_reportReport sections with optional tables and calloutsBase64 PDF
generate_from_markdownMarkdown stringBase64 PDF
validate_documentPdfDocument JSONValidation result (valid/errors)
list_element_typesnoneMarkdown reference of all element types

generate_pdf

Full-power access to the pretext-pdf API. Pass any PdfDocument descriptor.

{
  "document": {
    "pageSize": "A4",
    "footer": { "text": "Page {{pageNumber}} of {{totalPages}}", "fontSize": 9 },
    "content": [
      { "type": "heading", "level": 1, "text": "My Document" },
      { "type": "paragraph", "text": "Hello world." }
    ]
  },
  "filename": "my-document"
}

Returns:

{
  "success": true,
  "base64": "<base64-encoded PDF bytes>",
  "filename": "my-document.pdf",
  "size_bytes": 42816
}

generate_invoice

Business-friendly invoice generator. No PDF knowledge needed.

{
  "from": {
    "company": "Antigravity Systems",
    "address": "Gurugram, Haryana",
    "gstin": "06AABCA1234Z1ZK",
    "email": "hello@antigravity.dev"
  },
  "to": {
    "company": "TCS Ltd",
    "address": "Mumbai, Maharashtra",
    "gstin": "27AAACT2727Q1ZW"
  },
  "invoice_number": "INV-2026-001",
  "date": "2026-04-08",
  "due_date": "2026-05-08",
  "currency": "INR",
  "items": [
    {
      "description": "LLM Fine-tuning Pipeline",
      "hsn_code": "998314",
      "quantity": 1,
      "rate": 250000,
      "gst_rate": 18
    },
    {
      "description": "AI Strategy Workshop",
      "quantity": 2,
      "rate": 75000,
      "gst_rate": 18
    }
  ],
  "notes": "Payment due within 30 days. NEFT/IMPS preferred."
}

Returns:

{
  "success": true,
  "base64": "<base64-encoded PDF bytes>",
  "filename": "invoice-INV-2026-001.pdf",
  "size_bytes": 68420
}

Features:

  • Supports INR, USD, EUR, GBP
  • Auto-calculates IGST per line item when gst_rate is set
  • HSN/SAC code column appears automatically when any item has it
  • Company header with from/to details in a 2-column table
  • Professional footer with invoice number and page numbers

generate_report

Multi-section report with optional TOC, tables, and callout boxes.

{
  "title": "Haryana Real Estate Q1 2026",
  "subtitle": "Residential & Commercial Analysis",
  "author": "Antigravity Research",
  "include_toc": true,
  "sections": [
    {
      "heading": "Executive Summary",
      "body": "Strong growth across all micro-markets.\n\nGurugram led with 18% YoY volume growth.",
      "table": {
        "headers": ["Market", "Avg Rs./sqft", "YoY"],
        "rows": [
          ["New Gurugram", "9,800", "+15.6%"],
          ["Sohna Road", "8,400", "+12.1%"]
        ]
      },
      "callout": {
        "style": "warning",
        "text": "Repo rate risk: any hike above 6.75% could suppress volumes 10-15%."
      }
    }
  ]
}

list_element_types

No input. Returns a markdown reference of all 22 element types (paragraph, heading, table, list, image, svg, code, blockquote, callout, toc, form-field, comment, hr, spacer, page-break, rich-paragraph, qr-code, barcode, chart, footnote-def, float-group, and toc-entry) with key properties and examples.

generate_from_markdown

Convert a Markdown string to a PDF without writing any JSON. Supports headings, bold/italic, strikethrough, inline code, links, ordered/unordered lists (up to 3 levels), GFM tables (with column alignment), GFM task lists (☑/☐), blockquotes, fenced code blocks, and horizontal rules. Note: code blocks render as plain indented text — not styled monospace. For styled code blocks or richer layouts, use generate_pdf.

{
  "markdown": "# Hello\n\nThis is a **bold** paragraph.\n\n- Item 1\n- Item 2",
  "filename": "hello",
  "page_size": "A4",
  "font_size": 12
}

Returns:

{
  "success": true,
  "base64": "<base64-encoded PDF bytes>",
  "filename": "hello.pdf",
  "size_bytes": 18432
}

Limits: markdown max 100,000 characters. font_size must be 6–144. page_size one of: A4, Letter, Legal. Default filename: document.

validate_document

Validate a pretext-pdf document schema without rendering it. Use this as a cheap preflight check before calling generate_pdf — catches typos, missing required fields, and unknown props in strict mode.

{
  "document": {
    "pageSize": "A4",
    "content": [{ "type": "heading", "level": 1, "text": "Test" }]
  },
  "strict": true
}

Valid response:

{ "valid": true, "error_count": 0, "warning_count": 0, "errors": [], "warnings": [] }

Invalid response:

{
  "valid": false,
  "error_count": 2,
  "warning_count": 0,
  "errors": [
    {
      "path": "doc.content[0].colour",
      "message": "unknown property. did you mean \"color\"",
      "code": "UNKNOWN_PROPERTY",
      "severity": "error",
      "unknownProp": "colour",
      "suggestion": "color"
    },
    {
      "path": "doc.pageSize",
      "message": "unknown property. did you mean \"pageSize\"",
      "code": "UNKNOWN_PROPERTY",
      "severity": "error",
      "unknownProp": "pageSise",
      "suggestion": "pageSize"
    }
  ],
  "warnings": []
}

Tip: Pass strict: true to catch misspelled props with Levenshtein-nearest suggestions. Default is strict: false — only checks required fields and types.

Decoding the base64 PDF

In Node.js:

const bytes = Buffer.from(result.base64, 'base64')
fs.writeFileSync('output.pdf', bytes)

In TypeScript (browser):

const bytes = Uint8Array.from(atob(result.base64), c => c.charCodeAt(0))
const blob = new Blob([bytes], { type: 'application/pdf' })

In Python:

import base64
pdf_bytes = base64.b64decode(result['base64'])
with open('output.pdf', 'wb') as f:
    f.write(pdf_bytes)

License

MIT — Himanshu Jain

Reviews

No reviews yet

Sign in to write a review