mcpField
P
pdf-toolkit-mcp

pdf-toolkit-mcp

Local
github.comProductivity1Updated 28w ago

About pdf-toolkit-mcp

pdf-toolkit-mcp is an MCP server for PDF processing through iLoveAPI, intended for Claude Code, Claude Desktop, and other MCP clients. It offers 18 operations with input validation, path sandboxing, and progress notifications.

Key features

  1. 01Merge, split, and extract PDF pages
  2. 02Convert PDFs to and from Office and image formats
  3. 03Rotate pages, add page numbers, and apply watermarks
  4. 04OCR, repair, and password protection
  5. 05Validate inputs and restrict file paths
  6. 06Progress notifications and file resource URIs

Use cases

  1. 01Merge files, then compress and protect the result
  2. 02OCR scanned documents before converting them to Word
  3. 03Add watermarks or page numbers to PDFs
  4. 04Convert Office documents or images to PDF

MCP support

The MCP server exposes 18 PDF tools to clients over stdio; results include a summary and a file:// resource URI.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"eigencharlie-pdf-toolkit": {
"command": "npx",
"args": [
"-y",
"pdf-toolkit-mcp"
],
"env": {
"ILOVEAPI_PROJECT_PUBLIC_KEY": "<ILOVEAPI_PROJECT_PUBLIC_KEY>",
"ILOVEAPI_PROJECT_SECRET_KEY": "<ILOVEAPI_PROJECT_SECRET_KEY>",
"ILOVEAPI_SANDBOX_ROOT": "<ILOVEAPI_SANDBOX_ROOT>"
}
}
}
}
Run commandnpx -y pdf-toolkit-mcp
Environment variables to set
ILOVEAPI_PROJECT_PUBLIC_KEYSecretiLoveAPI Project Public Key (from https://developer.ilovepdf.com).
ILOVEAPI_PROJECT_SECRET_KEYSecretiLoveAPI Project Secret Key. Used locally to sign short-lived JWTs.
ILOVEAPI_SANDBOX_ROOTOptional filesystem sandbox: if set, all I/O must stay inside this directory.

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npmpdf-toolkit-mcp0.1.2

Tools

18

Saved tool list · updated 2w ago

ParameterTypeRequiredDescription
input_filesarrayYesTwo or more PDF files to merge, in order.
output_pathstringNoOptional output path. If it ends with the expected extension, the file is written there. If it is a directory, the file is placed inside with a timestamped name. Defaults to the same directory as the first input.

Details

From the project README

pdf-toolkit-mcp

18 PDF operations for Claude Code, Claude Desktop, and any MCP client — via iLoveAPI.

npm version npm downloads License: MIT Node.js TypeScript MCP Claude Code CI

Install · Tools · Recipes · Architecture · Security · 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

Manual iLoveAPIRaw @ilovepdf/ilovepdf-nodejspdf-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:
    1. Sign up → create a project → copy Project public key and Project secret key.
    2. 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).

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-<version>.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
ToolWhat it doesKey inputs
merge_pdfCombine ≥ 2 PDFs in orderinput_files[], output_path?
split_pdfSplit by page ranges ("1-3,5-7") or fixed chunk sizeinput_file, ranges?, fixed_range?
extract_pdf_pagesKeep a specific subset of pagesinput_file, pages ("1,3,5-9")
🔄 Convert — from PDF
ToolOutputNotes
pdf_to_word.docxScanned PDFs → run ocr_pdf first for best results
pdf_to_excel.xlsxWorks best on tabular source PDFs
pdf_to_powerpoint.pptxOne slide per PDF page
pdf_to_jpg.zip of .jpgmode: "pages" renders pages; "extract" pulls embedded images
🔄 Convert — to PDF
ToolAcceptsNotes
office_to_pdf.doc, .docx, .xls, .xlsx, .ppt, .pptxServer-side rendering
html_to_pdf.html, .htmLocal HTML only; external assets may not resolve
image_to_pdf.jpg, .jpeg, .pngOne image per page, preserves order
✏️ Edit
ToolWhat it doesKey inputs
rotate_pdfRotate pages 90 / 180 / 270° clockwiserotation, pages? (default: all)
add_page_numbersStamp numbered footer/headerstarting_number, vertical_position, horizontal_position
add_watermarkText or image watermarkmode: "text" + text, OR mode: "image" + image_file
🔐 Security
ToolWhat it doesKey inputs
unlock_pdfRemove known passwordinput_file, password
protect_pdfAdd passwordinput_file, password
🩹 Repair / OCR
ToolWhat it doesNotes
repair_pdfAttempt structural repair on damaged PDFsUseful before further processing
ocr_pdfRun OCR to make scans searchablelanguages[] (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) 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.

1. Assemble — merge + compress + (optional) protect
merge_pdf([a.pdf, b.pdf, c.pdf])
   → compress_pdf(level="recommended")
   → protect_pdf(password="…")
2. Convert & secure — Office doc to locked PDF
office_to_pdf(report.docx)
   → add_watermark(mode="text", text="CONFIDENTIAL", opacity=30)
   → protect_pdf(password="…")
3. 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
4. Prep for email — shrink + lock
compress_pdf(big.pdf, level="extreme")
   → protect_pdf(password="…")
5. 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)
  [ 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
VariableRequiredDefaultDescription
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:

CodeTriggerWhat to tell the user
MISSING_CREDENTIALSEnv vars not setPoint them at developer.ilovepdf.com
INVALID_INPUTHTTP 400 / Zod parse failureFix the arguments
AUTH_FAILEDHTTP 401Regenerate the project keys
PLAN_LIMITHTTP 402Free tier exhausted or tool not in plan
NOT_FOUNDHTTP 404Input file or task missing
RATE_LIMITEDHTTP 429Back off and retry
TASK_LIMITSDK TaskLimit errorToo many concurrent tasks
PATH_TRAVERSALPath escapes ILOVEAPI_SANDBOX_ROOTReject the request
API_ERRORUnmapped iLoveAPI errorCheck 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.com via the official SDK.
  • No console.log. JSON-RPC over stdio would corrupt on any stray stdout write, so every log line goes through process.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-nodejs SDK self-signs JWTs with your secret key — no secret leaves the machine.
  • Path sandbox (opt-in). Set ILOVEAPI_SANDBOX_ROOT to 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_pdf rejects .exe; image_to_pdf only 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
CommandWhat it does
npm run buildCompile TypeScript → dist/
npm run devWatch-mode build
npm run typechecktsc --noEmit — fast error surface
npm run lintESLint on src/ + tests/
npm testVitest unit suite (no network)
npm run test:integrationReal iLoveAPI calls (requires creds)
npm run inspectLaunch MCP Inspector against the local build
Debugging inside Claude Code
  1. Build locally: npm run build.
  2. Register the local dist instead of npm:
    claude mcp remove pdf-toolkit    # if previously registered
    claude mcp add pdf-toolkit -- node "$(pwd)/dist/index.js"
    
  3. Set PDF_TOOLKIT_DEBUG=1 in your shell before launching Claude Code for verbose stderr.
  4. Stderr is visible with claude mcp logs pdf-toolkit.

✅ Testing & CI

  • Unit tests — 25 tests across client, paths, errors, and tools.merge. Fully mocked, no network. Run with npm test.
  • Integration smoke test — tests/integration/smoke.test.ts spins up two minimal valid PDFs and exercises a real merge_pdf end-to-end. Gated on ILOVEAPI_*_KEY env vars; automatically skipped in PR CI for security.
  • CI matrix — .github/workflows/ci.yml runs lint → typecheck → build → test on:
    • OS: ubuntu-latest, windows-latest
    • Node: 18, 20, 22

🚢 Releasing

Publishing is automated on tag push:

npm version patch           # or minor / major
git push --follow-tags

The publish workflow then:

  1. Re-runs lint + typecheck + build + tests.
  2. Publishes to npm with --access public --provenance (supply-chain attestation).
  3. Creates a GitHub Release with auto-generated notes.

Repo secret required: NPM_TOKEN (npm automation token).


🗺 Roadmap

  • v0.1 — 18 PDF tools, stdio transport, plugin + skill, CI, npm publish
  • v0.1.1 — MCPB bundle (.mcpb) for Claude Desktop, marketplace manifest, MCP Registry submission (mcpName)
  • v0.2 — Submit the Claude plugin to anthropics/claude-plugins-official, publish an image-tools companion pack
  • v0.3 — 8 image tools (resize, convert, compress, crop, rotate, watermark, upscale, remove background)
  • v0.4 — Signature tools (signing flows require paid tier — gated behind env flag)
  • v1.0 — Optional Streamable-HTTP transport for hosted/multi-user setups

Have a feature request? Open an issue.


🙋 FAQ

Is this legal / safe / allowed by iLovePDF? Yes. It's a thin open-source client that uses your credentials — nothing is resold, relicensed, or proxied. The iLoveAPI Terms of Service explicitly permit open-source libraries using user-provided keys (several community SDKs have existed for years). This project does not ship any keys, does not use "iLovePDF"/"iLoveAPI" in its package name, and carries the required disclaimer.

Does it cost money? iLoveAPI offers ~2,500 credits per month free (enough for thousands of small ops). Heavier workloads need a paid iLoveAPI plan. This MCP itself is MIT and free forever.

Does it work offline? No. iLoveAPI is cloud-only, so every tool call requires internet access.

Can I pin a specific version? Yes: claude mcp add pdf-toolkit -- npx -y [email protected].

Can I self-host? Yes. Clone the repo, npm run build, and point your client at node ./dist/index.js. The server is entirely stateless.

What happens if iLoveAPI is down? The tool returns a PdfToolkitError with code: "API_ERROR" and data.http_status. Claude can retry with exponential backoff on your behalf.

Can I use this without Claude? Yes — any MCP-compatible client works: Cursor, Windsurf, Zed, MCP Inspector, custom clients. The server is 100% spec-compliant.


🤝 Contributing

Contributions welcome! Small checklist before opening a PR:

  1. npm run lint && npm run typecheck && npm test → all green.
  2. New tools follow the pattern in src/tools/merge.ts (Zod schema → runTask → writeOutputAndReport).
  3. Add at least one unit test.
  4. Update the Tool catalog in this README if you add/rename a tool.

Bug reports are even more welcome — include the tool name, the arguments, and (if safe to share) the stderr output.


📜 License & trademarks

Released under the MIT License © 2026 Carlos.

"iLovePDF" and "iLoveAPI" are trademarks of iLovePDF SL. This project is an independent, community-built client and is not affiliated with, endorsed by, sponsored by, or certified by iLovePDF SL. The package name intentionally avoids both marks.


🙏 Credits

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.