Skip to main content
ClaudeWave

MCP server for PDF authenticity verification — cryptographic digital signature verification, tamper detection, PAdES baseline level detection, and PDF/A / PDF/UA declaration identification.

MCP ServersOfficial Registry0 stars0 forksTypeScriptMITUpdated today
ClaudeWave Trust Score
95/100
Verified
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
  • Documented (README)
Last scanned: 9/19/2026
Install in Claude Code / Claude Desktop
Method: Manual
Claude Code CLI
git clone https://github.com/shuji-bonji/pdf-verify-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "pdf-verify-mcp": {
      "command": "node",
      "args": ["/path/to/pdf-verify-mcp/dist/index.js"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Clone https://github.com/shuji-bonji/pdf-verify-mcp and follow its README for install instructions.
Use cases

MCP Servers overview

# pdf-verify-mcp

[![CI](https://github.com/shuji-bonji/pdf-verify-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/shuji-bonji/pdf-verify-mcp/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/@shuji-bonji/pdf-verify-mcp.svg)](https://www.npmjs.com/package/@shuji-bonji/pdf-verify-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

[日本語](./README.ja.md)

MCP server for PDF **authenticity and conformance verification** — cryptographic digital signature verification, tamper detection, PAdES baseline level detection, and PDF/A (ISO 19005) / PDF/UA (ISO 14289) validation.

Part of the PDF family alongside [pdf-reader-mcp](https://github.com/shuji-bonji/pdf-reader-mcp) (structure analysis) and [pdf-spec-mcp](https://github.com/shuji-bonji/pdf-spec-mcp) (specification reference). Where `pdf-reader-mcp` tells you *what is in* a PDF, `pdf-verify-mcp` tells you *whether it is genuine*.

## Tools

| Tool | Purpose |
|------|---------|
| `verify_signatures` | Cryptographic verification, trust chain evaluation against trust anchors, revocation checking (embedded OCSP/CRL or online), RFC 3161 timestamp verification |
| `verify_integrity` | Tamper detection: incremental updates, changes after signing, **DocMDP certification violations assessed per P value** (below), and an object-level diff of the revision chain (which objects each update added, rewrote or freed). Incremental updates are legal, so the diff says what to review — no verdict rests on it. Where those objects sit on the page is [pdf-reader-mcp](https://github.com/shuji-bonji/pdf-reader-mcp) `locate_objects` |
| `detect_pades_level` | PAdES baseline level (B-B / B-T / B-LT / B-LTA) with content-validated LTV data |
| `identify_conformance` | Declared PDF/A / PDF/UA conformance from XMP metadata |
| `validate_conformance` | PDF/A (ISO 19005) and PDF/UA (ISO 14289) validation: veraPDF when installed, built-in rule subset otherwise |
| `validate_clauses` | Constraints mapped from ISO 32000-1/-2 clauses — the specification body itself, which the PDF/A and PDF/UA profiles do not cover |
| `evaluate_policy` | Deterministic 4-value trust verdict (trust_and_use / use_with_caution / human_review_required / reject) from a fixed rule table over the verification facts, with domain profiles (contract, financial, legal, medical, government). The judge is code; the narrative is the LLM |

## Verdicts

| Verdict | Meaning |
|---------|---------|
| `valid` | ByteRange digest matches and the CMS signature is cryptographically valid |
| `invalid` | Digest mismatch or signature verification failure — possible tampering |
| `indeterminate` | Unsupported format or verification could not complete |

## DocMDP certification permissions (v0.14)

A certification signature's `P` value states **which kinds of change are allowed**
(ISO 32000-2 **Table 257**). `verify_integrity` classifies the changes made after signing at the
object level and compares them against what that `P` permits.

| P | Permitted changes | Is adding an annotation a violation? |
|---|---|---|
| 1 | none (DSS / document-timestamp incremental updates are the §12.8.2.2 exception) | **yes** |
| 2 | filling in forms, instantiating page templates, signing | **yes** — annotations start at 3 |
| 3 | as for 2, plus annotation creation, deletion and modification | no |

Objects that a permitted change **necessarily drags along** — the page whose `/Annots` grew, the
catalog, `/Info`, the XMP stream — are classified as `housekeeping` and are not counted as
violations. Counting them would make *every* certified document violate, since a lawful P=3
annotation addition moves all four.

### `violationAssessment` is three-valued

| Value | Meaning |
|---|---|
| `permitted` | every change after signing is of a kind `P` allows |
| `violated` | at least one change is outside it |
| `indeterminate` | **it could not be determined** (the xref chain could not be walked, or a changed object's kind could not be read) |

> ⚠️ **`indeterminate` is not a pass.** This server disproves, and "could not be disproved" is a
> different statement from "is fine" — the same discipline as `validate_clauses` returning
> `needs_external_fact` rather than defaulting a check into a pass.
>
> `violatedByLaterChanges` (boolean) is kept for compatibility and **collapses `indeterminate` to
> `false`**. Read `violationAssessment` wherever "could not tell" must not be mistaken for
> "fine". `evaluate_policy` raises `indeterminate` to `human_review_required` as well.

A bare stream with no `/Type` is treated as *not determined* rather than as `content`: the same
bytes could be a form field's appearance stream (which P=2 permits) or a page's content stream
(which no P permits).

## Response size (v0.29.0)

A JSON response is never cut by length. Lists are capped instead, and every cut is reported next to the list as `{ returned, total }`: `signatures` / `levels` at 32 (`verify_signatures` does not verify the fields beyond the cap; `evaluate_policy` verifies all and caps only `facts.signatures`), `revisions` at 32, `violations` / `results` at 200 (counts such as `compliant`, `failedRules`, `violations`, `notDecided` cover all entries). A markdown response is cut at 50,000 characters with a visible marker.

## Trust & revocation (v0.2)

Pass `trust_anchors` (PEM/DER file paths) or set the `PDF_VERIFY_TRUST_ANCHORS` env var (a directory of certificates) to evaluate the signer's chain: results are `trusted` / `untrusted` / `not_evaluated` with the certificate path. The validation time is a verified signature timestamp, else the earliest document timestamp covering the signature, else the current time (v0.27.0); the CMS `signingTime` attribute is written by the signer and is not used. The chosen time is reported as `validationTime`.

`check_revocation` controls revocation checking: `embedded` (default — OCSP/CRL data in the DSS, CMS `SignedData.crls`, or the CMS signed attribute `adbe-revocationInfoArchival`; reported as `revocation.origin`), `online` (additionally query OCSP responders and CRL distribution points over HTTP), or `none` (`revocation.status: not_checked`). CRLs and OCSP responses whose signatures cannot be verified, whose `nextUpdate` is before the validation time, or whose `thisUpdate` is more than `revocation_freshness` seconds (default 86400) before it give `unknown` (v0.28.0). Pass `trusted_ocsp_responders` to trust an OCSP responder issued by another CA. Each intermediate CA's result is reported in `trust.chainRevocation`. A revoked signer certificate gives `revoked_after_validation_time` (verdict unchanged) when a timestamp proves the signature predates the revocation; otherwise `revoked` with verdict `indeterminate`. In online mode, missing issuer certificates are fetched via AIA caIssuers to complete the chain (v0.4). When anchors are provided, TSA certificate chains of RFC 3161 timestamps are evaluated too (`tsaTrust`).

| Step | What is checked | Network |
| --- | --- | --- |
| Integrity | `/ByteRange` hash matches the CMS `messageDigest` | none |
| Signature value | Signature value verifies with the signer certificate's public key | none |
| Certificate chain | Chains up to a trust anchor | `online` only: issuer certificates fetched via AIA caIssuers |
| Revocation | OCSP / CRL for the signer certificate | none under `embedded`; under `online`, HTTP queries when embedded data gives no answer |
| Timestamp | RFC 3161 token and TSA signature | none |

`verdict: valid` means integrity and signature value passed (`revoked` turns it into `indeterminate`). `online` results reflect the CA's state at query time and can change later. See the [site guide](https://shuji-bonji.github.io/pdf-agent-stack/mcp/pdf-verify#what-signature-verification-checks) for each step and how to choose a mode.

> Without trust anchors, `trust` stays `not_evaluated` and a `valid` verdict asserts cryptographic integrity, not signer identity.

Encrypted PDFs are decrypted automatically when permission-encrypted (empty user password); pass `password` for reader-password PDFs. Supported: RC4 (R2–R4), AES-128, AES-256 (R6). Decryption recovers string metadata (field name, /M, /Reason, /Location) and XMP — a signature's `/Contents` is exempt from encryption, so verification never depends on it.

Supported SubFilters: `ETSI.CAdES.detached` (PAdES), `adbe.pkcs7.detached`, `ETSI.RFC3161` (document timestamps). RFC 3161 signature timestamps are fully verified (imprint + TSA signature). Legacy MD5/SHA-1 signatures are verified via node:crypto and flagged as weak.

## PDF/A validation (v0.3)

`validate_conformance` uses a hybrid engine. With veraPDF installed (`PDF_VERIFY_VERAPDF` env var or on PATH) validation is delegated for authoritative results. Otherwise a built-in subset of ~15 high-value ISO 19005 rules runs natively (encryption, trailer /ID, LZW, font embedding, JavaScript/prohibited actions, OutputIntent, transparency for A-1, XFA, and more), each reported with its clause reference.

Native results are honest about their limits: violations mean definitively non-compliant; all-passed means "no violations in the checked subset" — never certification.

PDF/A-4 (`pdfa-4`, `pdfa-4e`, `pdfa-4f`) is accepted. Note that **PDF/A-4 has no conformance level** — there is no `pdfa-4b`; `e` and `f` are variants. The native rules were written from ISO 19005-1/-2 and have not been checked against ISO 19005-4, so a PDF/A-4 report says outright that the native verdict ranks below veraPDF. Validate part 4 with veraPDF.

## ISO 32000 clause constraints (v0.9)

`validate_clauses` covers different ground: the **body of the PDF specification**, not the PDF/A or PDF/UA profiles. A file can be judged COMPLIANT by veraPDF and still violate ISO 32000 — embedding a CFF font program under `/FontFile2` (Table 124) is a real example that surfaced only as a viewer warning.

The mapping from clauses to structural conditions, and its evaluation, li
mcp-serverpdfpdf-verify

What people ask about pdf-verify-mcp

What is shuji-bonji/pdf-verify-mcp?

+

shuji-bonji/pdf-verify-mcp is mcp servers for the Claude AI ecosystem. MCP server for PDF authenticity verification — cryptographic digital signature verification, tamper detection, PAdES baseline level detection, and PDF/A / PDF/UA declaration identification. It has 0 GitHub stars and its last recorded update is dated 2026-09-19.

How do I install pdf-verify-mcp?

+

You can install pdf-verify-mcp by cloning the repository (https://github.com/shuji-bonji/pdf-verify-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is shuji-bonji/pdf-verify-mcp safe to use?

+

Our security agent has analyzed shuji-bonji/pdf-verify-mcp and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains shuji-bonji/pdf-verify-mcp?

+

shuji-bonji/pdf-verify-mcp is maintained by shuji-bonji. The last recorded GitHub activity is dated 2026-09-19, with 0 open issues.

Are there alternatives to pdf-verify-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy pdf-verify-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: shuji-bonji/pdf-verify-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/shuji-bonji-pdf-verify-mcp)](https://claudewave.com/repo/shuji-bonji-pdf-verify-mcp)
<a href="https://claudewave.com/repo/shuji-bonji-pdf-verify-mcp"><img src="https://claudewave.com/api/badge/shuji-bonji-pdf-verify-mcp" alt="Featured on ClaudeWave: shuji-bonji/pdf-verify-mcp" width="320" height="64" /></a>

More MCP Servers

pdf-verify-mcp alternatives