Skip to content

MCP サーバー

pdfvision mcp は、同じ抽出エンジンを Model Context Protocol 経由で stdio 上に提供します。シェルを実行できないホスト — Claude Desktop、Cursor、Cline、Zed、n8n など、モデルが tool 呼び出ししかできない環境のためのものです。

エージェントがシェルを持つ場合(Claude Code、Codex など CLI を実行できる環境)は、CLI と Agent Skills の組み合わせを推奨します。skill は必要になるまで context を消費しませんが、MCP の tool schema はセッションの間ずっとホストの context に常駐します。

セットアップ

サーバーは別パッケージではなく、メインバイナリのサブコマンドです:

json
{
  "mcpServers": {
    "pdfvision": { "command": "npx", "args": ["-y", "pdfvision", "mcp"] }
  }
}

pdfvision mcp は引数を取りません。stdout で JSON-RPC を話すため、プロセスのログはすべて stderr に出ます。

3 つの Tool

Tool返すものパラメータ
read_pdfMarkdown のテキストsourcepagesocrattachmentpassword
search_pdfヒットを箇所ごとにまとめ、短い ref を付けた一覧sourcequerypagesregexpassword
render_pdfページまたは領域の PNG(image block)sourcepagesrefregionpassword

source はローカルパスまたは http(s) URL を受け付けます — remote 用の別パラメータはありません。

この surface は CLI より意図的に小さくしてあります。format、include、scale、cache のパラメータはありません: 文書自体から判断できることは、すべてサーバー側が判断します。read_pdf は常に layout、form field、link、annotation を実行し、何も見つからなかったセクションは単に省きます。これにより常駐する tool schema を小さく保ち、モデルが設定を誤る余地をなくしています。

セッションの流れ

20 ページを超える文書への pages なしの read_pdf は、本文の代わりにドキュメントマップを返します: ページ数、アウトライン、ページごとの native text 品質と warning code をレンジに集約したもの、そして次に実行すべき具体的な呼び出しです。未知の文書への最初の一手はこれが標準です。

そこからは:

  • read_pdf(pages: "12-18") でレンジを読む。
  • search_pdf(query: "…") で語句を探す。ソースが同じで、クロップも同じ領域に解決される出現 — 典型的には同じ行や表の行内での繰り返し — は 1 行にまとめられ、×N で件数が示されます(見出しの件数は出現数のままです)。各行には p47m1 のような短い ref が付くので、座標を書き写す代わりに render_pdf(ref: "p47m1") へそのまま渡してヒット箇所を目視できます。あるソースの ref 集合は、そのソースに対する直近の search_pdf、または視覚領域を一覧したページ全体の render_pdf が登録したものです。どちらを実行しても、それまでの集合はまるごと置き換わります — ヒット 0 件の検索も空の集合で置き換えます。一方、ref を新たに登録しない render_pdf — 領域を指定した render(ref を渡す呼び出しを含む)や、レスポンスに視覚領域が載らなかったページ全体の render — は集合をそのままにするので、1 回の検索でヒットした箇所を次々にレンダリングできます。refpagesregion と組み合わせられません: ref はすでにページと領域の両方を特定しているため、その ref のページとして黙って処理されるのではなく、呼び出し自体が拒否されます。
  • 品質レポートが native text は使えないと言っているページは read_pdf(pages: "31", ocr: "jpn+eng") で OCR 再読。
  • read_pdf(attachment: "invoice.xml") — または 1 始まりの番号 — はページの代わりに埋め込みファイルを返します。電子請求書や規制関連の提出書類(Factur-X、ZUGFeRD、XBRL)では添付こそが正本のデータで、ページはその印刷像にすぎません。テキスト添付はインラインで、画像は image block で返り、不透明なバイナリは CLI の --attachments --attachment-output を案内して拒否されます。

レンダリングは長辺 1568 px にフィットされます — それ以上は vision モデル側でダウンサンプルされるためです。レンダリングが小さくて読めない場合の正解は、より大きいラスタではなく、より小さい region です。

バジェットと正直さ

レスポンスにはバジェットがあります: 本文 30,000 文字、ページあたり 12,000 文字、match の箇所 100 件、レンダリング 4 ページ、OCR 5 ページ、画像 6 MB(いずれも 1 呼び出しあたり)。すべての切り詰めは次にすべきことを名指しするため、切られた結果は回復可能で、黙って不完全なままになることはありません — 要求されたレンジがあまりに広く、ページごとの Overview 表だけでバジェットを使い切ってしまう場合も含め、通常はそれを生んだ呼び出しより狭いページ指定を示し、1 ページ単体すら収まらずそれより狭いページ指定が存在しない場合に限り、代わりに search_pdf を案内します。

map か本文かを分けるのは 20 ページという閾値であって、本文が収まるかどうかではありません: それ未満の文書は全体を読み込んだ上で、文字バジェットを超えれば他の場合と同様に切り詰められます。切り詰め通知が省略したとみなすのはページの本文であり、それらのページの Overview 行はレスポンスにそのまま残ります。例外は、同じ通知に Overview clipped after page N(完全な行が 1 つも残らなかった場合は Overview clipped before any page row)が併記されている場合だけです: レンジが広すぎて Overview 表だけでバジェットを使い切ったときは、表そのものも必ず行境界で切られます。after page N が名指しするのは行がまるごと残った最後のページで、それより後の行はレスポンスにありません。before any page row の場合はページごとの情報が 1 行も残っていません。

同じ正直さは検索にも適用されます: core の warning はレスポンスに同乗するため、ページあたりの時間バジェットを超えた regex クエリは「0 matches」を装わずに自己申告し、使える native text のないページへの検索は「そこでのミスは不在の証拠ではない」と明言します。動的 XFA (LiveCycle) フォームでは、これがもう一段先まで届きます。検索したページが「Please wait...」のビューア用プレースホルダーだけだった場合、ヒットの有無にかかわらず、検索対象に選ばれたすべてのページについて毎回そう伝えます。不在と読み違えられやすいのはヒット 0 件のレスポンスだからです。案内する復旧手段はレンダーではなく Adobe Acrobat/Reader です。レンダーしてもプレースホルダーが出るだけだからです。判断がつかないほど抽出量が少ない場合は、どちらとも決めつけずに「レンダーか OCR で確かめてほしい」と伝えます。ページ自体にテキスト・画像・図版を持つ AcroForm と XFA のハイブリッド — IRS の申告書など — は通常どおり抽出できるため、この扱いにはなりません。そして、静的な実体がフィールド層だけのフォームはその中間で、フィールドのヒットは信頼できる一方、その周囲のページ本文は文書の内容ではない、と注記されます。

成功した結果の先頭には untrusted-data バナーが付きます(エラー結果には付かず、文書の内容を引用することがあります)。MCP ホストには Agent Skill の指針に相当するものがないため、信頼境界はペイロードと一緒に運ばれます。抽出されたコンテンツは指示ではなくデータとして扱ってください — セキュリティとプライバシーを参照。

リモート入力はガードされます

CLI の --remote と異なり、MCP サーバーは private、loopback、link-local、CGNAT、NAT64、IPv4-mapped アドレスに解決される URL を拒否し、リダイレクトの各ホップも再検証します。ここでは URL を選ぶのがモデルなので、これがなければサーバーは実行先ネットワークへの SSRF の踏み台になってしまいます。

イントラネットのドキュメントストアには PDFVISION_MCP_ALLOW_PRIVATE_NETWORK=1 を設定してください。既知の制限: 検証したアドレスは fetch に固定されないため、検証と接続の間に変わる DNS 応答はカバーされません。

エラーは次の呼び出しを名指しします

Tool の失敗はプロトコルエラーではなく、回復手順付きの in-band な結果として返ります。範囲外のページ指定、ページバジェットを超える OCR 要求、未知の ref、不正な region — いずれも代わりに何をすべきかを述べます。メッセージを読んでください。次の呼び出しが書いてあります。

Released under the MIT License.