PDF MCP Server avatar

PDF MCP Server

Pricing

Pay per usage

Go to Apify Store
PDF MCP Server

PDF MCP Server

Stateless PDF tools exposed via MCP. Open, split, merge, extract text, fill and flatten forms, and generate PDFs in a single run. Designed for deterministic, auditable document transformations by agents and workflows.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

CQ

CQ

Maintained by Community

Actor stats

0

Bookmarked

14

Total users

2

Monthly active users

8 days ago

Last modified

Share

PDF MCP Server — Document Intelligence

AI-powered PDF operations for Claude, VS Code, and any MCP client

Extract structured JSON from invoices, receipts, contracts, resumes, W-2s, 1099s, and bank statements using GPT-4o vision. Plus merge, split, render, and manipulate PDFs.

Quick Start

1. Try it on Apify

Run the Actor directly: pick a tool (e.g. pdf.get_metadata) and provide a pdfUrl (or pdfBase64). Running with no tool selected simply returns the server info (version + available tools). Results are written to the run's dataset, and any generated files (PDFs/images) to the key-value store.

2. Connect to Claude Desktop

Add to claude_desktop_config.json:

{
"mcpServers": {
"pdf": {
"url": "https://mcp.apify.com?actors=constant_quadruped/pdf-mcp-server"
}
}
}

3. Connect to VS Code

Install the MCP extension and add the same URL.


Features

CategoryCapabilities
AI ExtractionOpenAI models (default GPT-4o) extract structured JSON; text layer first, GPT-4o vision fallback for scans
Document TypesInvoices, receipts, contracts, resumes, W-2, 1099, bank statements
PDF OperationsMerge, split, extract pages, create from HTML
Form HandlingList fields, fill forms, flatten
RenderingConvert pages to PNG/JPEG images
Input FlexibilityURL or Base64 encoded PDFs

AI Document Extraction

The pdf.ai_extract tool sends the document to an OpenAI model (default gpt-4o) to extract structured data. It first tries the PDF's embedded text layer; if the PDF has no text layer (or text extraction fails), it renders pages to images and falls back to GPT-4o vision so scanned PDFs still work. You supply your own OpenAI API key. Extraction is capped at 10 pages per request.

Supported Document Types

TypeWhat Gets Extracted
invoiceInvoice number, dates, vendor info, customer info, line items with quantities/prices, subtotal, tax, total
receiptMerchant name, date/time, itemized purchases, subtotal, tax, total, payment method
contractParty names, effective dates, termination date, key terms, obligations, signatures
resumeName, contact info, work experience with dates, education, skills, certifications
w2Employer EIN/name/address, employee SSN/name/address, wages, federal/state tax withheld
form_1099Payer info, recipient info, amounts by box, form type (MISC, NEC, INT, DIV)
bank_statementAccount number, statement period, opening/closing balance, all transactions
autoAuto-detects document type and extracts relevant fields

Example: Extract Invoice Data

Input:

{
"tool": "pdf.ai_extract",
"pdfUrl": "https://example.com/invoice.pdf",
"documentType": "invoice",
"openaiApiKey": "sk-..."
}

Output:

{
"status": "ok",
"errors": [],
"warnings": [],
"artifacts": [
{ "id": "…", "type": "extraction_result", "filename": "…_extraction.json", "mime": "application/json", "size_bytes": 1234 }
],
"doc_id": "a1b2c3d4e5f6",
"document_type": "invoice",
"extraction": {
"invoice_number": "INV-2024-001",
"invoice_date": "2024-01-15",
"due_date": "2024-02-15",
"vendor_name": "Acme Corp",
"vendor_address": "123 Business St, NYC",
"customer_name": "Client Inc",
"customer_address": "456 Customer Ave",
"line_items": [
{ "description": "Widget A", "quantity": 10, "unit_price": 100.00, "amount": 1000.00 }
],
"subtotal": 1000.00,
"tax": 80.00,
"total": 1080.00,
"currency": "USD"
},
"confidence": 0.95,
"field_confidence": { "invoice_number": 0.99, "total": 0.98 },
"pages_analyzed": 1,
"used_vision": false,
"model_used": "gpt-4o",
"tokens_used": 1523
}

The exact extraction shape is produced by the language model from the schema above; field presence and nesting depend on the source document. Fields that cannot be found are returned as null.

Custom Extraction Schema

Need specific fields? Define your own schema:

{
"tool": "pdf.ai_extract",
"pdfUrl": "https://example.com/document.pdf",
"documentType": "auto",
"customFields": "{\"purchase_order_number\": \"string\", \"shipping_address\": \"string\", \"delivery_date\": \"string\"}",
"openaiApiKey": "sk-..."
}

All Available Tools

AI Extraction

ToolDescriptionRequired Parameters
pdf.ai_extractExtract structured data using GPT-4opdfUrl or pdfBase64, openaiApiKey

Document Info

ToolDescriptionRequired Parameters
pdf.openLoad and validate a PDFpdfUrl or pdfBase64
pdf.get_metadataGet title, author, page count, creation datepdfUrl or pdfBase64
pdf.extract_textExtract all text contentpdfUrl or pdfBase64

Page Operations

ToolDescriptionRequired Parameters
pdf.render_pagesConvert pages to PNG/JPEG imagespdfUrl or pdfBase64
pdf.extract_pagesExtract specific pages to new PDFpdfUrl or pdfBase64, pages
pdf.splitSplit into multiple PDFs by rangespdfUrl or pdfBase64, ranges
pdf.mergeCombine multiple PDFsurls

Form Operations

ToolDescriptionRequired Parameters
pdf.list_form_fieldsList all fillable fieldspdfUrl or pdfBase64
pdf.fill_form_fieldsFill form with valuespdfUrl or pdfBase64, formFields
pdf.flatten_formMake form fields permanentpdfUrl or pdfBase64

PDF Creation

ToolDescriptionRequired Parameters
pdf.create_from_htmlGenerate PDF from HTMLhtml or htmlUrl

Input Examples

Get Document Metadata

{
"tool": "pdf.get_metadata",
"pdfUrl": "https://example.com/document.pdf"
}

Output:

{
"status": "ok",
"errors": [],
"warnings": [],
"artifacts": [],
"metadata": {
"doc_id": "a1b2c3d4e5f6",
"page_count": 45,
"title": "Annual Report 2024",
"author": "Finance Team",
"subject": null,
"creator": "Microsoft Word",
"producer": "Adobe PDF Library",
"creation_date": "2024-01-01T00:00:00.000Z",
"modification_date": null,
"file_size_bytes": 245678,
"pages": [{ "number": 1, "width": 612, "height": 792 }]
}
}

Note: pdf.extract_text returns full-document text (per-page slicing is not supported by the underlying pdf-parse library — the pages value is echoed back but the full text is returned).

Extract Text from Specific Pages

{
"tool": "pdf.extract_text",
"pdfUrl": "https://example.com/document.pdf",
"pages": "1,2,3"
}

Create PDF from HTML

{
"tool": "pdf.create_from_html",
"html": "<html><body><h1>Report</h1><p>Generated content here.</p></body></html>",
"pdfFormat": "A4"
}

Merge Multiple PDFs

{
"tool": "pdf.merge",
"urls": "[\"https://example.com/doc1.pdf\", \"https://example.com/doc2.pdf\"]"
}

Split PDF into Parts

{
"tool": "pdf.split",
"pdfUrl": "https://example.com/large-document.pdf",
"ranges": "[{\"start\":1,\"end\":10},{\"start\":11,\"end\":20}]"
}

Fill Form Fields

{
"tool": "pdf.fill_form_fields",
"pdfUrl": "https://example.com/tax-form.pdf",
"formFields": "{\"name\": \"John Doe\", \"ssn\": \"123-45-6789\", \"date\": \"2024-01-15\"}"
}

Render Pages as Images

{
"tool": "pdf.render_pages",
"pdfUrl": "https://example.com/document.pdf",
"pages": "1",
"renderDpi": 150,
"renderFormat": "png"
}

Use Cases

Invoice Processing Automation

Extract vendor details, line items, and totals from invoices for automatic data entry into accounting systems.

Resume Parsing for HR

Convert PDF resumes into structured candidate data with work history, education, and skills for ATS integration.

Tax Document Processing

Automatically extract W-2 and 1099 data for tax preparation software or audit workflows.

Contract Analysis

Pull key terms, dates, and party information from contracts for review and compliance tracking.

Bank Statement Reconciliation

Extract transactions from bank statements for financial reconciliation and expense tracking.

Report Generation

Create professional PDFs from HTML templates for automated report distribution.

Form Automation

Programmatically fill tax forms, applications, and other fillable PDFs.


Technical Specifications

Limits

ParameterValue
Maximum file size50 MB (enforced)
Maximum pages500 pages (enforced)
AI extraction limit10 pages per request (enforced)
Default render DPI150

Supported Formats

  • Input: PDF (via pdfUrl or pdfBase64)
  • Output: JSON records (dataset) plus generated PDFs / PNG / JPEG / JSON artifacts (key-value store)
  • PDFs: standard, non-encrypted PDF files (encrypted / password-protected PDFs are rejected with ENCRYPTED_PDF)

Built With

  • pdf-lib — metadata, forms (list/fill/flatten), merge, split, extract pages, page geometry
  • pdf-parse — text-layer extraction (no OCR)
  • playwright (headless Chromium) — HTML→PDF generation and page rendering to PNG/JPEG
  • OpenAI Chat Completions API — pdf.ai_extract (gpt-4o / gpt-4o-mini / gpt-4-turbo), text and vision
  • Runs on the apify/actor-node-playwright-chrome base image; artifacts are held in memory and written to the Apify key-value store

Limitations

  • No OCR in pdf.extract_text. Scanned PDFs with no text layer return a NO_TEXT_LAYER warning and empty text. To read scanned documents, use pdf.ai_extract, which renders pages and falls back to GPT-4o vision (requires an OpenAI API key).
  • Encrypted / password-protected PDFs are not supported. They are rejected with ENCRYPTED_PDF. (The Apify input schema exposes no password field.)
  • Hard limits: 50 MB max file size and 500 max pages (rejected with TOO_LARGE); pdf.ai_extract processes at most 10 pages per request.
  • pdf.extract_text returns whole-document text, not per-page slices — pdf-parse does not support page ranges, so the pages value is echoed but the full text is returned.
  • Rendering fidelity: pages are rendered by screenshotting an embedded PDF in headless Chromium, not by a native PDF rasterizer, so output is a visual approximation. The renderDpi value is a scale hint and is not hard-capped in code.
  • AI extraction requires your own OpenAI API key and network access to api.openai.com; the output shape is model-generated and may vary by document. A transient OpenAI outage is returned as an AI_ERROR response (the run does not hard-fail).
  • State is per run. Documents and artifacts live in memory for a single Actor run — doc_id values cannot be reused across runs, and the Apify input does not expose doc_id/docIds for chaining. Each run executes exactly one tool.
  • MCP transport: the Actor is consumed over Apify's hosted MCP endpoint (https://mcp.apify.com) via an MCP-capable client and an Apify token; there is no self-hosted stdio/SSE MCP endpoint in this package. The bundled Express server (server/index.js) is a local REST/dev harness and is not the deployed entry point (the Docker image runs server/main.js).

Pricing

  • PDF operations (open, metadata, text, render, merge, split, extract, forms, HTML→PDF): billed as standard Apify platform usage (compute + storage) for the run. There are no per-document fees added by this actor.
  • AI extraction (pdf.ai_extract): you supply your own OpenAI API key and are billed directly by OpenAI according to their current pricing for the model you choose. This actor does not mark up or resell tokens.

MCP Integration

This actor is designed for the Model Context Protocol (MCP). Connect it to any MCP-compatible client.

Claude Desktop

Add to claude_desktop_config.json (typically at %APPDATA%\Claude\ on Windows or ~/Library/Application Support/Claude/ on macOS):

{
"mcpServers": {
"pdf": {
"url": "https://mcp.apify.com?actors=constant_quadruped/pdf-mcp-server"
}
}
}

Restart Claude Desktop to load the MCP server.

VS Code with Continue/Cline

Configure your MCP extension to use:

https://mcp.apify.com?actors=constant_quadruped/pdf-mcp-server

Other MCP Clients

Any client supporting MCP over HTTP can connect using the URL above.


Error Handling

All tools return a consistent response envelope. Errors are reported in an errors array of { code, message } objects (not a single string):

{
"status": "error",
"errors": [{ "code": "TOO_LARGE", "message": "File exceeds 50MB limit" }],
"warnings": [],
"artifacts": []
}

Common error codes (from the source):

  • INVALID_INPUT — missing/malformed parameters (e.g. no pdfUrl/pdfBase64)
  • FILE_NOT_FOUND — URL could not be fetched
  • MALFORMED_PDF — file is not a valid PDF
  • ENCRYPTED_PDF — PDF is encrypted / password-protected (not supported)
  • PAGE_OUT_OF_RANGE — requested page does not exist
  • TOO_LARGE — PDF exceeds the 50 MB / 500-page limit
  • NO_API_KEY — openaiApiKey missing for pdf.ai_extract
  • AI_ERROR — the OpenAI request failed (e.g. bad key or provider outage)
  • BROWSER_ERROR — Chromium/Playwright failed (rendering or HTML→PDF)
  • INTERNAL_ERROR — unexpected server error

NO_TEXT_LAYER is returned as a warning (not an error) by pdf.extract_text when a PDF has no selectable text — OCR is not attempted.


Support

For issues, feature requests, or questions:

  • Open a ticket on the Issues tab
  • Check existing issues for solutions

Changelog

v1.1

  • Added AI document extraction with GPT-4o vision
  • Support for W-2, 1099, and bank statement extraction
  • Custom extraction schema support
  • Improved error messages

v1.0

  • Initial release
  • PDF operations: merge, split, extract, render
  • Form handling: list, fill, flatten
  • HTML to PDF conversion