Skip to main content
Glama
GerardoBarrera

PDFMakerAPI MCP Server

PDFMakerAPI MCP server

npm Glama score Add to Cursor Install in VS Code

An MCP server for PDFMakerAPI. It exposes a single create_document tool that turns a plain-English document description into a shareable link which opens in the PDFMakerAPI editor — preview it, edit any field, and download the PDF.

Works with Claude Desktop, Claude.ai, Cursor, Windsurf, Cline, Zed, VS Code, ChatGPT, and any other MCP client. It's a thin client of the public API at https://api.pdfmakerapi.com, so it needs no account or credentials of its own.

What is PDFMakerAPI?

PDFMakerAPI is a PDF template builder and PDF generation API. Instead of hard-coding documents or wrestling with HTML-to-PDF converters that break when your content changes, you design a reusable template once in a visual, no-code editor — placing text, tables, images, and dynamic fields exactly where you want them — then feed it data to produce a finished, editable PDF.

Generate a single document or thousands. Fill a template in yourself, share a link so anyone completes it in the browser as a fillable PDF form, send JSON to the REST API, trigger generation from no-code tools like Zapier, Make, and n8n, or create documents straight from AI agents like Claude and ChatGPT. Prefer to start from a prompt? Describe what you need and let Quill build it.

Teams use PDFMakerAPI for invoices, receipts, certificates, reports, and contracts — anything you'd otherwise rebuild by hand every time the data changes. Start building free with 100 PDFs a month.

Related MCP server: Nutrient Document Engine MCP Server

Quick install

One-click:

Add to Cursor Install in VS Code

Or add the same config manually (works in every desktop client):

{
  "mcpServers": {
    "pdfmakerapi": {
      "command": "npx",
      "args": ["-y", "@pdfmakerapi/mcp"]
    }
  }
}

Setup by client

Settings → Developer → Edit Config (claude_desktop_config.json), add the mcpServers block above, and restart Claude.

Use the Add to Cursor button, or add the block to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project).

Add the block to ~/.codeium/windsurf/mcp_config.json (or via Settings → Cascade → MCP).

Cline → MCP Servers → Configure, and add the mcpServers block.

Use the Install in VS Code button, or add to .vscode/mcp.json (note: VS Code uses a servers key):

{
  "servers": {
    "pdfmakerapi": { "command": "npx", "args": ["-y", "@pdfmakerapi/mcp"] }
  }
}

In settings.json:

{
  "context_servers": {
    "pdfmakerapi": { "command": { "path": "npx", "args": ["-y", "@pdfmakerapi/mcp"] } }
  }
}

Hosted (remote) option — no install

If your client supports remote MCP servers, just point it at the hosted endpoint — no npx, no Node:

https://api.pdfmakerapi.com/mcp
  • Claude.ai (web): Settings → Connectors → Add custom connector → paste the URL.

  • ChatGPT (Plus/Pro/Enterprise): Settings → Connectors → add the URL.

  • Cursor / others: add { "url": "https://api.pdfmakerapi.com/mcp" } instead of command/args.

Usage

Ask your assistant for a document:

"Make a professional invoice for Acme with 3 line items." "Create a course completion certificate." "Build a clean one-page resume."

It calls create_document and returns a link like https://app.pdfmakerapi.com/d/<id> — open it to preview, edit any field, and download the PDF.

Configuration

Env var

Default

Purpose

PDFMAKERAPI_BASE_URL

https://api.pdfmakerapi.com

Point at a different API (e.g. http://localhost:3001 for local dev).

Develop

git clone https://github.com/GerardoBarrera/pdfmakerapi-mcp.git
cd pdfmakerapi-mcp
npm install
npm run build   # compile to dist/
npm run dev     # run from source (tsx)

Troubleshooting

  • Server doesn't appear in your client — restart the client after editing its MCP config, and check the JSON is valid (no trailing commas). For remote clients, confirm the URL is exactly https://api.pdfmakerapi.com/mcp.

  • npx fails to start — ensure Node.js 18+ is installed (node -v), then retry npx -y @pdfmakerapi/mcp@latest.

  • Connection / timeout on the remote endpoint — verify your network/proxy allows HTTPS to api.pdfmakerapi.com, and that you're using the Streamable HTTP transport.

  • "Document is too large" — documents are capped at ~1 MB of JSON; trim large tables or split into multiple documents.

  • The returned link won't open — copy the full link (it ends in a document ID); if it 404s, generate the document again.

  • Still stuck? — open a GitHub issue or email support@pdfmakerapi.com.

License

MIT

Available Tools

1 tool
create_documentCreate PDF DocumentAInspect

Create a professional, shareable PDF document — invoices, receipts, certificates, reports, resumes, letters, and more. Returns a link that opens the document in the PDFMakerAPI editor, where the user can preview it, edit any field, and download the PDF.

Design a THOROUGH, realistic document (don't leave it sparse) that exactly follows this model, then pass it as document.

DOCUMENT MODEL (PDFMakerAPI) Document:

  • id: string (short slug)

  • name: string

  • description: string (one short sentence)

  • pageSize: "letter" | "a4" | "legal" | "letter-landscape" | "a4-landscape" | "square" (default "a4")

  • pageBackgroundColor: hex string (default "#ffffff")

  • margin: "none" | "sm" | "md" | "lg" — page margin; default "lg"

  • gap: "none" | "sm" | "md" | "lg" — vertical spacing between top-level sections; default "lg"

  • variables: Variable[] — every {{placeholder}} you use MUST be declared here

  • children: Node[] — the document body, top to bottom

Variable: { id, name (snake_case, used as {{name}}), label (human), type: "text"|"date"|"number"|"currency", defaultValue?: string }

Node (every node has: id, name, width: "full"|"1/2"|"1/3"|"1/4"|"2/3"|"3/4"|"auto", order: number, align?: "left"|"center"|"right", style?: NodeStyle):

  • container: { type:"container", layout:{ direction:"row"|"column", gap:"none"|"sm"|"md"|"lg", justify?:"start"|"center"|"end"|"between", alignItems?:"start"|"center"|"end"|"stretch" }, children: Node[] }

  • text: { type:"text", content: string (supports \n and {{vars}}), fontSize?:"xs"|"sm"|"base"|"lg"|"xl", fontWeight?:"normal"|"medium"|"semibold"|"bold" }

  • table: { type:"table", columns: { id, name (data key), label (header), width?: "40%", align?: "left"|"center"|"right" }[], rowVariable: string }

  • spacer: { type:"spacer", height: "sm"|"md"|"lg"|"xl" }

  • divider: { type:"divider", lineStyle?: "solid"|"dashed"|"dotted" }

NodeStyle: { backgroundColor?: hex, backgroundMode?: "none"|"solid"|"gradient", gradientTo?: hex, textColor?: hex, padding?: "none"|"sm"|"md"|"lg"|"xl", borderRadius?: "none"|"sm"|"md"|"lg", fullBleed?: boolean }

VARIABLES — how data is inserted

  • In text content, insert a value with double braces and the exact snake_case name, e.g. {{invoice_number}} — no spaces inside the braces. Every {{name}} used MUST be declared in variables[].

  • Give every variable a realistic defaultValue so the result looks complete.

  • TABLES do NOT use {{}}. A table renders one row per item in its rowVariable array, pulling item[column.name] for each cell — so each column "name" must match the row object's key. The rowVariable variable's defaultValue must be a JSON-encoded string of the row array, e.g. JSON.stringify([{ description: "Brand design", qty: "1", amount: "$2,400.00" }]).

RULES

  • Use containers (direction:"row") to place items side by side.

  • For label/value pairs (dates, totals, "Bill To", reference numbers), nest a direction:"row" container with two text children — a BOLD label (fontWeight:"bold") and the value as a {{variable}} — each with a width (e.g. label "1/3", value "2/3") so they align in columns. Stack such rows in a column container.

  • Use a table node for any repeating rows (line items, attendees) and set rowVariable.

  • Spacing between sections comes from the document "gap" (default "lg") — do NOT insert spacer nodes between top-level sections.

  • Table column alignment: left-align text columns, right-align money/number columns, center short codes/status; a header's alignment matches its column.

  • Every id must be unique. Keep it clean and professional.

After the tool returns a url, share it with the user and tell them they can open it to preview, edit any field, and download the PDF.

ParametersJSON Schema
NameRequiredDescriptionDefault
documentYesThe PDFMakerAPI Document to create. Follow the DOCUMENT MODEL in this tool's description.

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYesShareable link that opens the document in the PDFMakerAPI editor to preview, edit, and download the PDF.
idYesThe stored document id.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate a write operation, and the description confirms creation, returning a URL to an editor rather than a direct PDF. It adds extensive behavioral context: preview, edit, download capability, and detailed document model rules. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured, starting with purpose, then model, variables, and rules. Front-loading works. Every sentence adds value; however, some details could be streamlined without losing clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single parameter with full schema coverage and an output schema, the description fully explains the document model, variable usage, layout rules, and return behavior. No gaps remain for an AI agent to understand tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage but provides minimal descriptions. The tool description compensates with a comprehensive DOCUMENT MODEL detailing each field, types, defaults, and usage rules. This adds immense semantic meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool creates PDF documents like invoices, receipts, certificates, etc. It uses a specific verb 'create' and identifies the resource as a PDFMakerAPI document. Despite no siblings, it effectively communicates its purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use (generate a PDF) and provides guidance on how to design the document. However, it does not explicitly state when not to use or alternative tools, but with no siblings, this is a minor gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 1 tool updatev1.0.0
    • Changedcreate_document5 fields changed
      • removedInput schema / properties / document / additionalProperties
        Removed value: -{}
      • changedInput schema / properties / document / description
        Previous value: -"The PDFMakerAPI Document object to create, following the schema in this tool's description."New value: +"The PDFMakerAPI Document to create. Follow the DOCUMENT MODEL in this tool's description."
      • addedInput schema / properties / document / properties
        Added value: +{
        +  "children": {
        +    "description": "The document body — an ordered array of nodes (container/text/table/spacer/divider). See the DOCUMENT MODEL above.",
        +    "items": {
        +      "additionalProperties": {},
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  "description": {
        +    "type": "string"
        +  },
        +  "gap": {
        +    "description": "\"none\" | \"sm\" | \"md\" | \"lg\" (default \"lg\").",
        +    "type": "string"
        +  },
        +  "id": {
        +    "type": "string"
        +  },
        +  "margin": {
        +    "description": "\"none\" | \"sm\" | \"md\" | \"lg\" (default \"lg\").",
        +    "type": "string"
        +  },
        +  "name": {
        +    "description": "Document name.",
        +    "type": "string"
        +  },
        +  "pageBackgroundColor": {
        +    "description": "Hex color, e.g. #ffffff.",
        +    "type": "string"
        +  },
        +  "pageSize": {
        +    "description": "\"letter\" | \"a4\" | \"legal\" | \"letter-landscape\" | \"a4-landscape\" | \"square\" (default \"a4\").",
        +    "type": "string"
        +  },
        +  "variables": {
        +    "description": "Declared variables; every {{name}} used in content MUST be declared here.",
        +    "items": {
        +      "additionalProperties": {},
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • removedInput schema / properties / document / propertyNames
        Removed value: -{
        -  "type": "string"
        -}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "id": {
        +      "description": "The stored document id.",
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "Shareable link that opens the document in the PDFMakerAPI editor to preview, edit, and download the PDF.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "url",
        +    "id"
        +  ],
        +  "type": "object"
        +}
  2. 1 tool updatev0.1.0
    • First observedcreate_document

TDQS

A4.6/5.0
Disambiguation5/5

With only one tool, there is no possibility of confusion between tools. The tool's purpose is clearly defined and distinct.

Naming Consistency5/5

A single tool has no naming inconsistencies. The name 'create_document' is descriptive and follows a common verb_noun pattern.

Tool Count4/5

The single tool is appropriate for a focused server that creates PDF documents. However, it might be considered slightly thin as it combines creation and editing via a returned URL.

Completeness3/5

The tool covers document creation comprehensively, but lacks supporting tools for managing documents (e.g., listing, updating, deleting). This leaves agents with no way to perform other lifecycle operations.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GerardoBarrera/pdfmakerapi-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server