PrintgraphのMCPでClaudeやChatGPTと話しながら請求書の HTML テンプレートを作る
Printgraph は、HTML テンプレートに JSON のデータを差し込んで PDF を返すサービスです。テンプレートは管理画面で書けますが、MCP(Model Context Protocol)サーバーも用意しているので、AI と話しながら作ることもできます。
つなげるのは開発者向けのツールだけではありません。普段チャットで使っている Claude(Web・デスクトップアプリ)や ChatGPT にも、コネクタとして追加できます。HTML を書けない人でも、「こういう請求書がほしい」と話すだけでテンプレートを Printgraph に登録できます。もちろん、ターミナルで Claude Code を使っている開発者もつなげます。
この記事では、MCP をつなぎ、請求書のテンプレートを作って登録し、修正を新しいバージョンとして積み、API から PDF を出すまでを順に説明します。例として、架空の「株式会社あおば工務店」がリフォーム工事の請求書を出す場面を使います。
1. MCP サーバーをつなぐ
どのアプリでも、登録する URL は同じです。
https://printgraph.jp/api/mcpAPI キーを AI に渡す必要はありません。認可は OAuth で行い、アプリごとにトークンが発行されます。Printgraph の「設定 → 連携アプリ」にもこの URL と、アプリ別の接続手順が出ています。
Claude(Web・デスクトップアプリ)
- 設定 → コネクタ を開きます
- カスタムコネクタを追加 を選び、上の URL を貼り付けます
- ブラウザが開くので Printgraph にログインし、連携を許可します
追加したら、チャットの入力欄のツールメニューで Printgraph が有効になっていることを確認してから話しかけます。
ChatGPT
手順は Claude と同じです。
- 設定 → コネクタ を開きます
- カスタムコネクタを追加 を選び、上の URL を貼り付けます
- ブラウザが開くので Printgraph にログインし、連携を許可します
Printgraph の MCP は、ChatGPT のコネクタが使う search / fetch ツールにも対応しているので、既存のテンプレートを探して読む操作もそのまま通ります。
Claude Code
ターミナルで次のコマンドを実行します。初回の接続時にブラウザが開くので、ログインして連携を許可します。
claude mcp add --transport http printgraph https://printgraph.jp/api/mcp許可する権限
連携時の同意画面では、次の 2 つの権限を確認して「連携を許可する」を押します(ワークフローのベータを使っている組織では、ワークフロー用の権限も並びます)。
- 閲覧(templates:read): テンプレートの一覧・内容を読む
- 編集(templates:write): テンプレートを作成・更新・削除する
連携中のアプリは「設定 → 連携アプリ」で確認でき、そこから解除するとトークンは期限内でもすぐに無効になります。
2. 何を作るかを伝える
つないだら、あとは普段どおりに頼みます。ここから先の流れは、Claude・ChatGPT・Claude Code のどれでも同じです。
ポイントは、差し込む値を最初に決めて伝えることです。どの値をテンプレートに書き込み、どの値を API から渡すかが決まっていれば、AI はそれに沿って変数を定義します。
例では次のように頼みました。
Printgraph に請求書のテンプレートを作ってください。A4 縦、1 ページに収まる想定です。 差し込む値は、請求番号・請求日・支払期限・宛先の会社名と担当者名・明細(品名、数量、単価)・備考です。明細は配列で渡します。 発行元は「株式会社あおば工務店」で固定にしてください。消費税は 10% で、小計・消費税・合計を明細から計算して出してください。
AI は HTML を書き、create_template ツールでそのまま Printgraph に登録します。チャットアプリでは、テンプレートを作ったり変えたりするツールを呼ぶ前に、実行してよいかを確認されることがあります。
返ってくる結果にはテンプレート ID と編集画面の URL が入っているので、画面を開くとプレビューで見た目を確かめられます。チャットで作った場合も、このリンクから管理画面に移ってプレビューを見るのが早いです。
3. できあがるテンプレート
登録されたテンプレートは、おおよそ次のような HTML です(長いので CSS は一部を省いています)。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<style>
@page { size: A4; margin: 15mm; }
body { font-family: "Noto Sans JP", sans-serif; font-size: 10pt; color: #222; }
h1 { text-align: center; letter-spacing: 0.5em; }
table.items { width: 100%; border-collapse: collapse; }
table.items th, table.items td { border: 1px solid #999; padding: 4px 8px; }
td.num { text-align: right; }
</style>
</head>
<body>
<h1>請求書</h1>
<p>請求番号: {{ invoice_number }}<br>
請求日: {{ issued_on }}<br>
お支払期限: {{ due_on }}</p>
<p><strong>{{ customer_name }} 御中</strong><br>{{ contact_name }} 様</p>
<p>株式会社あおば工務店</p>
{% assign subtotal = 0 %}
<table class="items">
<tr><th>品名</th><th>数量</th><th>単価</th><th>金額</th></tr>
{% for item in items %}
{% assign amount = item.quantity | times: item.unit_price %}
{% assign subtotal = subtotal | plus: amount %}
<tr>
<td>{{ item.name }}</td>
<td class="num">{{ item.quantity }}</td>
<td class="num">{{ item.unit_price }}</td>
<td class="num">{{ amount }}</td>
</tr>
{% endfor %}
</table>
{% assign tax = subtotal | times: 0.1 | floor %}
<p>小計 {{ subtotal }} 円 / 消費税 {{ tax }} 円 / <strong>合計 {{ subtotal | plus: tax }} 円</strong></p>
<p>{{ note }}</p>
</body>
</html>変数の差し込みは Liquid 記法です。{{ 変数名 }} で値を出し、{% for %} で繰り返し、times や plus で計算できます。
テンプレートと一緒に、変数の定義も登録されます。
invoice_number/issued_on/due_on/customer_name/contact_name/noteは string 型(文字列)itemsは json 型。配列やオブジェクトを受け取り、{% for item in items %}で回せます
変数には説明と既定値も付けられます。既定値があると、管理画面のプレビューにその値が入った状態で表示されるので、「プレビュー用に明細 3 行ぶんの既定値も入れて」と頼んでおくと確認が早くなります。
なお、app / sys / org / sheet / user / printgraph / global は予約語で、変数名には使えません。全テンプレートで共通にしたい会社名や住所は、管理画面の共有変数に登録して {{ global.変数名 }} で参照します(共有変数そのものは MCP からは編集できません)。
4. 直したいところを伝えて、新しいバージョンにする
プレビューを見て直したいところが出てきたら、そのまま会話を続けます。
金額を 3 桁区切りにして、合計の行をもう少し目立たせてください。振込先(あおば銀行 本店 普通 1234567)も下に足してください。
AI は get_template で今の本文と変数定義を読み、直した HTML を create_template_version で新しいバージョンとして追加します。既存のバージョンは上書きされません。
PDF の生成に使われるのは「メインバージョン」だけです。create_template_version は既定で追加したバージョンをメインにしますが、本番で使っているテンプレートを直すときは、次のように頼むのが安全です。
新しいバージョンは下書きとして追加して、まだメインにはしないでください。
こうすると setAsMain: false で追加され、本番の出力は変わりません。画面で確認して問題なければ「さっきのバージョンをメインにして」と頼むと、set_main_template_version で切り替わります。戻したいときも同じように、前のバージョンをメインにするだけです。
既存のテンプレートを元に別のものを作ることもできます。「見積書のテンプレートを、請求書と同じ見た目で作って」と頼むと、AI は search や get_template で請求書を読み、それを下敷きにして新しいテンプレートを作ります。
5. API から PDF を出す
MCP でできるのはテンプレートの管理までで、単発の PDF 生成は MCP からは行いません。PDF は、これまでどおり API キーを使って API から出します。
curl -X POST https://api.printgraph.jp/v1/pdf/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "YOUR_TEMPLATE_ID",
"params": {
"invoice_number": "INV-2026-1027",
"issued_on": "2026年10月27日",
"due_on": "2026年11月30日",
"customer_name": "株式会社みどり不動産",
"contact_name": "山田 太郎",
"items": [
{ "name": "浴室リフォーム工事", "quantity": 1, "unit_price": 980000 },
{ "name": "廃材処分費", "quantity": 1, "unit_price": 45000 }
],
"note": "お振込手数料はご負担ください。"
}
}' \
--output invoice.pdfparams のキーは、手順 3 で定義した変数名です。レスポンスは PDF のバイナリそのものです。PHP と JavaScript(Node.js)向けの SDK もあります。
役割を分けることもできます。帳票の見た目は担当者が Claude や ChatGPT と話しながら整え、開発者は API の呼び出しだけを実装する。テンプレートを直してもアプリケーションのデプロイは要らず、メインバージョンを切り替えれば次の PDF から反映されます。
うまく作るためのコツ
何度か作ってみて、AI に伝えておくと手戻りが減ったことをまとめます。
- 用紙サイズと余白を最初に言う。 「A4 縦、余白 15mm」のように伝えると、
@pageで指定してくれます。言わないと画面向けのレイアウトになりがちです - 差し込む値と固定の文言を分けて伝える。 変数にしたいものを列挙しておけば、変数の名前と型(string か json か)がぶれません
- 明細のように件数が変わるものは「配列で渡す」と言う。 json 型の変数になり、
{% for %}で回すテンプレートになります - 複数ページにまたがる帳票は、改ページの扱いを指定する。 「明細の行の途中で改ページしない」「表の見出しを次のページにも出す」と伝えると、
break-inside: avoidなどを入れてくれます - 今の帳票があるなら見せる。 チャットアプリなら、いま使っている請求書の PDF や画像を添付して「これと同じレイアウトで」と頼むと、ゼロから説明するより早く近いものができます
- QR コードは専用のフィルタで出せる。
{{ url | qr }}で img タグごと、{{ url | qr_data_uri }}で data URI だけを埋め込めます。サイズや誤り訂正レベルも指定できます
おわりに
帳票のテンプレートは、一度作れば長く使う一方で、最初の 1 枚を組むのに手間がかかります。MCP を使うと、その最初の 1 枚を Claude や ChatGPT との会話で用意し、細かい調整をバージョンとして安全に積んでいけます。
MCP 経由の操作には、有効なサブスクリプションが必要です。料金は PDF 1 枚 0.3 円の従量課金で、月額の固定費はありません。接続方法とツールの一覧は MCP 連携のドキュメント にまとめています。

望月 涼太 / polidog
Co-Founder / Web Engineer
