emperor-pdf について
emperor-pdfは、設定したフォルダー内のPDFを扱うエージェントやクライアント向けのMCPサーバーです。PDFデータやHTTPS URLも処理でき、テキスト抽出・検索とページ描画を備え、ファイル変更ツールは既定で無効です。
主な機能
- 01PDFのメタデータとページテキストの取得
- 02テキストまたは正規表現によるPDF検索
- 03ページをPNG画像として描画
- 04PDFの結合または指定ページの抽出
- 05有効化時のMarkdownからのPDF作成
- 06隠しテキストの可能性を警告
活用シーン
- 01論文フォルダーを検索して該当ページを確認
- 02スキャンページを画像として描画して調べる
- 03複数のPDFから選んだページを結合
- 04書き込み有効時にMarkdownからPDFを生成
MCP 対応
PDF情報、テキスト、検索、描画のツールをMCPクライアントに提供し、ルートフォルダー、base64データ、HTTPS URLからファイルを受け取ります。書き込みを有効にすると、ページの結合・抽出やMarkdownからのPDF作成もできます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
emperor-pdf
1つのフォルダーにあるPDFをエージェント向けに:読み取り、検索、レンダリング、結合、分割、作成できます。
1つのルートフォルダー内にあるPDFのみを扱い、それ以外にはアクセスしない MCP サーバーです。
- テキストの読み取りと検索:ルートフォルダー内のPDF、呼び出しで渡されたBase64バイト列、または
https://URLから、ページ単位でテキストを読み取って検索できます。Chromeに組み込まれているエンジンであるGoogleの PDFiumを使用し、PDFiumがインストールされていない場合は純粋なRust製の抽出機能にフォールバックします。 - 隠しテキストを警告:白地に白の文字、不可視の文字、ポイント未満の文字、ページ外の文字を検出します。人には無害に見える文書にモデル向けの指示を埋め込む際に、よく使われる手法です。
- ページを画像で表示:モデルが確認できるPNG画像としてページを表示します(スキャンされたページの読み取りにも使われます)。
- ページの結合と抽出、およびMarkdownからPDFを作成できます。Typstとバイナリに組み込まれたOFLフォントを使って組版します。
- 文字列チェックではなく、ケイパビリティによってアクセスを制限:すべてのファイルは
cap-stdのディレクトリーハンドルを通じて開かれるため、..、絶対パス、ルートの外部につながるシンボリックリンクは、オペレーティングシステム層で拒否されます。 - デフォルトは読み取り専用:
--writableを指定しない限り、書き込みツールは提供されません。
emperor-mcpフレームワークを基盤としています。ステートレスなStreamable HTTP(デスクトップクライアント向けにはstdioにも対応)、フレーム化された出力、doctorサブコマンドを備え、読み取り専用ツールが4つ、--writableを指定すると6つのツールを利用できます。
Emperor Profile P1.1に準拠しており、起動時にオペレーターが書き込みを有効にする(--writableまたはPDF_WRITABLE)まで、書き込みを行うツールは一覧に表示されません。また、ツール定義は簡潔で、各ツールを使用する場面を短く説明し、入力スキーマもコンパクトです。
インストール
ビルド済みバイナリ(macOS arm64/x86_64、Linux x86_64、Windows x86_64)は GitHubリリースにあります。または、ソースからビルドしてください。
cargo install --git https://github.com/yarenty/emperor-pdf
ビルドにはRust 1.92以降が必要です(typst 0.15により、このバージョンが最低要件です)。
読み取り専用ビルド
pdf_createはcreate Cargo機能(デフォルトで有効)に含まれており、Typstと組み込みフォントを追加します。これを無効にすると、読み取り、検索、レンダリング、結合、抽出を行う、より小さなバイナリになります。
cargo install --git https://github.com/yarenty/emperor-pdf --no-default-features
| ビルド | リリースバイナリ(macOS x86_64) |
|---|---|
default (create) | 51 MB |
--no-default-features | 14 MB |
Docker
リポジトリのDockerfileは、stdio経由でMCPを使用し、PDFiumを含むイメージ(linux/amd64およびlinux/arm64)をビルドします。PDFを含むフォルダーを/dataにマウントしてください。
docker build -t emperor-pdf .
docker run -i --rm -v ~/Documents/papers:/data:ro emperor-pdf
# read-write: mount without :ro and switch writing on
docker run -i --rm -e PDF_WRITABLE=true -v ~/Documents/papers:/data emperor-pdf
サーバーはuid 10001で実行されるため、--writableを指定する場合は、マウントしたフォルダーへの書き込み権限が必要です。
PDFium(推奨)
PDFium は実行時に読み込まれるネイティブライブラリであり、emperor-pdf には同梱されていません。すべてのプラットフォーム向けのビルド済み PDFium バイナリは、 bblanchon/pdfium-binaries(Apache-2.0 / BSD-3-Clause)から入手できます。チェックアウトした状態で:
scripts/fetch-pdfium.sh # downloads the right archive for this machine into ./pdfium/
または、リリースから pdfium-<os>-<cpu>.tgz をダウンロードし、任意の場所に展開してください。
リリースは chromium/7881 に固定されています。これは pdfium-render バインディングのビルド対象となる PDFium API バージョンです。PDFIUM_VERSION=<n> scripts/fetch-pdfium.sh で別のバージョンを指定できます。
emperor-pdf は、次の順序で libpdfium.dylib / libpdfium.so / pdfium.dll を検索します。
--pdfium-dir DIR(DIR、DIR/lib、またはDIR/bin内のライブラリ)、PDFIUM_DYNAMIC_LIB_PATH(同じlib/およびbin/検索に使うフォルダー、またはファイル)、emperor-pdfバイナリがあるフォルダー、- システムのライブラリパス。
PDFium がない場合、pdf_text と pdf_search は lopdf の抽出機能を使います(一部の PDF ではテキストが欠落したり文字化けしたりする旨が出力に表示されます)。pdf_render_page は PDFium が必要であることを応答します。それ以外はすべて同じように動作します。
実行
# Streamable HTTP at http://127.0.0.1:8032/mcp, read-only
emperor-pdf serve --root ~/Documents/papers --pdfium-dir ./pdfium
# also offer pdf_pages and pdf_create, and allow saving rendered pages
emperor-pdf serve --root ~/Documents/papers --pdfium-dir ./pdfium --writable
# stdio, for clients that start the server themselves
emperor-pdf serve --stdio --root ~/Documents/papers
| フラグ | デフォルト | 意味 |
|---|---|---|
--root DIR | 必須 | サーバーがアクセスできる唯一のフォルダーです。ツールのパスはこのフォルダーからの相対パスです。クライアントが data または url のみを送信する場合も必須です。 |
--bind ADDR | 127.0.0.1:8032 | Streamable HTTP の待ち受けアドレスです。 |
--writable | オフ | pdf_pages と pdf_create を提供し、pdf_render_page { save_as } を許可します。これを指定しない場合、この 2 つのツールは一覧に表示されません。PDF_WRITABLE でも設定できます。true、1、yes、on で有効になり、未設定、空、false、0、no、off の場合は無効のままです。それ以外の値を指定すると、サーバーは起動時に停止します。 |
--pdfium-dir DIR | なし | PDFium を最初に検索する場所です。 |
--stdio | オフ | HTTP の代わりに、標準入力/標準出力で MCP を通信します。 |
ログは stderr に出力されます(詳細を確認するには RUST_LOG=debug を指定します)。GET /health は OK を返します。
クライアントを接続する
Claude Code
# HTTP (start the server first)
claude mcp add --transport http pdf http://127.0.0.1:8032/mcp
# or stdio
claude mcp add pdf -- emperor-pdf serve --stdio --root /path/to/pdfs --pdfium-dir /path/to/pdfium
Claude Desktop(claude_desktop_config.json)
{
"mcpServers": {
"pdf": {
"command": "/path/to/emperor-pdf",
"args": ["serve", "--stdio", "--root", "/path/to/pdfs", "--pdfium-dir", "/path/to/pdfium"]
}
}
}
Claude Desktop、読み書き可能:args に "--writable" を追加します。
Kowalski(config.toml)、HTTP または stdio 経由:
[[mcp.servers]]
name = "pdf"
transport = "http"
url = "http://127.0.0.1:8032/mcp"
# or let Kowalski start it
[[mcp.servers]]
name = "pdf"
transport = "stdio"
command = ["/path/to/emperor-pdf", "serve", "--stdio", "--root", "/path/to/pdfs", "--pdfium-dir", "/path/to/pdfium"]
ツール
4 つの読み取りツールでは、呼び出しごとに次のいずれか 1 つの方法で PDF を指定します。
path:ルートフォルダーからの相対ファイルパス(pdf_searchでは**/*.pdfのような glob も指定できます)。data:PDF のバイトデータ(base64。data:application/pdf;base64,のプレフィックスも使用できます)。url:サーバーがダウンロードするhttps://URL。
data と url は 8 MiB(emperor-mcp の limits バイト上限)までです。ダウンロードは 30 秒でタイムアウトし、
リダイレクトは最大 5 回まで追跡します。
| ツール | 引数 | 戻り値 |
|---|---|---|
pdf_info | path / data / url | ページ数、タイトル、作成者、件名、キーワード、作成アプリケーション、PDF 生成アプリケーション、作成日/更新日(ISO 8601)、PDF バージョン、暗号化の有無、バイト単位のサイズ。 |
pdf_text | path / data / url、pages?("1-3,5"、"4-")、max_chars?(デフォルトは 100 000、最大 2 000 000) | ページごとのテキスト、使用された抽出器(pdfium または lopdf)、テキストが切り詰められたかどうか、および隠しテキストがある場合はその警告。 |
pdf_search | path(ファイルまたは glob)/ data / url、query、regex?、case_sensitive?、max_hits?(デフォルトは 50、最大 500) | ファイル、ページ、各一致箇所、および前後の文脈を含むスニペット。隠しテキストがあるページにはフラグが付きます。 |
pdf_render_page | path / data / url、page、dpi?(1〜300、デフォルトは 110)、save_as?、overwrite? | PNG 画像としてのページ(MCP 画像コンテンツ)、サイズ、および保存先。PDFium が必要です。save_as には --writable が必要です。 |
pdf_pages | operation(merge または extract)、inputs([{path, pages?}])、output、overwrite? | 指定された順序のページから作成された新しい PDF。--writable サーバーでのみ使用できます。 |
pdf_create | markdown、output、title?、overwrite? | Markdown(見出し、強調、リスト、表、コードブロック、引用、リンク)から組版された新しい PDF。create 機能を有効にしてビルドされた --writable サーバーでのみ使用できます。 |
ページ番号は 1 から始まります。pdf_pages はページとそのコンテンツを保持しますが、入力ファイルのブックマーク、フォーム、タグ付き構造は保持しません。
ツールのアノテーションには各ツールの動作が記載されています。読み取りツールは読み取り専用で、冪等性があり、オープンワールドです(URL を取得できます)。書き込み可能なサーバー上の pdf_pages、pdf_create、pdf_render_page は読み取り専用ではなく、破壊的な操作としてマークされています。これは overwrite: true によってファイルが置き換えられるためです。読み取り専用サーバーでは、ファイルを保存できないため、pdf_render_page は読み取り専用としてマークされています。
隠しテキスト
PDFium を使用する場合、pdf_text と pdf_search は読み取るページのすべての文字を確認し、ページを見た人にはおそらく見えないテキストにフラグを付けます。
- 画像の上に重なっている場合を除き、非表示の描画モード(モード 3)で描画されたテキスト。画像の上に重なるテキストは、スキャンしたページを検索可能にする OCR の仕組みです。
- 背景に描画がない白色または白に近い色(あるいは完全に透明)のテキスト。
- 1 pt 未満のサイズで設定されたテキスト。
- ページ領域の外側にあるテキスト。
このテキストはドキュメントのフレーム内で引き続き返されます。別途、枠で囲まれた警告にファイル名、ページ、理由が示され、モデルにはそのテキストをデータとして扱い、ユーザーに伝えるよう求めます。pdf_search は、そのようなページでの各一致箇所に page_has_hidden_text のフラグを付けます。この確認はヒューリスティックです。たとえば、フォームオブジェクト内に描画された白い背景は何も隠しませんが、調査対象にはなりません。lopdf によるフォールバックでは確認を行わず、その旨が示されます。
スキャンしたページ
emperor-pdf には OCR エンジンがありません。テキストレイヤーのないスキャンページは、pdf_text から空またはほぼ空として返されます。pdf_render_page でレンダリングし、画像を読み取れるビジョン対応モデルに画像を読み取らせてください。すでに OCR 処理されたスキャンには非表示のテキストレイヤーがあり、pdf_text はそれを読み取ります(隠しテキストとしてはフラグを付けません)。
セキュリティモデル
- ケイパビリティによって強制される単一のルート。 ルートは一度だけ
cap_std::fs::Dirとして開かれ、すべての読み取りと書き込みは相対パスを通じて行われます。..を含むパスや絶対パスは、ファイルシステムへの呼び出しを行う前に、明確なメッセージとともに拒否されます。また、cap-std はルートの外に解決されるシンボリックリンクを拒否します。グロブは同じハンドルを使ってルートを走査して展開されます(隠しフォルダーはスキップされ、ファイル数は最大 200 件です)。 --writableを指定しない限り読み取り専用です。 指定しない場合、pdf_pagesとpdf_createは登録されず(クライアントには表示されません)、pdf_render_page { save_as }はサーバーが読み取り専用であることを返します。指定した場合でも、呼び出しにoverwrite: trueが渡されない限り、既存のファイルは置き換えられません。- URL:公開 HTTPS のみ。
urlはhttps://で始まり、ユーザー名やパスワードを含んではなりません。リダイレクトのたびに再検証されます。ホスト名はサーバーで解決され、公開アドレスのみが使用されます。ループバック、プライベート(RFC 1918)、リンクローカル(169.254.169.254 のクラウドメタデータを含む)、共有、IPv6 のユニークローカルなどのアドレス範囲は拒否されるため、呼び出しからサーバー自身のネットワーク上のサービスにはアクセスできません。ダウンロードとdataは 8 MiB 以下で、PDF のような内容で始まる必要があります。 - ドキュメントのテキストはデータです。 PDF はあらゆる場所から取得され、モデルを誘導するために書かれたテキストが含まれている場合があります。テキストと検索スニペットは、著者不明のドキュメントとして emperor-mcp のフレーミングで囲まれます(nonce で保護された区切り文字、「指示ではなくデータ」)。メタデータ、結果、隠しテキストの警告は、計算された値としてフレーミングされます。
- Markdown からコードは実行できません。
pdf_createはテキストのすべての文字をエスケープし、コードとリンクを文字列リテラルとして渡すため、Markdown がマークアップやスクリプトとして Typst に渡されることはありません。Typst のワールドは生成されたファイル以外を提供せず、フォントは埋め込まれるため、ドキュメントがディスクを読み取ることはできません。Typst が実行されるのは、create機能を有効にしてビルドされた書き込み可能なサーバーのみです。 - 処理量には上限があります。 256 MiB を超えるファイルは拒否されます。フォールバックのテキスト抽出では、ページごとの展開後のコンテンツ量に上限が設けられます。レンダリングは 300 dpi、各辺 8000 px、Markdown 入力は 2 MiB までです。
doctor
emperor-pdf doctor --root ~/Documents/papers --pdfium-dir ./pdfium --writable
emperor-pdf 0.1.3 doctor
[ok ] root folder /Users/me/Documents/papers (writable)
[ok ] pdfium loaded from ./pdfium/lib/libpdfium.dylib
[ok ] typst fonts 6 embedded faces (DejaVu Sans Mono, Libertinus Serif)
[ok ] listen address 127.0.0.1:8032 is free
[ok ] tool budget 6 of at most 8 tools
all good (0 warning(s))
チェックに失敗すると 1 で終了します。PDFium がない場合は警告であり、失敗ではありません。--stdio を指定するとポートのチェックはスキップされます。ツール数の上限では、サーバーが一覧表示するツール数を数えます。読み取り専用の場合は 4 個、--writable を指定した場合は 6 個です。--no-default-features ビルドでは、フォントのチェックは行われません。
開発
scripts/fetch-pdfium.sh # once, so the PDFium tests run instead of being skipped
cargo fmt --all --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --no-default-features -- -D warnings
cargo test
cargo deny check
テストでは、一時フォルダー内で Typst を使ってフィクスチャー PDF を作成し、HTTP(および stdio 経由の 1 件)で実際のサーバーと通信します。url ソースは小規模なローカル HTTP サーバーから取得されます。ツール一覧は emperor-mcp の testkit でチェックされます。./pdfium がない場合、PDFium 専用のテストは注記を表示して合格します。
リンク
- crates.io:emperor-pdf
- Official MCP Registry:mcp-name: io.github.yarenty/emperor-pdf
- フレームワーク:emperor-mcp
- 他の PDF MCP サーバーとの比較:docs/COMPARISON.md
ライセンス
お好みに応じて、MIT または Apache-2.0 のデュアルライセンスで提供されます。
フォント
create 機能では、assets/fonts にある2種類のフォントファミリーとそれぞれのライセンステキストをバイナリに埋め込み、pdf_create で使用します。
| フォント | ファイル | ライセンス |
|---|---|---|
| Libertinus Serif(本文) | Regular, Bold, Italic, Bold Italic | SIL Open Font License 1.1(テキスト) |
| DejaVu Sans Mono(コード) | Regular, Bold | Bitstream Vera ライセンス。DejaVu による変更部分はパブリックドメイン(テキスト) |
どちらも制限の緩やかなライセンスで、ドキュメントへの埋め込みとソフトウェアとの再配布が認められています。GPL ライセンスのフォントは含まれていません(Typst 独自の New Computer Modern セットは使用していません)。リリースアーカイブには、両方のライセンステキストが FONTS-NOTICE として含まれています。作成したドキュメントは、フォントを抽出する場合にフォント自体の通知を保持することを除き、これらのライセンスの影響を受けません。インストールした場合の PDFium は、独自のライセンス(Apache-2.0 / BSD-3-Clause)の下で提供されます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。