Skip to main content
Glama
shuji-bonji

pdf-verify-mcp

by shuji-bonji

Check ISO 32000 Clause Constraints

validate_clauses
Read-onlyIdempotent

Checks a PDF against ISO 32000-1/-2 clauses to detect specification violations that PDF/A or PDF/UA validation misses. Reports per-constraint pass/fail status with clause IDs.

Instructions

Check a PDF against constraints mapped from ISO 32000-1/-2 clauses — the body of the PDF specification itself, not PDF/A or PDF/UA.

This covers what veraPDF does not look at. veraPDF judges PDF/A and PDF/UA profiles; a document can pass those and still violate ISO 32000 (for example embedding a CFF font program under /FontFile2, which Table 124 forbids).

The mapping and its evaluation live in @shuji-bonji/pdf-constraints; this tool reports which version decided the result. Same file plus same given facts always produce the same result.

Bundled domains: font-embedding, document-metadata, annotation

Args:

  • file_path (string): Absolute path to a local PDF file

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

  • domains (string[], optional): Restrict to specific domains

  • given (object, optional): External facts, e.g. { "isSubset": true }

Returns: Every report begins with a "scope" object - how far the reading got, not a verdict: whether the cross-reference chain could be walked to the end (chainStop), whether this tool had to rebuild the cross-reference table itself (reconstructed - when true, the table is this tool's reconstruction and not the one the file carries), how many objects and sections were read, and whether an encrypted document could be opened. Read it before the verdict: "no violations" over a rebuilt table is not the same statement as "no violations" over the file's own table.

Size (v0.29.0): results lists at most 200 entries (file order); violations and notDecided are counted over all of them and resultsTruncated = { returned, total } says when the list was cut. JSON is never cut by length.

Per-constraint results with the clause IDs they come from. Four states:

  • pass — nothing in this constraint could be disproved

  • fail — disproved, with the fact and its measured value as evidence

  • not_applicable — the clause does not apply to this document

  • needs_external_fact — a fact outside the file was not supplied, so the constraint was not decided (never defaulted into a pass)

Because these are T1 clauses, a failure can be stated plainly and the clause ID quoted — retrieve the wording with pdf-spec-mcp's get_requirements. Failures marked as traces are different: the clause addresses the PDF processor, so the file only shows that someone broke it, not that the last writer did.

Some failures carry a Context note. Those clauses are real and the failure is real, but the industry deviates from them deliberately — text markup QuadPoints are written in Z order by nearly every writer because following the clause literally breaks rendering in major viewers. Pass the context on; a failure reported without it reads as a defect.

Every result also carries observation — how far the reading got: whether the revision chain could be walked to the end, how many objects the cross-reference tables list, and whether the page tree was reached. This is the scope of the verdict, not a verdict. A subject count of zero means "not looked at" when the page tree was not reached; a chain that stopped early means the constraints were applied to part of the file. Read it before the numbers.

A result with no failures is not proof of conformance — only that nothing in the bundled constraints could be disproved.

Examples:

  • Find out why a viewer warns about a font that veraPDF considers fine

  • Check whether Info and XMP agree on the document dates (§14.3.4)

  • Verify a generated PDF before shipping it, beyond the PDF/A profile

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
givenNoFacts that are NOT in the file but are needed to decide some clauses, e.g. { "isSubset": true }. A clause whose applicability depends on a missing fact is reported as needs_external_fact — it is never defaulted into a pass.
domainsNoConstraint domains to apply. Omit to apply all bundled domains (font-embedding, document-metadata, annotation).
file_pathYesAbsolute path to a local PDF file (e.g., "/path/to/document.pdf")
response_formatNoOutput format: "markdown" for human-readable, "json" for structured datamarkdown

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.29.1

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, non-destructive behavior. The description adds substantial behavioral context beyond that: determinism ('Same file plus same given facts always produce the same result'), result-size limits and truncation semantics (200 entries, resultsTruncated), the reconstruction of the cross-reference table and its meaning, the four decision states including needs_external_fact (never defaulted into pass), and the warning that 'A result with no failures is not proof of conformance'. This is far more transparency than annotations alone provide.

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?

The description is long but appropriate for the tool's complexity. It is front-loaded with the core purpose, then structured into Args, Returns, and Examples. There is some redundancy (e.g., 'observation' is explained multiple times, and the 'scope' warning appears twice), which slightly dilutes conciseness, but each section earns its place by conveying necessary detail for correct invocation and interpretation.

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?

Given the absence of an output schema, the description must carry the full burden of explaining return semantics. It does so thoroughly: public scope object, result states, evidence for failures, context notes, traces, truncation, observation fields, and the conformance caveat. For a tool with nested parameters and complex outcomes, nothing essential for correct use is missing.

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 100% for all four parameters, giving a baseline of 3. The description adds meaning beyond that: it explains the 'given' parameter as external facts that can yield needs_external_fact outcomes, contextualizes 'domains' as the bundled set (font-embedding, document-metadata, annotation), and clarifies response_format choices. It does not repeat schema details but enriches them with operational consequences.

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 precise verb ('Check') and resource ('a PDF'), then delimits the scope: constraints mapped from ISO 32000-1/-2 clauses, explicitly excluding PDF/A or PDF/UA. It distinguishes itself from veraPDF and sibling conformance tools by pointing out what it covers that they do not. This gives an agent a clear, non-overlapping purpose.

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 explains when this tool is appropriate: when veraPDF is insufficient (e.g., 'Find out why a viewer warns about a font that veraPDF considers fine') and for going beyond PDF/A profiles before shipping. It names veraPDF as the alternative for profile checks. It does not explicitly enumerate exclusions for every sibling (signatures, integrity, policy), but the scope definition ('not PDF/A or PDF/UA') and examples make the intended use fairly unambiguous.

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