Skip to main content
Glama
X Literature MCP

X Literature MCP

by JiahongXu88

X Literature MCP

X Literature MCP (x-literature-mcp) is a local, read-only stdio MCP server for local PDF reading, page rendering, references, and keyword search via MCP. It gives any MCP client (Claude Code, Claude Desktop, or another MCP-compatible host) deterministic access to a folder of PDF papers: list, page-level text, page images, reference lists, and keyword search with page numbers.

It only preprocesses and serves source material. It does not call any LLM, summarize, judge novelty, write paper cards, build knowledge graphs, OCR scanned pages, do semantic search, or touch the network. Original PDFs are only read.

  • Node.js ≥ 20 + TypeScript, MCP TypeScript SDK v2 (@modelcontextprotocol/server 2.4)

  • Python 3.9+ with PyMuPDF for text extraction and page rendering (no Docling, no model downloads)

  • Derived cache: one JSON per PDF content hash, stored outside the repo and outside the PDF folder

Reference-list parsing is ported from PaperTeam (MIT); see docs/REUSE_NOTES.md. The heuristics were developed and tested mainly on Chinese journal PDFs (GB/T 7714 and CJIG styles) and also handle common English styles (IEEE, APA).

Install

git clone https://github.com/JiahongXu88/x-literature-mcp.git
cd x-literature-mcp
npm ci
npm run build
python -m pip install pymupdf      # PyMuPDF ≥ 1.24, installed separately (AGPL-3.0 / commercial)

Related MCP server: research-mcp

Configuration (environment variables)

Variable

Required

Meaning

X_LIT_PDF_ROOT

yes

Absolute path of the PDF folder (scanned recursively; symlinks skipped)

X_LIT_CACHE_DIR

no

Absolute path for the derived cache. Default: <OS temp>/x-literature-mcp-cache. Must not be inside the PDF folder.

X_LIT_PYTHON

no

Python executable with PyMuPDF. Default python (Windows) / python3

Upgrading from mot-literature-mcp ≤ 0.1.1: the old variable names (prefix MOT_LIT_ instead of X_LIT_) are still read as a fallback when the new name is unset, with a deprecation warning on stderr. The fallback will be removed in 0.3.0. Set an explicit cache folder if you want to keep reusing an existing cache.

Register with Claude Code

Non-destructive (adds one entry, leaves other servers untouched). Replace the placeholder paths with your own.

macOS / Linux:

claude mcp add --scope user x-literature \
  -e X_LIT_PDF_ROOT="/path/to/your/papers" \
  -e X_LIT_CACHE_DIR="/path/to/x-literature-mcp-cache" \
  -- node "/path/to/x-literature-mcp/dist/server.js"

Windows (PowerShell):

claude mcp add --scope user x-literature `
  -e X_LIT_PDF_ROOT="C:\path\to\your\papers" `
  -e X_LIT_CACHE_DIR="C:\path\to\x-literature-mcp-cache" `
  -- node "C:\path\to\x-literature-mcp\dist\server.js"

Windows (CMD):

claude mcp add --scope user x-literature -e X_LIT_PDF_ROOT="C:\path\to\your\papers" -e X_LIT_CACHE_DIR="C:\path\to\x-literature-mcp-cache" -- node "C:\path\to\x-literature-mcp\dist\server.js"

Check: claude mcp list (should show x-literature … ✔ Connected), or /mcp inside Claude Code. Remove: claude mcp remove --scope user x-literature.

Other MCP clients / project scope: copy .mcp.json.example to .mcp.json (or into your client's MCP configuration) and replace the placeholder paths (.mcp.json is git-ignored here).

Run manually

# macOS / Linux
X_LIT_PDF_ROOT=/path/to/your/papers X_LIT_CACHE_DIR=/path/to/x-literature-mcp-cache node dist/server.js
# PowerShell
$env:X_LIT_PDF_ROOT = "C:\path\to\your\papers"; $env:X_LIT_CACHE_DIR = "C:\path\to\x-literature-mcp-cache"; node dist\server.js
:: CMD
set X_LIT_PDF_ROOT=C:\path\to\your\papers
set X_LIT_CACHE_DIR=C:\path\to\x-literature-mcp-cache
node dist\server.js

The process speaks MCP on stdin/stdout; logs go to stderr only. Exit code 2 = bad configuration.

Tools (final contract)

All page numbers are 1-based PDF page indices. paper_id = p + first 16 hex chars of the file's SHA-256 (byte-identical copies share one id; other paths are listed as duplicate_paths). Errors come back as isError: true with {"error": code, "message": …}.

Tool

Input

Output

list_papers

limit? (1–200, default 50), offset?, query? (substring of file name / title)

paper_id, file_name, path (relative), title_candidate {text, method, confidence}, page_count, sha256_prefix, parse_status (ok/partial/failed), references_found, pages_needing_visual_review, duplicate_paths; next_offset. Indexes unparsed PDFs on first call. Never returns full text.

get_paper_structure

paper_id

page_count, bookmarks (native PDF outline, source: pdf_bookmark), sections (font/numbering heuristics, source: inferred_heading, confidence: low), references location, per-page chars/images/flags, reading_order_warning, notes

read_paper_pages

paper_id, start_page, end_page? (≤ 10 pages per call), max_chars? (500–60000, default 12000), char_offset?

First line: JSON header with per-page chars_returned/page_chars/truncated/flags and next {start_page, char_offset} (exact continuation point, null at end). Then === page N/M === blocks of text.

render_paper_page

paper_id, page, scale? (0.5–3, default 1.5; longest edge ≤ 2400 px)

MCP image block (image/png) + JSON with size

get_paper_references

paper_id, offset?, limit? (1–200, default 50)

status (found/not_found), style (numeric/author-year), heading {page, text}, issues, excluded[] {page, reason, lines, numbers, preview} (v0.1.1), entries[] {index, number?, raw_text, page_start, page_end, fields {authors?, year?, title?, venue?, doi?, arxiv_id?}, issues, quality {year, attribution?}, candidates? {year}} (quality/candidates since v0.1.1)

search_papers

query (1–200 chars; space-separated terms are ANDed on one page), paper_ids?, limit? (1–100, default 20)

hits[] {paper_id, file_name, page, match_count, snippet, reread {tool, paper_id, start_page}}, papers_unavailable

refresh_index

force?

files_found, unique_papers, duplicate_files, parsed_now, reused_from_cache, partial, failed[] {paper_id, code}, elapsed_ms

Example calls:

{"name": "list_papers", "arguments": {"limit": 20}}
{"name": "read_paper_pages", "arguments": {"paper_id": "p0123456789abcdef", "start_page": 4, "end_page": 6, "max_chars": 15000}}
{"name": "render_paper_page", "arguments": {"paper_id": "p0123456789abcdef", "page": 5, "scale": 1.5}}
{"name": "get_paper_references", "arguments": {"paper_id": "p0123456789abcdef"}}
{"name": "search_papers", "arguments": {"query": "遮挡 外观特征"}}

How to read results honestly

  • Text comes from the PDF text layer in PyMuPDF block order. On two-column pages (two_column_layout flag) order can differ from the visual layout; formulas and tables are often garbled. Check them with render_paper_page.

  • Page flags: empty_text, low_text (little text on a page with images — possible scan), garbled_text (> 5 % replacement/private-use glyphs). These pages are listed in pages_needing_visual_review; there is no OCR.

  • sections are guesses from font and numbering; bookmarks are the only native structure.

  • Reference fields are rule-based candidates (GB/T 7714, CJIG author-year, IEEE, APA). They are not verified, and a citation alone says nothing about inheritance or experimental comparison. issues reports numbering gaps, duplicates (bilingual pairs, or another article sharing a journal page), dropped table fragments, and very long/short entries.

  • raw_text, page_start/page_end and the page images are the source of truth; everything parsed from them is a candidate.

Reference quality fields and issue codes (v0.1.1)

Field / code

Meaning

What to do

quality.year = verified_by_pattern

fields.year sits in a bibliographic position (, 2019, 45(3), , 2017: pages, (2021-07-18), CJIG Authors. 2019.). Page ranges, [YYYY-MM-DD] access dates, arXiv ids, DOIs and URLs are removed before matching.

Usable as the printed year (the printed year can still differ from the canonical one, e.g. conference vs. journal version).

quality.year = ambiguous

Four-digit candidates exist but none (or more than one value) is in such a position. fields.year is omitted; the values are in candidates.year. Issue YEAR_AMBIGUOUS.

Read raw_text.

quality.year = not_found

No year. Issue YEAR_NOT_FOUND if only an access date is printed; an arXiv id's posting year is offered in candidates.year.

Read raw_text.

YEAR_FUTURE_REJECTED

A placed year later than next year was refused.

Read raw_text.

quality.attribution = suspected_other_article + NUMBERING_RESTART_SUSPECTED

Numbering starts again at [1] after a run of entries; the tail is kept, not removed.

render_paper_page on page_start.

NUMBER_OUT_OF_SEQUENCE (entry)

A number re-appears after a higher one (table cell, body citation, or another article). Bilingual pairs do not trigger it.

Check the page.

OTHER_ARTICLE_TEXT_EXCLUDED + excluded[]

CNKI pages that carry two articles print (下转第N页) / (上接第N页) and a rule across the page. When this PDF has a 下转 marker, the region above a later 上接 marker is another article's; without one, the region below 上接 is another article's tail. That region is left out of entries; excluded lists page, reason, line count and the [n] numbers seen. Needs block bboxes; markers on page 1 are not split (CONTINUATION_MARKER_UNRESOLVED).

render_paper_page on excluded[].page.

FOREIGN_HEADING_SKIPPED

A 参考文献 heading inside such a region was not used as this paper's heading.

—

NUMBER_LABELS_REATTACHED

Some PDFs emit the hanging [n] label as its own text block after the entry text, which shifted every number by one. A bare label is re-attached to the block that starts on the same baseline to its right (table cells starting with a digit are never targets).

—

Not fixed by rules (check pages yourself): entries absorbing tables, figure captions, author bios or English abstracts; formula/table text-layer damage; lost words from font mapping.

  • Search is substring matching after NFKC + lower-casing + removing whitespace (so 卡尔\n曼滤波 matches 卡尔曼滤波); it is not semantic search.

Cache and safety

  • Cache entry: <X_LIT_CACHE_DIR>/papers/<sha256>.<extractor-version>.json, plus manifest.json (path, size, mtime, hash). A changed file gets a new hash, so its old cache entry and paper_id stop being used; refresh_index re-parses only new/changed files.

  • No tool accepts a path. Files are resolved from the scan result and re-checked (realpath inside the root, size/mtime unchanged) before each read.

  • One unreadable/encrypted PDF is recorded as failed and does not stop the others.

  • Do not commit papers, renders or caches; .gitignore excludes *.pdf, *.png, cache folders.

Development

npm ci
npm run typecheck
npm test            # builds, then: unit tests + real stdio MCP e2e on synthetic PDFs generated at test time

Troubleshooting

Symptom

Fix

worker_unavailable / PyMuPDF not installed

python -m pip install pymupdf, or set X_LIT_PYTHON to the interpreter that has it

pdf_root_missing

X_LIT_PDF_ROOT must be an existing absolute folder

Server exits with code 2

Missing/relative X_LIT_PDF_ROOT or X_LIT_CACHE_DIR (see stderr)

unknown_paper_id

The file changed or was removed; call list_papers again

encrypted / open_failed

Password-protected or damaged PDF; open it elsewhere

First list_papers slow

It parses all PDFs once (about 8 s for 53 two-column journal papers on a desktop PC); later calls use the cache

Changelog

  • 0.2.0 — renamed from mot-literature-mcp to X Literature MCP (x-literature-mcp); MCP server name mot-literature → x-literature; environment variables MOT_LIT_* → X_LIT_* (old names still read as a deprecated fallback, see Configuration); default cache folder <OS temp>/x-literature-mcp-cache. Tool names, inputs, outputs, paper_id and cache keys are unchanged.

  • 0.1.1 — reference extraction r5.pt-v4n3 (old caches are ignored and rebuilt automatically). Layout-aware handling of 下转/上接 continuation markers (another article's references no longer merged or chosen as the heading); detached [n] labels re-attached (fixes off-by-one numbering); publication year taken only from bibliographic positions, with quality.year / candidates.year and YEAR_* issue codes (page numbers, access dates and arXiv ids are no longer reported as years); CJIG entries without a terminator and Surname RW. initials split correctly; numbering-restart and out-of-sequence flags. Tool names, inputs and existing output fields are unchanged; new fields are additive.

  • 0.1.0 — MVP: seven tools, PyMuPDF worker, SHA-256 cache.

License

MIT (see LICENSE). Dependencies: @modelcontextprotocol/server (Apache-2.0), zod (MIT). PyMuPDF is AGPL-3.0 / commercial and is installed separately by the user; it is not bundled.

Available Tools

7 tools
get_paper_referencesGet paper referencesC
Read-only

Reference-list entries as printed (raw_text) with PDF page numbers, plus candidate fields (number/authors/year/title/venue/DOI) parsed by deterministic rules. Fields are unverified candidates (fields.year only when quality.year=verified_by_pattern; otherwise see candidates/issues); text left out as another article's (continuation-marker evidence) is listed in 'excluded' with its page. A citation says nothing about inheritance or experimental comparison.

NameRequiredDescriptionDefault
limitNodefault 50
offsetNo
paper_idYes

TDQS

C2.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context the annotations do not: parsed fields are unverified candidates, fields.year is only populated when quality.year=verified_by_pattern, and text attributed to another article appears under 'excluded' with its page. It still says nothing about pagination or result-size behavior.

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

Conciseness3/5

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

Three sentences, front-loaded on the return shape with no filler, which is good. But the prose is heavily compressed and jargon-laden ('quality.year=verified_by_pattern', 'continuation-marker evidence') without explaining those terms, forcing the agent to decode terse internal vocabulary.

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?

With no output schema, the description does a reasonable job characterizing the returned entry and candidate/excluded structure. But for a paginated list tool it omits pagination mechanics entirely and gives no hint about reference-list size or ordering, leaving a real gap for correct invocation.

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 coverage is only 33% — offset and paper_id have no schema descriptions — yet the description spends all of its words on output fields and never mentions limit, offset, or how to page through a long reference list. The one documented parameter (limit, default 50) is documented in the schema, not the description.

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

Purpose4/5

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

The description states a specific resource and return shape: reference-list entries as printed (raw_text) with PDF page numbers, plus rule-parsed candidate fields. An agent can tell this returns bibliography entries rather than page images or structure, but it never names a sibling (e.g. get_paper_structure) to sharpen the boundary.

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

Usage Guidelines2/5

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

There is no explicit when-to-use or when-not guidance and no alternative tool is named. The closing note ('A citation says nothing about inheritance or experimental comparison') is an interpretation caveat, not routing guidance, so the agent must infer usage from the tool name alone.

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

get_paper_structureGet paper structureA
Read-only

Page count, native PDF bookmarks (if any), inferred section headings with pages, per-page text coverage and quality flags, References location. Inferred items are marked inferred and may be wrong.

NameRequiredDescriptionDefault
paper_idYes

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely non-structured information: the distinction between native PDF bookmarks and inferred headings, that inferred items are flagged in the result, and that they may be inaccurate. What it omits is the cost/latency of structure extraction and whether a paper_id with no index entry errors or returns empty.

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

Conciseness4/5

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

A single dense sentence lists the returned facets, front-loaded with the most concrete items, followed by one short caveat sentence. Nothing is redundant, though the run-on enumeration is harder to scan than a short bulleted list would be.

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?

For a single-parameter read-only introspection tool with no output schema, the description must convey the return shape, and it does so as a facet list rather than a structured field mapping. The absence of an output schema means agents still cannot tell exact key names or nesting. Adequate for choosing the tool, thin for consuming its result.

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?

There is exactly one parameter and the schema documents none of its semantics (0% coverage), so the description carries the burden. It does not explain paper_id, but the tool-level framing (this operates on a single paper's PDF) plus the strictly patterned id format in the schema makes the parameter's meaning derivable. No additional syntax or format detail is offered, keeping this just below full marks.

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

Purpose4/5

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

The description names a specific resource (paper structure) and enumerates its components: page count, native bookmarks, inferred section headings with pages, per-page text coverage and quality flags, References location. This clearly distinguishes it from siblings like read_paper_pages (raw text) or get_paper_references (reference listing). It lacks an explicit verb ('Get/Return'), but the enumeration makes the purpose unambiguous.

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

Usage Guidelines2/5

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

The description never states when to use this tool versus read_paper_pages, render_paper_page, or search_papers, nor does it mention prerequisites or what to do if the structure looks wrong. The caveat that inferred items 'may be wrong' hints at a follow-up path but does not name an alternative tool. Usage must be fully inferred.

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

list_papersList papersA
Read-only

List PDFs in the configured literature folder (de-duplicated by SHA-256). Returns paper_id, file name, title candidate, page count, parse status. Never returns full text. Indexes not-yet-parsed PDFs on first call.

NameRequiredDescriptionDefault
limitNodefault 50
queryNocase-insensitive substring filter on file name / title candidate
offsetNodefault 0

TDQS

A4/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing a real side effect ("Indexes not-yet-parsed PDFs on first call"), the de-duplication key, the exact fields returned, and an explicit non-return ("Never returns full text"). The first-call indexing is a write to a local cache that readOnlyHint does not cover, so surfacing it is genuinely valuable context rather than a restatement.

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 dense sentences, front-loaded with the core action and scope, then side effect, then return contract. No filler and nothing repeated from the schema.

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 zero-required-param listing tool with no output schema, the description covers corpus, de-duplication, return fields, and the indexing side effect. The one gap is pagination: with limit/offset present it never says whether a total count is returned or how the agent should decide it has listed everything.

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 documents all three parameters (limit, query, offset) at 100% coverage, so the baseline is 3. The description adds nothing about filtering or paging behavior — notably it never says whether `query` narrows the listed set or how `offset`/`limit` interact with de-duplication.

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

Purpose4/5

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

States a specific verb and resource ("List PDFs in the configured literature folder") plus the scope qualifier of SHA-256 de-duplication, so the agent knows exactly what corpus is enumerated. It implicitly separates itself from read_paper_pages via "Never returns full text", but it never names search_papers or the other siblings as the alternative for filtered retrieval.

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

Usage Guidelines3/5

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

Usage is only implied: an agent can infer this is the browse/enumerate entry point before calling read_paper_pages or get_paper_structure. There is no explicit when-to-use versus search_papers, and no stated exclusions or prerequisites (e.g. that the folder must be configured).

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

read_paper_pagesRead paper pagesA
Read-only

Text of a page range (1-based, max 10 pages per call), each page kept separate with its real page number. Output is bounded by max_chars; when truncated, 'next' tells you exactly where to continue (start_page + char_offset). PDF text layer only: verify formulas/tables with render_paper_page.

NameRequiredDescriptionDefault
end_pageNodefault = start_page
paper_idYes
max_charsNodefault 12000
start_pageYes
char_offsetNoskip this many characters of start_page (continuation)

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare a safe, non-open-world read, so this earns credit for the extra behavior it discloses: a hard 10-page-per-call cap that is not encoded in the schema, output bounding via max_chars, and the exact shape of truncation metadata ('next' = start_page + char_offset). The 'PDF text layer only' caveat is a useful reliability warning that annotations cannot convey.

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, front-loaded with what the tool returns, followed by pagination mechanics and the one caveat. No filler and no restatement of the tool name.

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?

With no output schema, the description still tells the agent what comes back (per-page text with real page numbers) and how to resume after truncation. Combined with the page-range cap and the fidelity caveat, nothing material for a correct call is missing.

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

Parameters5/5

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

Coverage is only 60%, and the description fills the critical gaps: it supplies the 10-page limit that the schema's end_page maximum does not enforce, explains max_chars as an output bound rather than a filter, and defines char_offset/start_page as a continuation pair driven by the returned 'next' value.

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?

States a specific verb and resource (text of a page range), plus scope constraints: 1-based indexing, max 10 pages per call, and per-page separation keyed to real page numbers. It also implicitly separates itself from render_paper_page by noting it reads the PDF text layer only.

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?

Gives explicit routing guidance to the sibling render_paper_page for verifying formulas and tables, and explains the continuation path when output is truncated. It does not address the other siblings (search_papers, get_paper_structure), but the primary alternative for this decision is clearly named.

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

refresh_indexRefresh indexA
Idempotent

Rescan the PDF folder and (re)build the local derived cache. Never modifies PDFs. force=true re-parses every paper; otherwise only new/changed files are parsed. One failing file does not stop the others.

NameRequiredDescriptionDefault
forceNo

TDQS

A4.1/5.0
Behavior4/5

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

Beyond the annotations, it discloses the key behavioral facts: PDFs are never modified, force=true re-parses everything while the default only handles new/changed files, and a single failing file does not abort the batch. These are consistent with readOnlyHint=false, idempotentHint=true and destructiveHint=false. It omits how long a forced full re-parse takes and what the call returns, which keeps it from a 5.

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?

Four short sentences, each contributing a distinct fact: purpose, safety guarantee, parameter semantics, and failure isolation. The core action is front-loaded and nothing is repeated.

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, non-destructive maintenance tool with no output schema, the description covers purpose, side effects, parameter behavior and error handling. The only real gap is that it does not say what a caller learns from the result (e.g., counts of parsed or failed files), which matters given failure isolation is advertised.

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

Parameters5/5

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

Schema coverage is 0% for the single parameter, so the description carries the full burden and does: 'force=true re-parses every paper; otherwise only new/changed files are parsed.' This gives both the meaning and the default behavior, which the bare boolean schema does not.

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

Purpose4/5

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

The description opens with a specific verb+resource pair: 'Rescan the PDF folder and (re)build the local derived cache.' That immediately separates it from read-only siblings like list_papers or search_papers, which consume the index rather than build it. It stops short of naming any sibling explicitly, so an agent must infer the relationship.

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

Usage Guidelines3/5

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

Usage context is implied rather than stated: the incremental-by-default behavior suggests it is safe to call routinely, and force=true implies a rarer full rebuild. There is no explicit 'call this when X' or guidance on when another tool is the better choice. An agent can infer intent but is not told preconditions or cost trade-offs.

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

render_paper_pageRender paper pageA
Read-only

Render ONE page as a PNG image (for checking formulas, tables, figures, two-column reading order). scale 0.5–3 (default 1.5); longest edge capped at 2400 px.

NameRequiredDescriptionDefault
pageYes
scaleNo
paper_idYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered; the description adds genuinely new behavior — the PNG output format, the scale range/default, and the 2400 px longest-edge cap that can silently downsample output at high scales. It does not mention rendering latency or failure modes for out-of-range pages.

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 clauses, front-loaded with the core action and output format, followed by constraints. No filler, and every clause carries usable information for invocation.

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 read-only, single-parameter-set rendering tool with no output schema, the definition covers what is produced, how large it can be, and why an agent would want it. The remaining gap is minor: it never confirms the image is returned inline versus as a path/URL, which matters for a binary-producing tool.

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 description coverage is 0%, so the description must carry the load; it does well for scale (range 0.5–3, default 1.5, and the resolution cap) and conveys that page is a single page number. It adds nothing about paper_id's required format (^p[0-9a-f]{16}$) or that page numbering is 1-based, leaving two of three parameters partially or wholly undocumented.

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?

States a specific verb (render) and resource (ONE page) plus the output artifact (PNG image), so an agent knows exactly what it produces. The emphasis on 'ONE' implicitly contrasts with the multi-page sibling read_paper_pages, and the parenthetical use cases ground the tool concretely.

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 parenthetical use cases (checking formulas, tables, figures, two-column reading order) give clear situational context for selecting this tool over text-extraction siblings. It stops short of naming an explicit alternative or stating when not to use it, so it falls just below the top tier.

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

search_papersSearch papersA
Read-only

Keyword search over page text (Chinese/English substring, whitespace- and width-insensitive; multiple space-separated terms must all occur on the same page). Returns paper_id + page + snippet; re-read hits with read_paper_pages. Query ≤ 200 chars.

NameRequiredDescriptionDefault
limitNodefault 20
queryYes
paper_idsNo

TDQS

A4.2/5.0
Behavior4/5

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

Beyond readOnlyHint/openWorldHint, it discloses the exact matching algorithm, the AND-across-terms rule, the 200-char query cap, and the return payload shape (paper_id + page + snippet). It does not state the search scope when paper_ids is omitted (all papers vs. an indexed subset) or how limit interacts with hit ordering, but the behavioral core is disclosed.

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 dense clauses, front-loaded with the operation and followed by the matching rules and the next-step hint. No filler, no restatement of the tool name or title.

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?

With no output schema, the description usefully explains the return shape itself, and the matching semantics cover the hardest-to-guess behavior. The remaining hole is scoping: an agent cannot tell whether omitting paper_ids searches the whole library or only the current context.

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 description coverage is only 33%, so the description is expected to compensate. It explains the query parameter's semantics and length limit well, but says nothing about paper_ids (that it restricts the search to specific papers) or limit (default 20 is only in the schema), leaving two of three parameters uninterpreted.

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?

"Keyword search over page text" gives a specific verb (search) and resource (page text), and the parenthetical spells out the matching model precisely (Chinese/English substring, whitespace/width-insensitive, AND across terms). No sibling performs search, so the tool is unambiguous without needing disambiguation.

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?

It names the downstream step explicitly ("re-read hits with read_paper_pages"), which tells the agent this is a discovery tool, not a retrieval tool. It stops short of contrasting with list_papers or get_paper_structure, so an agent browsing broadly still has to infer when keyword search beats enumeration.

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.

  1. 7 tool updatesv0.2.0
    • First observedget_paper_references
    • First observedget_paper_structure
    • First observedlist_papers
    • First observedread_paper_pages
    • First observedrefresh_index
    • First observedrender_paper_page
    • First observedsearch_papers

TDQS

A4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct role, from listing and searching to reading, rendering, structural inspection, reference extraction, and index maintenance. The potentially overlapping read and render tools are explicitly differentiated as text extraction versus visual verification.

Naming Consistency5/5

All seven tools use consistent lowercase snake_case with a predictable verb_noun pattern. Singular and plural resource names appropriately reflect whether each operation handles one page, multiple pages, or multiple papers.

Tool Count5/5

Seven tools are well scoped for a local PDF literature server. Each earns its place without fragmenting simple operations or introducing redundant convenience tools.

Completeness5/5

The set covers the complete read-only literature workflow: corpus discovery, indexing, keyword search, paginated reading, visual inspection, document structure, and reference extraction. There are no obvious dead ends for its apparent purpose, and filesystem-based collection changes are handled through refresh_index.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables MCP clients to list indexed PDF document collections and perform semantic search queries on them using locally extracted text and embeddings.
    2
    AGPL 3.0
  • 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
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables MCP clients to read local PDFs as markdown, plain text, tables, or positioned blocks; inspect metadata; search documents; list and fill form fields into new files; and identify pages needing vision, while keeping documents on-machine and limiting access to allowed directories.
    9
    24 PyPI
    AGPL 3.0