Install
$ agentstack add mcp-eigencharlie-pdf-toolkit-mcp Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
About
pdf-toolkit-mcp
18 PDF operations for Claude Code, Claude Desktop, and any MCP client — via iLoveAPI.
[](https://www.npmjs.com/package/pdf-toolkit-mcp) [](https://www.npmjs.com/package/pdf-toolkit-mcp) [](./LICENSE) [](https://nodejs.org) [](https://www.typescriptlang.org) [](https://modelcontextprotocol.io) [](https://docs.claude.com/claude-code) [](https://github.com/EigenCharlie/pdf-toolkit-mcp/actions)
[Install](#-install) · [Tools](#-tool-catalog) · [Recipes](#-workflow-recipes) · [Architecture](#-architecture) · [Security](#-security-model) · [FAQ](#-faq)
> Disclaimer. pdf-toolkit-mcp is an independent, community-built open-source client. It is not affiliated with, endorsed, sponsored, or certified by iLovePDF SL. The project talks to the public iLoveAPI REST service using your project credentials — nothing is proxied, resold, or relicensed. "iLovePDF" and "iLoveAPI" are trademarks of iLovePDF SL; this project does not claim ownership of those marks.
📖 Table of contents
- [Why pdf-toolkit-mcp](#-why-pdf-toolkit-mcp)
- [Quick tour](#-quick-tour)
- [Install](#-install)
- [Tool catalog](#-tool-catalog)
- [Workflow recipes](#-workflow-recipes)
- [Architecture](#-architecture)
- [Configuration reference](#-configuration-reference)
- [Security model](#-security-model)
- [Development](#-development)
- [Testing & CI](#-testing--ci)
- [Releasing](#-releasing)
- [Roadmap](#-roadmap)
- [FAQ](#-faq)
- [Contributing](#-contributing)
- [License & trademarks](#-license--trademarks)
- [Credits](#-credits)
🎯 Why pdf-toolkit-mcp
| | Manual iLoveAPI | Raw @ilovepdf/ilovepdf-nodejs | pdf-toolkit-mcp | | --- | :---: | :---: | :---: | | Callable from Claude Code / Claude Desktop / any MCP client | ❌ | ❌ | ✅ | | JWT signing + 5-step lifecycle handled for you | ❌ | ✅ | ✅ | | Validated Zod schemas (no bad inputs reach the API) | ❌ | ❌ | ✅ | | Path sandboxing against traversal | ❌ | ❌ | ✅ | | Structured error codes (RATE_LIMITED, PLAN_LIMIT, …) | ❌ | partial | ✅ | | Progress notifications during long OCR tasks | ❌ | ❌ | ✅ | | Bundled Claude Code skill with multi-step pipelines | ❌ | ❌ | ✅ | | Zero-setup install via npx -y | ❌ | ❌ | ✅ |
Free for personal use. iLoveAPI's free tier grants ~2,500 credits / month; this MCP itself is MIT-licensed and costs nothing.
🚀 Quick tour
After installation, just talk to Claude. The model figures out which tools to call:
You: Merge invoice-jan.pdf and invoice-feb.pdf into Q1.pdf, then compress it hard
and lock it with the password "2026q1".
Claude (planning):
1. merge_pdf → invoice-jan.pdf + invoice-feb.pdf → Q1.pdf
2. compress_pdf → Q1.pdf → Q1-compressed.pdf (level: extreme)
3. protect_pdf → Q1-compressed.pdf → Q1-compressed-protected.pdf
Claude (result):
✅ Created ~/docs/Q1-compressed-protected.pdf (312 KB, password-protected).
📦 Install
Prerequisites
- Node.js ≥ 18 (LTS recommended).
- iLoveAPI project keys — free tier at developer.ilovepdf.com. Takes ~2 minutes:
- Sign up → create a project → copy
Project public keyandProject secret key. - Export them (or drop them into your client's MCP config — examples below).
Option A — Claude Code (CLI one-liner)
export ILOVEAPI_PROJECT_PUBLIC_KEY="project_public_xxx"
export ILOVEAPI_PROJECT_SECRET_KEY="secret_key_xxx"
claude mcp add pdf-toolkit -- npx -y pdf-toolkit-mcp
Restart Claude Code and all 18 tools appear in the picker. Verify with /mcp → you should see pdf-toolkit: connected (18 tools).
Option B — Claude Code Plugin (includes the pdf-workflow skill)
/plugin marketplace add EigenCharlie/pdf-toolkit-mcp
/plugin install pdf-toolkit@EigenCharlie/pdf-toolkit-mcp
The plugin auto-configures the MCP server and installs a skill that teaches Claude five canonical multi-step PDF pipelines (see [Workflow recipes](#-workflow-recipes)).
Option C — Claude Desktop (claude_desktop_config.json)
Click to expand
Edit claude_desktop_config.json (%APPDATA%\Claude\ on Windows, ~/Library/Application Support/Claude/ on macOS):
{
"mcpServers": {
"pdf-toolkit": {
"command": "npx",
"args": ["-y", "pdf-toolkit-mcp"],
"env": {
"ILOVEAPI_PROJECT_PUBLIC_KEY": "project_public_xxx",
"ILOVEAPI_PROJECT_SECRET_KEY": "secret_key_xxx"
}
}
}
}
Restart Claude Desktop — the 🔌 icon should show pdf-toolkit connected.
Option D — any MCP client via stdio
ILOVEAPI_PROJECT_PUBLIC_KEY=… ILOVEAPI_PROJECT_SECRET_KEY=… npx -y pdf-toolkit-mcp
The server speaks the standard MCP JSON-RPC 2.0 framing over stdio. Wire it into Cursor, Windsurf, mcphub, mcp-inspector, or anything else that speaks MCP.
Option E — Claude Desktop .mcpb bundle (drag-and-drop)
Grab pdf-toolkit-mcp-.mcpb from the latest GitHub Release and drag it into Claude Desktop → Settings → Extensions. Claude will prompt for your iLoveAPI keys via the user_config section of the bundled manifest. No npx, no Node, no terminal.
> Bundles ship unsigned (no publisher certificate yet). macOS Gatekeeper / Windows SmartScreen may warn on first install; verify the SHA-256 in the release notes before accepting.
Option F — MCP Registry (auto-discovered by compatible clients)
The server is indexed on the official MCP Registry under io.github.EigenCharlie/pdf-toolkit-mcp. Clients that browse the registry (Claude Desktop extension pane, VS Code MCP picker, mcphub, etc.) can install it without any manual config — they'll point at the npm package and prompt for the two iLoveAPI env vars automatically.
🧰 Tool catalog
All 18 tools are exposed with strict Zod schemas, additionalProperties: false, and return both a text summary and a file:// resource URI so the client can surface the output.
📚 Organize
| Tool | What it does | Key inputs | | --- | --- | --- | | merge_pdf | Combine ≥ 2 PDFs in order | input_files[], output_path? | | split_pdf | Split by page ranges ("1-3,5-7") or fixed chunk size | input_file, ranges?, fixed_range? | | extract_pdf_pages | Keep a specific subset of pages | input_file, pages ("1,3,5-9") |
🔄 Convert — from PDF
| Tool | Output | Notes | | --- | --- | --- | | pdf_to_word | .docx | Scanned PDFs → run ocr_pdf first for best results | | pdf_to_excel | .xlsx | Works best on tabular source PDFs | | pdf_to_powerpoint | .pptx | One slide per PDF page | | pdf_to_jpg | .zip of .jpg | mode: "pages" renders pages; "extract" pulls embedded images |
🔄 Convert — to PDF
| Tool | Accepts | Notes | | --- | --- | --- | | office_to_pdf | .doc, .docx, .xls, .xlsx, .ppt, .pptx | Server-side rendering | | html_to_pdf | .html, .htm | Local HTML only; external assets may not resolve | | image_to_pdf | .jpg, .jpeg, .png | One image per page, preserves order |
✏️ Edit
| Tool | What it does | Key inputs | | --- | --- | --- | | rotate_pdf | Rotate pages 90 / 180 / 270° clockwise | rotation, pages? (default: all) | | add_page_numbers | Stamp numbered footer/header | starting_number, vertical_position, horizontal_position | | add_watermark | Text or image watermark | mode: "text" + text, OR mode: "image" + image_file |
🔐 Security
| Tool | What it does | Key inputs | | --- | --- | --- | | unlock_pdf | Remove known password | input_file, password | | protect_pdf | Add password | input_file, password |
🩹 Repair / OCR
| Tool | What it does | Notes | | --- | --- | --- | | repair_pdf | Attempt structural repair on damaged PDFs | Useful before further processing | | ocr_pdf | Run OCR to make scans searchable | languages[] (e.g. ["eng"], ["spa"], ["eng","spa"]). ⏱ Can exceed 60s on image-heavy PDFs |
> All tools accept absolute or CWD-relative paths for input_file(s) and an optional output_path (file or directory). Defaults place the result next to the first input with a timestamped name.
🍳 Workflow recipes
The bundled pdf-workflow skill ([skills/pdf-workflow/SKILL.md](skills/pdf-workflow/SKILL.md)) teaches Claude five canonical multi-step pipelines. You can also run these manually — just describe the end state and Claude chains the tools for you.
- Assemble — merge + compress + (optional) protect
merge_pdf([a.pdf, b.pdf, c.pdf])
→ compress_pdf(level="recommended")
→ protect_pdf(password="…")
- Convert & secure — Office doc to locked PDF
office_to_pdf(report.docx)
→ add_watermark(mode="text", text="CONFIDENTIAL", opacity=30)
→ protect_pdf(password="…")
- Extract & OCR — pull pages out of a scan and make them editable
extract_pdf_pages(scan.pdf, pages="3-9")
→ ocr_pdf(languages=["eng"])
→ pdf_to_word
- Prep for email — shrink + lock
compress_pdf(big.pdf, level="extreme")
→ protect_pdf(password="…")
- Scan cleanup — repair + OCR + number
repair_pdf(scan_broken.pdf)
→ ocr_pdf(languages=["eng"])
→ add_page_numbers(position="bottom-center")
🏛 Architecture
┌────────────────────────────┐ stdio ┌──────────────────────────┐
│ Claude Code / Desktop │◀───────────▶│ pdf-toolkit-mcp server │
│ (or any MCP client) │ JSON-RPC │ (this repo) │
└────────────────────────────┘ └────────────┬─────────────┘
│
▼
┌──────────────────────┐
│ @ilovepdf/ │
│ ilovepdf-nodejs │
│ (JWT + HTTP) │
└──────────┬───────────┘
│
▼ HTTPS
┌──────────────────────┐
│ iLoveAPI servers │
│ api.ilovepdf.com │
└──────────────────────┘
iLoveAPI 5-phase lifecycle (orchestrated in [src/api/tasks.ts](src/api/tasks.ts))
[ 10% ] start → POST /v1/start/{tool} (server assignment + task id)
[ 40% ] upload → POST /v1/upload (one call per file, progress scales)
[ 50% ] process → POST /v1/process (run the tool with params)
[ 90% ] download → GET /v1/download/{task} (bytes → Buffer)
[100% ] done → write to disk, emit file:// resource URI
The server emits MCP notifications/progress at each boundary so your client can render a live progress bar for slow operations (OCR, large merges).
Project layout
pdf-toolkit-mcp/
├── .claude-plugin/
│ ├── plugin.json # Plugin manifest
│ └── .mcp.json # MCP server config (npx -y pdf-toolkit-mcp)
├── skills/
│ └── pdf-workflow/
│ └── SKILL.md # 5-recipe skill for multi-step pipelines
├── src/
│ ├── index.ts # #!/usr/bin/env node shebang
│ ├── server.ts # MCP stdio bootstrap
│ ├── api/
│ │ ├── client.ts # iLoveAPI client singleton (CJS interop via createRequire)
│ │ ├── tasks.ts # 5-phase lifecycle orchestrator
│ │ ├── errors.ts # HTTP → structured PdfToolkitError mapping
│ │ └── types.ts # Types + error class
│ ├── tools/ # 18 tools, one file per concern
│ │ ├── _shared.ts # Zod fragments + writeOutputAndReport helper
│ │ ├── merge.ts split.ts compress.ts
│ │ ├── convertFromPdf.ts convertToPdf.ts
│ │ ├── pageOps.ts security.ts watermark.ts
│ │ ├── repair.ts ocr.ts
│ │ └── index.ts # allTools[] barrel
│ └── util/
│ ├── paths.ts # resolveInputs/resolveOutput + sandbox enforcement
│ ├── progress.ts # Progress adapter
│ └── logger.ts # stderr-only logger (stdio-safe)
├── tests/
│ ├── unit/ # client, paths, errors, tools.merge (25 tests)
│ └── integration/ # smoke.test.ts — gated on iLoveAPI creds
├── scripts/
│ └── inspector.sh # npm run inspect → MCP Inspector UI
└── .github/workflows/
├── ci.yml # ubuntu+windows × node 18/20/22
└── publish.yml # Publishes to npm on v* tags with --provenance
⚙️ Configuration reference
Environment variables
| Variable | Required | Default | Description | | --- | :---: | --- | --- | | ILOVEAPI_PROJECT_PUBLIC_KEY | ✅ | — | Project public key from developer.ilovepdf.com | | ILOVEAPI_PROJECT_SECRET_KEY | ✅ | — | Project secret key. Never logged. Used for local JWT signing. | | ILOVEAPI_SANDBOX_ROOT | ❌ | — | Absolute path. When set, all input/output paths must resolve inside this directory — traversal attempts throw PATH_TRAVERSAL. | | PDF_TOOLKIT_DEBUG | ❌ | — | Set to 1 to emit verbose stderr logs (request shape, phase timings). Secrets never logged. |
Structured error codes
Every failure surfaces a PdfToolkitError with a stable machine-readable code:
| Code | Trigger | What to tell the user | | --- | --- | --- | | MISSING_CREDENTIALS | Env vars not set | Point them at developer.ilovepdf.com | | INVALID_INPUT | HTTP 400 / Zod parse failure | Fix the arguments | | AUTH_FAILED | HTTP 401 | Regenerate the project keys | | PLAN_LIMIT | HTTP 402 | Free tier exhausted or tool not in plan | | NOT_FOUND | HTTP 404 | Input file or task missing | | RATE_LIMITED | HTTP 429 | Back off and retry | | TASK_LIMIT | SDK TaskLimit error | Too many concurrent tasks | | PATH_TRAVERSAL | Path escapes ILOVEAPI_SANDBOX_ROOT | Reject the request | | API_ERROR | Unmapped iLoveAPI error | Check data.http_status + data.iloveapi_code |
🔒 Security model
pdf-toolkit-mcp is designed to be safe to install on a developer machine:
- Stdio only. The server never opens a network socket; it only makes outbound HTTPS calls to
api.ilovepdf.comvia the official SDK. - No
console.log. JSON-RPC over stdio would corrupt on any stray stdout write, so every log line goes throughprocess.stderr. - Secrets never persisted. Credentials live in env vars for the lifetime of the process and are never written to disk, log files, or tool responses.
- JWT generated locally. The
@ilovepdf/ilovepdf-nodejsSDK self-signs JWTs with your secret key — no secret leaves the machine. - Path sandbox (opt-in). Set
ILOVEAPI_SANDBOX_ROOTto constrain the server to a single directory tree; any path resolving outside throws before the API is ever called. - Extension whitelists per tool.
html_to_pdfrejects.exe;image_to_pdfonly accepts common raster formats, etc. - MIT licensed, audit-friendly. ~2k lines of TypeScript. No obfuscation, no minification, no postinstall scripts.
👩💻 Development
git clone https://github.com/EigenCharlie/pdf-toolkit-mcp.git
cd pdf-toolkit-mcp
npm install
Common tasks
| Command | What it does | | --- | --- | | npm run build | Compile TypeScript → dist/ | | npm run dev | Watch-mode build | | npm run typecheck | tsc --noEmit — fast error surface | | npm run lint | ESLint on src/ + tests/ | | npm test | Vitest unit suite (no network) | | npm run test:integration | Real iLoveAPI calls (requires creds) | | npm run inspect | Launch [MCP I
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: EigenCharlie
- Source: EigenCharlie/pdf-toolkit-mcp
- License: MIT
- Homepage: https://github.com/EigenCharlie/pdf-toolkit-mcp
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.2 Imported from the upstream source.