mf-invoice-fetch
課税仕入の仕訳に対応する受領請求書PDFを、Gmail添付および各サービスの顧客ポータル(マネーフォワード/カゴヤ・ジャパン/Amazon/スイッチサイエンス)から取得し、references/invoices/ に配置して matches.json に登録するスキル。mf-invoice-check で「請求書PDF未登録」と出た仕訳を埋めるときに使う。「請求書を取ってきて」「請求書ダウンロード
SKILL.md.claude/skills/mf-invoice-fetch/SKILL.md
GitHub受領請求書PDFの取得・登録
mf-invoice-check が検出した「請求書PDF未登録」の仕訳に対して、実際のPDFを取得し
references/invoices/<年度>/ に配置して matches.json に登録する。
取得経路は2種類:
- Gmail添付 — Anthropic / Supabase / GitHub / Google Cloud / Cloudflare / SQLBAK
- 顧客ポータル — マネーフォワード / カゴヤ・ジャパン / Amazon / スイッチサイエンス (メール添付なし。Chrome MCP でブラウザ操作する)
Step 0: 未登録リストを作る
python c:/moneyforward/.claude/skills/mf-invoice-check/scripts/check_invoices.py <journals.json> --year 2026
出力の「請求書PDF未登録」が作業対象。各仕訳の 取引日・摘要・金額(税込) を控える。
税込金額 = branches[].debitor.value + debitor.tax_value。これが請求書の合計額と一致するかで
突合の正しさを検証する(日付だけで紐付けない)。
Step 1: Gmail添付から取得
scripts/gmail_fetch.py を使う。~/.gmail-mcp/credentials.json のリフレッシュトークンで
Gmail API を直接叩く(接続中の Gmail MCP には添付ダウンロード用ツールが無いため)。
python c:/moneyforward/.claude/skills/mf-invoice-fetch/scripts/gmail_fetch.py \
--after 2026/04/28 --out <staging_dir>
重要: トークン失効
invalid_grant が返ったらリフレッシュトークンが切れている(Google の testing モードは
7日で失効)。ユーザーに以下を実行してもらう。Claude Code の再起動は不要 —
このスクリプトは MCP 経由ではなく credentials.json を直接読むため、認証が通った時点で
同一セッションのまま続行できる。
npx @gongrzhe/server-gmail-autoauth-mcp auth
サービス別の検索クエリと採用する添付
| サービス | クエリ | 採用する添付 |
|---|---|---|
| Anthropic | from:invoice+statements@mail.anthropic.com |
Receipt-*.pdf(Invoice-* ではない) |
| Supabase | from:invoice+statements@supabase.com |
Receipt-*.pdf |
| GitHub | from:noreply@github.com subject:receipt |
github-<org>-receipt-<date>.pdf |
| Google Cloud | from:payments-noreply@google.com |
<請求書番号>.pdf |
| Cloudflare | from:noreply@notify.cloudflare.com subject:"invoice is attached" |
cloudflare-invoice-<日付>.pdf |
| SQLBak | from:noreply@sqlbak.com Payment Received |
payment_*.pdf |
Google Cloud は請求先アカウントが2つある
0167AE-67A318-FEC0D4 と 01833F-DE3AE7-E73305 の2アカウントがあり、毎月2通の
請求書メールが届く。2026年4月請求分以降、0167AE は ¥0 で課金が発生していないため、
仕訳は月1件しかない。01833F 側のPDFだけを仕訳に紐付け、¥0 の方は登録しない。
PDF内の金額は fitz(PyMuPDF)で ¥([\d,]+) を拾えば確認できる。
Step 2: 顧客ポータルから取得(Chrome MCP)
mcp__claude-in-chrome__* を使う(ログイン済みセッションが必要なため in-app Browser では不可)。
ログインが必要な画面でパスワードを入力してはいけない。 ログイン画面に当たったらタブを 開いたままユーザーにログインを依頼する。
マネーフォワード クラウド利用料
https://erp.moneyforward.com/office_usage_detail_statements
到達経路: クラウド会計 → 右上アカウントメニュー → ご利用プランの管理 → 「プランの変更、ご利用料金の確認はこちら」→ 料金明細タブ。
各行の「請求書」ボタンは .../office_usage_detail_statements/<ID>/bills を新規タブで開く。
PDFダウンロードは無く window.print() のみ(ネイティブ印刷ダイアログは自動操作不可)。
→ ページHTMLを保存してローカルで headless Chrome によりPDF化する(Step 3)。
請求書一覧の各行のリンクは JS でまとめて取れる:
Array.from(document.querySelectorAll('table tr')).map(tr=>({
d: tr.querySelector('td')?.innerText?.trim(),
a: Array.from(tr.querySelectorAll('a')).map(x=>x.href)
})).filter(x=>x.d)
日付対応: カード請求日は毎月5日、対応する請求日は前月末、PDF内の発行日は翌月2〜3日。 例: 仕訳 2026-07-05 ← 請求日 2026-06-30 ← 発行日 2026-07-03。 ファイル名は 発行日 を使う(既存ファイルもその規則)。
カゴヤ・ジャパン
https://kagoyaid.kagoya.jp/kagoyaid/invoice_list/<アカウント別トークン>
KAGOYA会員サイトの「請求管理」。トークンは会員サイトにログインして遷移すると得られる (アカウント固有なのでリポジトリに書かない)。
手順: 上部のセレクトで対象年月を選ぶ → 行のチェックボックスをON → 「ダウンロード」→ PDFが新規タブで開く(ダウンロードされない)。そのタブで以下を実行して保存する:
const r=await fetch(location.href); const b=await r.blob();
const a=document.createElement('a'); a.href=URL.createObjectURL(b);
a.download='kagoya_2026-04.pdf'; document.body.appendChild(a); a.click();
日付対応: カード請求日は翌月5〜8日。PDFの発行日は請求月の月末。 例: 仕訳 2026-05-08 ← 2026年4月分 ← 発行日 2026-04-30。
注意: PDFタブを tabs_close_mcp で閉じるとタブグループの追跡が壊れることがある。
閉じずに残し、最後にまとめて片付ける。
Amazon
注文番号がわかれば領収書ページに直接飛べる:
https://www.amazon.co.jp/gp/css/summary/print.html?orderID=<注文番号>
注文番号は仕訳の摘要に入っている(例: 注文250-4797853-6277405)。
PDFダウンロードは無いので、HTMLを保存してローカルでPDF化する(Step 3)。
ファイル名は注文日を使う。
スイッチサイエンス
注文確認メールに含まれる認証付きURLから注文ページへ入り、「注文後メニュー」に進む:
https://menu.switch-science.com/#/menu/<注文別トークン>/download
注文別トークンは注文ページの「注文後メニュー」リンクから取得する。メールの検索:
subject:(<注文番号>) スイッチサイエンス
本文中の https://www.switch-science.com/<shop_id>/orders/<order_id>/authenticate?key=...
を開く → ページ内の「注文後メニュー」リンクを取得。
書類ダウンロード画面で 「納品書兼適格請求書【インボイス】(発送後)」 を選び、
お名前に 本多 優鷹(様)を入れて「ダウンロード」。数秒後に
Y<注文番号>_invoice_delivery_note_<timestamp>_<id>.pdf が落ちる。
フォームに氏名を入れて送信する操作なので、ユーザーの承認を得てから実行すること。
宛名は既存の請求書に合わせて 本多 優鷹。
同一注文日に複数注文があると発行日が同じになるため、ファイル名に注文番号を付ける
(例: 2026-07-13_スイッチサイエンス_Y219311.pdf)。
Step 3: HTML → PDF 変換
PDFダウンロードが無いポータル(マネーフォワード・Amazon)用。
ブラウザ側でページHTMLを丸ごと落とす:
const a=document.createElement('a');
a.href=URL.createObjectURL(new Blob([document.documentElement.outerHTML],{type:'text/html'}));
a.download='<name>.html'; document.body.appendChild(a); a.click();
同一ページから2回連続でダウンロードすると Chrome にブロックされる。1ページ1ダウンロード。
ローカルで変換:
python c:/moneyforward/.claude/skills/mf-invoice-fetch/scripts/html_to_pdf.py <in.html> <out.pdf>
やってはいけないこと: getComputedStyle の結果を全要素にインライン化して保存する方法は
真っ白なPDFになる。外部CSSは link ごと捨てて、スクリプト・スタイル・class/style属性を
除去したうえで最小限の自前CSSを当てる(html_to_pdf.py はそれをやっている)。
変換後は fitz でテキストを抽出し、金額・発行日が読み取れることを必ず確認する。
空白ページが付くので get_text().strip() が空のページは削除する。
Step 4: 配置と matches.json 登録
配置先: references/invoices/<年度>/<発行日>_<取引先>.pdf
m = json.load(open('references/invoices/matches.json', encoding='utf-8'))
m['2026'][str(仕訳No)] = f'2026/{ファイル名}'
json.dump(m, open(..., 'w', encoding='utf-8'), ensure_ascii=False, indent=2)
登録前に必ず assert str(num) not in y と assert not os.path.exists(dst) を入れて、
既存エントリ・既存ファイルを上書きしないようにする。
Step 5: 再突合
Step 0 のスクリプトを再実行し、対象が消えたことを確認する。
メールでもポータルでも取れないもの
- 紙レシート(飲食店など)— スキャンが必要。ユーザーに依頼する
- 税務署(事業税等) — e-Tax 電子納付のため領収書なし。matches.json 登録不要
既知の命名の揺れ
Google Cloud の既存2件 2026-04-01_..._5536103869.pdf / 2026-04-02_..._5539071350.pdf は
どちらも 4/2 着メールで、PDF内の発行日(2月末・3月末)とも一致しない。以降は
PDF内の発行日で統一している。既存2件は未修正。