boxpdf-html について
boxpdf-htmlは、boxpdfライブラリを使って作成済みHTMLを静的PDFに変換します。請求書やレポートなどの文書出力を想定し、レンダリングとライブラリ解説を備えたMCPサーバーも含みます。
主な機能
- 01CLIとAPIによるHTMLからPDFへの変換
- 02MCPの変換ツールとライブラリ解説
- 03CSS診断と未対応スタイルの報告
- 04カスタム埋め込みフォントと画像処理
- 05大規模文書のストリーミング変換
- 06CLIによるPDFパスワード暗号化
活用シーン
- 01請求書やレシートのHTMLからPDFを作成
- 02文書用に生成したTailwind CSSをレンダリング
- 03大きなHTMLアーカイブを段階的に変換
- 04エージェントにPDF生成方法を案内
MCP 対応
stdio MCPサーバーは、HTMLと任意のCSSを描画する`html_to_pdf`と、ライブラリの要点を案内する`boxpdf_docs`を提供します。ガイド、README、テンプレートのリソースも公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| css | string | いいえ | レンダリング前に挿入する追加スタイルシート(例:コンパイル済み Tailwind の出力)。 |
| html | string | はい | HTML マークアップ。<style> ブロックやインラインスタイルを含められます。 |
| size | enum | いいえ | ページサイズ。Letter | Legal | Tabloid | A4 | A5 | A6 |
| debug | boolean | いいえ | boxpdf のデバッグ用オーバーレイを描画します。 |
| fonts | object | いいえ | 組み込みの Helvetica ファミリーの代わりに埋め込む、任意の TTF/OTF ファイルパス。 |
| fonts.bold | string | いいえ | |
| fonts.italic | string | いいえ | |
| fonts.regular | string | いいえ | |
| fonts.boldItalic | string | いいえ | |
| margin | number | いいえ | PDF のページ余白。単位はポイントです。 |
| baseUrl | string | いいえ | 相対 <img> および background-image URL の解決に使うディレクトリまたは URL。既定値は作業ディレクトリです。 |
| outputPath | string | いいえ | PDF の書き込み先(cwd からの相対パスも使用可)。省略した場合、PDF は base64 リソースとしてインラインで返されます。 |
| allowRemote | boolean | いいえ | http(s) 画像の取得を許可します。SSRF 防止のため、既定ではオフです。 |
詳細
@boxpdf/html-reader
@boxpdf/writer を基盤とした、読みやすい HTML から PDF へのレンダリングです。請求書、領収書、レポート、メールなど、実用的な静的 PDF がブラウザーのピクセル単位の再現よりも重要となる、作成済みのドキュメント HTML を対象としています。
npm install @boxpdf/html-reader @boxpdf/writer pdf-lib
元の boxpdf-html パッケージと boxpdf-html コマンドも引き続きサポートされています。これらは同じビルドから、@boxpdf/html-reader と同じバージョンで公開されています。新しいプロジェクトではスコープ付きパッケージを使用してください。既存のプロジェクトを変更する必要はありません。
CLI
HTML ファイルを直接レンダリングします。
npx @boxpdf/html-reader invoice.html invoice.pdf
スコープ付きパッケージでは、より短いコマンド名として html-reader も使用できます。
生成済みの Tailwind CSS を使う場合:
npx tailwindcss -i ./tailwind.css -o ./dist/tailwind.css --minify
npx @boxpdf/html-reader invoice.html invoice.pdf --css ./dist/tailwind.css
非常に大きな入力には、--stream を追加します。
npx @boxpdf/html-reader archive.html archive.pdf --stream
type archive.html | npx @boxpdf/html-reader - archive.pdf --stream
ストリーミングでは、HTML を 2 回に分けて処理します。1 回目は CSS、フォント、画像を処理し、2 回目はレイアウトと PDF 出力を段階的に行います。再度開けるように、標準入力は一時ファイルに一時保存されます。変換が成功した場合にのみ、出力先のファイルが置き換えられます。この方法には boxpdf 1.12.0 以降が必要です。
PDF 2.0 AES-256 パスワード暗号化を使う場合:
BOXPDF_PASSWORD='open me' \
npx @boxpdf/html-reader invoice.html invoice.pdf --password-env BOXPDF_PASSWORD
--password-env には環境変数名を指定します。この変数には、空でないパスワードを設定する必要があります。コマンドライン引数としてパスワード値を渡すことはできないため、コマンドラインやプロセス一覧にパスワードが表示されることはありません。
カスタムフォントとローカル画像を使う場合:
npx @boxpdf/html-reader invoice.html invoice.pdf \
--font ./Inter-Regular.ttf \
--bold-font ./Inter-Bold.ttf \
--font-family 'Inter=normal:Inter-Regular.ttf,bold:Inter-Bold.ttf'
便利なフラグ:
html-reader <input.html> <output.pdf>
html-reader - <output.pdf> # read HTML from stdin
html-reader input.html output.pdf --css app.css
html-reader input.html output.pdf --base-url ./public
html-reader input.html output.pdf --password-env BOXPDF_PASSWORD
html-reader input.html output.pdf --debug
html-reader input.html output.pdf --unsupported-css
html-reader input.html output.pdf --profile
html-reader input.html output.pdf --stream
CLI は、pdf-lib の組み込み Helvetica ファミリーをデフォルトで使用します。ブランドに合わせる必要がある場合、Unicode の文字を幅広くカバーする必要がある場合、または正確なメトリクスが重要な場合は、本番出力に実際の埋め込みフォントを使用してください。
MCP サーバー
boxpdf-html mcp は、AI エージェント向けの stdio MCP サーバーです。必要なものがすべて含まれており、html_to_pdf ツールと boxpdf ライブラリのドキュメント一式を備えているため、エージェントが別のサーバーを追加する必要はありません。
claude mcp add boxpdf-html -- npx -y @boxpdf/html-reader mcp
ツール
html_to_pdf— HTML 文字列(および任意のcss)を PDF にレンダリングします。outputPathに書き込むか、PDF を base64 リソースとしてインラインで返します。エージェントが入力を修正できるよう、常にwarningsとunsupportedCssの診断情報を返します。- 引数:
html(必須)、css、outputPath、size(Letter/A4/Legal/Tabloid、デフォルトはLetter)、margin(デフォルトは 40)、baseUrl、fonts: { regular, bold, italic, boldItalic }(TTF/OTF のパス)、allowRemote(デフォルトはfalse— 有効にしない限り、http(s) の画像取得はブロックされます)、debug。
- 引数:
boxpdf_docs— ライブラリを直接使って PDF を作成するための、要点を絞ったガイダンスです。topic:quickstart(デフォルト)、fonts、themes、tables、pagination、streaming、html-api、cloudflare。
リソース:boxpdf-html://guide、boxpdf-html://readme、boxpdf://readme、および 5 つの boxpdf://templates/<name> ソース(receipt、boarding-pass、resume、order-confirmation、certificate)。
このサーバーは JavaScript を実行せず、(デフォルトでは)ネットワークリクエストも行いません。outputPath への書き込みにはエージェントのファイルシステム権限が使われます。指定しない場合、1 MB を超える PDF はインラインで返さず、要約されます。
API
htmlToPdf — 1 回の呼び出しでバイト列を取得
htmlToPdf(html, options?) は最もシンプルな方法です。ドキュメントを作成し、フォントを埋め込み、レンダリングして、PDF のバイト列を返します。フォントは組み込みの Helvetica ファミリーがデフォルトのため、最小限の呼び出しではセットアップは不要です。
import { htmlToPdf } from "@boxpdf/html-reader";
const bytes = await htmlToPdf("<h1>Invoice</h1><p>Thanks for your order.</p>");
本番出力では、埋め込みフォント(loadFont 経由)と resolveImage コールバックを渡します。
import { readFile } from "node:fs/promises";
import { PDFDocument } from "pdf-lib";
import { loadFont, loadImage } from "@boxpdf/writer";
import { htmlToPdf } from "@boxpdf/html-reader";
const pdf = await PDFDocument.create();
const inter = await loadFont(pdf, await readFile("Inter-Regular.ttf"));
const interBold = await loadFont(pdf, await readFile("Inter-Bold.ttf"));
const logo = await loadImage(pdf, await readFile("logo.png"));
const bytes = await htmlToPdf(await readFile("invoice.html", "utf8"), {
pdf, // reuse the document you embedded into
font: inter,
boldFont: interBold,
resolveImage: ({ url }) => (url === "logo.png" ? logo : undefined),
margin: 40
});
オプション:font/boldFont/italicFont/boldItalicFont(デフォルトは Helvetica)、pdf(既存のドキュメントにレンダリング)、margin(デフォルトは 40)、size(デフォルトは US Letter)、width(CSS の包含ブロックの幅。デフォルトはページのコンテンツ幅)、debug、および htmlToBoxpdf が受け付けるすべてのオプション(resolveFont、resolveImage、baseUrl、defaultFontSize、defaultColor、diagnostics、profile)。
htmlToBoxpdf — 完全に制御できるノード
htmlToBoxpdf はレンダリングせずに、HTML を通常の boxpdf ノードに変換します。ノードそのもの、warnings/diagnostics、複数回のレンダリングパス、または renderFlow のヘッダー/フッターが必要な場合に使用してください。
import { readFile } from "node:fs/promises";
import { PDFDocument } from "pdf-lib";
import { loadFont, loadImage, renderFlow } from "@boxpdf/writer";
import { fontFamily, htmlToBoxpdf } from "@boxpdf/html-reader";
const html = await readFile("invoice.html", "utf8");
const pdf = await PDFDocument.create();
const inter = await loadFont(pdf, await readFile("Inter-Regular.ttf"));
const interBold = await loadFont(pdf, await readFile("Inter-Bold.ttf"));
const logo = await loadImage(pdf, await readFile("logo.png"));
const result = htmlToBoxpdf(html, {
font: inter,
boldFont: interBold,
resolveFont: fontFamily({
Inter: { normal: inter, bold: interBold },
"sans-serif": { normal: inter, bold: interBold }
}),
resolveImage: ({ url }) => (url === "logo.png" ? logo : undefined),
baseUrl: process.cwd(),
width: 532
});
console.log(result.warnings);
await renderFlow(pdf, result.nodes, { margin: 40 });
const bytes = await pdf.save();
width は PDF ポイント単位の CSS 包含ブロック幅です。40pt の余白がある US Letter ページのコンテンツ幅は 532pt なので、width: 532 が適切なデフォルト値です。
streamHtmlToPdf — メモリ使用量を抑えた大容量ドキュメントの変換
streamHtmlToPdf は、2 回のパスそれぞれで HTML を再度開く関数を受け取り、
PDF バイト列を逐次書き込みます。呼び出す前にフォントを埋め込んでください。
出力の開始前にリソースの事前チェックで見つかった画像を埋め込むには、
prepare を使用します。
import { createReadStream, createWriteStream } from "node:fs";
import { PDFDocument, StandardFonts } from "pdf-lib";
import { nodeAdapter } from "@boxpdf/writer";
import { streamHtmlToPdf } from "@boxpdf/html-reader";
const pdf = await PDFDocument.create();
const font = await pdf.embedFont(StandardFonts.Helvetica);
const result = await streamHtmlToPdf(
() => createReadStream("archive.html"),
nodeAdapter(createWriteStream("archive.pdf")),
{ pdf, font, width: 532, margin: 40 }
);
console.log(result.pageCount, result.dom.maxBufferedNodes);
通常のブロックラッパーと表は、サイズを制限した継続フラグメントとして解放されます。フレックス/グリッド、配置または変形されたコンテナー、分割されていない単一のテキストノードなどのアトミックなレイアウトには明示的な安全上限があり、安全にストリーミングできない場合は、わかりやすいエラーが発生します。同じ階層内での位置に意味が依存するセレクターでは、ラッパーのフラグメント化が保守的に無効になります。
フォント
フォントは明示的に指定します。boxpdf-html はシステムフォントを検出せず、ブラウザーのフォントスタックも同梱していません。これによりレンダリングの決定性が保たれ、サーバーレスのランタイムでも動作します。
最低限、font を渡してください。HTML で太字または斜体を使用する場合は、boldFont と italicFont も渡してください。
const result = htmlToBoxpdf(html, {
font,
boldFont,
italicFont,
width: 532
});
CSS の font-family には、fontFamily() を使用します。
const resolveFont = fontFamily({
Inter: {
normal: interRegular,
bold: interBold,
italic: interItalic,
boldItalic: interBoldItalic
},
Helvetica: {
normal: fallback,
bold: fallbackBold
},
"sans-serif": {
normal: fallback,
bold: fallbackBold
}
});
リゾルバーは { families, weight, style } を受け取り、pdf-lib の PDFFont を返します。より柔軟なマッピング、フォントのエイリアス、言語固有のフォールバック、またはウェイトの合成が必要な場合は、独自のリゾルバーを指定できます。
注意点:
font-family: system-uiは、リゾルバーがsystem-uiに対応付けている場合にのみ機能します。- pdf-lib の標準フォントは便利ですが、用途が限られています。実際のドキュメントには、埋め込み TTF/OTF フォントを使用してください。
- 複雑な文字のシェーピングは、pdf-lib/fontkit の動作に依存します。対象としているのは、西洋言語の請求書やレポートのテキストです。
- フォントメトリクスはレイアウトに影響します。視覚的な安定性が重要な場合は、テストと本番環境で同じ埋め込みフォントを使用してください。
Tailwind CSS
Tailwind は、クラス名だけではなく、生成された CSS をレンダリングすると機能します。一般的な手順は次のとおりです。
- Tailwind のクラスを使ってドキュメントの HTML を記述します。
- その HTML を対象に Tailwind を実行します。
- 生成された CSS をインライン化するか、
boxpdf-htmlに渡します。 - PDF で使用するコンテンツ領域に合わせた包含幅でレンダリングします。
ソースの例:
<div class="p-6 bg-[#f8fafc] text-gray-900">
<div class="max-w-[520px] rounded-[10px] border bg-white p-5 shadow-sm">
<div class="grid grid-cols-[1fr_2fr] gap-x-4 gap-y-3">
<div class="rounded-md border border-blue-200 bg-blue-50 p-3">
<p class="text-xs font-semibold uppercase tracking-wide text-blue-700">Status</p>
<p class="mt-1 text-sm font-bold">Paid</p>
</div>
<div class="rounded-md border border-gray-200 p-3">
<p class="text-xs font-semibold uppercase tracking-wide text-gray-600">Notes</p>
<p class="mt-1 text-sm leading-5">Two fraction column wraps later.</p>
</div>
</div>
</div>
</div>
CSS をビルドします。
@import "tailwindcss";
@source "./invoice.html";
npx tailwindcss -i ./tailwind-input.css -o ./tailwind-output.css --minify
npx @boxpdf/html-reader invoice.html invoice.pdf --css ./tailwind-output.css
対応する Tailwind のパターンには、一般的な余白、色、テキスト、ボーダー、角丸、幅/高さ、フレックス、グリッド、表、画像、任意の値を使ったユーティリティが含まれます。未対応のユーティリティ宣言は、--unsupported-css または diagnostics: { unsupportedCss: true } で報告できます。
Tailwind の注意点:
- レスポンシブ/状態バリアントは CSS として解析されます。ビューポートとのインタラクションはありません。作成する PDF に合わせて、生成する CSS の対象を 1 つ選んでください。
- 2 次元の変形では、順序指定された
translate、scale、rotate、skew、matrixの関数リスト、それらの X/Y バリアント、transform-origin、および独立したtranslate、rotate、scaleプロパティに対応しています。長さ/パーセンテージによる移動と、deg、grad、rad、turnの角度に対応しています。3 次元の変形、影、フィルター、トランジション、ブラウザー専用の効果は無視されるか、未対応として報告されます。 - Tailwind の preflight によるリセットは、ほとんどの場合問題ありません。診断では、ノイズの多いベースセレクターではなく、意図的にユーティリティセレクターに重点を置いています。
- テキストのレイアウトが重要な場合は、Tailwind のデザイン確認時と PDF のレンダリング時に同じフォントを使用してください。
画像
pdf-lib の画像はレンダリング前に埋め込む必要があるため、この API では resolveImage を使用します。
const images = new Map([
["logo.png", await loadImage(pdf, await readFile("logo.png"))]
]);
htmlToBoxpdf(html, {
font,
resolveImage: ({ url }) => images.get(url),
baseUrl: process.cwd()
});
CLI は、<img src> と CSS の url(...) で参照されるローカル、http(s)、data: の画像 URL を事前に読み込みます。画像が見つからない場合も、幅/高さを推定できればレイアウトボックスは保持されます。
CSS と HTML のサポート範囲
サポート対象:
parse5を使用した HTML フラグメントおよび完全なドキュメント。css-treeを使用したスタイルシートおよびインラインスタイル。- セレクター:タグ、クラス、ID、属性、子孫、子/兄弟コンビネーター、一般的な構造疑似クラス、エスケープされた Tailwind セレクター。
- カスケードの基本:スタイルシートのルール、インラインスタイル、
!important、継承、カスタムプロパティ、var()、一般的なcalc()。 - レイアウト:ブロック、インライン、インラインブロック、インラインフレックス、インライングリッド、フレックス、グリッドのフォールバック、テーブル、フロート、絶対/相対配置、z-index、overflow hidden、置換画像。
- テキスト:リッチなインラインラン、強制改行、通常/折り返しなし/pre形式の空白、変換、装飾、配置、垂直方向の配置、リストのぶら下げインデント、折り返し。
- サイズ/スタイル:CSS px からポイントへの変換、pt、em/rem、vw/vh、一般的な箇所でのパーセンテージ、最小/最大幅、box-sizing、マージン/パディング/gap、背景、背景画像、枠線、辺ごとの枠線、枠線の結合、角丸、object-fit。
ブラウザーではありません:
- JavaScript は実行されません。
- インタラクティブまたは動的なレイアウトには対応していません。
- 完全なブラウザーの描画モデルには対応していません。
- システムフォントの検出には対応していません。
- CSS のサポートは、静的なドキュメント出力を中心に意図的に拡張されています。実際のテンプレートで未対応の宣言を見つけるには、診断機能を使用してください。
診断
const result = htmlToBoxpdf(html, {
font,
width: 532,
diagnostics: { unsupportedCss: true, sampleLimit: 3 },
profile: (event) => console.log(event.phase, event.elapsedMs)
});
console.log(result.diagnostics?.unsupportedCss);
未対応の CSS 診断は、プロパティと値のペアごとに集約され、セレクターのサンプルも含まれます。プロファイルイベントでは、解析、CSS、スタイル計算、レンダーツリーの構築、出力ノード数が確認できます。
便利なコマンド:
pnpm run typecheck
pnpm run test
pnpm run build
pnpm run tailwind:fixture
pnpm run visual:check
pnpm run pack:release
BOXPDF_DEP_VERSION=^1.7.0 pnpm run publish:release
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。