# Pdf Toolkit Mcp

> Unofficial PDF toolkit (merge/split/compress/OCR/convert/watermark/protect/...) via iLoveAPI.

- **Type:** MCP server
- **Install:** `agentstack add mcp-eigencharlie-pdf-toolkit-mcp`
- **Verified:** Pending review
- **Seller:** [EigenCharlie](https://agentstack.voostack.com/s/eigencharlie)
- **Installs:** 0
- **Latest version:** 0.1.2
- **License:** MIT
- **Upstream author:** [EigenCharlie](https://github.com/EigenCharlie)
- **Source:** https://github.com/EigenCharlie/pdf-toolkit-mcp
- **Website:** https://github.com/EigenCharlie/pdf-toolkit-mcp

## Install

```sh
agentstack add mcp-eigencharlie-pdf-toolkit-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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](https://www.iloveapi.com) 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](https://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)

```bash
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):

```jsonc
{
  "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

```bash
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](https://github.com/EigenCharlie/pdf-toolkit-mcp/releases/latest) 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](https://registry.modelcontextprotocol.io) 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.

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`](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](https://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.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

```bash
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](https://github.com/EigenCharlie)
- **Source:** [EigenCharlie/pdf-toolkit-mcp](https://github.com/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.

## Pricing

- **Free** — Free

## Versions

- **0.1.2** — security scan: pending review — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-eigencharlie-pdf-toolkit-mcp
- Seller: https://agentstack.voostack.com/s/eigencharlie
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
