Skip to main content
Glama

pdf-library-mcp

A local library for mathematical PDFs. Each document is converted to Markdown once, cached forever, indexed for search, and exposed to Claude over MCP — so answering a question about a 500-page textbook costs a few hundred tokens instead of the whole book.

Built for maths, physics and CS material, in English and Greek, including scanned and handwritten lecture notes.

PDF → hash → inspect → extract → quality gate → cache → index → MCP
                                       ↓
                         flag the pages worth re-doing properly

Why this exists, and why it isn't a fork

There are several good PDF-extraction projects. This is not a replacement for any of them — it depends on two. The problem is that each solves one part of the job, and the part that was missing is the part that matters for daily use with an agent.

Project

What it gives

What was still missing

PyMuPDF4LLM

Very fast, local, layout-aware Markdown with tables

No LaTeX. It silently drops display equations. No persistence, no search

Marker

Genuinely good LaTeX for equations, strong reading order, OCR via its own models

~100× slower. Nothing is cached; every read re-runs the models

MinerU

Another strong formula-aware extractor

Same: an extractor, not a library

Existing PDF MCP servers

Search and selective page reading

Built around generic documents; mathematics is not a first-class concern

Every one of those is an extractor. What a person actually needs when reading maths with an agent is a library: something that remembers it already read the book, knows which pages came out badly, and hands back three pages instead of eight hundred.

That layer is what this project is. Concretely, it adds:

  • Content-addressed caching. A document is identified by the SHA-256 of its bytes. Re-importing the same file runs no extraction, no OCR, no model.

  • Two quality tiers with a per-page upgrade path, so a book is searchable in seconds and only the pages that need the slow engine ever see it.

  • A quality gate that detects silently lost mathematics — the failure mode no extractor reports and no check on the output can see.

  • Greek as a first-class language, at every layer from OCR repair to search.

  • An MCP interface built around a token budget, where search returns snippets and content arrives only when asked for — including an image of the original page, priced and opt-in, for when the text cannot be trusted.

Forking any single extractor would have meant inheriting its licence and its scope while still writing all of the above. Depending on them behind an interface keeps each one replaceable — and keeps the GPL one at a process boundary.


Related MCP server: rag-paper

Two tiers, not a choice of engine

Running a model-based extractor over an 800-page textbook takes hours. Waiting that long before the book is usable is the wrong trade, so import and quality are separate stages:

Tier

Engine

Speed

Produces

fast

PyMuPDF4LLM

~11 pages/second, no models

Structure, prose, tables. Superscripts become inline LaTeX. Display equations are often lost

high

Marker

~0.1 pages/second on an Apple-silicon GPU

Real LaTeX for display and inline maths, better multi-column order, OCR for scans

Measured on the LaTeX test fixture with warm models (benchmarks/compare_engines.py): Marker is about 120× slower and recovers every display equation the fast tier dropped.

Import always runs the fast tier. The quality gate then marks which pages are worth upgrading, and reprocess sends only those to Marker. Everything else keeps its cached text. Upgrading one page never touches the other 842.


Three findings that shaped the design

These came out of running the thing on real material, and each one changed the code.

1. Lost equations are invisible in the output

The damaging failure is silent: the fast extractor drops a display equation and leaves a blank line. Nothing in the resulting Markdown says anything is wrong — it is perfectly well-formed text that happens to be missing the mathematics.

So the gate reads the page's fonts instead of its text. A page typeset with TeX's large-operator and extensible-delimiter fonts (CMEX, the AMS symbol fonts, any OpenType math font) that produces no $$ block lost its equations, and is flagged display_math_missing.

On a real LaTeX textbook this fires on nearly every page. That is the honest answer: for that material the fast tier is a search index, and Marker is how you read the maths.

SQLite's unicode61 tokeniser does no stemming, so μερικά κλάσματα failed to find μερικών κλασμάτων — the same phrase in a different case. Accent folding does not help, because the endings genuinely differ.

The index therefore applies accent folding, final-sigma normalisation, and a light Greek stemmer, with identical treatment of queries. LaTeX is stripped from the indexed text as well, so \int_{-\infty}^{\infty} cannot pollute ranking while the readable Markdown keeps it untouched.

3. Search has to survive the OCR, not assume it

Two separate problems, two separate answers. Greek inflection is regular, so a stemmer handles it. OCR damage is not: παραγοντική read as παραχουτική differs in two places at once, and no rule recovers that.

So search widens in three stages, and stops at the first that finds anything:

Stage

Matches

Reported as

exact

every word present, after folding and stemming

exact

partial

any word present

partial

approximate

character trigrams overlap

approximate

The trigram index is scored an order of magnitude lower than real word matches, so it can never outrank them — it only exists for the case where nothing else found anything. Results carry the stage that produced them, because an approximate match deserves to be read as one.

4. No OCR model knows Greek mathematical notation

Greek textbooks write the trigonometric functions with Greek names: ημ for sine, συν for cosine, εφ for tangent. Two things go wrong, and both are deterministic to fix:

  • The characters are misread. In handwriting the σ of συν looks like a 6 and the υν like 0v, so συνx is transcribed faithfully but meaninglessly as 60vx.

  • Even when the characters are right, they are typeset as separate variables: ημx becomes \eta \mu x, which renders as the product η·μ·x rather than sin(x).

Because the set of Greek function names is small and closed, both are repaired deterministically — inside math spans only, so ordinary words like ημέρα and εφαρμογή are never touched. The repair is gated on the document actually using that notation, and pdf-library repair applies it to documents already on disk without re-running OCR.

5. The errors worth fixing are the ones that change the meaning

Reading three OCR'd pages against their originals turned up four kinds of mis-parse, and they do not all deserve the same treatment.

Two are mechanical and are repaired outright. Words broken across a line come back either split (παραγο- / -ντική) or already joined with the tail emitted a second time (ολοκλήρωμα / - ρωμα), and the two shapes need opposite handling. And the Greek article η is a single letter, so OCR reads it as a Latin h and, because it stands alone, files it as a mathematical variable: η δυσκολία becomes $h$ δυσκολία.

One is only reported, deliberately. An underbrace annotation — a term with f(x) and g'(x) written underneath — is extracted as a fraction over those labels. The output is valid LaTeX that means something else entirely, and no check on the text alone can see it. But \frac{g'(x)}{g(x)} is also a perfectly ordinary logarithmic derivative, so removing it automatically would break real mathematics. Pages are flagged underbrace_as_fraction instead, and the reader is pointed at the image.

The fourth is not fixable and is not pretended otherwise: OCR of handwritten Greek confuses γ with χ, η with υ, σ with δ. That is what the trigram index and the image are for.

6. Lecture notes have structure, just not Markdown structure

Handwritten notes contain no headings, so size-based chunking produced a dozen untitled fragments. But the structure is there in the words: Παράδειγμα, Λύση, Περίπτωση 2, Βήμα 3, Θεώρημα 2.5. Those are recognised on their folded stems and become both the chunk heading and its type, which makes search --type solution and get_section work on material that has no headings at all.

OCR damages those words too — Λύση arrives as Λύψ, Εφαρμογή as Εφαρμόχή — and an exact match loses the heading on exactly the pages that need one most, so near-matches are accepted. That tolerance has to be paid for: it would otherwise promote Εφαρμόζουμε, the verb built on the same root as the heading Εφαρμογή. Two guards keep it honest — a marker must begin with a capital, and must not end in a verb ending.


The image escape hatch

Extraction of handwriting will never be perfect, and no amount of repair changes that. So there is one tool that shows the reader the original — and it is the only expensive thing here, which is why it is opt-in and priced.

Measured on a page of handwritten Greek notes:

tokens

vs. the page's text

The page's extracted text

364

Full page image, 150 dpi

2318

6.4×

One equation, cropped

385

1.1×

Cropping is not just cheaper — at the same budget the equation is rendered 1510×448 instead of 692×977, so it is both cheaper and sharper than the page that contains it. Because Marker's JSON output gives a bounding box for every block, get_pages tells the reader which blocks on an OCR'd page are equations, and get_page_image(page=4, block=2) shows exactly that one.

Images are never returned by any other tool, never automatically, and the render scale is derived from a token budget rather than a DPI, so asking for "about 400 tokens" gets the largest image that fits.

On speed

Both tiers are bounded by third-party model inference, and the rest was measured rather than assumed:

  • The fast tier runs at ~27 pages/second, of which 96% is PyMuPDF's ONNX layout model. It cannot be switched off — pymupdf4llm requires it — so that is the floor.

  • Marker runs at ~0.1 pages/second. A reprocess of many pages is already a single invocation, so the model load is paid once rather than per page.

  • Everything else is noise: opening the library and running a search costs 0.55 ms, so the MCP server's per-call setup is not worth caching.

The real speed feature is that none of this happens twice. A re-import is a cache hit in about a millisecond, reindexing never re-extracts, and repair fixes stored text without touching OCR.

Install

python3.11 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/pdf-library doctor

The quality engine is optional and large (it pulls in torch), and its model runner needs the llama.cpp server binary — without it Marker installs cleanly and then fails on the first equation, so doctor checks for both:

.venv/bin/pip install -e '.[marker]'
brew install llama.cpp

The first Marker run downloads several GB of models before it does any work.


Command line

pdf-library import ~/books/real-analysis.pdf
pdf-library import ~/books/                    # a whole directory
pdf-library list
pdf-library search "dominated convergence"
pdf-library page real-analysis 243 244
pdf-library section real-analysis "Dominated Convergence"
pdf-library report real-analysis --problems-only
pdf-library reprocess real-analysis --pages 243
pdf-library repair real-analysis               # Greek notation, no OCR
pdf-library blocks real-analysis 243           # laid-out regions of a page
pdf-library image real-analysis 243 --block 2  # crop one region to a JPEG
pdf-library reindex --all
pdf-library doctor

tools/proofread.py <document> writes a self-contained HTML page with each original page beside the extracted Markdown, LaTeX typeset — the only reliable way to judge extraction quality is to look at it.


Claude Code and Claude Desktop

claude mcp add pdf-library -- /absolute/path/to/.venv/bin/pdf-library-mcp

For Claude Desktop, in claude_desktop_config.json:

{
  "mcpServers": {
    "pdf-library": {
      "command": "/absolute/path/to/.venv/bin/pdf-library-mcp",
      "env": { "PDF_LIBRARY_ROOT": "~/Documents/pdf-library" }
    }
  }
}

Tools

Tool

Returns

import_pdf

Starts a background import, or reports a cache hit immediately

search_library

Headings, pages and snippets. Accent- and inflection-insensitive

get_pages

Markdown for named pages only

get_chunk

One chunk — a theorem, a proof, a definition

get_section

Every chunk under one heading

list_documents

The library, metadata only

document_status

Progress, quality report, pages worth upgrading

get_page_image

The original page, or one cropped block, as an image. Opt-in and priced

reprocess

Re-extracts named pages with Marker

Imports never block the transport: import_pdf returns a job id and document_status reports progress. Responses are trimmed to a configured token budget, and content-returning tools label extracted text as untrusted data.


Storage

~/Documents/pdf-library/
├── library.db                  SQLite: documents, pages, chunks, FTS5, jobs
└── documents/<document_id>/
    ├── source.pdf
    ├── document.md
    ├── metadata.json
    └── pages/0001.md ...

Page files are both the unit of caching and the unit of retrieval, which is what makes single-page reprocessing possible.


Scanned and handwritten documents

A page with no text layer produces nothing at the fast tier. It is recorded as scanned and flagged for upgrade, not silently returned as an empty page.

On handwritten Greek lecture notes Marker recovers the mathematics well — nested subscripts such as \frac{A_{2,m_2}}{(x-r_2)^{m_2}} come through intact — while the surrounding prose keeps a steady rate of character confusions (γ read as χ, η as υ). Stemmed search absorbs some of that; exact quotation of OCR'd handwriting does not.

One error class deserves a warning: underbrace annotations can be read as fractions. A term with f(x) and g'(x) labelled underneath it may be extracted as a fraction with those labels as the denominator. The result is syntactically valid LaTeX and no automated check can catch it, so read pages with underbraces against the original.


Configuration

See config.example.toml. Override the library root with $PDF_LIBRARY_ROOT, or the config file with $PDF_LIBRARY_CONFIG. Nothing is hard-coded.

Changing how text is normalised invalidates existing indexes; doctor detects that and pdf-library reindex --all rebuilds them without re-extracting any PDF.


Tests

.venv/bin/python -m pytest tests -q

138 tests. Fixtures are compiled from LaTeX so the mathematics has a known ground truth; regenerate them with python tests/fixtures/make_fixtures.py.

The suite covers the promises that matter: a second import runs no engine, a digital PDF triggers no OCR, a display equation is never split across chunks, Greek queries match across inflections and across OCR damage, an exact match is never reported as approximate, images stay inside their token budget, and every MCP tool answers within its own.


Deliberately not included

Not because they are bad ideas, but because they were not needed to make the thing work well:

  • A vector database. SQLite FTS5 with proper normalisation answers these queries, and semantic search can be added behind the same interface later.

  • An LLM in the default pipeline. The quality gate is deterministic. An LLM belongs on the handful of pages that fail it, opt-in, never on all of them.

  • A third extraction engine. Two tiers cover the range; a third is weight without a measured gain.

  • A spelling dictionary for OCR'd Greek prose. One wrong "correction" in a mathematical text is worse than visible nonsense; the trigram index and the image escape hatch solve the same problem without that risk.

  • Anything server-shaped: no Postgres, no queue, no web frontend. It is a local tool for one person's bookshelf.


Where this is going

docs/NEXT.md carries the agreed next steps and the decisions behind them.

Licence

This project's own source is MIT — see LICENSE, which also documents the copyleft terms of the extraction engines it drives. PyMuPDF is AGPL-3.0 and is a required dependency; Marker is GPL-3.0 with a commercial-use condition, is optional, and runs as a subprocess rather than being imported.

Available Tools

9 tools
document_statusA

Processing state and quality report for one document: whether it is complete, which pages are scanned or low quality, how many equations were found, and which pages would benefit from re-extraction. Poll this after import_pdf.

ParametersJSON Schema
NameRequiredDescriptionDefault
documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of disclosing behavior. It describes what the tool reports and implies it is a read-only status check, but does not explicitly state that it does not modify data, nor does it mention error conditions (e.g., document not found, still processing). The output schema exists, so return format is covered, but behavioral details are partially implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: it leads with the core purpose, lists the report contents, and ends with a clear usage instruction. Both sentences earn their place, with no redundant wording or filler. It is well-structured for quick parsing by an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter) and the existence of an output schema, the description is fairly complete. It tells the agent what the tool reports and when to use it. It does not cover edge cases like partial results while processing, but that is a minor omission given the polling context and the availability of the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, meaning the description must compensate for parameter meaning. The description mentions 'one document' and the parameter is named 'document', making it clear that it expects an identifier for a document. However, it does not specify the format (e.g., ID vs. path) or how to obtain it, relying on shared context from sibling tools. It adds some meaning beyond the raw schema but leaves room for ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: it provides a processing state and quality report for a single document, enumerating specific details (completeness, page quality, equation count, re-extraction suggestions). This is specific and distinguishes it from siblings like search_library or get_pages, which serve different functions. The phrase 'Poll this after import_pdf' also ties it to a specific workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage guidance: 'Poll this after import_pdf.' This tells the agent when to call it and implies it is for checking the result of an import operation. It does not explicitly state when not to use it or mention alternatives, but the context is clear given the sibling tools and the specific trigger.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_chunkA

Return one chunk in full, by the id shown in search results. This is the cheapest way to read a single theorem, proof or definition.

ParametersJSON Schema
NameRequiredDescriptionDefault
chunk_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden. It adds useful traits: the result is a 'full' chunk, the operation is the 'cheapest way' to read a single item, and the chunk represents a theorem, proof, or definition. However, it does not disclose error behavior, authentication requirements, or consequences of an invalid/stale id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The action and resource are front-loaded in the first sentence, and the cost/use-case rationale is in the second. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read operation with an output schema, the description is largely complete: it identifies the parameter source, the content type, and the cost profile. It could add explicit not-found behavior or a pointer to alternatives, but nothing essential is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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. It does by explaining that chunk_id is the id shown in search results, which is the key semantic an agent needs to use the tool. For a single integer parameter, this is nearly sufficient.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Return') and resource ('one chunk'), and adds the scope 'in full' and the id provenance 'shown in search results'. It also names the content type (theorem, proof, or definition), which clearly differentiates it from sibling tools like get_pages and get_section.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'This is the cheapest way to read a single theorem, proof or definition' gives a clear when-to-use signal, and 'by the id shown in search results' tells the agent where to obtain the argument. It does not explicitly name alternatives or state when not to use it, but the context is clear enough for correct selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_page_imageA

Show the original scanned page, or one region of it, as an image. This is the expensive tool and the last resort: an image costs several times what the same page's text costs, and it stays in context for the rest of the conversation. Use it only when the extracted text is evidently corrupted — nonsense words in a formula, an equation that does not parse — and always pass a block number if you can, since cropping to one equation is both cheaper and sharper than the whole page. get_pages lists the block numbers for OCR'd pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageYes
blockNo
documentYes
max_tokensNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly warns about cost ('costs several times what the same page's text costs') and context retention ('stays in context for the rest of the conversation'), and notes that cropping to a block is cheaper and sharper. It does not mention whether the tool is read-only or error behaviors, but the key operational traits are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense yet efficient. Each sentence earns its place: purpose, cost/context warning, usage condition, and block guidance. It is front-loaded with the core purpose and immediately gives actionable constraints, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description does not specify the return format, but the agent can infer it will receive an image. It covers the critical cost/context trade-off and integrates with sibling get_pages for block numbers. The main gap is a lack of error or fallback details, but overall it provides sufficient information for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It explains the block parameter's purpose and how to obtain block numbers via get_pages, and implicitly clarifies page and document are required. It does not mention max_tokens, but that parameter is likely self-explanatory. The description adds meaning beyond the schema for the most critical parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource: 'Show the original scanned page, or one region of it, as an image.' It distinguishes itself from text-focused siblings like get_pages, get_chunk, and get_section by explicitly framing it as an image tool and as the expensive last resort.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: only when extracted text is corrupted, with concrete examples (nonsense words in a formula, equation that does not parse). It also provides when-not-to-use (last resort) and points to get_pages for block numbers, effectively routing the agent to the right alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pagesA

Return the Markdown of specific pages of one document, with LaTeX preserved. Ask for the few pages a search pointed at, plus a neighbouring page if context is missing. Requesting a wide range is how you flood your own context; the reply is truncated at the configured token budget.

ParametersJSON Schema
NameRequiredDescriptionDefault
pagesYes
documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses that the reply is truncated at the configured token budget and warns about flooding context, which is critical for an agent to avoid misuse. It does not detail error handling or edge cases, but the disclosed behaviors are significant and well-covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with the core purpose, and each sentence adds value—purpose, usage guidance, and a warning. There is no redundancy or wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description does not need to explain return values. It covers the essential usage, the token-budget warning, and the context strategy. The main gap is the lack of explicit parameter constraints like page indexing, but overall it is sufficient for an agent to make correct calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It implies 'document' identifies the document and 'pages' are the specific page numbers, but it does not explicitly state indexing (e.g., 1-based) or the expected format. The guidance to 'ask for the few pages a search pointed at' gives practical context but lacks precise parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns the Markdown of specific pages of one document, preserving LaTeX. It specifies the exact resource (pages of a document) and the action (return Markdown), making it easily distinguishable from siblings like get_chunk or get_section.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives practical guidance on when to use it: after a search, request the few relevant pages plus a neighboring page if context is missing. It also warns against requesting wide ranges due to token truncation. However, it does not explicitly name alternative tools for cases like retrieving a full section or a chunk, so the routing guidance is incomplete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sectionA

Return every chunk filed under one heading of a document, joined in order. Use when you know the section name; otherwise search first.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionYes
documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, but the description implies a read-only operation. It does not mention side effects or error conditions, but the tool name and description strongly suggest it is non-mutating.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, combining the core functionality and a usage hint in a single sentence. It avoids unnecessary detail while remaining informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description and sibling context provide a good overall understanding, but the lack of parameter descriptions leaves some gaps regarding input formats. The output schema exists but is not shown, so the return type is not fully specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides no descriptions for the 'document' and 'section' parameters. While parameter names are self-explanatory, the format of 'section' (exact heading, partial match, case sensitivity) is ambiguous, leaving the agent to infer expected input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: returning every chunk under a specific heading of a document, joined in order. This distinguishes it from sibling tools like get_chunk (single chunk) and get_pages (pages).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises when to use this tool: 'Use when you know the section name; otherwise search first.' This provides clear guidance and points to the alternative search_library tool when the section name is unknown.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_pdfA

Add a PDF to the library, or confirm it is already there. Extraction runs in the background and returns a job id immediately; poll document_status until status is 'complete'. A file whose content hash is already known is an instant cache hit and is never reprocessed, so there is no cost to calling this, but also no reason to call it twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYes
forceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does an excellent job: it discloses background extraction, immediate job-id return, cache-hit idempotency, no reprocessing, and zero cost for duplicates. This is comprehensive behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose, and every clause adds value (async behavior, polling, cache semantics, cost implications). No redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the async workflow, polling requirement, idempotency, and cost trade-offs—all essential for correct invocation. Parameter meanings are missing, but that is a separate dimension; for the tool's behavior, the description is thorough and leaves no critical ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning the description does not explain either 'path' or 'force'. The purpose of 'force' is left entirely to the schema, and even 'path' is not contextualized beyond being a file path. The description fails to compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Add a PDF to the library' with a clear verb and resource, and immediately clarifies the cache-hit behavior that distinguishes it from the sibling get/search/reprocess tools. It fully defines the tool's role in the library workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit operational guidance: poll document_status until complete, and warns against calling twice due to cache hits. It does not name alternative tools, but the context makes the intended usage clear and self-contained.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_documentsA

List every document in the library with its id, page count and processing state. Metadata only, no content.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosing behavior. It explicitly states that only metadata is returned and no content, which is a key behavioral trait. It also implies a read-only operation, though it does not mention pagination or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that conveys all necessary information without any redundancy or fluff. It is appropriately concise for a straightforward list operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a tool with no parameters and a simple list operation. It specifies the exact output fields (id, page count, processing state), so the agent knows what to expect. No additional context is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema description coverage is 100%. According to the rubric, the baseline score of 3 applies, and there is no additional parameter information to add since none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List', the resource 'documents in the library', and specifies the returned fields (id, page count, processing state). It also distinguishes itself from the sibling tool 'search_library' by emphasizing 'every document' rather than a search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear guideline by stating 'Metadata only, no content,' which informs the agent about the nature of the response. While it does not explicitly contrast with search_library, the purpose itself sufficiently implies when to use this tool for listing all documents.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reprocessA

Re-extract selected pages of a document with the high-quality engine (Marker), which produces real LaTeX for equations. Slow and optional: use it for the specific pages whose math came out badly, never for a whole book. Runs as a background job.

ParametersJSON Schema
NameRequiredDescriptionDefault
pagesNo
engineNo
documentYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. It does disclose important traits: it is slow, optional, runs as a background job, and produces real LaTeX. However, it does not state whether results overwrite previous extraction, whether the call is idempotent, or how the agent should learn when the background job completes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with no filler. The core action and engine are front-loaded, followed by usage guidance and background behavior. Every sentence adds distinct value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, usage, and basic behavior, and an output schema exists so return values are covered elsewhere. However, for a background job, it should ideally point the agent to a status-checking sibling like document_status, and clarify whether the re-extraction replaces the prior extraction or creates new data. These gaps are material for an agent deciding how to invoke and monitor the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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. It maps all three parameters: 'pages' through 'selected pages' and 'specific pages,' 'engine' through 'high-quality engine (Marker),' and 'document' through 'of a document.' It also adds a key usage constraint about not reprocessing a whole book. It does not explain default behavior when pages is null, but it largely covers the parameter meanings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Re-extract selected pages'), a specific resource ('a document'), and a distinctive method (Marker high-quality engine producing real LaTeX). This clearly separates it from sibling tools like get_pages, which would only fetch or view pages rather than re-run extraction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit guidance: use for 'specific pages whose math came out badly' and 'never for a whole book.' It also labels the tool as 'slow and optional,' which helps an agent decide when to invoke this tool versus cheaper or simpler alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_libraryA

Full-text search across every processed document. This is the entry point for any question about library content: it returns headings, page numbers and short snippets, never full text. Follow up with get_pages or get_chunk for the passages that look right. Accent-insensitive and works for Greek and English.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
documentNo
chunk_typeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that results are limited to headings, page numbers, and snippets (never full text), and that search is accent-insensitive and supports Greek and English. This goes beyond a simple 'searches documents' statement. It doesn't mention pagination or behavior on no results, but for a search tool this is solid coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, with the purpose front-loaded in the first sentence. It is concise, every sentence adds value (purpose, output type/follow-up, language behavior), and there is no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 4 parameters and an output schema, the description is adequate for the core purpose but incomplete for parameters. It explains the return type (headings, page numbers, snippets) but omits any guidance on how to use 'document' or 'chunk_type' filters. The presence of an output schema reduces the need to describe return format, but the parameter semantics gap makes it not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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, but it does not. It implies 'query' is the search term via 'Full-text search,' but never explains 'limit,' 'document,' or 'chunk_type.' The 'document' parameter likely filters to a specific document, which is a significant omission given the description says 'every processed document.' The lack of parameter explanation is a clear gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Full-text search across every processed document.' It distinguishes itself from siblings by being 'the entry point for any question about library content' and explicitly notes it returns 'headings, page numbers and short snippets, never full text,' which separates it from get_pages and get_chunk. The verb and resource are specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit usage guidance: 'This is the entry point for any question about library content' establishes when to use it, and 'Follow up with get_pages or get_chunk for the passages that look right' names the alternatives and the condition for switching. It also warns 'never full text,' implying those follow-ups are needed for full content. This is clear when-to-use and when-not-to-use guidance.

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. Dates show when Glama detected each change.

  1. 9 tool updatesv0.1.0
    • First observeddocument_status
    • First observedget_chunk
    • First observedget_page_image
    • First observedget_pages
    • First observedget_section
    • First observedimport_pdf
    • First observedlist_documents
    • First observedreprocess
    • First observedsearch_library

TSQS

Score is being calculated.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    A local academic research assistant that indexes PDFs into a searchable vector library and exposes MCP tools for semantic search, claim extraction, contradiction detection, and multi-step research synthesis.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local-first paper RAG server that enables searching and managing academic PDFs via MCP tools, supporting metadata enrichment and citation graphs.
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A local MCP server for searching scientific papers, retrieving metadata and abstracts, and legally downloading Open Access PDFs via OpenAlex, CrossRef, and Unpaywall APIs.
    5
    3
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    Enables semantic search across personal PDF paper collections with page-level citations, allowing users to query their library from any MCP-capable client.
    9
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/InstinctEx/pdf-library-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server