@utilitly/mcp
A local, offline PDF server that lets an AI inspect and edit PDFs on your own machine, always writing new files instead of changing the originals.
Inspect a PDF (
pdf_info): page count, file size, first-page dimensions, and whether it's password-protected.Merge several PDFs into one, in the order given (
merge_pdfs).Split a PDF into separate files by page ranges like
"1-2, 3-end"(split_pdf).Extract selected pages into a single new PDF (
extract_pages).Rotate all or some pages by a multiple of 90° (
rotate_pdf).Delete pages, as long as at least one remains (
delete_pages).Reorder every page into a new sequence (
reorder_pages).Duplicate pages, after each one or at the end, with a cap of 10,000 added pages (
duplicate_pages).Safety: never overwrites or deletes (collisions become
-2), reads inputs only, requires absolute or~/paths, is confined to the folders given at install, refuses encrypted PDFs, and makes no network calls.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@utilitly/mcpMerge ~/Downloads/march.pdf and ~/Downloads/april.pdf and delete blank page 3."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@utilitly/mcp
A PDF MCP server for Claude, the ChatGPT desktop app, Codex, Gemini CLI, Cursor and any other app that can run a local MCP server. Ask your AI to merge, split, rotate, delete, reorder or duplicate pages, and it does the work with PDF files on your own computer.
The server runs locally, next to the AI app, and edits files where they sit. It's built on Utilitly's open-source PDF engines, ported from the free tools on utilitly.com, and it never replaces a file: every result is a new PDF beside the original.
Install
You need Node.js 22 or newer. The first run downloads the server through npx.
The folders after the package name are the only places the server may read and write. Change them to wherever your PDFs live.
Claude Code
claude mcp add utilitly -- npx -y @utilitly/mcp ~/Documents ~/Downloads ~/DesktopClaude Desktop: open Settings, then Developer, then Edit Config, and add this to claude_desktop_config.json. Restart Claude Desktop afterwards.
{
"mcpServers": {
"utilitly": {
"command": "npx",
"args": ["-y", "@utilitly/mcp", "~/Documents", "~/Downloads", "~/Desktop"]
}
}
}Cursor: put the same mcpServers block in ~/.cursor/mcp.json.
ChatGPT desktop app and Codex share one setup, so adding the server to either one adds it to both. In the ChatGPT app, open Settings, then MCP servers, then Add server. Choose STDIO, enter the command npx with the arguments -y @utilitly/mcp ~/Documents ~/Downloads ~/Desktop, save, and restart. From the Codex CLI:
codex mcp add utilitly -- npx -y @utilitly/mcp ~/Documents ~/Downloads ~/DesktopGemini CLI: everything after -- goes to npx, and -s user makes the server available in every folder you start Gemini in.
gemini mcp add -s user utilitly npx -- -y @utilitly/mcp ~/Documents ~/Downloads ~/DesktopAnything else that can start a local (stdio) MCP server: the command is npx with the arguments -y @utilitly/mcp, followed by the folders.
The server is also listed in the official MCP Registry as com.utilitly/mcp, so apps and directories that read the registry can find it by that name.
About the folder list
The check happens after symlinks are resolved, so a link inside an allowed folder can't lead somewhere else.
Leave the folders out and the server may use any file you can. It still never overwrites or deletes anything, and it never shows the AI what's inside a PDF. But an AI misled by something it read elsewhere could copy any of your PDFs into any folder, so list folders unless you need it everywhere.
Related MCP server: pdf-toolbox-mcp
Try it in 30 seconds
Once it's installed, ask in plain words and use full paths:
"Merge ~/Downloads/march.pdf and ~/Downloads/april.pdf."
"Delete the blank page 3 from ~/Desktop/scan.pdf."
"Split ~/Documents/handbook.pdf into pages 1-12, 13-30 and 31 to the end."
"Pages 2 to 4 of ~/Desktop/scan.pdf are sideways; turn them the right way up."
"How many pages does ~/Documents/contract.pdf have, and is it locked?"
Tools
Tool | What it does | New file it writes |
| Page count, file size, first page size, and whether the PDF is password-protected. Changes nothing. | none |
| Combines PDFs in the order given. |
|
| One file per range, e.g. |
|
| The selected pages as one PDF, in page order. |
|
| Turns pages by a multiple of 90 degrees. |
|
| Removes pages; at least one has to stay. |
|
| Puts every page in a new order. |
|
| Adds copies after each page or at the end. |
|
Results land in the same folder as the input. Every writing tool also takes an optional output_path, and split_pdf an optional output_folder. Page selections read like "2", "1-3, 5" or "4-end".
Problems come back to the AI as a short code and a sentence it can act on, such as NO_PAGES: "9" doesn't match any page. The PDF has 4 pages. or ENCRYPTED: File 2 is password-protected. Remove the password first, then try again.
What it can and can't touch
It never overwrites. If
report-merged.pdfalready exists, the result becomesreport-merged-2.pdf, and anoutput_paththat already exists is refused.Input files are only read, never changed.
Paths must be absolute or start with
~/, so the AI can't stumble into the wrong folder through a relative path.With folders listed at install, nothing outside them can be read or written.
Password-protected PDFs are refused rather than altered.
pdf_inforeports when a file is locked.One call can add at most 10,000 pages beyond what its input files hold, and one split writes at most 1,000 files (or one per page for longer PDFs). A mistaken request, like a hundred million copies, is refused before anything is built.
Why nothing is uploaded
The PDF work happens inside this server, on your machine, with no network code anywhere in it. test/network.test.ts proves that on every change: it makes opening a connection, looking up a host name and calling fetch all throw, then runs every tool, and they all succeed.
Your AI app still talks to its model as usual. That conversation includes whatever you type, file paths included, and each tool's short reply: the paths it wrote, page counts and file sizes. This server never puts the contents of a PDF into the conversation.
Good to know
merge_pdfs,split_pdf,extract_pages,delete_pages,reorder_pagesandduplicate_pagesbuild fresh PDFs, so bookmarks, document properties and working form fields aren't carried into the result.rotate_pdfkeeps the whole document.Images and fonts shared between pages stay shared, so results don't balloon in size.
To check what's running,
npx -y @utilitly/mcp --versionprints the version and--helpthe usage.
License
MIT. Built on the @utilitly PDF engines and pdf-lib (both MIT), and the official MCP TypeScript SDK (Apache-2.0).
Available Tools
8 toolsdelete_pagesDelete pagesA
Removes the selected pages and keeps the rest in order, named with -trimmed. At least one page must remain. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| pages | Yes | Pages to remove, such as "2", "1-3, 5" or "4-end". Commas separate parts. | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Explains that the result is written as a new file next to the input (or to output_path), that it never replaces an existing file, and that the input is left unchanged — this directly explains why destructiveHint=false despite a mutation, which annotations alone would not convey. It also discloses the constraint that at least one page must remain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the action and output naming, then the constraint, then the file-writing behavior. No filler and no repetition of schema text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be described. The description covers the side effects, output location, safety constraint, and a precondition — everything an agent needs to call this mutation tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema documents path, pages, and output_path. The description still adds value by stating the default output location, the '-trimmed' naming convention, and the rule that an existing file is never overwritten, which reinforces the schema's 'must not exist yet' constraint.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Removes the selected pages') and adds a distinguishing behavior — surviving pages are kept in order and the output is named with '-trimmed'. It doesn't explicitly contrast with close siblings like extract_pages or split_pdf, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'At least one page must remain' gives a clear precondition for when this tool can be used, and the output_path note implies the default case. However, there is no explicit routing to alternatives (e.g., use extract_pages to keep only a subset) and no statement of when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
duplicate_pagesDuplicate pagesA
Adds copies of the selected pages, right after each one or all at the end, named with -duplicated. Copies share the page's images, so the file barely grows. One call can add at most 10,000 pages. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| pages | Yes | Pages to copy, such as "2", "1-3, 5" or "4-end". Commas separate parts. | |
| copies | No | Extra copies of each page. Default 1. | |
| placement | No | "after" (default) puts copies right after each page; "end" adds them at the end. | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations (which only say non-read-only, non-destructive, non-idempotent): it discloses naming convention, that images are shared so file growth is small, a hard 10,000-page cap, that a new file is created, that existing files are never overwritten, and that the input is unmodified. All of this is consistent with destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with what happens to the pages before moving to limits and side effects. Every clause carries operational information; nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and full parameter documentation already present, the description only needs to add limits and side effects, and it does: page cap, naming, shared images, non-destructive write target. An agent has everything needed to call this safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so placement, copies, output_path, and pages syntax are already documented. The description restates placement and default output location rather than adding new semantics, which is the baseline case when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Adds copies of the selected pages") plus the exact resulting artifact (new file next to input, pages named with -duplicated). This is clearly distinct from extract_pages or merge_pdfs without needing their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operating context: copies land after each page or at the end, capped at 10,000 pages per call, output goes to a new file. It does not name siblings or state when to prefer extract_pages/split_pdf instead, so routing between the family is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_pagesExtract pagesA
Copies the selected pages into one new PDF, in page order, named with -pages. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| pages | Yes | Pages, such as "2", "1-3, 5" or "4-end". Commas separate parts. | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations it discloses real side effects: a new file is written next to the input by default, an existing file is never replaced, and the input PDF is left unchanged — consistent with readOnlyHint=false and destructiveHint=false and useful for deciding whether the call is safe. It does not say what actually happens when a conflicting "-pages" file already exists (error vs. renamed), which is the one behavioral detail still missing given idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence opens with the operation and result file, then covers destination, overwrite behavior, and input preservation — no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations, a 100%-covered schema, and an output schema, the description only needs to cover side effects and destination semantics, which it does. The unresolved edge case of a pre-existing target file name is a minor gap rather than a blocker.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the page-range syntax and path rules are already fully documented in the schema, so the baseline is 3. The description adds only the default output naming/destination, which slightly overlaps the output_path schema description rather than extending it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Copies the selected pages into one new PDF" is a specific verb+resource with the output naming rule ("-pages") stated, so the agent knows exactly what artifact is produced. It stops short of differentiating from close siblings such as duplicate_pages or split_pdf, which are the most likely mix-ups for an agent selecting a tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the use case (pulling selected pages out into a separate file) and notes output_path as an override, but never states when to prefer this over split_pdf or duplicate_pages, and names no alternatives or exclusions. Usage has to be inferred from the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_pdfsMerge PDFsA
Combines PDFs into one, in the order given. The result is named after the first file, with -merged. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Absolute paths of the PDFs to combine, in order | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations, which only declare destructiveHint=false and idempotentHint=false: it discloses the output naming rule, the default output location, that existing files are never overwritten, and that inputs are left unchanged. That is exactly the side-effect information an agent needs before calling a write tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with what happens and followed by naming, destination, and non-destructive guarantees. No sentence is redundant with another.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the description still covers naming, destination, overwrite protection, and input preservation — everything needed to invoke a merge correctly without surprises.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both params are already documented, including ordering and the output_path existence constraint. The description adds one genuinely new fact — the -merged suffix derived from the first file — but otherwise restates schema content, which is the baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("combines") and resource (PDFs) plus the ordering semantics in the first clause, which immediately separates it from split_pdf, extract_pages, and reorder_pages in the sibling set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear operational context — you merge multiple PDFs into one — and no other sibling performs this operation, so no explicit alternative needs naming. However, it never states a when-to-use condition or any exclusion (e.g. single-file input, encrypted PDFs), leaving the agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_infoPDF infoARead-onlyIdempotent
Reads a PDF and reports its page count, file size, first page size in points, and whether it is password-protected. Changes nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| pages | Yes | Null when the file is encrypted in a way that hides its page list |
| encrypted | Yes | |
| first_page | Yes | |
| file_size_bytes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so 'Changes nothing' largely restates structured data. What the description does add is the scope of inspection, notably that password protection is detected — a behavioral fact not present in annotations. The remaining gap is what happens when the file is encrypted or unreadable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the verb and resource, followed by the precise list of returned facts and the read-only guarantee. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no elaboration, and the annotations fully cover the safety profile. The one unresolved point specific to this tool — whether a password-protected file is still inspected or raises an error — is left ambiguous.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter at 100% schema description coverage, and the schema already spells out that the path must be absolute or start with ~/. The description adds nothing about the path argument, so the baseline 3 for schema-covered parameters applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (reads) and resource (a PDF) and enumerates exactly what is reported: page count, file size, first page size in points, password-protection status. That enumeration clearly separates it from every sibling, all of which mutate PDF structure (merge, split, rotate, delete, reorder, duplicate).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'Changes nothing' signals this is the non-mutating inspection option among mutating siblings, but the description never says when to call it (e.g., before splitting or extracting) or names any alternative. An agent can infer the role but must do the reasoning itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reorder_pagesReorder pagesA
Puts the pages in a new order, named with -reordered. The order must list every page exactly once; use pdf_info for the page count. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| order | Yes | Every page number once, in the new order, e.g. [3, 1, 2] | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses the output filename convention, that the result is written as a new file beside the input (or to output_path), that no existing file is ever replaced, and that the input is untouched. These details align with destructiveHint=false and idempotentHint=false while telling the agent precisely what side effects to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the operation and its output naming, then the ordering constraint and safety guarantees. No redundant or filler text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter mutation tool with an output schema and full annotation coverage, everything an agent needs is present: input requirements, page-count source, output location rules, and overwrite/immutability guarantees. Return-value detail is correctly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so path, order, and output_path are already fully documented in the schema, including the example [3, 1, 2] and the .pdf/not-yet-existing constraint. The description restates the all-pages-once rule and the default output location but adds no syntax or format detail beyond structured fields, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Puts the pages in a new order") plus the concrete output identity via the `-reordered` suffix, so an agent knows exactly what is produced. It does not explicitly contrast with the closest siblings (extract_pages, delete_pages, rotate_pdf), so differentiation relies on the tool name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"The order must list every page exactly once; use pdf_info for the page count" gives a hard precondition and routes the agent to the sibling that supplies the missing input. It stops short of naming alternatives for partial reordering or subsetting (extract_pages/delete_pages), which would have made it a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rotate_pdfRotate pagesA
Turns pages clockwise by a multiple of 90 degrees (negative turns counter-clockwise), every page unless pages is given. Named with -rotated. Writes the result as a new file next to the input (or to output_path) and never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| angle | Yes | Degrees clockwise: 90, 180, 270, or -90 for counter-clockwise | |
| pages | No | Pages, such as "2", "1-3, 5" or "4-end". Commas separate parts. Every page when left out. | |
| output_path | No | Optional absolute path for the new PDF, ending in .pdf. It must not exist yet. By default the result goes next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in the new PDF |
| output_path | Yes | Where the new PDF was written |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: output is written to a new file (input-rotated by default or output_path), existing files are never overwritten, and the input is unchanged. This directly corroborates destructiveHint=false and readOnlyHint=false rather than contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, then the scoping default, then the output/non-destructive behavior in a tight multi-clause structure. No filler sentences; every clause carries usable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations and an output schema present, the remaining burden is behavioral disclosure of the write path, which the description fully covers (new file, no overwrite, input preserved). Nothing an agent needs in order to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents angle direction, page-range syntax, and output_path constraints. The description restates the defaults (every page, result next to input) but adds no syntax or edge-case detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (turns pages clockwise by multiples of 90 degrees) plus the default scope (every page unless pages is given). Rotation is clearly distinct from all listed siblings (info, merge, split, extract, delete, reorder, duplicate).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: the default is all pages, angles may be negative for counter-clockwise, and the result goes to a new file. It doesn't name a when-not condition or an alternative tool, but no sibling actually overlaps with rotation, so little is left ambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
split_pdfSplit a PDFA
Splits a PDF into one new file per comma-separated range, named -part1, -part2 and so on. "1-2, 3-end" gives two files, and one call writes at most 1,000 (or one per page for longer PDFs). Never replaces an existing file; the input is left unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to a PDF file, or one starting with ~/. | |
| ranges | Yes | Ranges such as "1-2, 3, 4-end": one output file per comma-separated part | |
| output_folder | No | Optional absolute path of an existing folder for the files. By default they go next to the input. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | Yes | Pages in each new PDF |
| output_paths | Yes | The new PDFs, one per range |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic write profile (readOnly=false, destructive=false, idempotent=false); the description adds real substance beyond that: the input file is left unchanged, existing files are never overwritten, and there is a hard output cap of ~1,000 files. The cap sentence ("at most 1,000 (or one per page for longer PDFs)") is phrased ambiguously, and it does not say whether a name collision errors or skips.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the core action and output naming, with no filler. The middle sentence's 1,000-file limit clause is the one place where compression costs clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the safety profile, the description supplies what an agent still needs: output file naming, the per-range-to-file mapping, a non-overwrite guarantee, and a scale limit. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a 3 is the baseline, but the description earns a point by explaining how the ranges value maps to concrete outputs (-part1, -part2 ordering) and by demonstrating the 'end' keyword. It still adds nothing about output_folder behavior beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (splits a PDF) and pins down the output shape precisely: one new file per comma-separated range, named -part1, -part2. That output convention is what separates it from extract_pages or duplicate_pages, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The worked example ("1-2, 3-end" gives two files) implies when to reach for this tool, but there is no explicit when-to-use, when-not, or pointer to extract_pages for single-range extraction. Usage is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
delete_pages - First observed
duplicate_pages - First observed
extract_pages - First observed
merge_pdfs - First observed
pdf_info - First observed
reorder_pages - First observed
rotate_pdf - First observed
split_pdf
TDQS
Scored across 8 tools
Each tool maps to a distinct page-level operation (merge, split, extract, rotate, delete, reorder, duplicate) plus a read-only info tool, and the descriptions clarify the outputs. The only mild overlap is split_pdf vs extract_pages, both of which produce page subsets, but the distinction (multiple range-based files vs one copied subset) is spelled out well enough.
Seven of eight tools follow a clean verb_noun pattern (merge_pdfs, split_pdf, extract_pages, rotate_pdf, delete_pages, reorder_pages, duplicate_pages). pdf_info breaks the pattern by putting the noun first, a minor deviation that is still readable and unambiguous.
Eight tools is well within the sweet spot for a focused PDF utility server, and each one corresponds to a meaningful, non-redundant operation. Nothing feels padded or missing at the count level.
The surface covers inspection plus the core structural editing lifecycle (merge, split, extract, rotate, delete, reorder, duplicate) with consistent output behavior. Gaps exist for common PDF tasks like text/content extraction, compression, and encryption or metadata editing, though these are workaroundable and outside the apparent structural-editing scope.
Maintenance
Related MCP Connectors
Merge, split, extract, rotate, reorder and stamp PDF pages from your AI chat, all offline.
Merge, split, extract, rotate, reorder and stamp PDF pages from your AI chat, all offline.
Merge, split, extract, rotate, reorder and stamp PDF pages from your AI chat, all offline.
Split, merge and compress PDF files locally - private by design, no uploads.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to perform comprehensive PDF operations locally, including compression, text extraction, PII redaction, page organization, splitting, merging, watermarking, creation, and form filling, all without cloud uploads.7 npm-
- AlicenseBqualityAmaintenanceEnables AI agents to perform local-first PDF processing entirely on-device, including OCR write-back to make scans searchable, unlocking and re-encrypting PDFs, splitting/merging/rotating pages, and compressing files, with no cloud calls or file uploads.2531 PyPI1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to edit text inside real PDF files in place while preserving fonts and layout, with a before/after preview. Also supports compressing, merging, splitting, converting, translating, generating and querying PDFs through a hosted remote MCP endpoint.MIT
- AlicenseBqualityBmaintenanceLets AI assistants read, search, edit, annotate, sign, redact and OCR PDF files entirely on the local machine, with no uploads and non-destructive writes to new files. It also merges, splits and reorganises pages, fills forms, compares versions to detect tampering, and converts documents between PDF, Word, Excel, images and text, including turning bank statements into spreadsheet rows.22AGPL 3.0