PDF Verify (PDF Agent Stack) について
PDF Verifyは、署名、改ざん、文書規格を確認するワークフロー向けの、PDF真正性・規格準拠検証用MCPサーバーです。暗号学的検証、改訂履歴の分析、ポリシー評価を組み合わせ、判定不能を合格と区別します。
主な機能
- 01電子署名と信頼チェーンを検証
- 02署名後の変更を検出
- 03PAdESベースラインレベルを特定
- 04PDF/AとPDF/UAの準拠性を検証
- 05固定ルールで信頼ポリシーを評価
活用シーン
- 01契約書や財務PDFの署名を確認
- 02署名後の不正な変更を調査
- 03アーカイブ文書のPDF/A準拠性を検証
- 04分野別ポリシーで文書リスクを確認
MCP 対応
PDF Verifyは、署名・完全性検証、PAdES検出、準拠性の識別と検証、条項チェック、ポリシー評価のMCPツールを公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
7掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| password | string | いいえ | 暗号化された PDF のパスワードです。権限制限のみの PDF では省略できます(空のユーザーパスワードを自動的に試します)。 |
| file_path | string | はい | ローカル PDF ファイルの絶対パス(例:"/path/to/document.pdf") |
| trust_anchors | array | いいえ | 信頼アンカー証明書への絶対パス(PEM または DER)。PDF_VERIFY_TRUST_ANCHORS 環境変数(*.pem/*.crt/*.cer/*.der ファイルを含むディレクトリ)と統合されます。省略され、環境変数も未設定の場合、信頼状態は not_evaluated と報告されます。 |
| response_format | enum | いいえ | 出力形式:"markdown" は人が読みやすい形式、"json" は構造化データmarkdown | json |
| check_revocation | enum | いいえ | 失効チェック:「none」、「embedded」(PDF/CMS 内の OCSP/CRL データ。デフォルト)、または「online」(HTTP 経由で OCSP レスポンダーと CRL 配布ポイントにも問い合わせます)。none | embedded | online |
| revocation_freshness | integer | いいえ | 検証時刻より前に CRL / OCSP レスポンスが発行されていても(thisUpdate)「good」と判定できる秒数です。デフォルトは 86400(24 h)です。0 の場合、検証時刻以降に発行されたデータのみを受け入れます。それより古いデータは「unknown」になります。 |
| trusted_ocsp_responders | array | いいえ | ローカルで信頼されている OCSP レスポンダーの証明書(PEM または DER)への絶対パス(RFC 6960 §4.2.2.2)。レスポンダーが発行 CA またはその委任先でなくても、そのいずれかが署名したレスポンスは受け入れられます。 |
詳細
pdf-verify-mcp
PDF の真正性と適合性を検証する MCP サーバーです。暗号学的な電子署名の検証、改ざん検出、PAdES ベースラインレベルの検出、PDF/A(ISO 19005)/PDF/UA(ISO 14289)の検証を行います。
PDF-Reder-mcp(構造分析)および pdf-spec-mcp(仕様リファレンス)とともに、PDF ファミリーの一部を構成します。pdf-reader-mcp が PDF に何が含まれているかを示すのに対し、pdf-verify-mcp は PDF が本物かどうかを示します。
ツール
| ツール | 目的 |
|---|---|
verify_signatures | 暗号学的検証、トラストアンカーに対する信頼チェーンの評価、失効確認(埋め込み OCSP/CRL またはオンライン)、RFC 3161 タイムスタンプの検証 |
verify_integrity | 改ざん検出:増分更新、署名後の変更、P 値ごとに評価される DocMDP 認証違反(下記参照)、およびリビジョンチェーンのオブジェクトレベルの差分(各更新で追加、書き換え、解放されたオブジェクト)。増分更新は合法であるため、この差分が示すのはレビュー対象であり、これに基づいて判定することはありません。該当オブジェクトがページ上のどこにあるかは、pdf-reader-mcp の locate_objects で確認できます |
detect_pades_level | コンテンツ検証済みの LTV データを用いた PAdES ベースラインレベル(B-B / B-T / B-LT / B-LTA) |
identify_conformance | XMP メタデータから PDF/A/PDF/UA の宣言済み適合性を特定 |
validate_conformance | PDF/A(ISO 19005)および PDF/UA(ISO 14289)の検証:インストールされている場合は veraPDF、それ以外は組み込みのルールサブセットを使用 |
validate_clauses | ISO 32000-1/-2 の条項にマッピングされた制約。PDF/A および PDF/UA プロファイルでは対象とならない仕様本文そのものを検証 |
evaluate_policy | 検証結果に対する固定ルール表から、信頼に関する 4 値の判定(trust_and_use / use_with_caution / human_review_required / reject)を決定します。ドメインプロファイル(contract、financial、legal、medical、government)に対応しています。判定を行うのはコードであり、説明文を作成するのは LLM です |
判定
| 判定 | 意味 |
|---|---|
valid | ByteRange ダイジェストが一致し、CMS 署名が暗号学的に有効 |
invalid | ダイジェストの不一致または署名検証の失敗 — 改ざんの可能性あり |
indeterminate | 未対応の形式、または検証を完了できなかった |
DocMDP 認証権限(v0.14)
認証署名の P 値は、どの種類の変更が許可されるかを示します
(ISO 32000-2 Table 257)。verify_integrity は署名後に行われた変更を
オブジェクトレベルで分類し、その P 値が許可する変更と照合します。
| P | 許可される変更 | 注釈の追加は違反か? |
|---|---|---|
| 1 | なし(DSS/文書タイムスタンプの増分更新は §12.8.2.2 の例外) | はい |
| 2 | フォームへの入力、ページテンプレートのインスタンス化、署名 | はい — 注釈は 3 から許可 |
| 3 | 2 の変更に加え、注釈の作成、削除、変更 | いいえ |
許可された変更に必然的に伴うオブジェクト(/Annots が増えたページ、カタログ、
/Info、XMP ストリーム)は housekeeping として分類され、違反には数えられません。
これらを数えると、合法な P=3 の注釈追加によって 4 つすべてが移動するため、
あらゆる認証済み文書が違反となってしまいます。
violationAssessment は3値です
| 値 | 意味 |
|---|---|
permitted | 署名後のすべての変更が、P で許可されている種類です |
violated | 少なくとも1つの変更が許可範囲外です |
indeterminate | 判定できませんでした(xref チェーンをたどれなかった、または変更されたオブジェクトの種類を読み取れなかった) |
⚠️
indeterminateは合格ではありません。 このサーバーは違反を立証します。また、「違反を立証できなかった」は「問題ない」とは異なります。これは、チェックをデフォルトで合格にせず、validate_clausesがneeds_external_factを返すのと同じ考え方です。
violatedByLaterChanges(ブール値)は互換性のために維持されており、indeterminateをfalseにまとめます。「判定できなかった」を「問題ない」と取り違えてはいけない場合は、violationAssessmentを参照してください。evaluate_policyもindeterminateをhuman_review_requiredに引き上げます。
/Type のないストリームは、content としてではなく、未判定として扱われます。同じバイト列でも、フォームフィールドの外観ストリーム(P=2で許可)か、ページのコンテンツストリーム(どのPでも許可されない)かの可能性があるためです。
レスポンスサイズ(v0.29.0)
JSON レスポンスが長さによって途中で切られることはありません。代わりにリストに上限が設けられ、切り詰めはすべてリストの横に { returned, total } として報告されます。上限は signatures / levels が32(verify_signatures は上限を超えるフィールドを検証せず、evaluate_policy はすべて検証し、facts.signatures のみ上限を適用)、revisions が32、violations / results が200です(compliant、failedRules、violations、notDecided などの件数はすべての項目を対象とします)。Markdown レスポンスは50,000文字で、見えるマーカーを付けて切り詰められます。
evaluate_policy のコンテンツインベントリ(v0.30.0)
evaluate_policy は、文書が保持している、動作する、または未処理のコンテンツも数え、facts.content に報告します。これは ISO 32000-2 §12.8.7 Table 264(法的コンテンツの証明)の件数です。対象は、JavaScriptActions、LaunchActions、URIActions、GoToRemoteActions、HideAnnotationActions、MovieActions、SoundActions、さらに SubmitFormActions、URI ホスト、/OpenAction または文書 /AA の有無、注釈の数、ファイル内に残っている /Subtype /Redact 注釈の数です。ネストされた(直接の)アクション辞書もたどるため、リンク上のインライン /A もカウントされます。次の2つのルールがこれを参照します。
POL-CAUTION-REDACT-PENDING— 墨消し注釈がまだ存在します(ISO 32000-2 §12.5.6.23)。適用済みの墨消しでは注釈は残らないため、注釈が示すコンテンツはファイルから削除されていません。use_with_caution。POL-CAUTION-ACTIVE-CONTENT— ECMAScript、Launch、リモート GoTo、または SubmitForm/ImportData アクションが存在します。理由には、/OpenAction//AAによってその一部が文書を開いたときに実行されるかどうかが示されます。use_with_caution。URI アクションは判定結果を変えません。URI ホストは参考情報として報告されます。
インベントリは観測結果であり、判定ではありません。取得できなかった場合は null(「カウントされていません」)として報告され、0とは見なされません。読み取れないオブジェクトがある場合、件数は下限値になります。カウント対象外の Table 264 のキー:AlternateImages、ExternalStreams、TrueTypeFonts、ExternalRefXobjects、ExternalOPIdicts、NonEmbeddedFonts、DevDepGS_*。
信頼と失効(v0.2)
trust_anchors(PEM/DER ファイルパス)を渡すか、PDF_VERIFY_TRUST_ANCHORS 環境変数に証明書ディレクトリを設定すると、署名者の証明書チェーンを評価できます。結果は証明書パスとともに trusted/untrusted/not_evaluated で示されます。検証時刻には、検証済みの署名タイムスタンプ、署名をカバーする最も早い文書タイムスタンプ、または現在時刻(v0.27.0)のいずれかが使われます。CMS の signingTime 属性は署名者が書き込むため、使用されません。選択された時刻は validationTime として報告されます。
check_revocation で失効チェックを制御します。embedded(デフォルト。DSS 内の OCSP/CRL データ、CMS SignedData.crls、または CMS 署名属性 adbe-revocationInfoArchival を使用し、revocation.origin として報告)、online(さらに HTTP 経由で OCSP レスポンダーと CRL 配布ポイントに問い合わせ)、または none(revocation.status: not_checked)を指定できます。署名を検証できない CRL および OCSP レスポンス、nextUpdate が検証時刻より前のもの、または thisUpdate が検証時刻より revocation_freshness 秒(デフォルトは 86400 秒)以上前のものは、unknown になります(v0.28.0)。別の CA が発行した OCSP レスポンダーを信頼するには、trusted_ocsp_responders を渡します。各中間 CA の結果は trust.chainRevocation として報告されます。タイムスタンプによって署名が失効前であると証明される場合、署名者の証明書は revoked_after_validation_time(判定は変更されません)になります。それ以外の場合は、判定が indeterminate の revoked になります。オンラインモードでは、チェーンを完成させるため、不足している発行者証明書を AIA caIssuers 経由で取得します(v0.4)。信頼アンカーが指定されている場合は、RFC 3161 タイムスタンプの TSA 証明書チェーンも評価されます(tsaTrust)。
| ステップ | チェック内容 | ネットワーク |
|---|---|---|
| 整合性 | /ByteRange のハッシュが CMS messageDigest と一致するか | なし |
| 署名値 | 署名値を署名者証明書の公開鍵で検証できるか | なし |
| 証明書チェーン | 信頼アンカーまでチェーンがつながるか | online のみ:AIA caIssuers 経由で発行者証明書を取得 |
| 失効 | 署名者証明書の OCSP/CRL | embedded ではなし。online では、埋め込みデータで回答が得られない場合に HTTP で問い合わせ |
| タイムスタンプ | RFC 3161 トークンと TSA 署名 | なし |
verdict: valid は、整合性と署名値の検証に合格したことを意味します(revoked の場合は indeterminate になります)。online の結果は問い合わせ時点での CA の状態を反映するため、後から変わることがあります。各ステップの詳細とモードの選び方については、サイトガイドを参照してください。
信頼アンカーがない場合、
trustはnot_evaluatedのままです。また、validの判定が示すのは暗号学的な整合性であり、署名者の身元ではありません。
暗号化された PDF は、権限による暗号化の場合(空のユーザーパスワード)に自動的に復号されます。閲覧用パスワードが設定された PDF には、password を渡してください。対応形式:RC4(R2~R4)、AES-128、AES-256(R6)。復号によって、文字列メタデータ(フィールド名、/M、/Reason、/Location)と XMP が復元されます。署名の /Contents は暗号化の対象外のため、検証で参照されることはありません。
対応する SubFilter:ETSI.CAdES.detached(PAdES)、adbe.pkcs7.detached、ETSI.RFC3161(文書タイムスタンプ)。RFC 3161 署名タイムスタンプは、インプリントと TSA 署名を含め、完全に検証されます。従来の MD5/SHA-1 署名は node:crypto で検証され、脆弱な署名として示されます。
PDF/A 検証(v0.3)
validate_conformance はハイブリッドエンジンを使用します。veraPDF がインストールされている場合(PDF_VERIFY_VERAPDF 環境変数または PATH 上)、権威ある結果を得るために検証を veraPDF に委ねます。それ以外の場合は、価値の高い ISO 19005 ルール約 15 項目(暗号化、トレーラーの /ID、LZW、フォントの埋め込み、JavaScript/禁止アクション、OutputIntent、A-1 の透明度、XFA など)の組み込みサブセットをネイティブで実行し、それぞれに条項参照を付けて報告します。
ネイティブの結果は、その限界を正直に示します。違反があれば明確な不適合を意味します。すべて合格しても「チェック対象のサブセットに違反がない」という意味にとどまり、認証を意味するものではありません。
PDF/A-4(pdfa-4、pdfa-4e、pdfa-4f)に対応しています。PDF/A-4 には適合レベルがありません。pdfa-4b は存在せず、e と f はバリアントです。ネイティブルールは ISO 19005-1/-2 をもとに作成されており、ISO 19005-4 との照合は行われていません。そのため、PDF/A-4 のレポートでは、ネイティブ判定の信頼度が veraPDF より低いことを明示します。part 4 の検証には veraPDF を使用してください。
XMP 拡張スキーマと TDMRep(v0.31.0)
ISO 19005 では、XMP プロパティが許可されるのは、そのスキーマが事前定義されている(XMP Specification、pdfaid)か、パケット内の pdfaExtension:schemas で記述されている場合に限られます(19005-1 6.7.8、19005-2/-3/-4 6.6.2.3)。veraPDF は違反を「XMP property is either not predefined, or is not defined in any XMP extension schema」と報告しますが、名前空間はチェックのコンテキストにしか示しません。v0.31.0 以降、validate_conformance はその名前を違反の detail に含めます。たとえば、http://www.w3.org/ns/tdmrep/ (tdm:reservation, tdm:policy) — W3C TDM Reservation Protocol (TDMRep): … のように示し、2 つがどのように共存するかも説明します。つまり、パケットに TDMRep スキーマ(reservation は Integer、policy は URL)が記述されていれば、PDF/A と TDMRep は互換性があります。identify_conformance は、パケットで宣言されているすべての名前空間を、事前定義済み/記述済み/既知として示し、PDF/A が宣言されている場合は記述されていない名前空間も指摘します。evaluate_policy は、助言の中で原因を名前付きで再度示します。veraPDF 1.28.2 での測定では、TDMRep を含み拡張スキーマを持たない PDF/A-3B パケットは、両方のプロパティについて 6.6.2.3.1 の test1 および test2 に失敗します。同じパケットに記述を加えると、XMP の失敗は発生しません。
ISO 32000 条項の制約(v0.9)
validate_clauses は別の範囲を扱います。対象は PDF/A や PDF/UA のプロファイルではなく、PDF 仕様書の本文です。veraPDF が COMPLIANT と判定したファイルでも、ISO 32000 に違反することがあります。/FontFile2 に CFF フォントプログラムを埋め込む(表 124)ことは、ビューアーの警告としてしか表面化しなかった実例です。
条項と構造条件の対応付けとその評価は、@shuji-bonji/pdf-constraints にあります。制約が追加されてルールが変わるため、すべてのレポートには判定に使用したバージョンが記載されます。
各制約は、次の 4 つの状態のいずれかに解決されます。
| 状態 | 意味 |
|---|---|
pass | この制約に反することを証明できるものはありません |
fail | 反することが証明されており、事実とその測定値が証拠として示されています |
not_applicable | この条項はこの文書には適用されません |
needs_external_fact | ファイル外の事実が提供されていないため、制約は判定されていません |
レポートでは、次の 2 点を意図的に区別しています。
needs_external_factは合格ではありません。 フォントが サブセット かどうかを知っているのは、作成者だけです。PDF には記載されていません。given: { isSubset: true }で指定してください。指定しない場合、制約は暗黙に合格とせず、判定精度が下がります。- 失敗の中には、違反ではなく記録となるものがあります。 条項が PDF プロセッサー(書き込み処理)を対象としている場合、ファイルから分かるのは、誰かがその条項に違反したということだけです。§14.3.4 では既存の不整合をそのまま残すことが明示的に認められているため、最後に書き込んだ人が必ずしも原因とは限りません。
これらは T1 条項であるため、失敗を明確に述べ、条項 ID を引用できます。条項の文言は、pdf-spec-mcp の get_requirements で取得してください。
PDF/UA 検証(v0.6)
flavour: "pdfua-1"(または "pdfua-2")を渡すと、ISO 14289 に対するアクセシビリティ適合性を検証します。veraPDF がインストールされている場合は --flavour ua1 を指定して実行し、そうでない場合はネイティブの12項目をチェックします。項目は MarkInfo/Marked、StructTreeRoot、pdfuaid 宣言、/Lang、DisplayDocTitle、文書タイトル、Figure の /Alt、画像のタグ付け、見出し階層、テーブルの TH/TR、Link の /Contents、暗号化の障壁です。タグは /RoleMap を通じて解決されます。
PDF/UA のネイティブ違反には severity が付きます。適合していないことを証明できるのは error ルールのみで、warning ルールは人による確認が必要な項目を示します。アクセシビリティは完全には機械判定できません。代替テキストが存在するかは確認できますが、それが適切であるかは確認できません。
ネイティブの検証範囲は pdf-lib が対応する範囲までです。コンテンツストリームの分析を必要とするルール(7.1-3(コンテンツがアーティファクトまたはタグ付きとしてマークされているか)、7.2-34(ページコンテンツの言語)、7.18.1-1(Annot タグ内にネストされた注釈)、7.18.3-1(/Tabs))は、近似的な判定を行わず veraPDF に委ねます。アクセシビリティが重要な場合は veraPDF をインストールしてください。
明示的に flavour を指定しない場合、文書が PDF/UA を宣言し、かつ PDF/A を宣言していないときにのみ PDF/UA が選択されます。pdf-reader-mcp の
inspect_tagsを使って構造ツリー自体を調べてください。適合性の判定はこのサーバーが行います。
インストール
プラグインとして(shuji-bonji/claude-plugins マーケットプレイス経由、推奨):
/plugin marketplace add shuji-bonji/claude-plugins
/plugin install pdf-verify-mcp@shuji-bonji
または、MCP 設定に直接追加します:
{
"mcpServers": {
"pdf-verify": {
"command": "npx",
"args": ["-y", "@shuji-bonji/pdf-verify-mcp@latest"]
}
}
}
@latestを使用するか、バージョンを固定してください。 バージョンを指定せずにnpx -y <pkg>を実行すると、初回にキャッシュされたものが使われ続けます。-yはインストール確認を省略するだけで、更新の確認は行いません。古いキャッシュを削除するには、rm -rf ~/.npm/_npxを実行してください。
使用例
- 「/path/to/contract.pdf の署名を検証してください。署名後に変更されていますか?」
- 「この認証済み PDF は認証後に変更されていますか?」
- 「この署名は LTV 対応(B-LT または B-LTA)ですか?」
- 「この文書は PDF/A-2b への適合を宣言していますか?」
開発
npm install
npm test # vitest (fixtures are generated in-memory)
npm run build
npm run check # biome lint + format
npm run test:fixtures # write sample signed/tampered PDFs to tests/fixtures/generated/
テスト用フィクスチャ(自己署名証明書と署名済み PDF)は pkijs と WebCrypto を使ってプログラムで生成されるため、リポジトリにバイナリアセットはありません。
ライセンス
MIT © shuji-bonji
依存関係:pkijs/asn1js(BSD-3-Clause)、pdf-lib(MIT)、normativepdf(MIT)、@shuji-bonji/pdf-constraints(MIT)、@modelcontextprotocol/sdk(MIT)、zod(MIT)。
相互参照セクションはnormativepdfによって読み取られます。これは、すべての動作が ISO 32000 の条項に結び付けられた、条項駆動型の PDF ライブラリです。厳格なため、読み取れないセクションはエラーになります。破損ファイルの復旧ポリシー(古い startxref へのフォールバック、循環する /Prev チェーンの上限設定、線形化ファイルの2つのセクションを1つの保存データにまとめる処理)は、仕様の解釈ではなくフォレンジック上の判断であるため、このサーバー側に残されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。