PDFDispatch Docs

AI assistants (MCP)

Our hosted MCP server lets an AI assistant make PDFs and screenshots with your PDFDispatch key. To set it up, you give the assistant one URL and one header.

View as Markdown

What it is

MCP (Model Context Protocol) is how AI assistants such as Claude Code, Cursor and VS Code call outside tools. Our MCP server sits in front of the API and turns each tool call into one API request:

https://mcp.pdfdispatch.com/mcp

It speaks Streamable HTTP. The server has no accounts of its own: every request carries your PDFDispatch key, the server passes it on to the API, and the API’s rules apply as they do to any other client (your plan, its size limit, its requests per minute). You do not need anything else installed.

The assistant gets the finished file as a link. It can download it into your project, show it to you, or pass it to another tool, for example to merge it with other PDFs.

Setup

You need a key from pdfdispatch.com/app/keys (see Authentication). Make one just for the assistant, so you can revoke it alone. The server expects it in a header:

Authorization: Bearer pdd_...

Keys from a contract account work too.

Keep the key in an environment variable or in the client’s secret store. Do not write it into a config file that goes into git: every PDF made with it counts on your plan. The examples below read it from PDD_KEY:

export PDD_KEY=pdd_your_key_here

Claude Code

The easiest way is our plugin. It adds the server, asks for your key once and keeps it in your system’s secure storage, and comes with a skill that teaches Claude to write print CSS, check layouts with a screenshot and save the results into your project. In Claude Code:

/plugin marketplace add soriresitve/pdfdispatch-ai
/plugin install pdfdispatch@pdfdispatch

To change the key later, open /plugin and configure PDFDispatch. The plugin’s source is public: github.com/soriresitve/pdfdispatch-ai.

To add only the server, without the plugin, one command:

claude mcp add --transport http pdfdispatch https://mcp.pdfdispatch.com/mcp \
  --header "Authorization: Bearer $PDD_KEY"

Your shell fills in the key when you run the command, and Claude Code saves it in ~/.claude.json, outside your project. By default the server is there only for you in the current project (--scope local). Add --scope user to have it in all your projects.

To share the setup with your team, do not use --scope project with the command above: it would write your key into .mcp.json, which is meant to be committed. Write .mcp.json yourself instead, with a variable that Claude Code fills in when it starts, so each person uses their own key:

{
  "mcpServers": {
    "pdfdispatch": {
      "type": "http",
      "url": "https://mcp.pdfdispatch.com/mcp",
      "headers": {
        "Authorization": "Bearer ${PDD_KEY}"
      }
    }
  }
}

Run /mcp in Claude Code to check that the server is connected.

Cursor

Add the server to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Cursor fills in ${env:PDD_KEY} from your environment, so the file holds no key:

{
  "mcpServers": {
    "pdfdispatch": {
      "url": "https://mcp.pdfdispatch.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PDD_KEY}"
      }
    }
  }
}

Set PDD_KEY in your shell profile or system environment, then restart Cursor.

The “Add to Cursor” button on pdfdispatch.com/ai writes the same entry for you. For the same habits as the Claude Code plugin, copy our rule file pdfdispatch.mdc into your project as .cursor/rules/pdfdispatch.mdc.

VS Code

Add .vscode/mcp.json to the project (or run MCP: Open User Configuration for all projects). With an input, VS Code asks for the key the first time the server starts and keeps it in its secret storage:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "pdfdispatch-key",
      "description": "PDFDispatch API key",
      "password": true
    }
  ],
  "servers": {
    "pdfdispatch": {
      "type": "http",
      "url": "https://mcp.pdfdispatch.com/mcp",
      "headers": {
        "Authorization": "Bearer ${input:pdfdispatch-key}"
      }
    }
  }
}

The file holds no key, so it can be committed. If you prefer an environment variable, "Bearer ${env:PDD_KEY}" works too.

The “Install in VS Code” button on pdfdispatch.com/ai adds the server to your user configuration in one click; VS Code then asks for the key once.

Claude Desktop

Claude Desktop cannot send a header to a remote server from its config file. It can reach ours through the mcp-remote bridge, which runs locally with Node.js and adds the header. In claude_desktop_config.json:

{
  "mcpServers": {
    "pdfdispatch": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.pdfdispatch.com/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer pdd_your_key_here"
      }
    }
  }
}

Leave no space around the colon in Authorization:${AUTH_HEADER}: on some systems a space inside args breaks the command. This file stays on your computer, but it does hold the key, so keep it out of backups you share.

Other clients

Any client that can add a remote MCP server over Streamable HTTP with a custom header works. Give it the URL https://mcp.pdfdispatch.com/mcp and the header Authorization: Bearer pdd_..., taken from a variable or a secret field if the client has one.

To give the assistant the same PDF habits as our Claude Code plugin, paste pdf-documents.md into its instructions (AGENTS.md, a system prompt or similar).

A client that cannot send a header cannot use the server yet, because it does not support OAuth sign-in. That includes custom connectors in claude.ai. See Not yet.

Tools

ToolWhat it doesMain inputs
html_to_pdfA complete HTML page to PDF, with Chromium. Best for invoices, reports, tickets and certificates.html, optional header_html and footer_html (printed on every page), filename
markdown_to_pdfMarkdown to a PDF with a clean built-in style.markdown, optional title, css (replaces the built-in style), filename
url_to_pdfPrints a public web page.url, optional screen (the page’s screen styles instead of its print styles), filename
office_to_pdfWord, Excel, PowerPoint, OpenDocument, RTF, CSV and many more formats to PDF, with LibreOffice.files (links), optional merge, landscape, pages (for example 1-3)
merge_pdfsTwo or more PDFs into one, in the order given.files (links)
screenshotHTML or a public web page as a PNG, JPEG or WebP image.html or url, width (1200), height (800), full_page (true), selector, format (png)
upload_fileA link to upload a file from your computer, for office_to_pdf and merge_pdfs.filename with its extension

You do not call these yourself. You ask the assistant for a PDF and it picks the tool and fills in the inputs. It helps to say which tool you want when you care, for example “use markdown_to_pdf” for a plain text report.

Page options

html_to_pdf, markdown_to_pdf and url_to_pdf share these:

InputDefaultWhat
paperA4A3, A4, A5, Letter, Legal or Tabloid.
landscapefalseLandscape instead of portrait.
marginabout 1 cmAll four sides, for example 15mm or 0.5in.
print_backgroundtruePrint background colours and images.
prefer_css_page_sizefalseTake the size from the page’s CSS @page rule instead of paper.
scale1Zoom of the content, 0.1 to 2.
outlinefalsePDF bookmarks from the headings.
accessiblefalseA tagged PDF for screen readers.
wait_delay, wait_for_expressionnoneWait before printing, for pages that draw with scripts (waiting).

Two defaults differ from the API’s own: the MCP server uses A4 paper (the API uses Letter) and prints backgrounds (the API does not), because that is what most people asking an assistant for a document expect.

Other API fields

Every tool except upload_file takes extra_fields: any other form field of its API route, by its API name. For example {"pdfa": "PDF/A-2b"} for a PDF/A file, or {"userPassword": "..."} to encrypt it. A field named there replaces the server’s own value. This is also how you reach the PDF tools that have no tool of their own yet: the conversion routes accept their options in the same request (see Combining with PDF options).

Results and links

Every tool that makes a file stores it and answers with a link:

https://mcp.pdfdispatch.com/files/<id>/invoice-1042.pdf

The link works for one hour. After that it answers 410 Gone. To keep a file, have the assistant download it, for example with curl -fsSL -o invoice-1042.pdf "<link>". The answer also gives the file’s name, type, size, the time the link expires and the API’s request id (quote it when you write to support).

Screenshots up to 1 MiB also come back as the image itself, so the assistant can look at the layout it made and fix it before making the PDF. Larger screenshots come back as a link only.

A link from one tool can go straight into another: make three PDFs, then give their links to merge_pdfs.

Files on your computer

office_to_pdf and merge_pdfs take their files as links, because the assistant talks to the server over HTTP and cannot attach a file to a tool call. A link can be:

  • a public https URL, which the server downloads (public addresses only, nothing on your network),
  • a link the server gave as a result,
  • an upload made with upload_file.

For a file on your computer, the assistant calls upload_file with the file’s name. It gets an upload_url and a file_url, uploads the file with an HTTP PUT:

curl -fsS -T contract.docx "<upload_url>"

and then passes file_url to the next tool. The upload link works for 15 minutes; the uploaded file is kept for one hour. Uploads are free and can never be downloaded again, by you or anyone else: only results are served.

The format is read from the file’s extension, so the name must have one (contract.docx, not contract).

What it costs

Each tool call that makes a file counts as one PDF on your plan, exactly like one API request (what counts). A screenshot and a merge count as one each. With several Office files and no merge, you get one ZIP and it still counts as one.

These cost nothing:

  • upload_file, and the upload itself.
  • Calls the server refuses before it reaches the API: an empty html, an unknown paper size, a file:// URL, a link that cannot be downloaded, a file over 50 MiB.
  • Calls the API refuses. They follow the API’s rules: a request that fails counts nothing.

In the rare case that the API made the file but the server could not store it, the call still counts, and the error says so and gives the request id.

Limits

LimitValue
One MCP request (the HTML or Markdown in a tool call, for example)10 MiB
One input file, downloaded or uploaded50 MiB
Files in one office_to_pdf or merge_pdfs call50
Result links1 hour
Upload links15 minutes to upload, then 1 hour to use
Inline screenshotsup to 1 MiB

Your plan’s limits apply on top: the API still refuses a request larger than your plan allows (5 MB on the Free plan, see Limits per plan), and its requests per minute and time limits are the same.

Errors

A failed call comes back as a tool result marked as an error, with a sentence the assistant can act on. When the API refused the request, the result keeps its status, its code and the link to that code’s row in these docs:

PDFDispatch refused the request (HTTP 429, code 42910): ... More: https://docs.pdfdispatch.com/limits/#42910

The codes are the API’s own, listed in Limits and errors. Errors from the PDF engine (a field it does not accept, for example) come back with their plain text.

A request without a key, or with something that does not look like one, gets 401 before any tool runs. Check that the header reaches the server: a variable that was not set often sends Bearer with nothing after it.

Privacy

  • Your key is passed to the API with each request and is never stored or logged by the MCP server.
  • Results and uploads are stored in the EU, under a random name that cannot be guessed. Results can be downloaded for one hour; everything is deleted after one day at the latest.
  • The link is the only protection. Anyone who has a result link can download that file during its hour, so treat links like the files themselves.
  • The server logs one line per tool call: the tool, how long it took, the size and the API’s request id. Never the key, your input, a file or a link.

Not yet

  • OAuth: signing in from the client, without pasting a key, is not supported yet. Until it is, clients that cannot send a header (custom connectors in claude.ai, for example) cannot use the server.
  • Tools of their own for split, compress, encrypt and the other PDF tools. Until then, use them through extra_fields on a conversion.

If a client does not work with the server, or you have a question, write to support@pdfdispatch.com .