← Back to search

@shuji-bonji/pdf-reader-mcp

GitHub Actions Scanned 25d ago

MCP server for PDF structure analysis - read, inspect, and validate PDF internals

B
79.8 / 100

Versions

0.11.1latest
Jul 27, 2026
0.11.0
Jul 27, 2026
0.10.0
Jul 26, 2026
0.9.2
Jul 25, 2026
0.9.1
Jul 19, 2026
+ show 14 moreshow less
0.9.0
Jul 19, 2026
0.8.0
Jul 18, 2026
0.7.0
Jul 18, 2026
0.6.3
Jul 13, 2026
0.6.2
May 8, 2026
0.6.1
May 8, 2026
0.6.0
May 7, 2026
0.5.0
May 6, 2026
0.4.0
May 6, 2026
0.3.0
May 6, 2026
0.2.3
May 6, 2026
0.2.2
Apr 18, 2026
0.2.1
Apr 18, 2026
0.2.0
Feb 7, 2026
PermissionsTool SafetyAuthAnnotationsCode QualityStabilitySpecVuln HistoryAuthorTransparencyCommunity

Tools 19

validate_metadata
annotations: verified low

[DEPRECATED — will be removed in the next major version] For standards conformance, prefer pdf-verify-mcp's \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
validate_tagged
annotations: verified low

[DEPRECATED — will be removed in the next major version] Prefer pdf-verify-mcp's \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
compare_structure
annotations: verified low

Compare the internal structures of two PDF documents and identify differences. Args: - file_path_1 (string): Absolute path to the first PDF file - file_path_2 (string): Absolute path to the second PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Structural comparison including: property-by-property diff (page count, PDF version, encryption, tagged status, object counts, page dimensions, file size, catalog entries, signatures), font comparison (fonts unique to each file and shared fonts), and a summary. The comparison needs both files, so an unreadable file is an error — but the error names which of the two could not be read, and says that the other one was fine. Examples: - Compare two versions of the same document - Verify structural consistency across PDF exports - Identify differences in PDF generation pipelines

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
inspect_signatures
annotations: verified low

Examine digital signature fields in a PDF document. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Total signature field count, signed/unsigned breakdown, and details for each field (signer name, reason, location, signing time, filter/subFilter). Note: This tool inspects signature field structure only. Cryptographic signature verification is not performed. Examples: - Check if a PDF has been digitally signed - Inspect signer information and signing dates - Verify signature field structure

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
extract_tables
annotations: verified low

Extract every \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
inspect_annotations
annotations: verified low

Extract and categorize all annotations in a PDF document. Args: - file_path (string): Absolute path to a local PDF file - pages (string, optional): Page range. Format: "1-5", "3", or "1,3,5-7". Omit for all pages. - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Total annotation count, breakdown by subtype (Link, Widget, Highlight, Text, etc.) and by page, flags for links/forms/markup presence, and individual annotation details. Examples: - Check for form fields (Widget annotations) - Find all links in a document - Inventory markup annotations (highlights, comments)

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
inspect_tags
annotations: verified low

Analyze the Tagged PDF structure tree for accessibility assessment. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Whether the PDF is tagged, the structure tree hierarchy with roles, max nesting depth, total element count, and role distribution (e.g., Document, P, H1, Table, Figure). Examples: - Check if a PDF is tagged for accessibility (PDF/UA) - Inspect the tag hierarchy and role distribution - Assess document structure quality

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
locate_objects
annotations: verified low

Report where the given objects sit on the page. Bridges "which object" to "which coordinates": pdf-verify-mcp's verify_integrity names the objects an incremental update changed, and pdf-writer-mcp's add_annotation wants a page number and a rectangle. The rectangle is returned in PDF user space (origin bottom-left, pt, x1 < x2 and y1 < y2 — ISO 32000-1 §7.9.5 normalised form), which is exactly what add_annotation takes. Args: - file_path (string): Absolute path to a local PDF file - object_numbers (number[]): Object numbers to locate, e.g. [25, 27] - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Per object: whether it exists, its /Type and /Subtype, and the places it occupies, each with the basis the coordinates rest on: - annotation-rect — the object's own /Rect. Exact. - page-box — the object is a page; the rectangle is its crop/media box. - page-content-stream — the object draws the page; the rectangle is the WHOLE page, not the part that changed. - page-resource — a font, image or colour space used by the page. No rectangle exists for it. Limits (observations, not judgements): - Narrowing a content stream to the paragraph that moved needs a content-stream walk with graphics state; this tool does not do it and says so rather than inventing a rectangle. - An object that does not exist (freed by a later revision) is returned with found: false — not as "no coordinates". - In an encrypted document, coordinates and types are still reliable (numbers and names are not encrypted, ISO 32000-1 §7.6.2) but field names are reported as null instead of mojibake. Examples: - Turn verify_integrity's "obj 27 was added after signing" into a page and rectangle - Find which page a changed form field widget is on before annotating it

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
inspect_fonts
annotations: verified low

List all fonts used in a PDF document with their properties. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Font name, type (TrueType, Type1, CIDFont, etc.), encoding, embedded/subset status, and pages where each font is used. Examples: - Check if all fonts are embedded (required for PDF/A, PDF/X) - Identify font types and encodings - Find which pages use specific fonts

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
extract_structured_text
annotations: none low

Extract a tagged PDF's text in logical content order, with each piece labelled by its structure type. This answers "what is the text of the H1?" — which read_text (flat, coordinate order), inspect_tags (structure, no text) and extract_tables (text, tables only) each cannot. Args: - file_path (string): Absolute path to a local PDF file - pages (string, optional): Page range ("1-5", "3", "1,3,5-7"). Omit for all pages. An element that touches the range is returned whole, even if it continues outside it. - roles (string[], optional): Structure types to include, e.g. ["H1","H2"] for an outline - include_bbox (boolean): Also report where each element is drawn (default: false) - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: isTagged, the document language, and a flat list of elements in logical content order. Each element has: role, depth (nesting; top level is 0), text, pages, and optionally alt / label / rows / boxes / boxNote. \

inspect_structure
annotations: verified low

Examine PDF internal object structure including catalog entries, page tree, and object statistics. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Catalog entries (keys and COS types), page tree info (page count, MediaBox samples), object statistics, and encryption status. Object statistics report three separate counts: - byType: the COS type of each indirect object (ISO 32000-2 §7.3) — one of dict, stream, array, name, string, integer, real, boolean, null, ref - byDocType: the /Type of each dictionary (Catalog, Pages, Page, Font, ObjStm, XRef, ...) - unreadable: objects the cross-reference table names but that could not be read. This is counted apart from totalObjects: 0 means "every object was read", not "nothing was checked". Examples: - Examine document catalog for structural features - Count PDF objects and streams - Check page dimensions across the document

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
search_text
annotations: verified low

Search for text within a PDF document. Returns matching locations with surrounding context. Case-insensitive search across all or specified pages. Each match includes the page number, the matched text, and configurable surrounding context. The search runs over the same text \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
get_metadata
annotations: verified low

Extract metadata from a PDF document including title, author, creation date, page count, PDF version, and structural information. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Metadata including: title, author, subject, keywords, creator, producer, creation/modification dates, page count, PDF version, linearized/encrypted/tagged/signature flags, file size. Examples: - Get document properties for cataloging - Check if a PDF is tagged (accessibility) - Verify PDF version compatibility

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
read_images
annotations: verified low

Extract embedded images from a PDF document as PNG or JPEG files. Each image is returned as an MCP image content block, so a vision-capable model can look at it directly. A text block lists the metadata for all of them (page, index, size in the file, size returned, colour space, encoded bytes). These are the image XObjects the page draws, not a picture of the page. A page whose content is vector drawing, or whose text is what you want to see, is not covered by this tool. Response size is bounded: at most ${(MAX_IMAGE_RESPONSE_BYTES / (1024 * 1024)).toFixed(0)} MB of encoded image data per call. Images beyond the budget are named in the text block with the reason and are not returned — nothing is dropped silently. A 200 dpi A4 scan is ~11.6 MB of pixels on its own, so pass \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
read_url
annotations: verified low

Fetch a PDF from a URL and extract its text content. Text is ALL this tool returns — see the scope note below. Downloads the PDF from the specified URL, then extracts text with Y-coordinate-based reading order. Supports HTTP and HTTPS. Maximum file size: 50MB. Timeout: 30 seconds. **Scope (#25):** the fetched bytes are discarded after extraction; this tool deliberately does not save them. Every other tool of this server takes a \

readOnlyHint true openWorldHint true idempotentHint false destructiveHint false
summarize
annotations: verified low

Generate a quick overview report of a PDF document. Combines metadata, text presence check, image count, and a text preview from the first page into a single summary. Useful as a first step before deciding which detailed tools to use. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
read_text
annotations: none low

Extract text content from a PDF document with Y-coordinate-based reading order preservation. Text is extracted page by page, sorted by vertical position (top to bottom) then horizontal position (left to right), providing natural reading order. \

get_page_count
annotations: verified low

Get the total number of pages in a PDF document. This is a lightweight operation that only reads the PDF header, not the full content. Args: - file_path (string): Absolute path to a local PDF file Returns: Page count as a number. Examples: - Quick check before deciding which pages to extract - Validate a PDF file is readable

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false
render_page
annotations: verified low

Rasterise pages of a PDF to PNG or JPEG images, returned as MCP image content blocks. This is the tool for documents whose text cannot be read as text: pages \

readOnlyHint true openWorldHint false idempotentHint true destructiveHint false

Permissions 4

network medium
Server uses network capabilities via: fetch()
filesystem low
Server uses filesystem capabilities via: fs/promises
shell high
Server uses shell capabilities via: child_process, spawn()
env_vars low
Server uses env_vars capabilities via: process.env

Scan Findings 71

info
Tool 'validate_metadata' annotations are consistent annotation_checker · 80%
info
Tool 'validate_tagged' annotations are consistent annotation_checker · 80%
info
Tool 'compare_structure' annotations are consistent annotation_checker · 80%
info
Tool 'inspect_signatures' annotations are consistent annotation_checker · 80%
info
Tool 'extract_tables' annotations are consistent annotation_checker · 80%
info
Tool 'inspect_annotations' annotations are consistent annotation_checker · 80%
info
Tool 'inspect_tags' annotations are consistent annotation_checker · 80%
info
Tool 'locate_objects' annotations are consistent annotation_checker · 80%
info
Tool 'inspect_fonts' annotations are consistent annotation_checker · 80%
low
Tool 'extract_structured_text' has no annotations annotation_checker · 100%
info
Tool 'inspect_structure' annotations are consistent annotation_checker · 80%
info
Tool 'search_text' annotations are consistent annotation_checker · 80%
info
Tool 'get_metadata' annotations are consistent annotation_checker · 80%
info
Tool 'read_images' annotations are consistent annotation_checker · 80%
info
Tool 'read_url' annotations are consistent annotation_checker · 80%
info
Tool 'summarize' annotations are consistent annotation_checker · 80%
low
Tool 'read_text' has no annotations annotation_checker · 100%
info
Tool 'get_page_count' annotations are consistent annotation_checker · 80%
info
Tool 'render_page' annotations are consistent annotation_checker · 80%
info
Sandbox failed to start for behavioral verification behavioral_verifier · 100%
medium
Vulnerable dependency: vitest@3.0.0 (GHSA-5xrq-8626-4rwp) dependency_analyzer · 95%
medium
Vulnerable dependency: vitest@3.0.0 (GHSA-82fw-gwwq-j7x9) dependency_analyzer · 95%
medium
Vulnerable dependency: vitest@3.0.0 (GHSA-9crc-q9x8-hgqq) dependency_analyzer · 95%
medium
High-entropy string (5.78 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/scripts/golden.mjs:177 entropy_analyzer · 51%
medium
High-entropy string (6.00 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/scripts/golden-specimens-halves.mjs:41 entropy_analyzer · 54%
medium
High-entropy string (5.81 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/15-reading-scope.test.ts:87 entropy_analyzer · 52%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/15-reading-scope.test.ts:85 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/16-render-timeout.test.ts:30 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/03-tier1-images.test.ts:111 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/03-tier1-images.test.ts:132 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/03-tier1-images.test.ts:157 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/03-tier1-images.test.ts:182 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/13-render-page.test.ts:62 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/13-render-page.test.ts:94 entropy_analyzer · 75%
medium
High-entropy string (5.82 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/halves-specimens.ts:41 entropy_analyzer · 52%
medium
High-entropy string (6.06 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/11-tier2-locate-objects.test.ts:25 entropy_analyzer · 55%
medium
High-entropy string (5.73 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/11-tier2-locate-objects.test.ts:35 entropy_analyzer · 50%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/e2e/11-tier2-locate-objects.test.ts:25 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/tier1/struct-tree-walker.test.ts:26 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/tier1/recover-service.test.ts:33 entropy_analyzer · 75%
medium
Buffer.from base64 in shuji-bonji-pdf-reader-mcp-d1cae30/tests/tier1/signature-service.test.ts:42 entropy_analyzer · 75%
medium
High-entropy string (5.97 bits/char) in shuji-bonji-pdf-reader-mcp-d1cae30/src/services/structure-service.ts:40 entropy_analyzer · 54%
info
package.json metadata manifest_parser · 100%
info
Tool: validate_metadata manifest_parser · 85%
info
Tool: validate_tagged manifest_parser · 85%
info
Tool: compare_structure manifest_parser · 85%
info
Tool: inspect_signatures manifest_parser · 85%
info
Tool: extract_tables manifest_parser · 85%
info
Tool: inspect_annotations manifest_parser · 85%
info
Tool: inspect_tags manifest_parser · 85%
info
Tool: locate_objects manifest_parser · 85%
info
Tool: inspect_fonts manifest_parser · 85%
info
Tool: extract_structured_text manifest_parser · 85%
info
Tool: inspect_structure manifest_parser · 85%
info
Tool: search_text manifest_parser · 85%
info
Tool: get_metadata manifest_parser · 85%
info
Tool: read_images manifest_parser · 85%
info
Tool: read_url manifest_parser · 85%
info
Tool: summarize manifest_parser · 85%
info
Tool: read_text manifest_parser · 85%
info
Tool: get_page_count manifest_parser · 85%
info
Tool: render_page manifest_parser · 85%
info
Transport: stdio manifest_parser · 90%
info
Required env vars (3) manifest_parser · 80%
info
Sandbox failed to start for output poisoning scan output_poisoning · 100%
medium
Permission: network access detected permission_analyzer · 70%
low
Permission: filesystem access detected permission_analyzer · 90%
high
Permission: shell access detected permission_analyzer · 95%
low
Permission: env_vars access detected permission_analyzer · 90%
info
SBOM generated: 169 components sbom_generator · 100%
medium
No build provenance detected (SLSA L0) slsa_assessor · 90%