[{"data":1,"prerenderedAt":720},["ShallowReactive",2],{"content-/agent-browser-evaluation-chrome-extension":3,"all-pages-for-dir":718,"og-image-/agent-browser-evaluation-chrome-extension":719},{"id":4,"title":5,"body":6,"category":700,"description":701,"extension":702,"meta":703,"navigation":704,"path":705,"project_name":706,"published":707,"publishedAt":708,"seo":709,"stem":710,"tags":711,"todo":715,"updatedAt":716,"__hash__":717},"pages/2026-04/2026-04-06/agent-browser-setup.md","agent-browserの評価とセットアップ - Chrome拡張機能の壁とDevTools MCPとの使い分け",{"type":7,"value":8,"toc":686},"minimark",[9,13,17,21,25,28,71,74,92,95,105,108,174,177,181,184,188,197,212,216,223,431,446,531,534,537,540,543,547,633,636,641,654,659,670,673,679,682],[10,11,12],"h1",{"id":12},"agent-browserの評価とセットアップ",[14,15,16],"p",{},"Vercel製のagent-browserをインストールして、Claude Codeからブラウザ操作する環境を整えた。基本機能はすんなり動いたが、Chrome拡張機能を絡めた検証で壁にぶつかり、3時間ほどターミナルとにらめっこすることになった。",[18,19,20],"h2",{"id":20},"基本動作の確認",[22,23,24],"h3",{"id":24},"インストール",[14,26,27],{},"グローバルインストールは2ステップで完了する。",[29,30,35],"pre",{"className":31,"code":32,"language":33,"meta":34,"style":34},"language-bash shiki shiki-themes vitesse-light vitesse-light","pnpm add -g agent-browser\nagent-browser install   # Chrome for Testing をダウンロード\n","bash","",[36,37,38,58],"code",{"__ignoreMap":34},[39,40,43,47,51,55],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"senZ8","pnpm",[39,48,50],{"class":49},"sdGka"," add",[39,52,54],{"class":53},"snbK4"," -g",[39,56,57],{"class":49}," agent-browser\n",[39,59,61,64,67],{"class":41,"line":60},2,[39,62,63],{"class":45},"agent-browser",[39,65,66],{"class":49}," install",[39,68,70],{"class":69},"sxvE3","   # Chrome for Testing をダウンロード\n",[14,72,73],{},"Claude Codeのスキルとして登録する場合は、以下を実行して「Global + Symlink」を選択する。",[29,75,77],{"className":31,"code":76,"language":33,"meta":34,"style":34},"npx skills add vercel-labs/agent-browser\n",[36,78,79],{"__ignoreMap":34},[39,80,81,84,87,89],{"class":41,"line":42},[39,82,83],{"class":45},"npx",[39,85,86],{"class":49}," skills",[39,88,50],{"class":49},[39,90,91],{"class":49}," vercel-labs/agent-browser\n",[22,93,94],{"id":94},"動作テスト",[14,96,97,100,101,104],{},[36,98,99],{},"agent-browser profiles"," を叩くと、ローカルのChromeプロファイルが18件ずらっと表示された。",[36,102,103],{},"--profile Default","で起動すると、普段使っているChromeのcookieをコピーした状態でブラウザが立ち上がる。",[14,106,107],{},"基本コマンドを一通り試した結果:",[109,110,111,124],"table",{},[112,113,114],"thead",{},[115,116,117,121],"tr",{},[118,119,120],"th",{},"操作",[118,122,123],{},"結果",[125,126,127,136,144,154,164],"tbody",{},[115,128,129,133],{},[130,131,132],"td",{},"Chromeプロファイル一覧取得",[130,134,135],{},"18件検出",[115,137,138,141],{},[130,139,140],{},"headed モードで起動",[130,142,143],{},"ブラウザ画面が表示される",[115,145,146,151],{},[130,147,148],{},[36,149,150],{},"snapshot -i",[130,152,153],{},"インタラクティブ要素を@refつきで取得",[115,155,156,161],{},[130,157,158],{},[36,159,160],{},"screenshot",[130,162,163],{},"PNGファイルとして保存",[115,165,166,171],{},[130,167,168],{},[36,169,170],{},"eval",[130,172,173],{},"ページコンテキストでJS実行",[14,175,176],{},"ここまでは手が止まることなく進んだ。問題はこの先だった。",[18,178,180],{"id":179},"会計ソフトaのchrome拡張機能を動かす検証","会計ソフトAのChrome拡張機能を動かす検証",[14,182,183],{},"会計ソフトAにはChrome拡張機能があり、これをagent-browser上で動作させられるか試した。",[22,185,187],{"id":186},"chromestoragelocal-が空になる問題","chrome.storage.local が空になる問題",[14,189,190,193,194,196],{},[36,191,192],{},"--extension"," オプションで拡張を読み込み、",[36,195,103],{}," でChromeのcookieもコピーした状態で起動する。拡張のアイコンは表示されている。しかし、拡張のポップアップを開くと初期状態に戻っていた。",[14,198,199,200,202,203,211],{},"原因を調べると、",[36,201,103],{}," がコピーするのはcookieだけで、",[204,205,206,207,210],"strong",{},"拡張機能の ",[36,208,209],{},"chrome.storage.local"," はセッションごとにリセットされる","ことがわかった。会計ソフトAの拡張はログイン情報をchrome.storage.localに保持しているため、毎回未ログイン状態で起動する。",[22,213,215],{"id":214},"defaultsjsonフォールバックの試み","defaults.jsonフォールバックの試み",[14,217,218,219,222],{},"chrome.storage.localが空なら、拡張ディレクトリに ",[36,220,221],{},"defaults.json"," を置いて、storage.localが空のときにフォールバックで読み込む仕組みを考えた。",[29,224,228],{"className":225,"code":226,"language":227,"meta":34,"style":34},"language-javascript shiki shiki-themes vitesse-light vitesse-light","// background.js に追記するイメージ\nchrome.storage.local.get(null, (data) => {\n  if (Object.keys(data).length === 0) {\n    fetch(chrome.runtime.getURL('defaults.json'))\n      .then(r => r.json())\n      .then(defaults => chrome.storage.local.set(defaults));\n  }\n});\n","javascript",[36,229,230,235,283,322,355,382,419,425],{"__ignoreMap":34},[39,231,232],{"class":41,"line":42},[39,233,234],{"class":69},"// background.js に追記するイメージ\n",[39,236,237,241,245,248,250,253,255,258,261,265,268,271,274,277,280],{"class":41,"line":60},[39,238,240],{"class":239},"s4oTP","chrome",[39,242,244],{"class":243},"shFtX",".",[39,246,247],{"class":239},"storage",[39,249,244],{"class":243},[39,251,252],{"class":239},"local",[39,254,244],{"class":243},[39,256,257],{"class":45},"get",[39,259,260],{"class":243},"(",[39,262,264],{"class":263},"stQ0i","null",[39,266,267],{"class":243},",",[39,269,270],{"class":243}," (",[39,272,273],{"class":239},"data",[39,275,276],{"class":243},")",[39,278,279],{"class":243}," =>",[39,281,282],{"class":243}," {\n",[39,284,286,290,292,295,297,300,302,304,307,311,314,318,320],{"class":41,"line":285},3,[39,287,289],{"class":288},"sHkkW","  if",[39,291,270],{"class":243},[39,293,294],{"class":239},"Object",[39,296,244],{"class":243},[39,298,299],{"class":45},"keys",[39,301,260],{"class":243},[39,303,273],{"class":239},[39,305,306],{"class":243},").",[39,308,310],{"class":309},"sz8Xr","length",[39,312,313],{"class":263}," ===",[39,315,317],{"class":316},"sM54T"," 0",[39,319,276],{"class":243},[39,321,282],{"class":243},[39,323,325,328,330,332,334,337,339,342,344,348,350,352],{"class":41,"line":324},4,[39,326,327],{"class":45},"    fetch",[39,329,260],{"class":243},[39,331,240],{"class":239},[39,333,244],{"class":243},[39,335,336],{"class":239},"runtime",[39,338,244],{"class":243},[39,340,341],{"class":45},"getURL",[39,343,260],{"class":243},[39,345,347],{"class":346},"sMJiu","'",[39,349,221],{"class":49},[39,351,347],{"class":346},[39,353,354],{"class":243},"))\n",[39,356,358,361,364,366,369,371,374,376,379],{"class":41,"line":357},5,[39,359,360],{"class":243},"      .",[39,362,363],{"class":45},"then",[39,365,260],{"class":243},[39,367,368],{"class":239},"r",[39,370,279],{"class":243},[39,372,373],{"class":239}," r",[39,375,244],{"class":243},[39,377,378],{"class":45},"json",[39,380,381],{"class":243},"())\n",[39,383,385,387,389,391,394,396,399,401,403,405,407,409,412,414,416],{"class":41,"line":384},6,[39,386,360],{"class":243},[39,388,363],{"class":45},[39,390,260],{"class":243},[39,392,393],{"class":239},"defaults",[39,395,279],{"class":243},[39,397,398],{"class":239}," chrome",[39,400,244],{"class":243},[39,402,247],{"class":239},[39,404,244],{"class":243},[39,406,252],{"class":239},[39,408,244],{"class":243},[39,410,411],{"class":45},"set",[39,413,260],{"class":243},[39,415,393],{"class":239},[39,417,418],{"class":243},"));\n",[39,420,422],{"class":41,"line":421},7,[39,423,424],{"class":243},"  }\n",[39,426,428],{"class":41,"line":427},8,[39,429,430],{"class":243},"});\n",[14,432,433,434,437,438,441,442,445],{},"しかしここで次の壁が立った。",[36,435,436],{},"chrome.runtime.getURL()"," で拡張内のファイルにアクセスするには、",[36,439,440],{},"manifest.json"," の ",[36,443,444],{},"web_accessible_resources"," にそのファイルを宣言する必要がある。",[29,447,450],{"className":448,"code":449,"language":378,"meta":34,"style":34},"language-json shiki shiki-themes vitesse-light vitesse-light","{\n  \"web_accessible_resources\": [{\n    \"resources\": [\"defaults.json\"],\n    \"matches\": [\"\u003Call_urls>\"]\n  }]\n}\n",[36,451,452,457,474,498,521,526],{"__ignoreMap":34},[39,453,454],{"class":41,"line":42},[39,455,456],{"class":243},"{\n",[39,458,459,463,465,468,471],{"class":41,"line":60},[39,460,462],{"class":461},"sqvqQ","  \"",[39,464,444],{"class":309},[39,466,467],{"class":461},"\"",[39,469,470],{"class":243},":",[39,472,473],{"class":243}," [{\n",[39,475,476,479,482,484,486,489,491,493,495],{"class":41,"line":285},[39,477,478],{"class":461},"    \"",[39,480,481],{"class":309},"resources",[39,483,467],{"class":461},[39,485,470],{"class":243},[39,487,488],{"class":243}," [",[39,490,467],{"class":346},[39,492,221],{"class":49},[39,494,467],{"class":346},[39,496,497],{"class":243},"],\n",[39,499,500,502,505,507,509,511,513,516,518],{"class":41,"line":324},[39,501,478],{"class":461},[39,503,504],{"class":309},"matches",[39,506,467],{"class":461},[39,508,470],{"class":243},[39,510,488],{"class":243},[39,512,467],{"class":346},[39,514,515],{"class":49},"\u003Call_urls>",[39,517,467],{"class":346},[39,519,520],{"class":243},"]\n",[39,522,523],{"class":41,"line":357},[39,524,525],{"class":243},"  }]\n",[39,527,528],{"class":41,"line":384},[39,529,530],{"class":243},"}\n",[14,532,533],{},"会計ソフトAの拡張はサードパーティ製で、manifest.jsonを書き換えると署名が壊れる可能性がある。そもそも、defaults.jsonにログイン情報を平文で置くこと自体がセキュリティ上の問題だ。",[22,535,536],{"id":536},"断念と結論",[14,538,539],{},"ここで一歩引いて考え直した。やりたいことは「ログイン済みの会計ソフトAをClaude Codeから操作する」こと。それなら、普段使っているChromeにそのまま接続できるChrome DevTools MCPのほうが筋がいい。",[14,541,542],{},"agent-browserは毎回クリーンなセッションを立てる設計で、それ自体はCI/CDやE2Eテストには正しい判断だ。ただ、ログイン済みサービスを操作する用途には合わない。",[18,544,546],{"id":545},"chrome-devtools-mcpとの比較","Chrome DevTools MCPとの比較",[109,548,549,561],{},[112,550,551],{},[115,552,553,556,558],{},[118,554,555],{},"観点",[118,557,63],{},[118,559,560],{},"Chrome DevTools MCP",[125,562,563,574,585,595,608,622],{},[115,564,565,568,571],{},[130,566,567],{},"Chrome管理",[130,569,570],{},"専用Chromeを自動起動",[130,572,573],{},"既存Chromeに接続",[115,575,576,579,582],{},[130,577,578],{},"cookie",[130,580,581],{},"プロファイルからコピー（リセットあり）",[130,583,584],{},"そのまま利用",[115,586,587,590,593],{},[130,588,589],{},"拡張ストレージ",[130,591,592],{},"空で起動",[130,594,584],{},[115,596,597,600,605],{},[130,598,599],{},"拡張機能",[130,601,602,604],{},[36,603,192],{},"で明示指定",[130,606,607],{},"インストール済みがそのまま動く",[115,609,610,613,619],{},[130,611,612],{},"並行セッション",[130,614,615,618],{},[36,616,617],{},"--session","で複数管理",[130,620,621],{},"単一Chrome接続",[115,623,624,627,630],{},[130,625,626],{},"CI適性",[130,628,629],{},"headlessで動作、CI向き",[130,631,632],{},"headed前提、ローカル向き",[18,634,635],{"id":635},"使い分けの基準",[14,637,638],{},[204,639,640],{},"agent-browserが向いている場面:",[642,643,644,648,651],"ul",{},[645,646,647],"li",{},"未ログインサイトのスクレイピング・テスト",[645,649,650],{},"CI/CDパイプラインでのE2Eテスト",[645,652,653],{},"クリーンな環境での再現テスト",[14,655,656],{},[204,657,658],{},"Chrome DevTools MCPが向いている場面:",[642,660,661,664,667],{},[645,662,663],{},"ログイン済みのSaaS操作（会計ソフト、管理画面など）",[645,665,666],{},"Chrome拡張機能が必要な操作",[645,668,669],{},"普段のブラウジング環境をそのまま使いたいとき",[18,671,672],{"id":672},"学びメモ",[14,674,675,676,678],{},"agent-browserの ",[36,677,103],{}," の仕組みを追いかけたことで、「cookieのコピー」と「拡張ストレージの引き継ぎ」がまったく別のレイヤーだと体感した。Chromeのプロファイルデータは一枚岩ではなく、cookie、拡張ストレージ、ブックマーク、履歴がそれぞれ別のファイルに分かれている。agent-browserはそのうちcookieだけをコピーする設計を選んでいる。",[14,680,681],{},"defaults.jsonフォールバックの実装を書きかけてから断念するまで1時間ほど使ったが、「このツールの設計思想と自分の用途が合っていない」と気づけたのは収穫だった。道具の得手不得手を見極めてから手を動かすべきだった。",[683,684,685],"style",{},"html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}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);}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 .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sqvqQ, html code.shiki .sqvqQ{--shiki-default:#99841877;--shiki-dark:#99841877}",{"title":34,"searchDepth":60,"depth":60,"links":687},[688,692,697,698,699],{"id":20,"depth":60,"text":20,"children":689},[690,691],{"id":24,"depth":285,"text":24},{"id":94,"depth":285,"text":94},{"id":179,"depth":60,"text":180,"children":693},[694,695,696],{"id":186,"depth":285,"text":187},{"id":214,"depth":285,"text":215},{"id":536,"depth":285,"text":536},{"id":545,"depth":60,"text":546},{"id":635,"depth":60,"text":635},{"id":672,"depth":60,"text":672},"dev","Vercel製agent-browserの動作確認からChrome拡張機能の検証まで。chrome.storage.localの制限に突き当たり、defaults.jsonフォールバックを試み、最終的にChrome DevTools MCPとの使い分け基準を整理した記録。","md",{},true,"/agent-browser-evaluation-chrome-extension","claude-code-tools",false,"2026-04-06T00:00:00.000Z",{"title":5,"description":701},"2026-04/2026-04-06/agent-browser-setup",[63,560,712,713,714],"Chrome拡張機能","ブラウザ自動化","Claude Code","memo",null,"E52u8zQedvlpXe7WR6FLVKxIs3czagck4jjoAftIJjU",[],"https://log.eurekapu.com/favicon.svg",1775511575059]