[{"data":1,"prerenderedAt":366},["ShallowReactive",2],{"content-/mf-devtools-mcp-direct-operation":3,"all-pages-for-dir":364,"og-image-/mf-devtools-mcp-direct-operation":365},{"id":4,"title":5,"body":6,"category":344,"description":345,"extension":346,"meta":347,"navigation":348,"ogImage":349,"path":350,"project_name":351,"published":352,"publishedAt":353,"seo":354,"stem":355,"tags":356,"todo":362,"unpublished":352,"updatedAt":349,"__hash__":363},"pages/2026-03/2026-03-28/mf-devtools-mcp-direct-operation.md","DevTools MCPでクラウド会計APIを直接操作 - Chrome拡張なしで全帳簿データを取得した実験記録",{"type":7,"value":8,"toc":327},"minimark",[9,14,23,26,31,34,57,60,62,66,72,117,124,126,130,133,138,145,148,152,155,166,169,173,176,180,183,186,188,192,195,273,276,278,281,284,288,291,293,296,323],[10,11,13],"h1",{"id":12},"devtools-mcpでクラウド会計apiを直接操作","DevTools MCPでクラウド会計APIを直接操作",[15,16,17,18,22],"p",{},"Chrome拡張の依存度を下げたいという議論から始まり、「そもそも拡張なしでAPIを叩けるのでは」という仮説を検証した。結論から言うと、DevTools MCPの ",[19,20,21],"code",{},"evaluate_script"," でCSRFトークンを取り出し、会計サービスの内部APIを直接叩いてテスト事業者の全帳簿データを取得できた。Chrome拡張は一切使っていない。",[24,25],"hr",{},[27,28,30],"h2",{"id":29},"発端-3種類のトークンを整理する","発端: 3種類のトークンを整理する",[15,32,33],{},"Chrome拡張とDevTools MCPの役割分担を議論するうちに、「CSRFトークンとOAuthトークンの違いは？」という質問に即答できず手が止まった。話を進めるにはまず認証の仕組みを図に起こす必要があった。",[35,36,37,45,51],"ol",{},[38,39,40,44],"li",{},[41,42,43],"strong",{},"CSRFトークン",": Rails UJSがmetaタグに埋め込む。同一セッション内のPOST/PATCH/DELETEリクエストで必要",[38,46,47,50],{},[41,48,49],{},"OAuthアクセストークン",": 公式API（v3）用。外部アプリ連携のBearerトークン",[38,52,53,56],{},[41,54,55],{},"リフレッシュトークン",": アクセストークンの更新用。長寿命",[15,58,59],{},"SVGを5つ作成してトークンのライフサイクルと取得フローを図にした。この整理で「DevTools MCPはCSRFトークンさえ取れれば内部APIを叩ける」という道筋が見えた。",[24,61],{},[27,63,65],{"id":64},"核心-evaluate_scriptでcsrfトークンを取得する","核心: evaluate_scriptでCSRFトークンを取得する",[15,67,68,69,71],{},"DevTools MCPの ",[19,70,21],{}," は、開いているページ上で任意のJavaScriptを実行できる。つまりmetaタグからCSRFトークンを読み取るのは1行で済む。",[73,74,79],"pre",{"className":75,"code":76,"language":77,"meta":78,"style":78},"language-javascript shiki shiki-themes vitesse-light vitesse-light","document.querySelector('meta[name=\"csrf-token\"]').content\n","javascript","",[19,80,81],{"__ignoreMap":78},[82,83,86,90,94,98,101,105,109,111,114],"span",{"class":84,"line":85},"line",1,[82,87,89],{"class":88},"s4oTP","document",[82,91,93],{"class":92},"shFtX",".",[82,95,97],{"class":96},"senZ8","querySelector",[82,99,100],{"class":92},"(",[82,102,104],{"class":103},"sMJiu","'",[82,106,108],{"class":107},"sdGka","meta[name=\"csrf-token\"]",[82,110,104],{"class":103},[82,112,113],{"class":92},").",[82,115,116],{"class":88},"content\n",[15,118,119,120,123],{},"取得したトークンを ",[19,121,122],{},"X-CSRF-Token"," ヘッダーに載せてfetchすれば、ブラウザのセッションCookieが自動で付与される。Chrome拡張のcontent script → background script → API呼び出しという3段リレーが丸ごと消える。",[24,125],{},[27,127,129],{"id":128},"実験-テスト事業者の全帳簿データを取得","実験: テスト事業者の全帳簿データを取得",[15,131,132],{},"テスト事業者（個人・2025年度）を対象に、6種類の帳簿データを取得してスプレッドシートに転記した。",[134,135,137],"h3",{"id":136},"仕訳帳-rest-apiで取得","仕訳帳: REST APIで取得",[15,139,140,141,144],{},"最初にハードコードした期間（2025-01-01〜2025-12-31）で取得したところ、開始仕訳しか返ってこなかった。「データが少なすぎる」と首をひねってよく見ると、この事業者は",[41,142,143],{},"2月決算","だった。会計年度が2025-03-01〜2026-02-28。",[15,146,147],{},"期間を修正して再取得し、83件の仕訳が返ってきた。REST APIのレスポンスをパースしてスプレッドシートに流し込む処理は、拡張で使っていたロジックをほぼそのまま移植できた。",[134,149,151],{"id":150},"残高試算表-urlの推測ミスと拡張コードの見落とし","残高試算表: URLの推測ミスと拡張コードの見落とし",[15,153,154],{},"残高試算表はAPIではなくHTMLページのスクレイピングで取得する方式。URLを推測して叩いたが404が返った。",[15,156,157,158,161,162,165],{},"30分ほどURLパターンを試行錯誤した後、ふと拡張のソースコード ",[19,159,160],{},"export.js"," を開いたら、",[41,163,164],{},"正しいURLがそのまま書いてあった","。拡張コードは8割リファレンスとして使えるのに、それを見ずに推測で突っ走ったのは反省点。",[15,167,168],{},"正しいURLでページを取得し、HTMLテーブルをパースして転記した。",[134,170,172],{"id":171},"月次推移年次推移-同じパターンの繰り返し","月次推移・年次推移: 同じパターンの繰り返し",[15,174,175],{},"月次推移（補助科目あり/なし）と年次推移（補助科目あり/なし）も、残高試算表と同じ「ページスクレイピング」方式。URLの構造が似ていたので、残高試算表での反省を踏まえて最初から拡張のコードを開いた。URLを一発で当てて、4帳簿とも1回の試行で転記まで完了した。",[134,177,179],{"id":178},"連携明細-サービス一覧の壁","連携明細: サービス一覧の壁",[15,181,182],{},"連携明細はサービス一覧ページからデータを取得する方式。テスト事業者は6口座が登録されていたが、取得できたのは3口座のみだった。",[15,184,185],{},"原因を調べると、設定用のJSONレスポンスにサービス一覧の全件が含まれていなかった。ページネーションか別エンドポイントがあるはずだが、今回は深追いせずに残り3口座は保留とした。",[24,187],{},[27,189,191],{"id":190},"chrome拡張-vs-devtools-mcp-比較ドキュメントを作成","Chrome拡張 vs DevTools MCP: 比較ドキュメントを作成",[15,193,194],{},"実験結果を踏まえて、両者の比較をまとめた。",[196,197,198,214],"table",{},[199,200,201],"thead",{},[202,203,204,208,211],"tr",{},[205,206,207],"th",{},"観点",[205,209,210],{},"Chrome拡張",[205,212,213],{},"DevTools MCP",[215,216,217,229,240,251,262],"tbody",{},[202,218,219,223,226],{},[220,221,222],"td",{},"データ受け渡し",[220,224,225],{},"content script→background script→API。3段のメッセージパッシング",[220,227,228],{},"evaluate_scriptで直接取得。中継なし",[202,230,231,234,237],{},[220,232,233],{},"環境構築",[220,235,236],{},"npm install、ビルド、拡張インストールが必要",[220,238,239],{},"Chromeをデバッグモードで起動するだけ",[202,241,242,245,248],{},[220,243,244],{},"Windows環境",[220,246,247],{},"ビルドツールチェーンの問題が出やすい",[220,249,250],{},"環境依存が少ない",[202,252,253,256,259],{},[220,254,255],{},"自動化",[220,257,258],{},"バックグラウンドで実行可能",[220,260,261],{},"ブラウザが前面に必要",[202,263,264,267,270],{},[220,265,266],{},"テスト",[220,268,269],{},"Jest/Vitestで単体テスト可能",[220,271,272],{},"テストの仕組みは自前で用意",[15,274,275],{},"結論として、「対話的に帳簿データを引っ張ってくる」用途にはDevTools MCPのほうが軽い。一方で、定期実行やバッチ処理にはChrome拡張のほうが向いている。",[24,277],{},[27,279,280],{"id":280},"ランブック整備と次のステップ",[15,282,283],{},"次回すぐ同じ操作を再現できるよう、手順書（ランブック）を作成した。Chromeのデバッグモード起動、DevTools MCPへの接続、CSRFトークン取得、各帳簿のエンドポイントとパラメータを一通り記載。",[134,285,287],{"id":286},"playwright-別プロファイル方式の検討","Playwright + 別プロファイル方式の検討",[15,289,290],{},"DevTools MCPはブラウザを手動で開く必要があるが、Playwrightなら別プロファイルでブラウザを起動してプログラマティックに操作できる。通常使用中のプロファイルのロックファイルと競合しないため、「作業しながらバックグラウンドでデータ取得」が実現できる可能性がある。ただし今回は検証まで至らず、次回の宿題として残した。",[24,292],{},[27,294,295],{"id":295},"振り返り",[297,298,299,305,311,317],"ul",{},[38,300,301,304],{},[41,302,303],{},"拡張のコードは8割リファレンス",": URLパターン、パラメータ構造、レスポンスの加工ロジックがそのまま使える。推測で動く前にまず拡張のコードを読む、というのを習慣にしたい",[38,306,307,310],{},[41,308,309],{},"会計年度のハードコードは罠",": 1月〜12月と決め打ちしていた。事業者の決算月は設定APIで取得してから期間を組み立てるべき",[38,312,313,316],{},[41,314,315],{},"設定JSONに全件が入っていない問題",": 連携明細の口座漏れは、拡張でも同じ問題を踏む可能性がある。ページネーション or 別エンドポイントの調査が必要",[38,318,319,322],{},[41,320,321],{},"DevTools MCPで試行錯誤が加速する",": 拡張だとコード修正→ビルド→リロード→動作確認で毎回2〜3分かかっていた。DevTools MCPはevaluate_scriptを書き換えて再実行するだけなので、10秒で次の仮説を試せる",[324,325,326],"style",{},"html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":78,"searchDepth":328,"depth":328,"links":329},2,[330,331,332,339,340,343],{"id":29,"depth":328,"text":30},{"id":64,"depth":328,"text":65},{"id":128,"depth":328,"text":129,"children":333},[334,336,337,338],{"id":136,"depth":335,"text":137},3,{"id":150,"depth":335,"text":151},{"id":171,"depth":335,"text":172},{"id":178,"depth":335,"text":179},{"id":190,"depth":328,"text":191},{"id":280,"depth":328,"text":280,"children":341},[342],{"id":286,"depth":335,"text":287},{"id":295,"depth":328,"text":295},"dev","Chrome DevTools MCPのevaluate_scriptでCSRFトークンを取得し、クラウド会計サービスのAPIを直接叩いて全帳簿データをスプレッドシートに転記した実験。拡張機能が不要になる可能性と、試行錯誤の過程を記録","md",{},true,null,"/mf-devtools-mcp-direct-operation","misc-dev",false,"2026-03-28T00:00:00.000Z",{"title":5,"description":345},"2026-03/2026-03-28/mf-devtools-mcp-direct-operation",[213,357,358,359,360,361],"クラウド会計","Chrome拡張機能","CSRF","APIスクレイピング","会計","memo","TBH2zSMwHLWonn42xp5s0_QT3Aw9aKZtPSbJV9Z7I84",[],"https://log.eurekapu.com/og/blog/mf-devtools-mcp-direct-operation.png?v=2026-03-28T00%3A00%3A00.000Z&title=DevTools%20MCP%E3%81%A7%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E4%BC%9A%E8%A8%88API%E3%82%92%E7%9B%B4%E6%8E%A5%E6%93%8D%E4%BD%9C%20-%20Chrome%E6%8B%A1%E5%BC%B5%E3%81%AA%E3%81%97%E3%81%A7%E5%85%A8%E5%B8%B3%E7%B0%BF%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9F%E5%AE%9F%E9%A8%93%E8%A8%98%E9%8C%B2&author=Kei%20Komatsu&sig=d732056188192758",1782528821665]