MCP tools
The PDFox MCP server exposes 21 tools. tools/list returns only the tools your OAuth token has scopes for. Each tool returns a text summary in content and machine-readable data in structuredContent. Failures come back as a tool result with isError: true and structuredContent.error (message, code).
orgId. All IDs are UUIDs. Only use IDs returned by earlier tool calls.Authoring guidance
get_template_language_guide
Returns the PDFox authoring guide as guide (HTML, CSS, Handlebars, schema and sample JSON rules, asset embedding, print tips), plus allowedHelpers and structuralHelpers. No parameters. Call it before writing template HTML. Scope: template:read.
list_template_helpers
Returns helpers (name, example, description) for every whitelisted helper: formatCurrency, formatNumber, formatDate, uppercase, lowercase, default, add, subtract, multiply, divide, percent, eq, neq, gt, gte, lt, lte, qrCodeDataUri, barcodeDataUri. The structural helpers each, if, unless and with are also supported. No parameters. Scope: template:read.
Templates
list_templates
Returns templates (id, name, description, mode, currentVersionId, disabledAt, createdAt, updatedAt), count, limit, offset and templateLimit. Schemas are not included: use get_template_schema. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | optional | 1–100, default 50 |
offset | integer | optional | Default 0 |
get_template
Returns template: the list fields plus schema, sampleJson, versionId and versionNumber of the published version. For a never-published template these come from the draft and the version fields are null. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
get_template_schema
Returns templateId, templateName, schema, sampleJson, versionId and versionNumber, from the published version (or the draft if never published). Shape your data to match before generating. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
get_template_draft
Returns template with the editable draft: draftHtml, draftCss, draftBindings, draftSchema, draftBuilderSchema, draftSampleJson and metadata. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
Drafts
Drafts never affect generation until someone publishes them in the dashboard. See Template drafts for the workflow.
create_template_draft
Creates a new unpublished template. Returns template (same shape as get_template_draft; the new ID is template.id) and published: false. Scope: template:write.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | required | 1–200 chars |
html | string | required | Handlebars HTML |
schema | object | required | Non-empty JSON Schema for the data object |
sampleJson | object | required | Non-empty example data covering every variable in the HTML |
description | string | optional | Max 1000 chars |
mode | string | optional | code (default), visual or pdfox-builder |
css | string | optional | Template CSS |
bindings | object | optional | Editor field bindings |
metadata | object | optional | Template metadata, such as pdfSettings |
update_template_draft
Changes only the fields you send. If you send html, schema or sampleJson, you must also send non-empty schema and sampleJson in the same call. Returns template and published: false. Scope: template:write.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
name | string | optional | 1–200 chars |
description | string | optional | Max 1000 chars |
html | string | optional | Handlebars HTML |
css | string | optional | Template CSS |
schema | object | optional | JSON Schema (see the rule above) |
sampleJson | object | optional | Example data (see the rule above) |
bindings | object | optional | Editor field bindings |
grapesjs | object | optional | Visual editor project data |
builderSchema | object | optional | PDFox builder document |
metadata | object | optional | Replaces the template metadata |
validate_template_draft
Checks the draft for Handlebars syntax errors, unknown helpers, unsafe content and schema errors. Returns templateId, valid, handlebarsIssues, schemaValidationErrors and renderError. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
data | object | optional | Data to render with. Defaults to the draft sample JSON. |
preview_template_draft
Renders the draft to HTML. Returns templateId, the rendered html inline, and validationErrors. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
data | object | optional | Data to render with. Defaults to the draft sample JSON. |
preview_template_pdf
Renders the draft to a PDF. Returns preview (uri, mimeType, sizeBytes) and attaches the PDF as an embedded base64 resource at pdfox://template-previews/{templateId}/preview.pdf. Scope: template:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
data | object | optional | Data to render with. Defaults to the draft sample JSON. |
pdfSettings | object | optional | Page size, orientation and margin overrides for this preview |
Assets
See Template assets for file types and plan limits.
list_assets
Returns assets (id, organizationId, assetType, filename, mimeType, sizeBytes, renderPath, createdAt, and for fonts fontFamily and cssSnippet), plus count, storageUsedBytes, storageLimitBytes, assetCount, assetLimit, customAssetsEnabled and fontUploadEnabled. No parameters. Scope: asset:read.
upload_asset
Uploads a file and returns asset in the same shape as a list_assets item. Call list_assets first to avoid duplicates. Scope: asset:write.
| Parameter | Type | Required | Description |
|---|---|---|---|
filename | string | required | Original filename with extension (max 255 chars) |
assetType | string | required | image, logo or font |
mimeType | string | required | For example image/png or font/woff2 |
base64Data | string | required | File bytes as standard base64, with no data: prefix |
Generation
Both tools render the template's published version. A template with no published version returns NO_PUBLISHED_VERSION.
generate_pdf
Queues a job and returns straight away with jobId and status: "queued". Use it for batches, then check progress with get_job and fetch the file with download_pdf. Scope: document:create.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
data | object | required | Data matching the template schema |
webhookUrl | string (uri) | optional | URL to POST to when the job finishes |
meta.filename | string | optional | Filename without .pdf (max 200 chars). A numeric suffix is added if the name is taken. |
meta.retentionSeconds | integer | optional | Seconds to keep the PDF. Cannot exceed your plan maximum. |
generate_pdf_and_wait
Queues a job and polls until it finishes or waitMs runs out. Scope: document:create and document:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId | string (uuid) | required | Template ID from list_templates |
data | object | required | Data matching the template schema |
webhookUrl | string (uri) | optional | URL to POST to when the job finishes |
meta.filename | string | optional | Filename without .pdf (max 200 chars). A numeric suffix is added if the name is taken. |
meta.retentionSeconds | integer | optional | Seconds to keep the PDF. Cannot exceed your plan maximum. |
waitMs | integer | optional | 0–120000, default 30000 |
- Completed:
jobanddocument(id, jobId, filename, mimeType, sizeBytes, expiresAt,uri,downloadUrl,jobUrl), with the PDF attached as an embedded base64 resource.downloadUrlworks in a browser signed in to PDFox. - Still running:
jobandtimedOut: true. Poll withget_job, then calldownload_pdf. Do not callgenerate_pdf_and_waitagain for the same data. - Failed:
isError: truewithjoband the last 10events.
Duplicate requests
If the same user sends the same template, data and webhook URL through MCP within 60 seconds of an earlier accepted request, PDFox does not queue a second job. The tool returns isError: true with code DUPLICATE_GENERATION_REQUEST, plus existingJobId and existingJob. Use get_job or download_pdf with that ID instead.
{
"isError": true,
"content": [{ "type": "text", "text": "Duplicate generation request. Use get_job or download_pdf with job 7c9e6679-7425-40de-944b-e07fc1f90ae7; ..." }],
"structuredContent": {
"error": { "message": "Duplicate generation request. ...", "code": "DUPLICATE_GENERATION_REQUEST" },
"existingJobId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"existingJob": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"templateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"templateVersionId": "a1b2c3d4-0000-4000-8000-000000000001",
"status": "processing",
"sourceType": "mcp",
"createdAt": "2026-06-01T12:00:00.000Z",
"startedAt": "2026-06-01T12:00:01.000Z",
"completedAt": null
}
}
}Jobs and downloads
get_job
Returns job: id, templateId, templateName, status (queued, processing, completed, failed or cancelled), sourceType, errorMessage, createdAt, startedAt, completedAt, documentId, documentFilename and documentExpiresAt. Input data is not returned. Scope: document:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId | string (uuid) | required | Job ID from a generate tool or list_jobs |
list_jobs
Returns recent jobs (same fields as get_job), newest first, with limit and offset. Scope: document:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | optional | 1–100, default 20 |
offset | integer | optional | Default 0 |
get_job_events
Returns jobId and the last 10 events (id, eventType, message, details, createdAt). Useful for debugging failures. Scope: document:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId | string (uuid) | required | Job ID from a generate tool or list_jobs |
download_pdf
Returns job and document (as for a completed generate_pdf_and_wait) with the PDF attached as an embedded base64 resource. Returns JOB_NOT_COMPLETED or JOB_FAILED if the job has not finished successfully. Clients can also fetch the PDF with resources/read on its pdfox://documents/{jobId}/{filename} URI. Scope: document:read.
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId | string (uuid) | required | Job ID from a generate tool or list_jobs |
Usage
get_pdf_quota
Returns quota with period (daily and monthly reset times), included (plan limits, usage, payment status), purchasedPacks, and effective (canGenerateNow, remainingToday, remainingThisMonth, nextLimitReason). No parameters. Scope: usage:read.
get_usage_history
Returns organizationId and history, a list of { date, count } entries for days with generation. No parameters. Scope: usage:read.
get_pdf_quota before large batches and check effective.canGenerateNow so you don't run out of credits mid-batch.