「さあ自動化しよう」と思ってClaude in Chromeを起動したのに、途中で止まってしまったり、クリックが効かなかったりと、思い通りに動かないことは珍しくありません。
私自身、個人開発している壁紙アプリのAdMob管理画面から週次レポートを取り出す作業を Claude in Chrome に任せはじめた当初、5回に2回は途中で止まっていました。プロンプトが悪いのか、ページが悪いのか、そもそもこの用途に向いていないのか。切り分けの軸を持たないまま、指示文だけを何度も書き直していた時期があります。
結論から申し上げますと、多くの失敗は「Claudeの能力」ではなく「ページの状態とClaudeの前提のずれ」から生まれておりました。
ここでは実際によく起きるトラブルを症状別に整理し、それぞれの対処法と、3週間の運用で得られた実測値をまとめました。
ボタンをクリックしても反応しない
「ログインボタンをクリックして」と頼んでも何も起きない、あるいはClaudeが「クリックしました」と報告するのに画面が変わらないケースです。
原因として多いもの:
ボタンが動的に生成されていて、Claudeがクリックした時点ではまだDOMに存在しない
JavaScriptのイベントリスナーがonclick属性ではなくaddEventListenerで設定されており、Claudeの操作が届かない
要素が視覚的には見えているが、他の透明なレイヤーの下に隠れている
対処法:
まずページをリロードしてから再試行してみましょう。それでも改善しない場合は、「少し待ってからクリックして」のように時間指定を加えると成功率が上がります。また、キーボード操作を活用する方法もあります。「Tabキーでボタンにフォーカスを当ててEnterキーで押して」と指示すると、マウスクリックでは届かない要素にアクセスできることがあります。
ページが正しく読み込まれない・スクロールできない
Claudeが「ページを開きました」と言うのに、内容を把握できていなかったり、スクロールして追加コンテンツを読み込めなかったりするパターンです。
よくある状況:
無限スクロール(Infinite Scroll)のページで、ファーストビューの情報しか取得できない
SPA(シングルページアプリ)でURLは変わっているのにコンテンツが切り替わっていない
ページの読み込みが完了する前にClaudeが操作を試みてしまう
対処法:
「ページが完全に読み込まれるまで3秒待ってから操作して」のように明示的な待機指示を入れましょう。無限スクロールのページなら「3回スクロールダウンして、その後表示されているコンテンツを読んで」のように段階的に指示すると精度が上がります。
SPAの場合は、URLが変わった後にもう一度「現在のページの内容を読んで」と指示すると、最新のDOM状態を取得し直します。
ログイン・認証の画面で止まる
ログインフォームへの入力まではうまくいったのに、認証後に次のページへ進めない、あるいはセッションが切れてしまう問題です。
主な原因:
2段階認証(2FA)の要求(Claude in Chromeでは自動処理できません)
SSO(シングルサインオン)のリダイレクト先で止まる
Cookieやセッションの期限切れ
対処法:
2段階認証が設定されているサービスへのログインは、現時点でClaudeが自動処理できません。あらかじめブラウザ側でログイン済みの状態にしてからClaude in Chromeのタスクを開始するのが確実です。
セッション切れの問題は、タスクの実行間隔が長い場合に起きやすいです。タスク冒頭に「まず[サービス名]にログインしているか確認して、セッションが切れていたら再ログインして」という確認ステップを加えると対応できます。
CAPTCHAで止まってしまう
Claude in ChromeはCAPTCHAを自動解除することができません。これは現在の仕様です。
現実的な対処法:
対象サービスでIPアドレスやCookieに基づくCAPTCHAスキップが有効な場合は、一度ブラウザから手動ログインしておくと、以降のCAPTCHA表示が省略されることがあります。Google系サービスでは、アカウントにあらかじめログインしておくと、CAPTCHA表示頻度が大幅に下がります。
どうしてもCAPTCHAを回避できないサービスは、Claude in Chromeによる完全自動化の対象外と考えて、手動とClaudeの組み合わせで運用するのが現実的です。
PDFや動的コンテンツが読み取れない
ウェブ上のPDFをClaudeに読ませようとしたり、JavaScriptで動的に生成されるグラフや表を取得しようとしたりした場合に失敗するケースです。
PDFの読み取りについて:
ブラウザ内蔵のPDFビューアで表示されるPDFは、ClaudeがDOMからテキストを取得しにくい構造になっています。代替策として、PDFのURLをClaudeに確認してもらい、そのURLを直接Claude.aiのチャットにアップロードする方法が確実です。
動的コンテンツについて:
APIで非同期取得されるデータは、ページのHTMLには記述されていないため読み取れないことがあります。「ページのソースではなく、現在画面に表示されているテキストだけを読んで」と明示的に指示すると改善することがあります。また「スクリーンショットを撮って内容を教えて」と視覚情報をもとにした処理を依頼する方法も有効です。
実行が途中で止まる・エラーで終了する
複数ステップのタスクを実行させていると、中途半端なところで処理が停止してしまうことがあります。
コンテキスト超過の場合:
長時間・多ステップのタスクは、コンテキストウィンドウを使い切ってしまうことがあります。タスクを小さな単位に分割して、それぞれを独立したセッションで実行しましょう。「1〜10番のURLを処理して」「11〜20番のURLを処理して」のように明示的に範囲を区切ると安定します。
ネットワークエラーやタイムアウトの場合:
ページの読み込みが重い場合に発生しやすいです。「タイムアウトになった場合は10秒待ってからリトライして」と指示に加えると、Claudeが自動でリトライを試みます。
処理が止まったときは、まず自分で手動でそのページを開いてみましょう。対象サービスがメンテナンス中や障害中であれば、Claude in Chromeではなくサービス側が原因です。
タスクは完了したのに結果が期待と違う
Claudeが「完了しました」と報告しているが、実際の処理が期待と違う状態になっているケースです。
代表例:
フォームへの入力は終わっているが「保存」ボタンを押さずに終わっている
検索結果の1ページ目しか処理していない
条件に合わないアイテムも一緒に処理してしまっている
対処法:
タスクの指示に「処理後に必ず確認ステップを入れて」と付け加えると、Claudeが自己チェックを行うようになります。「○件処理したら、処理件数と対象の名前を一覧で報告して」のように検証しやすいアウトプット形式を指定するのも効果的です。
複数ページにわたる処理は「次のページがある場合はページネーションボタンを押して続けて、なければ終了して」のように終了条件を明確にしておく点が肝心です。
なお、この「完了と報告されたのに実際は何も起きていない」という失敗は、Web監視の自動化でも同じ形で現れます。監視が「異常なし」と言い続ける状態の切り分けについては、Web 監視が『異常なし』と言い続けた二週間 に記録しております。
MCPサーバーとの連携でエラーが出る
Claude in ChromeをCoworkのMCPサーバーと組み合わせて使っている場合、接続エラーが発生することがあります。
Coworkの設定画面でMCPサーバーの接続状態を確認しましょう。サーバーが「Disconnected」になっている場合は、Coworkアプリを再起動するとほとんどのケースで復旧します。
それでも解決しない場合は、MCPサーバーのログを確認します。多くのMCPサーバーはエラーをstderrに出力しているため、ターミナルから起動して直接メッセージを確認できます。ポート番号の競合や環境変数の未設定が原因であることが多いです。
切り分けの手順 — 5ステップで原因を特定する
指示文をやみくもに書き直すより、どの層で止まっているかを先に確定させたほうが早く終わります。私は次の順番で確認しております。
同じ操作を自分の手で行う。 ページが開くか、ボタンが押せるか、ログインが通るか。ここで失敗するならサービス側の問題であり、プロンプトを直しても解決しません。
タスクを1ステップだけに削る。 「ログインして、レポート画面へ行って、CSVを落として」を「レポート画面を開いて、見出しを読み上げて」だけにします。どのステップで壊れるかがこれで確定します。
失敗した1ステップの前に待機を挟む。 「操作の前に5秒待って」を加えるだけで直るなら、原因はタイミングです。直らないならDOM構造か権限です。
視覚経路に切り替える。 「スクリーンショットを撮って、見えているボタンのラベルを列挙して」と指示します。Claudeが認識できていない要素がここで判明します。
検証ステップを恒久化する。 直った指示文に「操作後、成功メッセージが見えることを確認して。見えなければ報告して停止して」を必ず添えます。
3〜4を飛ばして指示文全体を書き直す誘惑が強いのですが、原因が確定していない書き直しは、たいてい別の失敗を呼び込むだけでした。
公式ドキュメントには書かれていない、運用で気づいた点
3週間、のべ42回の実行ログを見返して分かったことを共有いたします。対象は AdMob 管理画面からの週次レポート取得と、App Store Connect の売上画面の読み取りです。
待機は「3秒」では足りない画面がある。 一般的なページなら3秒で足りますが、AdMob の管理画面のようにグラフを非同期で描画するSPAでは、3秒では表が空のまま読まれてしまいました。6秒に延ばしたところ、空読みは12回中0回になりました。「完全に読み込まれるまで待って」という自然文だけでは、Claudeが判断する「完全」とレンダリング完了が一致しません。秒数を明示するほうが安定します。
「検証ステップ」の効果が最も大きい。 待機指示なし・検証なしの初期プロンプトでは、42回中26回(約62%)しか最後まで到達しませんでした。ここに「秒数指定の待機」と「操作後に成功条件を目視確認して、満たさなければ停止して報告する」の2つを加えた結果、完走は40回(約95%)まで変わりました。平均実行時間は1分48秒から2分21秒へ33秒ほど延びましたが、失敗して手作業でやり直す数分に比べれば、はるかに安い代償です。
失敗した2回は、いずれも「静かな失敗」ではありませんでした。 検証ステップを入れて以降、失敗するときは必ず「成功メッセージが確認できませんでした」と報告して停止します。黙って誤った結果を返すことがなくなった点が、数字以上に大きい変化でした。
同じサイトでも時間帯で挙動が変わります。 管理画面の初回描画は、午前中の混雑時に体感で2倍近く遅くなりました。スケジュール実行に載せる場合は、余裕を持った待機秒数を既定にしておくほうが安全です。
広告管理画面のように「数字が動く」画面では、読み取り結果を必ず前回値と突き合わせます。 メディエーションの優先度調整を任せたときの試行錯誤は、AdMob メディエーションの優先度調整を Claude in Chrome に任せた 3 週間 にまとめております。
待機秒数を固定しない — 「条件が満たされるまで」に書き換える
3秒を6秒に延ばした対処は、その画面をその時間帯に見たときの数字にすぎません。混雑する時間帯に描画が2倍近く遅くなるのであれば、6秒はいずれ足りなくなりますし、空いている時間帯には毎回4秒を捨てていることになります。
秒数を当てにいくのをやめて、待つ条件そのものを書くほうが安定しました。
「今週の収益」という見出しと、その下の表に1行以上のデータが表示されるまで、
2秒おきに最大30秒まで確認してください。
30秒たっても表示されない場合は、スクリーンショットを撮って停止し、
どこまで表示されていたかを報告してください。
この書き方には3つの要素が入っております。
待つ対象を「読み込み完了」ではなく、画面に出る具体物(見出しの文字列と表の行)で書く
確認の間隔と上限を数字で与える
上限に達したときの動作を書く
3つ目が抜けると、上限を過ぎた時点でClaudeが自分の判断で見切りをつけて先へ進みます。「表示されるまで待って」という一文だけでは、待つのをやめる条件が読み手側に委ねられたままです。
固定待機との違いは、速い日には待たずに進み、遅い日には粘るところにあります。私の週次レポート取得では、指示文の見た目は長くなりましたが、時間帯ごとに秒数を調整する必要がなくなりました。
ただし、すべての操作をこの形にすると指示文が長大になり、それ自体が別の失敗要因になります。私は固定秒数をスケジュール実行の既定として残したうえで、AdMobの管理画面のように描画が重い1〜2箇所だけをポーリング型に置き換えております。
視覚経路に逃がすと、代わりに何が増えるのか
切り分けの4番目でスクリーンショットに切り替えるのは有効な手ですが、無料ではありません。ここを曖昧にしたまま「困ったら画面を見せる」を常用の指示文に残すと、別の症状として跳ね返ってきます。
画像は面積からトークン数に換算されます。公式ドキュメントが示す見積もり式は「幅px × 高さpx ÷ 750」で、長辺が1568pxを超える画像はその範囲に収まるよう縮小されてから換算されます。式に代表的なビューポートを入れると次のようになります。
撮影時のサイズ
換算に使われるサイズ
概算トークン数
1280 × 800
1280 × 800
約 1,365
1512 × 982
1512 × 982
約 1,980
1920 × 1080
1568 × 882
約 1,844
3024 × 1964(Retina 2倍)
1568 × 1018
約 2,128
1568 × 1568(縮小後の上限付近)
1568 × 1568
約 3,278
これは式からの概算であり、実際の請求値とは差が出ます。桁を掴むための数字として扱ってください。表から読み取れるのは、高解像度で撮っても縮小が効くため2,000トークン前後に収束するという点と、それでもテキストで見出しと表だけを読ませる場合(数百から千トークン台)とは1桁違うという点です。
10ステップの操作を1手ごとにスクリーンショットで確認させると、画像だけで約2万トークンを積み上げます。料金として見れば入力1Mトークンあたり3ドルの単価で6セント程度ですから、週次のタスクなら気にする額ではありません。
効いてくるのは料金より先にコンテキストのほうです。前のほうで触れた「実行が途中で止まる」うちのいくつかは、切り分けのために視覚経路へ逃がしたまま戻し忘れて、自分でコンテキストを埋めていた結果でした。原因を探しているときは画面を見せる、原因が確定したらテキスト経路へ戻す。私は視覚経路を切り分けの道具と位置づけて、恒常運用の指示文には残さないようにしております。残すのは、最後の1ステップの成功確認だけです。
MCPサーバーを起動前に検証する
「Disconnected」に気づかないままタスクを走らせて、10分後に空の結果を受け取る。これを何度か繰り返した末に、起動前チェックを1本のスクリプトにまとめました。ポート競合・環境変数欠落・疎通の3点を、タスク開始前に確定させるためのものです。
// preflight.mjs — Claude in Chrome のタスクを流す前に MCP サーバー側を検証する
// 実行: node preflight.mjs
import net from 'node:net' ;
const CHECKS = [
{ name: 'my-mcp-server' , host: '127.0.0.1' , port: 3333 , env: [ 'MCP_API_KEY' ] },
{ name: 'sheets-mcp' , host: '127.0.0.1' , port: 3334 , env: [ 'GOOGLE_CREDENTIALS_PATH' ] },
];
function probe ( host , port , timeoutMs = 1500 ) {
return new Promise (( resolve ) => {
const socket = net. connect ({ host, port });
const done = ( reachable ) => {
socket. destroy ();
resolve (reachable);
};
socket. setTimeout (timeoutMs);
socket. once ( 'connect' , () => done ( true ));
socket. once ( 'timeout' , () => done ( false ));
socket. once ( 'error' , () => done ( false ));
});
}
const failures = [];
for ( const check of CHECKS ) {
const missing = check.env. filter (( key ) => ! process.env[key]);
const reachable = await probe (check.host, check.port);
if (missing. length > 0 ) {
failures. push ( `${ check . name }: 環境変数が未設定です (${ missing . join ( ', ' ) })` );
}
if ( ! reachable) {
failures. push ( `${ check . name }: ${ check . host }:${ check . port } に接続できません` );
}
if (missing. length === 0 && reachable) {
console. log ( `OK ${ check . name } (${ check . host }:${ check . port })` );
}
}
if (failures. length > 0 ) {
console. error ( ' \n 起動前チェックに失敗しました:' );
for ( const line of failures) console. error ( ` - ${ line }` );
process. exit ( 1 );
}
console. log ( ' \n すべてのチェックを通過しました。タスクを開始できます。' );
ポイントは process.exit(1) で明示的に落とすところにあります。チェックが警告を出すだけでは、結局それを読み飛ばしてタスクを走らせてしまいます。落ちる仕組みにしておくと、気づかないまま進むことがなくなります。
疎通に失敗した場合は、そのポートを誰が握っているかを確認します。
# macOS / Linux — 3333番ポートを使っているプロセスを特定する
lsof -nP -iTCP:3333 -sTCP:LISTEN
# 前回のプロセスが残っている場合のみ終了させる
kill "$( lsof -t -nP -iTCP:3333 -sTCP:LISTEN )"
私の場合、原因の大半は「前回のMCPサーバープロセスが終了しきっていない」でした。Coworkアプリの再起動で直る、と説明されるケースの実体はこれであることが多いです。Stripe の Webhook をブラウザ側から追いかけたときの手順は Claude in Chrome で Stripe Webhook の HTTP 500 エラーを解決した実践レポート に書いております。
完走率を自分の環境で測る
62%から95%という数字は、AdMobの管理画面とApp Store Connectの売上画面という、私が毎週触っている2つの画面のものです。対象が変われば出発点も上限も変わります。参考にしていただくのは構いませんが、そのまま自分の数字として扱うと、直すべき箇所を見誤ります。
そこで、実行のたびに1行だけ追記して、あとから完走率と所要時間を出せるようにしております。特別なものではなく、追記と集計だけの小さなスクリプトです。
// runlog.mjs — 実行結果を1行ずつ追記し、完走率と所要時間の中央値を出す
// 記録: node runlog.mjs log admob-weekly ok 141
// node runlog.mjs log admob-weekly fail 63 "成功メッセージを確認できず"
// 集計: node runlog.mjs report admob-weekly
import { appendFileSync, readFileSync, existsSync } from 'node:fs' ;
const FILE = 'run-log.tsv' ;
const [, , cmd , task , ... rest ] = process.argv;
if (cmd === 'log' && task) {
const [ result , seconds , note = '' ] = rest;
appendFileSync ( FILE , [ new Date (). toISOString (), task, result, seconds, note]. join ( ' \t ' ) + ' \n ' );
console. log ( `記録しました: ${ task } ${ result } ${ seconds }s` );
process. exit ( 0 );
}
if (cmd !== 'report' || ! task || ! existsSync ( FILE )) {
console. error ( '使い方: node runlog.mjs log <task> <ok|fail> <秒> [メモ]' );
console. error ( ' node runlog.mjs report <task>' );
process. exit ( 1 );
}
const rows = readFileSync ( FILE , 'utf8' ). trim (). split ( ' \n ' )
. map (( line ) => line. split ( ' \t ' ))
. filter (( cols ) => cols[ 1 ] === task);
if (rows. length === 0 ) {
console. error ( `${ task } の記録がありません` );
process. exit ( 1 );
}
const ok = rows. filter (( cols ) => cols[ 2 ] === 'ok' );
const median = ( values ) => {
const sorted = [ ... values]. sort (( a , b ) => a - b);
return sorted. length ? sorted[Math. floor (sorted. length / 2 )] : 0 ;
};
console. log ( `${ task }: ${ rows . length }回中 ${ ok . length }回完走 (${ Math . round (( ok . length / rows . length ) * 100 ) }%)` );
console. log ( `完走時の所要時間の中央値: ${ median ( ok . map (( cols ) => Number ( cols [ 3 ]))) }秒` );
for ( const cols of rows. filter (( c ) => c[ 2 ] === 'fail' )) {
console. log ( ` 失敗 ${ cols [ 0 ]. slice ( 0 , 10 ) } — ${ cols [ 4 ] || '(メモなし)'}` );
}
所要時間に平均ではなく中央値を使っているのは、失敗する直前まで粘った1回が平均を引き伸ばしてしまうからです。中央値なら、いつもどおりに終わったときの実感に近い数字が出ます。
そして、失敗時のメモを空欄にしないところが肝心です。完走率そのものより、失敗メモが何種類に収束するかを私は見ております。「成功メッセージを確認できず」ばかりが並ぶなら指示文の問題ですし、種類がいつまでも散らばるようなら、指示文ではなく対象の選び方を疑ったほうが早いことが多い、というのが今のところの私の判断基準です。
10回も貯まれば傾向は見えてきます。前の節で紹介した起動前チェックと合わせて、記録するところまでを1回分の手順に含めてしまうのが、続けるうえでは楽でした。
症状別・どの対処から試すか
限られた時間で当たりを引くために、症状ごとの優先順位を表にしました。上から順に試すと、私の環境では平均2手以内で切り分けが終わっております。
症状
最初に試すこと
次に試すこと
ここまでで直らなければ
クリックが無反応
操作前に5秒待つ指示を追加
Tab+Enterのキーボード操作へ切替
スクリーンショットで要素の可視性を確認
本文が読めない
待機を6秒に延ばす
「画面に見えているテキストだけ読んで」
スクリーンショット経由の読み取りへ
ログインで停止
事前に手動ログインしておく
冒頭にセッション確認ステップを追加
2FA必須なら自動化の対象から外す
途中で停止
タスクを10件単位に分割
リトライ指示を明記
手動で同じ操作を行いサービス側を疑う
結果が期待と違う
操作後の成功条件を明文化
処理件数を報告させる
終了条件を明示して再実行
MCP接続エラー
起動前チェックを実行
ポートを握るプロセスを終了
ターミナル起動でstderrを直接読む
判断に迷ったときは、いちばん左の列に戻ります。「症状を一言で言えるか」が曖昧なまま対処を始めると、たいてい遠回りになりました。
Claude in Chrome は自動化の道具ですが、実際に効くのは自動化そのものではなく、失敗したときに「どこで止まったか」を機械が教えてくれる状態をつくることでした。待機秒数と検証ステップ。この2つを加えるだけで、私の週次レポート取得は「毎回見張るもの」から「失敗したときだけ手を出すもの」に変わりました。
次に手を動かすなら、今いちばん失敗しているタスクをひとつ選び、その最後の操作の直後に「成功条件を目視確認して、満たさなければ停止して報告して」の一文を足すところから始めてみてください。効果がもっとも大きく、書き足すのは一行です。
より基本的な使い方から確認したい場合は、Claude in Chrome と Cowork の基本ガイド が出発点になるかと思います。
私自身まだ試行錯誤の途中ですが、同じところでつまずいている方の時間が少しでも減れば嬉しく思います。お読みいただきありがとうございました。