Install
$ agentstack add mcp-paradyno-pdf-mcp-server ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
📄 PDF MCP Server
A high-performance MCP server for PDF processing, built in Rust.
[](https://opensource.org/licenses/Apache-2.0) [](https://github.com/paradyno/pdf-mcp-server/actions/workflows/ci.yml) [](https://codecov.io/gh/paradyno/pdf-mcp-server)
Give your AI agents powerful PDF capabilities — extract text, search, split, merge, encrypt, and more. All dependencies are Apache 2.0 licensed, keeping your project clean and permissive.
✨ Features
| Category | Tools | |----------|-------| | 📖 Reading | extract_text · extract_metadata · extract_outline · extract_annotations · extract_links · extract_form_fields | | 🔍 Search & Discovery | search · list_pdfs · get_page_info · summarize_structure | | 🖼️ Media | Image extraction (via extract_text) · convert_page_to_image | | ✂️ Manipulation | split_pdf · merge_pdfs · compress_pdf · fill_form | | 🔒 Security | protect_pdf · unprotect_pdf · Password-protected PDF support · Path sandboxing · SSRF protection | | 📦 Resources | Expose PDFs as MCP Resources for direct client access | | ⚡ Performance | Batch processing · LRU caching (with byte budget) · Operation chaining via cache keys |
🚀 Installation
npm (Recommended)
npm install -g @paradyno/pdf-mcp-server
Pre-built Binaries
Download from GitHub Releases:
| Platform | x86_64 | ARM64 | |----------|--------|-------| | 🐧 Linux | pdf-mcp-server-linux-x64 | pdf-mcp-server-linux-arm64 | | 🍎 macOS | pdf-mcp-server-darwin-x64 | pdf-mcp-server-darwin-arm64 | | 🪟 Windows | pdf-mcp-server-windows-x64.exe | — |
From Source
cargo install --git https://github.com/paradyno/pdf-mcp-server
⚙️ Configuration
Claude Desktop
Add to your claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"pdf": {
"command": "npx",
"args": ["@paradyno/pdf-mcp-server"]
}
}
}
Claude Code
claude mcp add pdf -- npx @paradyno/pdf-mcp-server
VS Code
{
"mcp.servers": {
"pdf": {
"command": "npx",
"args": ["@paradyno/pdf-mcp-server"]
}
}
}
🛠️ Tools
Source Types
All tools accept PDF sources in multiple formats:
{ "path": "/documents/file.pdf" }
{ "base64": "JVBERi0xLjQK..." }
{ "url": "https://example.com/document.pdf" }
{ "cache_key": "abc123" }
📖 extract_text
Extract text content with LLM-optimized formatting (paragraph detection, multi-column reordering, watermark removal).
Example & Parameters
{
"sources": [{ "path": "/documents/report.pdf" }],
"pages": "1-10",
"include_metadata": true
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | pages | string | No | all | Page selection (e.g., "1-5,10,15-20") | | include_metadata | boolean | No | true | Include PDF metadata | | include_images | boolean | No | false | Include extracted images (base64 PNG) | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
📖 extract_outline
Extract PDF bookmarks / table of contents.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/book.pdf" }]
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
Response:
{
"results": [{
"source": "/documents/book.pdf",
"outline": [
{
"title": "Chapter 1: Introduction",
"page": 1,
"children": [
{ "title": "1.1 Background", "page": 3, "children": [] }
]
}
]
}]
}
📖 extract_metadata
Extract PDF metadata (author, title, dates, etc.) without loading full content.
Example & Parameters
{
"sources": [{ "path": "/documents/report.pdf" }]
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
📖 extract_annotations
Extract highlights, comments, underlines, and other annotations.
Example & Parameters
{
"sources": [{ "path": "/documents/report.pdf" }],
"annotation_types": ["highlight", "text"],
"pages": "1-5"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | annotation_types | array | No | all | Filter by types (highlight, underline, text, etc.) | | pages | string | No | all | Page selection | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
📖 extract_links
Extract hyperlinks and internal page navigation links.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/paper.pdf" }],
"pages": "1-10"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | pages | string | No | all | Page selection | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
Response:
{
"results": [{
"source": "/documents/paper.pdf",
"links": [
{ "page": 1, "url": "https://example.com", "text": "Click here" },
{ "page": 3, "dest_page": 10, "text": "See Chapter 5" }
],
"total_count": 2
}]
}
📖 extract_form_fields
Read form field names, types, current values, and properties from PDF forms.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/form.pdf" }],
"pages": "1"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | pages | string | No | all | Page selection | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
Response:
{
"results": [{
"source": "/documents/form.pdf",
"fields": [
{
"page": 1,
"name": "full_name",
"field_type": "text",
"value": "John Doe",
"is_read_only": false,
"is_required": true,
"properties": { "is_multiline": false, "is_password": false }
},
{
"page": 1,
"name": "agree_terms",
"field_type": "checkbox",
"is_checked": true,
"is_read_only": false,
"is_required": false,
"properties": {}
}
],
"total_fields": 2
}]
}
🖼️ convert_page_to_image
Render PDF pages as PNG images (base64). Enables Vision LLMs to understand visual layouts, charts, and diagrams.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/chart.pdf" }],
"pages": "1-3",
"width": 1200
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | pages | string | No | all | Page selection | | width | integer | No | 1200 | Target width in pixels | | height | integer | No | — | Target height in pixels | | scale | float | No | — | Scale factor (overrides width/height) | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
Response:
{
"results": [{
"source": "/documents/chart.pdf",
"pages": [
{
"page": 1,
"width": 1200,
"height": 1553,
"data_base64": "iVBORw0KGgo...",
"mime_type": "image/png"
}
]
}]
}
🔍 search
Full-text search within PDFs with surrounding context.
Example & Parameters
{
"sources": [{ "path": "/documents/manual.pdf" }],
"query": "error handling",
"context_chars": 100
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | query | string | Yes | — | Search query | | case_sensitive | boolean | No | false | Case-sensitive search | | max_results | integer | No | 100 | Maximum results to return | | context_chars | integer | No | 50 | Characters of context around match | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
🔍 get_page_info
Get page dimensions, word/char counts, token estimates, and file sizes. Useful for planning LLM context usage.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/report.pdf" }]
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching | | skip_file_sizes | boolean | No | false | Skip file size calculation (faster) |
Response:
{
"results": [{
"source": "/documents/report.pdf",
"pages": [{
"page": 1,
"width": 612.0, "height": 792.0,
"rotation": 0, "orientation": "portrait",
"char_count": 2500, "word_count": 450,
"estimated_token_count": 625,
"file_size": 102400
}],
"total_pages": 10,
"total_chars": 25000,
"total_words": 4500,
"total_estimated_token_count": 6250
}]
}
> Note: Token counts are model-dependent approximations (~4 chars/token for Latin, ~2 tokens/char for CJK). Use as rough guidance only.
🔍 summarize_structure
One-call comprehensive overview of a PDF's structure. Helps LLMs decide how to process a document.
Example, Parameters & Response
{
"sources": [{ "path": "/documents/report.pdf" }]
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources | | password | string | No | — | PDF password if encrypted | | cache | boolean | No | false | Enable caching |
Response:
{
"results": [{
"source": "/documents/report.pdf",
"page_count": 25,
"file_size": 1048576,
"metadata": { "title": "Annual Report", "author": "Acme Corp" },
"has_outline": true,
"outline_items": 12,
"total_chars": 50000,
"total_words": 9000,
"total_estimated_tokens": 12500,
"pages": [
{ "page": 1, "width": 612.0, "height": 792.0, "char_count": 2000, "word_count": 360, "has_images": true, "has_links": false, "has_annotations": false }
],
"total_images": 5,
"total_links": 3,
"total_annotations": 2,
"has_form": false,
"form_field_count": 0,
"form_field_types": {},
"is_encrypted": false
}]
}
🔍 list_pdfs
Discover PDF files in a directory with optional filtering.
Example & Parameters
{
"directory": "/documents",
"recursive": true,
"pattern": "invoice*.pdf"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | directory | string | Yes | — | Directory to search | | recursive | boolean | No | false | Search subdirectories | | pattern | string | No | — | Filename pattern (e.g., "report*.pdf") |
✂️ split_pdf
Extract specific pages from a PDF to create a new PDF.
Example, Parameters & Page Range Syntax
{
"source": { "path": "/documents/book.pdf" },
"pages": "1-10,15,20-z",
"output_path": "/output/excerpt.pdf"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | source | object | Yes | — | PDF source | | pages | string | Yes | — | Page range (see syntax below) | | output_path | string | No | — | Save output to file | | password | string | No | — | PDF password if encrypted |
Page Range Syntax:
| Syntax | Description | |--------|-------------| | 1-5 | Pages 1 through 5 | | 1,3,5 | Specific pages | | z | Last page | | r1 | Last page (reverse) | | 5-z | Page 5 to end | | z-1 | All pages reversed | | 1-z:odd | Odd pages only | | 1-z:even | Even pages only | | 1-10,x5 | Pages 1–10 except page 5 |
✂️ merge_pdfs
Merge multiple PDFs into a single file.
Example & Parameters
{
"sources": [
{ "path": "/documents/chapter1.pdf" },
{ "path": "/documents/chapter2.pdf" }
],
"output_path": "/output/complete-book.pdf"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | sources | array | Yes | — | PDF sources to merge (in order) | | output_path | string | No | — | Save output to file |
✂️ compress_pdf
Reduce PDF file size using stream optimization, object deduplication, and compression.
Example, Parameters & Response
{
"source": { "path": "/documents/large-report.pdf" },
"compression_level": 9,
"output_path": "/output/compressed.pdf"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | source | object | Yes | — | PDF source | | object_streams | string | No | "generate" | "generate" (best) · "preserve" · "disable" | | compression_level | integer | No | 9 | 1–9 (higher = better compression) | | output_path | string | No | — | Save output to file | | password | string | No | — | PDF password if encrypted |
Response:
{
"results": [{
"source": "/documents/large-report.pdf",
"original_size": 5242880,
"compressed_size": 2097152,
"compression_ratio": 0.4,
"bytes_saved": 3145728
}]
}
✂️ fill_form
Write values into existing PDF form fields and produce a new PDF.
Example, Parameters & Limitations
{
"source": { "path": "/documents/form.pdf" },
"field_values": [
{ "name": "full_name", "value": "Jane Smith" },
{ "name": "agree_terms", "checked": true }
],
"output_path": "/output/filled-form.pdf"
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | source | object | Yes | — | PDF source | | field_values | array | Yes | — | Fields to fill (see below) | | output_path | string | No | — | Save output to file | | password | string | No | — | PDF password if encrypted |
Field value format:
| Field | Type | Description | |-------|------|-------------| | name | string | Field name (use extract_form_fields to discover names) | | value | string | Text value (for text fields) | | checked | boolean | Checked state (for checkbox/radio fields) |
Supported field types: Text fields, checkboxes, radio buttons. ComboBox/ListBox selection is read-only.
🔒 protect_pdf
Add password protection using 256-bit AES encryption.
Example & Parameters
{
"source": { "path": "/documents/confidential.pdf" },
"user_password": "secret123",
"allow_print": "none",
"allow_copy": false
}
| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | source | object | Yes | — | PDF source | | user_password | string | Yes | — | Password to open the PDF | | owner_password | string | No | user_password | Password to change permissions | | allow_print | string | No | "full" | "full" · "low" · "none" | | `al
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: paradyno
- Source: paradyno/PDF-MCP-Server
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.