benspdf
Pairs the PDF tools with a local Ollama model so questions about PDFs are answered entirely offline. The bundled benspdf-cli connects to Ollama (e.g. llama3.1, selectable via --model or BENSPDF_MODEL) and drives the PDF tools — page counts, metadata, layout, rendering — without any data leaving the machine.
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., "@benspdfhow many pages are in ~/Downloads/report.pdf?"
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.
Ben's PDF tools for AI agents, exposed over the Model Context Protocol (MCP).
Your PDFs are read on your own machine and never uploaded. With a hosted model your questions still reach that model; pair the tools with a local Ollama model and nothing leaves the machine at all.
Works with Claude Desktop, Claude Code, VS Code, Kiro, Cursor, the ChatGPT desktop app, and any other MCP client. The one-click buttons above need uv; for every other client, or to do it by hand, see Setup.
Tools
Tool | What it does |
| Counts the pages in a PDF |
| Reads document properties: title, author, dates, producer |
| Says whether a PDF is readable text or a scan that needs OCR |
| Page sizes, orientation, rotation and page boxes |
| Encryption, and what the file permits: printing, copying, editing |
| Renders pages to images, so a page can be looked at |
| Generates a throwaway PDF, handy for trying things out |
| Saves results to a real location on disk |
| Lists recent temporary results |
| Deletes temporary results now |
Related MCP server: pdfeverything
Where results go
When a tool makes a new PDF, it goes into a scratch folder instead of your own
folders, and you get back a short id like art_a1b2c3d4.pdf. Tools accept those
ids anywhere they accept a file path, so several steps can be chained together.
Results carry the artifact's path as well as its id, so you can open a rendered
page or an intermediate file straight away without exporting it first.
export is the only tool that writes into your folders, so nothing shows up
until you ask for it. Each time the server starts it clears out scratch files
older than 7 days. Set BENSTOOLS_WORKSPACE to put the scratch folder somewhere
other than ~/.benstools/work.
Setup
Install uv
once, then point your client at uvx benspdf-mcp and uv fetches the package,
plus a suitable Python, on first run.
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"On macOS, brew install uv works too.
Add the server to your client with one of the configs below, then restart the server from your client's UI. Once connected, just ask in plain language:
How many pages are in ~/Downloads/report.pdf?
Claude Desktop
Edit claude_desktop_config.json, which lives at
~/Library/Application Support/Claude/ on macOS and %APPDATA%\Claude\ on
Windows. You can also open it from Settings → Developer → Edit Config.
{
"mcpServers": {
"benspdf": {
"command": "uvx",
"args": ["benspdf-mcp"]
}
}
}Claude Code
One command, no config file. Add --scope user to enable it everywhere rather
than just the current project.
claude mcp add benspdf -- uvx benspdf-mcpCheck it connected with claude mcp list.
VS Code
.vscode/mcp.json in your workspace, or the same file in your user profile.
Note VS Code uses servers rather than mcpServers, and wants an explicit
type.
{
"servers": {
"benspdf": {
"type": "stdio",
"command": "uvx",
"args": ["benspdf-mcp"]
}
}
}Kiro
.kiro/settings/mcp.json in your workspace, or ~/.kiro/settings/mcp.json to
enable it everywhere. autoApprove skips the confirmation prompt for tools you
trust.
{
"mcpServers": {
"benspdf": {
"command": "uvx",
"args": ["benspdf-mcp"],
"autoApprove": ["pdf_page_count"]
}
}
}Cursor
The button at the top does this for you. By hand, it's ~/.cursor/mcp.json to
enable it everywhere, or .cursor/mcp.json in a project.
{
"mcpServers": {
"benspdf": {
"type": "stdio",
"command": "uvx",
"args": ["benspdf-mcp"]
}
}
}Windsurf
~/.codeium/windsurf/mcp_config.json. You can also reach it from Cascade:
Settings → Cascade → Manage MCPs → View raw config, which is worth using
since the path has moved between versions.
{
"mcpServers": {
"benspdf": {
"command": "uvx",
"args": ["benspdf-mcp"]
}
}
}Continue
~/.continue/config.yaml, or a .yaml file under .continue/mcpServers/ in a
project. Continue is the one client here that doesn't take the JSON shape above:
its config is YAML, and mcpServers is a list rather than an object keyed by name.
mcpServers:
- name: benspdf
command: uvx
args:
- benspdf-mcpChatGPT desktop app, Codex CLI, Codex IDE extension
All three are Codex clients and share one config file, ~/.codex/config.toml,
so adding the server once covers all of them. Note this one is TOML, not JSON.
[mcp_servers.benspdf]
command = "uvx"
args = ["benspdf-mcp"]Any other MCP client
Almost every client uses the same JSON as Claude Desktop above — an mcpServers
object, with command set to uvx and args to ["benspdf-mcp"]. Some want an
explicit "type": "stdio"; adding it is harmless where it isn't required.
If a client just asks for a command to run, it's:
uvx benspdf-mcpFully offline with Ollama
The clients above keep your PDFs local, but they answer using a hosted model. Pair the tools with a local model instead and nothing leaves your machine.
You'll need Ollama with a model pulled, plus this package:
pip install benspdf-mcp ollama
ollama pull llama3.1Then run the bundled CLI:
benspdf-cli # uses the first model you have
benspdf-cli --model llama3.1 # or pick one
BENSPDF_MODEL=llama3.1 benspdf-cli # or set it oncepython -m benspdf.cli does the same thing, handy from a source checkout.
You: how many pages in ~/Downloads/report.pdf?
[Using tool: pdf_page_count]
[Result: 12 pages in report.pdf]
Assistant: The PDF has 12 pages.Reference
Each tool's own description tells your client what it does and when to use it, so in normal use there is nothing to look up. If you want the detail — every field a tool returns, and the reasoning behind the answers it gives — see the tool reference.
To work on the code, see CONTRIBUTING.md.
License
Apache 2.0
Available Tools
10 toolscreate_test_pdf_fileA
Create a test PDF, handy for trying the other tools without hunting for one.
The pages are blank, so this is for exercising tools rather than for anything that needs real content.
Args: output_path: Optional path to also write the PDF to. Omit to keep it as a temporary artifact. num_pages: Number of blank pages to create (default: 3) title: Optional title for the PDF metadata
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| num_pages | No | ||
| output_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral load. It usefully discloses that omitting output_path leaves the result as a temporary artifact and that pages are blank, which are real behavioral facts. It does not mention overwrite behavior, error conditions, or permissions, though those matter little for a local fixture generator.
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?
Purpose and the caveat about blank pages are front-loaded, and the args block is compact. The prose is slightly conversational but every sentence adds 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?
An output schema exists, so return values need not be described. For a simple zero-required-parameter fixture generator with no annotations, the description covers purpose, usage context, and all parameters adequately; only edge-case behavior is unspecified.
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 description coverage is 0%, so the description has to compensate, and it does: all three parameters are explained with meaning beyond the schema, including output_path's omit-to-stay-temporary behavior and the defaults for num_pages and title. Only minor format/syntax details are absent.
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 ('Create a test PDF') and clarifies the artifact is intentionally blank. It is clearly distinct from the reader/inspector siblings, but it never names one, so the differentiation is implied rather than stated.
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?
'Handy for trying the other tools without hunting for one' gives a concrete trigger for use, and the note that pages are blank states the intended scope ('exercising tools rather than for anything that needs real content'). No explicit when-not or named alternative, but the context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discardA
Delete temporary artifacts from the workspace now.
Only accepts artifact ids, never file paths, so this cannot delete the user's own files. Artifacts expire on their own, so this is only needed when the user explicitly asks to clean up.
Args: refs: Artifact id, or list of artifact ids, to delete.
| Name | Required | Description | Default |
|---|---|---|---|
| refs | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the destructive scope limit (artifact ids only, never user file paths), which is the key safety fact. It omits reversibility/confirmation expectations and any rate or batching behavior, so it stops short of full disclosure.
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-loaded with the action and the critical constraint, then usage guidance, then a compact Args block. Every sentence adds distinct information with no 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?
For a one-parameter destructive tool with an output schema present (so return values need not be described), the definition covers purpose, scope-safety, and input shape adequately. Minor gaps remain around undo/irreversibility.
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 0% and the single param has no schema description, so the description must compensate. It does by stating refs is "Artifact id, or list of artifact ids", matching the anyOf shape; it does not say where to obtain those ids (e.g., list_artifacts).
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 ("Delete temporary artifacts from the workspace") and immediately narrows scope with the artifact-id-only constraint. This makes clear it is not a generic file deletion tool and differentiates it from siblings like list_artifacts or export.
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?
Explicitly conveys when-not to use it ("Artifacts expire on their own, so this is only needed when the user explicitly asks to clean up"), which is exactly the routing signal an agent needs. No alternative tool is named, but the usage condition is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
exportA
Save one or more results to a real location on disk.
The only tool that writes to the user's filesystem, so call it once at the end, when they have said where the output should go. Never hand an artifact id back as if it were a finished file; artifacts expire.
Args:
refs: Artifact id, or list of artifact ids, to export.
dest: Where to write. For a single artifact this may be a full file
path. For several artifacts, or when name is given, this is a
directory and is created if missing.
name: Filename template used when writing into a directory.
Placeholders: {n} 1-based index (e.g. "page_{n:03d}{ext}"),
{ext} extension, {id} artifact id, {stem} id without extension.
Defaults to "{n:03d}{ext}".
overwrite: Replace existing files instead of failing. Defaults to
False so nothing is destroyed by accident.
| Name | Required | Description | Default |
|---|---|---|---|
| dest | Yes | ||
| name | No | ||
| refs | Yes | ||
| overwrite | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses that artifacts expire, that dest is created if missing, and that overwrite defaults to False 'so nothing is destroyed by accident,' which tells the agent exactly what the destructive path is. Nothing about the mutation's safety profile is left to inference.
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 purpose and routing constraint in the first two sentences, then uses a compact Args block for parameters. Every sentence carries information an agent needs; no filler or restatement of the name.
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 not be explained. For a 4-parameter write tool with zero schema coverage and no annotations, the description covers purpose, timing, safety, destination semantics, naming, and overwrite behavior — nothing an agent needs in order to call it correctly 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 description coverage is 0%, so the description must compensate and it does, documenting all four parameters: refs accepts a single id or list, dest shifts meaning between file path and directory depending on arity, name documents its {n}/{ext}/{id}/{stem} placeholders plus the default, and overwrite explains its default and rationale.
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 ('Save one or more results to a real location on disk') and immediately differentiates itself from siblings by declaring it is 'the only tool that writes to the user's filesystem.' An agent can distinguish it from list_artifacts, discard, and the pdf_* readers without opening any schema.
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 explicit timing ('call it once at the end, when they have said where the output should go') and a concrete anti-pattern ('Never hand an artifact id back as if it were a finished file; artifacts expire'). This is precisely the when-to-use and when-not-to-use guidance the dimension asks for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_artifactsA
List recent temporary artifacts in the workspace, newest first.
Useful when you have lost track of an artifact id from earlier in the conversation, so you can find it again instead of redoing the work.
Args: limit: Maximum number of artifacts to return.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose scope ('in the workspace'), ordering ('newest first'), and the transient nature of the artifacts. However, it says nothing about how results are capped beyond limit, whether older items become unreachable, auth/permission requirements, or failure behavior.
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-loaded with the core action and scope, followed by a one-sentence rationale for using it. The 'Args:' block is slightly formal for a single parameter but not wasteful.
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 not be explained, and with one optional parameter the surface is small. The description covers what artifacts are, their ordering, and the intended use case, leaving only minor gaps such as total-count or truncation behavior.
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 0% (the 'limit' property has only a title and default of 20), so the description must compensate; it does minimally by defining limit as 'Maximum number of artifacts to return.' That is really just a restatement of the parameter name, with no guidance on sensible values or behavior when omitted beyond the schema default.
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?
The description names a specific verb and resource ('List recent temporary artifacts in the workspace') and adds ordering ('newest first'), so the operation is unambiguous. It is plainly distinct from the PDF-oriented siblings, though it does not explicitly contrast itself with any of them (none overlap meaningfully).
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?
It gives a concrete triggering situation: 'Useful when you have lost track of an artifact id from earlier in the conversation, so you can find it again instead of redoing the work.' That is clear when-to-use guidance tied to a real alternative (redoing the work), but it does not state any when-not conditions or name an alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_check_accessA
Check a PDF's encryption and what it permits: printing, copying, editing.
Answers "is this locked, and what am I allowed to do with it?".
encrypted and needs_password are separate answers and the difference
matters: most encrypted files have no user password, so they open silently and
only carry restrictions. permissions gives a boolean per action,
restrictions lists what is denied, and an unencrypted file permits
everything — a PDF has nowhere to keep restrictions but its encryption
dictionary.
Treat restrictions as what the file asks of viewers, not as enforcement: once a document is open nothing stops the bits being ignored, and a file that denies copying still yields its text to pdf_extract_text. Report them as the author's intent, never as an action being impossible.
Worth reaching for when another tool reports a file as encrypted; this one still answers, since the encryption dictionary is readable when the pages are not.
Args: ref: PDF file path, or a workspace artifact id.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: it distinguishes encrypted vs needs_password, explains that most encrypted files open silently, and warns that restrictions are authorial intent rather than enforcement and can be bypassed. That caveat is exactly the kind of non-obvious behavior an agent would otherwise get wrong.
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-loaded with the core question and organized into short, purposeful paragraphs. The closing caveat is slightly redundant ('Treat restrictions as what the file asks of viewers, not as enforcement' is restated as 'Report them as the author's intent, never as an action being impossible'), costing a little tightness.
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 one-parameter read tool with an output schema, nothing needed is missing: usage conditions, the meaning of each returned field (permissions, restrictions, encrypted, needs_password), and the interpretation caveat are all present. An agent can call and interpret this correctly without further context.
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 0% (the single `ref` property has no description), so the description compensates by defining it as 'PDF file path, or a workspace artifact id.' That resolves the main ambiguity — the accepted value forms — though it does not cover edge cases like relative vs absolute paths.
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 ('Check a PDF's encryption and what it permits: printing, copying, editing') and frames the question it answers. It also implicitly differentiates from siblings by naming pdf_extract_text and by calling out the encrypted-file case that other tools cannot handle.
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?
Explicitly says when to reach for it: 'when another tool reports a file as encrypted; this one still answers.' It also gives the complementary case (unencrypted files permit everything) so the agent knows what result to expect in each branch.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_check_textA
Check whether a PDF has a text layer, looks scanned, or needs OCR.
Answers "can I read this, or is it a picture of a document?". Worth running before extracting text from a file you have not seen.
verdict is "text", "scanned", "mixed", or "no_text" — the last meaning
nothing readable but nothing scan-like either, so blank, vector-only, or
illustrated pages that OCR cannot help. needs_ocr follows from it, summary
is a sentence worth quoting, and the per page evidence behind the verdict
comes back alongside, including each page's image_coverage (the largest
image's share of the page area).
Samples up to 10 pages spread across the document, so a true sampled means
the answer is an estimate for the pages in between. It does not return the
text (use pdf_extract_text) and it does not run OCR.
Args: ref: PDF file path, or a workspace artifact id.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it enumerates the verdict values and their meaning, explains that no_text implies OCR cannot help, describes the sampling behavior (up to 10 pages spread, so 'sampled' means an estimate for in-between pages), and the side-effect boundaries (no text returned, no OCR run). This is exactly the behavioral context an agent needs.
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 purpose and the verdict taxonomy before the caveats, and every sentence carries information. It runs a bit long across several paragraphs, but there is very little filler for the amount of behavioral detail conveyed.
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?
Output schema exists, yet the description still gives an adequate orientation to the return values (verdict, needs_ocr, summary, per-page image_coverage). Combined with the sampling caveat and the explicit non-behaviors, an agent has everything needed to call and interpret this tool.
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 0% and the only param is documented solely as an untyped string, but the description compensates by defining ref as 'PDF file path, or a workspace artifact id' — a meaningful disambiguation the schema lacks. It does not elaborate on path/artifact-id precedence, so not a 5.
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 (check a PDF for a text layer / scanned / OCR need) and immediately frames the user-level question it answers ('can I read this, or is it a picture of a document?'). It also distinguishes itself from text extraction and OCR, so an agent can place it relative to alternatives without opening a schema.
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?
Explicitly says when to run it ('before extracting text from a file you have not seen') and names what it is not for, routing text extraction to pdf_extract_text and noting it does not run OCR. The conditional trigger plus the two exclusions give clear when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_metadataA
Read a PDF's document properties: title, author, dates, producer, keywords.
Answers "who made this, when, and with what". It does not count pages (use pdf_page_count) and says nothing about whether the pages hold readable text (use pdf_check_text).
A PDF can store these fields in two independent places, the legacy Info
dictionary and an XMP packet, and the two often disagree. The normalized
answer is at the top level, preferring XMP, with sources naming the store
each value came from and conflicts listing every field where the two differ,
both values included. Both stores also come back verbatim as info and xmp.
When has_conflicts is true, say so rather than quoting one value as fact.
Args: ref: PDF file path, or a workspace artifact id.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses the dual Info/XMP storage, that they often disagree, the normalized top-level answer, the `sources`/`conflicts` fields, verbatim `info`/`xmp`, and warns against quoting one value as fact. It does not discuss permissions, rate limits, or error behavior on unreadable/invalid PDFs, so it stops short of full coverage.
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-loaded with purpose and alternatives before the deeper behavior notes, and every sentence carries information. It is somewhat long for a one-parameter reader, with the conflict-handling prose edging toward output-schema territory, but nothing is filler.
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 explained, yet the description still supplies the interpretation rule (prefer XMP, surface conflicts, don't assert a value when has_conflicts is true) that the schema alone would not convey. For a single-param reader with rich output, an agent has everything it needs.
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 0% and the lone parameter is documented only as 'ref', so the description must compensate — and it does, explaining ref is either a PDF file path or a workspace artifact id. That resolves the main ambiguity (path vs. artifact id) but adds no format examples or constraints.
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?
Opens with a specific verb and resource ('Read a PDF's document properties') and enumerates the fields returned. It explicitly separates itself from pdf_page_count and pdf_check_text, so an agent can route without opening either schema.
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 a crisp use condition ('who made this, when, and with what') and names two named alternatives for the adjacent asks (page counting, text extractability). Both when-to-use and when-not-to-use are stated, not inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_page_countA
Count the pages in a PDF. Answers "how many pages is this?".
Reads only the document's page tree, so it stays cheap on large files. It does not read page text, page sizes, or document properties.
Args: ref: PDF file path, or a workspace artifact id.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the internal mechanism (reads only the page tree), the resulting cost profile (cheap on large files), and explicit exclusions (no text, sizes, or document properties). It doesn't cover failure modes such as encrypted or unreadable PDFs.
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-loaded with the core action, followed by a short rationale sentence and a compact Args block. Every sentence earns its place with no 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?
For a single-parameter read tool with an output schema, this definition covers purpose, cost profile, scope exclusions, and parameter meaning. Nothing further is needed to invoke it 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 description coverage is 0%, so the description must compensate, and it does by clarifying that 'ref' accepts either a filesystem path or a workspace artifact id — meaningful added semantics beyond the bare string in the schema. Field format details and examples are still absent.
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 (count) and resource (pages in a PDF), with the user-facing question it answers. It is unambiguous against siblings like pdf_metadata or pdf_render_pages, which operate on the same resource but deliver different output.
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 usage context ('how many pages is this?') and a cost-based rationale for choosing it on large files. It does not explicitly name alternatives (e.g. pdf_metadata) or state when-not to use it, but the intended scenario is easy to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_page_layoutA
Measure a PDF's page sizes, orientation and rotation.
Answers "what size is this, is it all the same, and why does one page come out sideways?". Reads page geometry only, so it stays cheap on long documents.
sizes groups the pages by shape, most pages first, each carrying the page
numbers it covers as a range like "1-16,18", so a 300 page document answers in
one entry instead of 300 rows.
Sizes are the page as a reader sees it: CropBox clipped to MediaBox with
/Rotate applied, so a landscape box rotated 90 degrees reports as portrait.
Pages within 3pt of a known paper are grouped and named together, since real A4
varies by a millimetre.
Pass pages for per page rows carrying the raw boxes: "1-20", "3", "1,5,9-12"
or "all", capped at 100 rows.
It does not look at page content; for whether the pages hold readable text use pdf_check_text.
Args: ref: PDF file path, or a workspace artifact id. pages: Optional page range for per page detail. Omit for groups only.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | ||
| pages | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: it discloses that only geometry is read (implying a cheap, non-mutating operation), the group-vs-row behavior, the CropBox-to-MediaBox + /Rotate normalization, a 3pt paper-size tolerance, and a 100-row cap on per-page output.
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-loaded with the one-line purpose, then grouped and per-page behavior, then the sibling exclusion, then args. It is denser than strictly required (the A4-variation aside could be trimmed), but virtually every sentence conveys actionable detail rather than filler.
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-shape explanation is not required; the description supplies everything else needed to call it correctly, including grouping semantics, range syntax, the row cap, and the boundary against the text-checking sibling.
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 description coverage is 0%, so the description must compensate and does: `ref` is defined as a file path or workspace artifact id, and `pages` accepts documented range syntax ("1-20", "3", "1,5,9-12", "all"), is capped at 100 rows, and is optional with a stated default of groups-only.
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: measure a PDF's page sizes, orientation and rotation. It explicitly demarcates scope from siblings by naming pdf_check_text for content/readability questions, so an agent can distinguish it from pdf_metadata and pdf_render_pages without opening a schema.
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?
Frames the use case as three concrete questions (what size, is it all the same, why sideways) and routes the content case to pdf_check_text. It also gives an explicit when-to-use-the-`pages`-param rule (omit for groups only, pass for per-page rows).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pdf_render_pagesA
Render PDF pages to images, so a page can be looked at rather than read.
Use it to see what a page looks like: checking a change landed (did a redaction remove content, did a split cut where intended), previewing, and pages where appearance is the content — handwriting, signatures, charts, checkbox state.
For reading a scan prefer pdf_ocr, whose text layer is searchable and needs no vision model; render when OCR is unavailable or would mangle what matters.
Every page is saved as a PNG artifact and its id returned. With view, the
default, the first few images also come back to be looked at, since images are
expensive in context. Limits are explicit: 20 pages per call, and resolution is
reduced for a page that would be enormous — both reported, never silent.
Args: ref: PDF file path, or a workspace artifact id. pages: Which pages: "1-20", "3", "1,5,9-12" or "all". Defaults to all, up to the per-call limit. dpi: Resolution, 36 to 600. 150 suits reading and previewing. view: Return the images to look at, not just artifact ids.
| Name | Required | Description | Default |
|---|---|---|---|
| dpi | No | ||
| ref | Yes | ||
| view | No | ||
| pages | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does: it discloses that each page is saved as a PNG artifact with an id returned, that `view` returns images because they are context-expensive, and that hard limits (20 pages/call, reduced resolution for huge pages) are enforced and always reported, never silent.
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-loaded with the core purpose, then usage, then args; the structure is sound and nearly every sentence adds value. The behavioral paragraph is somewhat long, but the limit/reporting details justify the space.
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 4-param tool with no annotations and no output schema, the description is complete: it explains inputs, the returned artifacts/ids, the default return behavior, and the enforced limits. An agent can call it correctly without further context.
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 0%, so the description must document all four parameters and does: `ref` (path or artifact id), `pages` with concrete syntax examples and default, `dpi` with its 36-600 range and a recommended 150, and `view` with its default and purpose.
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?
Opens with a specific verb+resource: 'Render PDF pages to images', and immediately frames the distinction 'looked at rather than read'. This clearly separates it from text-oriented siblings like pdf_ocr and pdf_check_text.
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 explicit when-to-use cases (checking a redaction landed, previewing, appearance-as-content like handwriting/signatures) and names the alternative pdf_ocr with the exact condition that selects it. Nothing is left to inference.
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.
10 tool updates
v0.1.1- First observed
create_test_pdf_file - First observed
discard - First observed
export - First observed
list_artifacts - First observed
pdf_check_access - First observed
pdf_check_text - First observed
pdf_metadata - First observed
pdf_page_count - First observed
pdf_page_layout - First observed
pdf_render_pages
TDQS
Scored across 10 tools
Each of the six PDF inspection tools targets a genuinely different aspect: page count, metadata stores, text layer/OCR need, encryption/permissions, page geometry, and visual rendering. Descriptions actively cross-reference and delimit each other (e.g. 'for whether pages hold readable text use pdf_check_text'), leaving no real overlap. The workspace tools (discard/list_artifacts/export/create_test_pdf_file) are likewise distinct in purpose.
Most PDF tools share a 'pdf_' prefix, but verb/noun ordering is inconsistent (pdf_page_count and pdf_metadata are noun-first while pdf_check_text and pdf_render_pages are verb-first), and the four workspace tools drop the prefix entirely (discard, export, list_artifacts, create_test_pdf_file). All snake_case keeps it readable, but the convention is mixed rather than predictable.
Ten tools is well-scoped for a PDF utility server, with a coherent split between PDF inspection (six tools), artifact/file lifecycle (three tools), and a test-fixture generator. Each tool earns its place without redundancy.
Several descriptions explicitly point users to pdf_extract_text and pdf_ocr ('use pdf_extract_text', 'prefer pdf_ocr'), yet neither tool is in the set, so the surface can check for text and render pages but cannot extract text or run OCR. Core inspection and output/export flows are covered, but this text-extraction hole is a notable gap.
Maintenance
Related MCP Connectors
Generate and read PDFs for AI agents: a generate_pdf and a read_pdf tool, priced per document.
PDF, image, video, OCR, screenshot, SQL, QR and text tools for agents. No API key, no signup.
Merge, split, extract, rotate, reorder and stamp PDF pages from your AI chat, all offline.
Free PDF tools for AI agents: merge, split, rotate, watermark, page numbers, metadata, flatten.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI agents to securely read and extract information from PDF files including text content, metadata, and page counts from both local files and URLs within the project context.11,612 npmMIT
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to perform 13 PDF operations (merge, split, compress, watermark, encrypt, and more) on local files via MCP.2-
- AlicenseAqualityCmaintenanceEnables AI agents to process and inspect PDFs by detecting document type, extracting text, and generating Markdown with layout information.71MIT
- 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.15 npm-