PDF MCP Server
Pricing
Pay per usage
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
Maintained by CommunityActor stats
0
Bookmarked
14
Total users
2
Monthly active users
8 days ago
Last modified
Categories
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
| Category | Capabilities |
|---|---|
| AI Extraction | OpenAI models (default GPT-4o) extract structured JSON; text layer first, GPT-4o vision fallback for scans |
| Document Types | Invoices, receipts, contracts, resumes, W-2, 1099, bank statements |
| PDF Operations | Merge, split, extract pages, create from HTML |
| Form Handling | List fields, fill forms, flatten |
| Rendering | Convert pages to PNG/JPEG images |
| Input Flexibility | URL 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
| Type | What Gets Extracted |
|---|---|
invoice | Invoice number, dates, vendor info, customer info, line items with quantities/prices, subtotal, tax, total |
receipt | Merchant name, date/time, itemized purchases, subtotal, tax, total, payment method |
contract | Party names, effective dates, termination date, key terms, obligations, signatures |
resume | Name, contact info, work experience with dates, education, skills, certifications |
w2 | Employer EIN/name/address, employee SSN/name/address, wages, federal/state tax withheld |
form_1099 | Payer info, recipient info, amounts by box, form type (MISC, NEC, INT, DIV) |
bank_statement | Account number, statement period, opening/closing balance, all transactions |
auto | Auto-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
extractionshape 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 asnull.
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
| Tool | Description | Required Parameters |
|---|---|---|
pdf.ai_extract | Extract structured data using GPT-4o | pdfUrl or pdfBase64, openaiApiKey |
Document Info
| Tool | Description | Required Parameters |
|---|---|---|
pdf.open | Load and validate a PDF | pdfUrl or pdfBase64 |
pdf.get_metadata | Get title, author, page count, creation date | pdfUrl or pdfBase64 |
pdf.extract_text | Extract all text content | pdfUrl or pdfBase64 |
Page Operations
| Tool | Description | Required Parameters |
|---|---|---|
pdf.render_pages | Convert pages to PNG/JPEG images | pdfUrl or pdfBase64 |
pdf.extract_pages | Extract specific pages to new PDF | pdfUrl or pdfBase64, pages |
pdf.split | Split into multiple PDFs by ranges | pdfUrl or pdfBase64, ranges |
pdf.merge | Combine multiple PDFs | urls |
Form Operations
| Tool | Description | Required Parameters |
|---|---|---|
pdf.list_form_fields | List all fillable fields | pdfUrl or pdfBase64 |
pdf.fill_form_fields | Fill form with values | pdfUrl or pdfBase64, formFields |
pdf.flatten_form | Make form fields permanent | pdfUrl or pdfBase64 |
PDF Creation
| Tool | Description | Required Parameters |
|---|---|---|
pdf.create_from_html | Generate PDF from HTML | html 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_textreturns full-document text (per-page slicing is not supported by the underlyingpdf-parselibrary — thepagesvalue 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
| Parameter | Value |
|---|---|
| Maximum file size | 50 MB (enforced) |
| Maximum pages | 500 pages (enforced) |
| AI extraction limit | 10 pages per request (enforced) |
| Default render DPI | 150 |
Supported Formats
- Input: PDF (via
pdfUrlorpdfBase64) - 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 geometrypdf-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-chromebase 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 aNO_TEXT_LAYERwarning and empty text. To read scanned documents, usepdf.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_extractprocesses at most 10 pages per request. pdf.extract_textreturns whole-document text, not per-page slices —pdf-parsedoes not support page ranges, so thepagesvalue 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
renderDpivalue 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 anAI_ERRORresponse (the run does not hard-fail). - State is per run. Documents and artifacts live in memory for a single Actor run —
doc_idvalues cannot be reused across runs, and the Apify input does not exposedoc_id/docIdsfor chaining. Each run executes exactly onetool. - 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 runsserver/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. nopdfUrl/pdfBase64)FILE_NOT_FOUND— URL could not be fetchedMALFORMED_PDF— file is not a valid PDFENCRYPTED_PDF— PDF is encrypted / password-protected (not supported)PAGE_OUT_OF_RANGE— requested page does not existTOO_LARGE— PDF exceeds the 50 MB / 500-page limitNO_API_KEY—openaiApiKeymissing forpdf.ai_extractAI_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