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).

The OAuth token fixes the organisation, so no tool takes an 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.

ParameterTypeRequiredDescription
limitintegeroptional1–100, default 50
offsetintegeroptionalDefault 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates

get_template_draft

Returns template with the editable draft: draftHtml, draftCss, draftBindings, draftSchema, draftBuilderSchema, draftSampleJson and metadata. Scope: template:read.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate 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.

ParameterTypeRequiredDescription
namestringrequired1–200 chars
htmlstringrequiredHandlebars HTML
schemaobjectrequiredNon-empty JSON Schema for the data object
sampleJsonobjectrequiredNon-empty example data covering every variable in the HTML
descriptionstringoptionalMax 1000 chars
modestringoptionalcode (default), visual or pdfox-builder
cssstringoptionalTemplate CSS
bindingsobjectoptionalEditor field bindings
metadataobjectoptionalTemplate 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
namestringoptional1–200 chars
descriptionstringoptionalMax 1000 chars
htmlstringoptionalHandlebars HTML
cssstringoptionalTemplate CSS
schemaobjectoptionalJSON Schema (see the rule above)
sampleJsonobjectoptionalExample data (see the rule above)
bindingsobjectoptionalEditor field bindings
grapesjsobjectoptionalVisual editor project data
builderSchemaobjectoptionalPDFox builder document
metadataobjectoptionalReplaces 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
dataobjectoptionalData 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
dataobjectoptionalData 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
dataobjectoptionalData to render with. Defaults to the draft sample JSON.
pdfSettingsobjectoptionalPage 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.

ParameterTypeRequiredDescription
filenamestringrequiredOriginal filename with extension (max 255 chars)
assetTypestringrequiredimage, logo or font
mimeTypestringrequiredFor example image/png or font/woff2
base64DatastringrequiredFile 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
dataobjectrequiredData matching the template schema
webhookUrlstring (uri)optionalURL to POST to when the job finishes
meta.filenamestringoptionalFilename without .pdf (max 200 chars). A numeric suffix is added if the name is taken.
meta.retentionSecondsintegeroptionalSeconds 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.

ParameterTypeRequiredDescription
templateIdstring (uuid)requiredTemplate ID from list_templates
dataobjectrequiredData matching the template schema
webhookUrlstring (uri)optionalURL to POST to when the job finishes
meta.filenamestringoptionalFilename without .pdf (max 200 chars). A numeric suffix is added if the name is taken.
meta.retentionSecondsintegeroptionalSeconds to keep the PDF. Cannot exceed your plan maximum.
waitMsintegeroptional0–120000, default 30000
  • Completed: job and document (id, jobId, filename, mimeType, sizeBytes, expiresAt, uri, downloadUrl, jobUrl), with the PDF attached as an embedded base64 resource. downloadUrl works in a browser signed in to PDFox.
  • Still running: job and timedOut: true. Poll with get_job, then call download_pdf. Do not call generate_pdf_and_wait again for the same data.
  • Failed: isError: true with job and the last 10 events.

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.

ParameterTypeRequiredDescription
jobIdstring (uuid)requiredJob 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.

ParameterTypeRequiredDescription
limitintegeroptional1–100, default 20
offsetintegeroptionalDefault 0

get_job_events

Returns jobId and the last 10 events (id, eventType, message, details, createdAt). Useful for debugging failures. Scope: document:read.

ParameterTypeRequiredDescription
jobIdstring (uuid)requiredJob 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.

ParameterTypeRequiredDescription
jobIdstring (uuid)requiredJob 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.

Call get_pdf_quota before large batches and check effective.canGenerateNow so you don't run out of credits mid-batch.