PDF Verify (PDF Agent Stack)

io.github.shuji-bonji由 GitHub 帳號 shuji-bonji 發布v0.35.0更新於 Nov 6, 2026

Verify PDF signatures, detect tampering, and identify PDF/A and PAdES conformance levels.

已驗證STDIO僅桌面檔案與儲存安全與監控

概覽

AI 產生的概覽

本機 MCP 伺服器,用來查核 PDF 真實性:驗證數位簽章、偵測簽署後的變更,並回報 PDF/A、PDF/UA 與 PAdES 結構。

可以做什麼
  • 以密碼學方式驗證簽章,包含 RFC 3161 時間戳、信任鏈與撤銷狀態
  • 偵測竄改:增量更新、簽署後變更、DocMDP 權限違規及物件層級差異
  • 觀察 PAdES 基準等級,以及中繼資料中宣告的 PDF/A 或 PDF/UA 符合性
  • 依 PDF/A、PDF/UA 規範驗證(已安裝 veraPDF 時交由它判定),或檢查 ISO 32000 條款限制
  • 產生確定的四級信任判定,支援領域設定,並清點文件中的作用中內容
適用情境
需要判斷已簽署 PDF 是否真實、簽署後是否被變更,或文件是否宣告並符合 PDF/A、PDF/UA 時適用,例如合約、檔案、發票或無障礙檢查。
執行需求
以 stdio 在本機執行,通常透過 npx 呼叫該 npm 套件。不需帳號或 API 金鑰。選用:安裝 veraPDF 或以 PDF_VERIFY_VERAPDF 指定路徑,取得權威的 PDF/A、PDF/UA 結果;以 PDF_VERIFY_TRUST_ANCHORS 或 trust_anchors 路徑評估簽署者身分;線上撤銷模式需要網路存取。
安裝前請注意
結果用於否證而非認證:未提供信任錨點時,valid 只代表密碼學完整性,不代表簽署者身分,撤銷狀態也可能未檢查。沒有 veraPDF 時的原生驗證只是較弱的子集。線上撤銷模式會透過 HTTP 查詢 OCSP 回應端與 CRL 發佈點。加密 PDF 的密碼以工具參數傳入。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 PDF Verify (PDF Agent Stack),將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

pdf-verify-mcp

[CI] [npm version] [License: MIT]

日本語

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 (structure analysis) and 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

ToolPurpose
verify_signaturesCryptographic verification, trust chain evaluation against trust anchors, revocation checking (embedded OCSP/CRL or online), RFC 3161 timestamp verification
verify_integrityTamper 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 locate_objects
detect_pades_levelPAdES baseline level (B-B / B-T / B-LT / B-LTA) with content-validated LTV data
identify_conformanceDeclared PDF/A / PDF/UA conformance from XMP metadata
validate_conformancePDF/A (ISO 19005) and PDF/UA (ISO 14289) validation: veraPDF when installed, built-in rule subset otherwise
validate_clausesConstraints mapped from ISO 32000-1/-2 clauses — the specification body itself, which the PDF/A and PDF/UA profiles do not cover
evaluate_policyDeterministic 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

VerdictMeaning
validByteRange digest matches and the CMS signature is cryptographically valid
invalidDigest mismatch or signature verification failure — possible tampering
indeterminateUnsupported 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.

PPermitted changesIs adding an annotation a violation?
1none (DSS / document-timestamp incremental updates are the §12.8.2.2 exception)yes
2filling in forms, instantiating page templates, signingyes — annotations start at 3
3as for 2, plus annotation creation, deletion and modificationno

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

ValueMeaning
permittedevery change after signing is of a kind P allows
violatedat least one change is outside it
indeterminateit 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.

Content inventory in evaluate_policy (v0.30.0)

evaluate_policy also counts what the document carries that acts, or that is unfinished, and reports it under facts.content — the counts of ISO 32000-2 §12.8.7 Table 264 (legal content attestations): JavaScriptActions, LaunchActions, URIActions, GoToRemoteActions, HideAnnotationActions, MovieActions, SoundActions, plus SubmitFormActions, the URI hosts, whether /OpenAction or a document /AA is present, the annotation count, and the number of /Subtype /Redact annotations still in the file. Nested (direct) action dictionaries are walked, so an inline /A on a link counts. Two rules read it:

  • POL-CAUTION-REDACT-PENDING — a redaction annotation is still present (ISO 32000-2 §12.5.6.23). An applied redaction leaves no annotation behind, so the content it marks has not been removed from the file. use_with_caution.
  • POL-CAUTION-ACTIVE-CONTENT — ECMAScript, Launch, remote go-to, or SubmitForm/ImportData actions are present; the reason says whether /OpenAction / /AA makes some of it run on open. use_with_caution. URI actions never change the verdict; their hosts go to an advisory.

The inventory is an observation, not a verdict: null (could not be taken) is reported as "not counted", never as 0, and unreadable objects make the counts lower bounds. Keys of Table 264 that are not counted: AlternateImages, ExternalStreams, TrueTypeFonts, ExternalRefXobjects, ExternalOPIdicts, NonEmbeddedFonts, DevDepGS_*.

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).

StepWhat is checkedNetwork
Integrity/ByteRange hash matches the CMS messageDigestnone
Signature valueSignature value verifies with the signer certificate's public keynone
Certificate chainChains up to a trust anchoronline only: issuer certificates fetched via AIA caIssuers
RevocationOCSP / CRL for the signer certificatenone under embedded; under online, HTTP queries when embedded data gives no answer
TimestampRFC 3161 token and TSA signaturenone

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 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.

XMP extension schemas and TDMRep (v0.31.0)

ISO 19005 accepts an XMP property only when its schema is predefined (XMP Specification, pdfaid) or described in the packet by pdfaExtension:schemas (19005-1 6.7.8, 19005-2/-3/-4 6.6.2.3). veraPDF reports a breach as "XMP property is either not predefined, or is not defined in any XMP extension schema" and names the namespace only in the check context. From v0.31.0 validate_conformance carries that name into the violation detail — e.g. http://www.w3.org/ns/tdmrep/ (tdm:reservation, tdm:policy) — W3C TDM Reservation Protocol (TDMRep): … — and says how the two coexist: PDF/A and TDMRep are compatible when the packet describes the TDMRep schema (reservation as Integer, policy as URL). identify_conformance lists every namespace the packet declares, marked predefined / described / known, and notes the undescribed ones when PDF/A is declared. evaluate_policy repeats the named cause in an advisory. Measured with veraPDF 1.28.2: a PDF/A-3B packet with TDMRep and no extension schema fails 6.6.2.3.1 test1 and test2 on both properties; the same packet with the description raises no XMP failure.

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, live in @shuji-bonji/pdf-constraints. Every report names the version that decided it, because the rules move as constraints are added.

Each constraint resolves to one of four states:

StateMeaning
passNothing in this constraint could be disproved
failDisproved, with the fact and its measured value as evidence
not_applicableThe clause does not apply to this document
needs_external_factA fact outside the file was not supplied, so the constraint was not decided

Two things the report distinguishes deliberately:

  • needs_external_fact is not a pass. Whether a font is a subset is known only to whoever made it — the PDF does not say. Supply it with given: { isSubset: true }; without it the constraint degrades rather than defaulting into silent approval.
  • Some failures are traces, not violations. Where a clause addresses the PDF processor (the act of writing), a file can only show that someone broke it — §14.3.4 explicitly allows leaving an existing inconsistency alone, so the last writer is not necessarily at fault.

Because these are T1 clauses, a failure can be stated plainly and its clause ID quoted — retrieve the wording with pdf-spec-mcp's get_requirements.

PDF/UA validation (v0.6)

Pass flavour: "pdfua-1" (or "pdfua-2") to validate accessibility conformance against ISO 14289. veraPDF is delegated to with --flavour ua1 when installed; otherwise 12 native rules run: MarkInfo/Marked, StructTreeRoot, pdfuaid declaration, /Lang, DisplayDocTitle, document title, Figure /Alt, image tagging, heading hierarchy, table TH/TR, Link /Contents, and encryption barriers. Tags are resolved through /RoleMap.

PDF/UA native violations carry a severity: only error rules can prove non-conformance, while warning rules flag what needs human review. Accessibility is not fully machine-decidable — whether alt text is present is checkable, whether it is meaningful is not.

The native subset stops where pdf-lib does. Rules needing content-stream analysis — 7.1-3 (content marked as artifact or tagged), 7.2-34 (language of page content), 7.18.1-1 (annotations nested in Annot tags), 7.18.3-1 (/Tabs) — are left to veraPDF rather than approximated. Install veraPDF when accessibility matters.

Without an explicit flavour, PDF/UA is selected only when the document declares PDF/UA and not PDF/A. Use pdf-reader-mcp's inspect_tags to examine the structure tree itself; conformance judgment lives here.

Errors (v0.33.0, legacy names removed in v0.34.0)

A failed call returns isError: true with a JSON body in the PDF family shape. Branch on code, not on the sentence.

json
{  "error": "File not found: /path/to/no-such-file.pdf",  "code": "DOC_NOT_FOUND",  "retryable": false,  "hint": "Check that the file exists and the path is correct"}
codeWhenretryable
INVALID_ARGUMENTMissing or relative path, a path that is not a regular file, an unknown flavour. The reason is in detail.reasontrue
DOC_NOT_FOUNDNo file at the pathfalse
INVALID_PDFThe file breaks an ISO 32000 structural clause named in error (a text file or an empty file breaks §7.5.2). A finding about the file, not a server failurefalse
ENCRYPTED_PDFEncryption stops the check. Supply password. A PDF/A check of a document whose key cannot be derived returns this whatever the engine (0.35.0); for a document whose key can be derived, engine: "native" runs the subsettrue
WRONG_PASSWORDThe supplied password is wrongtrue
FILE_TOO_LARGEOver the size limitfalse
INVALID_BYTE_RANGEA signature's /ByteRange is malformedfalse
VERAPDF_NOT_FOUND / VERAPDF_NOT_AVAILABLEengine: "verapdf" was asked for and veraPDF cannot be usedtrue
VERAPDF_NO_RESULTveraPDF ran and returned no validation resultfalse
INTERNAL_ERRORA failure of this server onlyfalse

The legacy names are gone from 0.34.0. Up to 0.32.x the body was { error: true, code, message, suggestion } with the codes FILE_NOT_FOUND, PARSE_FAILED, MISSING_PATH, RELATIVE_PATH, NOT_A_FILE and INVALID_FLAVOUR. 0.33.x, the transition release, also returned detail.legacyCode, message and suggestion; 0.34.0 removed them. Read error instead of message, hint instead of suggestion, and code (with detail.reason for INVALID_ARGUMENT) instead of the old code: FILE_NOT_FOUND → DOC_NOT_FOUND, PARSE_FAILED → INVALID_PDF, MISSING_PATH / RELATIVE_PATH / NOT_A_FILE / INVALID_FLAVOUR → INVALID_ARGUMENT.

Input that the MCP SDK rejects before the handler runs (for example a key the schema does not declare) keeps the SDK's own message.

Installation

As a plugin (via the shuji-bonji/claude-plugins marketplace, recommended):

bash
/plugin marketplace add shuji-bonji/claude-plugins/plugin install pdf-verify-mcp@shuji-bonji

Or add directly to your MCP config:

json
{  "mcpServers": {    "pdf-verify": {      "command": "npx",      "args": ["-y", "@shuji-bonji/pdf-verify-mcp@latest"]    }  }}

Use @latest (or pin a version). npx -y <pkg> without a version keeps running whatever it cached the first time — -y only skips the install prompt, it does not check for updates. To clear a stale cache: rm -rf ~/.npm/_npx.

Usage examples

  • "Verify the signatures in /path/to/contract.pdf — has it been altered since signing?"
  • "Was this certified PDF modified after certification?"
  • "Is this signature LTV-enabled (B-LT or B-LTA)?"
  • "Does this document declare PDF/A-2b conformance?"

Development

bash
npm installnpm test           # vitest (fixtures are generated in-memory)npm run buildnpm run check      # biome lint + formatnpm run test:fixtures  # write sample signed/tampered PDFs to tests/fixtures/generated/

Test fixtures (self-signed certificate + signed PDFs) are generated programmatically with pkijs + WebCrypto — no binary assets in the repository.

License

MIT © shuji-bonji

Dependencies: pkijs / asn1js (BSD-3-Clause), pdf-lib (MIT), normativepdf (MIT), @shuji-bonji/pdf-constraints (MIT), @modelcontextprotocol/sdk (MIT), zod (MIT).

Cross-reference sections are read by normativepdf, a clause-driven PDF library in which every behaviour is tied to an ISO 32000 clause. It is strict — an unreadable section is an error there. The recovery policy for damaged files (falling back to an older startxref, capping a cyclic /Prev chain, folding a linearised file's two sections back into one save) stays in this server, because it is a forensic judgement rather than a reading of the specification.

來源:README.md,提交 a32b0e4

工具

7

verify_signatures

Verify PDF Digital Signatures (cryptographic)

Cryptographically verify the digital signatures in a PDF document. For each signature this tool: recomputes the ByteRange digest and compares it with the CMS messageDigest attribute, verifies the CMS/PKCS#7 signature value against the signer certificate, verifies any RFC 3161 signature timestamp, evaluates the certificate chain against trust anchors, and checks revocation status. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') - trust_anchors (string[], optional): Paths to trust anchor certificates (PEM/DER). Also reads the PDF_VERIFY_TRUST_ANCHORS env var (directory). - check_revocation ('none' | 'embedded' | 'online'): Revocation mode (default: 'embedded'; 'online' queries OCSP/CRL endpoints over HTTP) - revocation_freshness (integer seconds, default 86400): How long before the validation time a CRL / OCSP response may have been issued and still count as "good" - trusted_ocsp_responders (string[], optional): Certificates of locally trusted OCSP responders (RFC 6960 §4.2.2.2) - password (string, optional): Password for an encrypted PDF (permission-encrypted PDFs are decrypted automatically with the empty user password) Returns: An object of the form { scope, signatures: [...] }. The top level changed from an array to an object in v0.21.0 - read .signatures for the list. signatures is null - not [] - when the document is encrypted and the key could not be derived (supply password); note then says why. [] means the fields were looked for and none is signed (v0.35.0). Size (v0.29.0): a JSON response is never cut by length. At most 32 signature fields are verified (file order); when the file has more, signaturesTruncated = { returned, total } is set and the remaining fields are NOT verified — evaluate_policy verifies every field. A markdown response is cut at 50,000 characters with a visible marker. Every report begins with file_path (the path as received

輸入參數passwordfile_path必填trust_anchorsresponse_formatcheck_revocationrevocation_freshnesstrusted_ocsp_responders

verify_integrity

Verify PDF Integrity (tamper detection)

Analyze a PDF for modifications after signing. Reports: number of revisions (incremental updates), whether bytes were added after each signature's signed range, whether the last signature covers the entire file, DocMDP certification permissions and violations, and DSS presence. DocMDP is assessed against what the P value actually permits (ISO 32000-2 Table 257): P=1 permits nothing, P=2 form fill-in and signing, P=3 additionally annotation creation/deletion/modification. The later changes are classified from the object-level diff (changeClass), so adding an annotation to a P=2 document is reported as a violation while the same change to a P=3 document is not. Objects a permitted change necessarily drags along — the page whose /Annots grew, the catalog, /Info, the XMP stream — are classified as housekeeping and do not by themselves constitute a violation. Per ISO 32000-2 §12.8.2.2, DSS/document-timestamp incremental updates after a P=1 certification are NOT violations (flagged as laterChangesAppearLtvOnly). violationAssessment is three-valued: "permitted" / "violated" / "indeterminate". **"indeterminate" is not a pass** — it means the chain could not be walked or a changed object's kind could not be read, so nothing could be disproved. The boolean violatedByLaterChanges collapses indeterminate to false for backward compatibility; read violationAssessment when "could not tell" must not be mistaken for "fine". Also reports an object-level diff of the incremental-update chain: for each revision, which objects were added, rewritten or freed, with the object's /Type and a plain-language role (annotation, form field widget, page object, content stream, …), plus the shortlist of objects written after the last signed range (objectChangesAfterLastSignature). Cross-reference and object streams are flagged as bookkeeping. Where the objects sit on the page is pdf-reader-mcp's answer, not this server's. Limits of the diff — it is an observation, never a verdict: - Incremen

輸入參數file_path必填response_format

detect_pades_level

Detect PAdES Baseline Level

Observe which PAdES baseline level (ETSI EN 319 142) the structure of each signature matches. **This is an observation, not a conformance verdict.** ETSI EN 319 142 is not in this family's spec corpus, and unlike PDF/A there is no third-party validator to delegate to — so the result says "the structure matches B-LT", never "conforms to PAdES B-LT". Every report carries normativeBasis: "T3" to make that explicit. Detection is structural: B-B (CAdES signature), B-T (+ RFC 3161 signature timestamp), B-LT (+ DSS with validation data), B-LTA (+ document timestamp). Legacy adbe.pkcs7.detached signatures are reported as non-PAdES. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: An object of the form { scope, levels: [...] }. The top level changed from an array to an object in v0.21.0 - read .levels for the list. Size (v0.29.0): at most 32 signatures are listed; levelsTruncated = { returned, total } says when the list was cut. JSON is never cut by length. Every report begins with file_path (the path as received, so answers to side-by-side calls can be matched to their inputs; markdown shows it as "File:" under the heading), then 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. Per-signature level with evidence (signature timestamp, DSS, VRI, document timestamp presence). Note: B-LT / B-LTA additionally require that the DSS revocation data actually covers the signer certificate (conte

輸入參數file_path必填response_format

identify_conformance

Identify PDF/A / PDF/UA Declarations

Identify declared PDF/A (pdfaid) and PDF/UA (pdfuaid) conformance in a PDF's XMP metadata. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') Returns: Every report begins with file_path (the path as received, so answers to side-by-side calls can be matched to their inputs; markdown shows it as "File:" under the heading), then 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. Declared PDF/A part/conformance level and PDF/UA part, plus the PDF version. xmpNamespaces (v0.31.0): every namespace the packet declares, each marked predefined (XMP Specification / ISO 19005), describedByExtensionSchema (a pdfaSchema:namespaceURI in the packet names it), and known (what this family can say it is — e.g. the W3C TDMRep namespace, or pdfuaid). A PDF/A declaration together with a namespace that is neither predefined nor described is what a PDF/A validator reports under ISO 19005-2 6.6.2.3 (19005-1 6.7.8); the note says so, as a declaration-level observation, not a validation result. IMPORTANT: This tool only IDENTIFIES the declared conformance — a declaration does not guarantee actual conformance. For real PDF/A rule checking use the validate_conformance tool (native rule subset, or veraPDF when installed). Examples: - Check whether a document claims PDF/A-2b before archiving - Detect PDF/UA declarations for accessibility workflows

輸入參數file_path必填response_format

validate_conformance

Validate PDF/A and PDF/UA Conformance

Validate a PDF against a PDF/A flavour (ISO 19005, archiving) or a PDF/UA flavour (ISO 14289, accessibility). Hybrid engine: when veraPDF is installed (PDF_VERIFY_VERAPDF env var or on PATH) validation is delegated to it for an authoritative result. Otherwise a built-in rule subset is checked natively: - PDF/A (15 rules): encryption, file ID, LZW, font embedding, JavaScript/prohibited actions, OutputIntent, transparency for A-1, XFA, and more - PDF/UA (12 rules): MarkInfo/Marked, StructTreeRoot, pdfuaid declaration, /Lang, DisplayDocTitle, document title, Figure /Alt, image tagging, heading hierarchy, table TH/TR, Link /Contents Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') - flavour (string, optional): e.g. "pdfa-2b", "pdfa-4", "pdfa-4f", "pdfua-1". Defaults to the XMP declaration (PDF/A wins when both are declared; fallback: pdfa-2b). PDF/A-4 has no A/B/U level, so there is no "pdfa-4b" - engine ('auto' | 'verapdf' | 'native'): Engine selection (default: 'auto') - password (string, optional): Password for an encrypted PDF. The document is decrypted first so the rules see real structures; permission-encrypted PDFs (empty user password) are decrypted automatically. PDF/A without a derivable key: ENCRYPTED_PDF with next_actions naming the password (v0.35.0) — not a list of violations for objects that were never read When veraPDF does not run, the report says so before the numbers: authoritativeValidation.performed is false and names the reason ("not_installed", "configured_path_unusable" when PDF_VERIFY_VERAPDF points at something that is not executable, or "native_engine_requested"). A configured-but-unusable path is never silently replaced by another executable. With engine: "verapdf" the call fails instead of falling back to native: the error code is VERAPDF_NOT_AVAILABLE when PDF_VERIFY_VERAPDF is set but unusable, and VERAPDF_NOT_FOUND when veraPDF is in

輸入參數engineflavourpasswordfile_path必填response_format

validate_clauses

Check ISO 32000 Clause Constraints

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 file_path (the path as received, so answers to side-by-side calls can be matched to their inputs; markdown shows it as "File:" under the heading), then 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

輸入參數givendomainsfile_path必填response_format

evaluate_policy

Evaluate Trust Policy (deterministic verdict)

Produce a deterministic 4-value trust verdict (trust_and_use / use_with_caution / human_review_required / reject) for a PDF. Runs verify_signatures, verify_integrity and detect_pades_level internally (plus validate_conformance for long-term-preservation profiles) and folds the facts through a fixed rule table — the same facts and profile always yield the same verdict. The verdict is decided entirely by code; use the returned firedRules/advisories to explain the outcome, never to override it. It judges authenticity and integrity only, never the truth of the document's content. Args: - file_path (string): Absolute path to a local PDF file - response_format ('markdown' | 'json'): Output format (default: 'markdown') - profile ('general' | 'contract' | 'financial' | 'legal' | 'medical' | 'government'): Judgment profile (default: 'general') - trust_anchors (string[], optional): Trust anchor certificate paths. Without them, signer identity stays not_evaluated and the verdict is capped at use_with_caution - check_revocation ('none' | 'embedded' | 'online'): Revocation mode (default: 'embedded') - revocation_freshness (integer seconds, default 86400): How long before the validation time a CRL / OCSP response may have been issued and still count as "good" - trusted_ocsp_responders (string[], optional): Certificates of locally trusted OCSP responders (RFC 6960 §4.2.2.2) - password (string, optional): Password for an encrypted PDF Returns: Every report begins with file_path (the path as received, so answers to side-by-side calls can be matched to their inputs; markdown shows it as "File:" under the heading), then 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 whe

輸入參數profilepasswordfile_path必填trust_anchorsresponse_formatcheck_revocationrevocation_freshnesstrusted_ocsp_responders

版本歷史

7
  1. v0.35.0最新Nov 6, 2026
  2. v0.34.0Nov 5, 2026
  3. v0.33.0Nov 4, 2026
  4. v0.32.2Nov 3, 2026
  5. v0.31.0Oct 13, 2026
  6. v0.30.0Oct 12, 2026
  7. v0.29.1Sep 19, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分