mcpField
C
chrome-devtools-mcp

chrome-devtools-mcp

github.com/gsmlg-devテスト・品質040 回インストール3 週間前に更新
リポジトリ

chrome-devtools-mcp について

chrome-devtools-mcp は、Chrome DevTools を通じて Chrome を操作・検査する MCP サーバーで、ブラウザー自動化やテスト向けです。ページのスナップショット、操作、スクリプト実行、スクリーンショット、性能・アクセシビリティ検査を提供し、拡張機能やメモリ用ツールも任意で有効にできます。

主な機能

  1. 01ページの移動と読み込み待機
  2. 02ページ構造の確認と要素操作
  3. 03スクリプト実行による状態確認
  4. 04ビューポートのスクリーンショット撮影
  5. 05性能・レイアウト・アクセシビリティの検査
  6. 06拡張機能とメモリ用ツールの任意有効化

活用シーン

  1. 01ブラウザー操作とデータ取得の自動化
  2. 02ページエラーやネットワーク失敗の確認
  3. 03異なるビューポートでのレスポンシブ検証
  4. 04ウェブページ上での拡張機能動作の確認

MCP 対応

MCP サーバーとして、Chrome の操作・検査ツールを MCP クライアントに提供します。ページ ID で対象ページを指定でき、設定フラグで拡張機能やメモリ用ツールを有効にできます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gsmlg-dev/code-agent --skill chrome-devtools-mcp

インストール後、Claude Code で/chrome-devtools-mcpを入力して読み込まれたか確認します。

詳細

コアコンセプト

ブラウザーのライフサイクル:ブラウザーは、永続的な Chrome プロファイルを使用して、最初のツール呼び出し時に自動的に起動します。MCP サーバーの設定で CLI 引数を指定して構成します:npx chrome-devtools-mcp@latest --help。

以下のフラグを指定すると、追加のツールを有効にできます。

  • 拡張機能ツールを有効にするには、--categoryExtensions フラグを使用します。
  • メモリツールを有効にするには、--memoryDebugging フラグを使用します。

ページの指定:ページ単位のツールでは、対象のページを指定するために pageId パラメーターが必要です。list_pages を使用して、利用可能なページとその ID(例:pageId: 1)を確認するか、new_page でページを作成したときに返される ID を使用します。 注:evaluate_script でページを対象にする場合は、pageId が必要です。ただし、--categoryExtensions が有効な場合は pageId は省略可能です。その代わりに serviceWorkerId を渡すと、拡張機能のバックグラウンドサービスワーカー内で評価できます。

要素の操作:take_snapshot を使用して、要素の uid を含むページ構造を取得します。各要素には、操作に使用する一意の uid があります。要素が見つからない場合は、新しいスナップショットを取得してください。要素が削除されたか、ページが変更された可能性があります。

ワークフローパターン

ページを操作する前に
  1. 移動:navigate_page または new_page
  2. 待機:探しているものが分かっている場合は、コンテンツが読み込まれるのを確認するために wait_for を使用します。
  3. スナップショット:pageId を指定して take_snapshot を実行し、ページ構造を把握します。
  4. 操作:スナップショットに含まれる要素の uid を click、fill などに使用し、対応する pageId を渡します。
効率的なデータ取得
  • 大きな出力(スクリーンショット、スナップショット、トレース)には filePath パラメーターを使用します。
  • ページネーション(pageIdx、pageSize)とフィルタリング(types)を使用して、データ量を最小限に抑えます。
  • ページの状態を更新する必要がない場合は、入力操作で includeSnapshot: false を設定します。
ツールの選択
  • 自動化/操作:take_snapshot(テキストベースで高速なため、自動化に適しています)
  • 視覚的な確認:take_screenshot(ユーザーが視覚的な状態を確認する必要がある場合)
  • 追加の詳細情報:アクセシビリティツリーにないデータには evaluate_script
並列実行

複数のツール呼び出しを並列で送信できますが、正しい順序を維持してください:移動 → 待機 → スナップショット → 操作。

拡張機能のテスト

拡張機能ツール(install_extension、list_extensions など)は、MCP サーバーの起動時に --categoryExtensions フラグを指定した場合にのみ利用できます。これらのツールが利用できない場合は、MCP サーバーの設定を更新してMCP サーバー(または AI クライアント)を再起動するよう、ユーザーに依頼してください。

  1. インストール:展開済みの拡張機能へのパスを指定して install_extension を使用します。
  2. 特定:応答から、または list_extensions を呼び出して拡張機能 ID を取得します。
  3. アクションを実行:該当する場合は、trigger_extension_action を使用してポップアップまたはサイドパネルを開きます。
  4. サービスワーカーを確認:evaluate_script で serviceWorkerId を使用し(pageId と args は省略)、拡張機能の状態を確認するか、バックグラウンドアクションを実行します。ページ内で評価する場合は、pageId を渡し(serviceWorkerId は省略)ます。
  5. ページの動作を確認:拡張機能が動作するページに移動し、take_snapshot を使用して、コンテンツスクリプトが要素を挿入したか、ページを正しく変更したかを確認します。

トラブルシューティング

chrome-devtools-mcp で不十分な場合は、Chrome DevTools UI を使用するようユーザーに案内してください。

chrome-devtools-mcp または Chrome の起動時にエラーが発生した場合は、https://github.com/ChromeDevTools/chrome-devtools-mcp/blob/main/docs/troubleshooting.md を参照してください。

Chrome DevTools MCP の使用方法

重要な制約:スクリーンショットのサイズ制限

API への送信には、いずれかの寸法が 8000px を超えてはならないという厳しい制限があります。ページ全体のスクリーンショットは、この制限を頻繁に超えます。

解決策:デフォルトではビューポートのみのスクリーンショットを常に使用する
// ✓ CORRECT: Viewport-only (default)
take_screenshot({ fullPage: false })

// ✓ CORRECT: Save to filesystem for large pages
take_screenshot({ fullPage: false, path: './screenshots/page.png' })

// ✗ AVOID: Full-page without size check
take_screenshot({ fullPage: true })
ページ全体のスクリーンショットが必要な場合

まずページの高さを確認します。

const height = execute_script('return document.documentElement.scrollHeight')
if (height > 8000) {
  take_screenshot({ fullPage: false, path: './screenshot.png' })
} else {
  take_screenshot({ fullPage: true })
}

別の方法:スクロールしながらビューポートのスクリーンショットを複数枚撮影します。

take_screenshot({ fullPage: false, path: './top.png' })
execute_script('window.scrollBy(0, window.innerHeight)')
take_screenshot({ fullPage: false, path: './middle.png' })

ナビゲーションとタイミング

ナビゲーション後は、JavaScript の実行とレンダリングを待つため、必ず待機してください。

navigate('https://example.com')
wait(1000) // Minimum recommended wait

// For dynamic apps, wait for specific elements
navigate('https://example.com')
execute_script(`
  return new Promise(resolve => {
    const check = () => {
      if (document.querySelector('#app')) resolve();
      else setTimeout(check, 100);
    };
    check();
  });
`)

エラー検出パターン

コンソールエラー
const errors = execute_script(`
  return performance.getEntriesByType('navigation')[0].type === 'reload'
    ? []
    : (window.__consoleErrors || []);
`)
ネットワーク障害
const failed = execute_script(`
  return performance.getEntriesByType('resource')
    .filter(r => r.transferSize === 0 && r.duration > 0)
    .map(r => ({ url: r.name, duration: r.duration }));
`)
レイアウトの問題
const issues = execute_script(`
  const issues = [];

  // Horizontal overflow
  if (document.documentElement.scrollWidth > window.innerWidth) {
    issues.push({ type: 'horizontal-overflow', width: document.documentElement.scrollWidth });
  }

  // Elements outside viewport
  document.querySelectorAll('*').forEach(el => {
    const rect = el.getBoundingClientRect();
    if (rect.right > window.innerWidth) {
      issues.push({ type: 'overflow-right', element: el.tagName });
    }
  });

  return issues;
`)

レスポンシブテスト

複数のビューポートを効率よくテストします。

const viewports = [
  { width: 375, height: 667, name: 'mobile' },
  { width: 768, height: 1024, name: 'tablet' },
  { width: 1440, height: 900, name: 'desktop' }
];

for (const vp of viewports) {
  set_viewport(vp.width, vp.height);
  wait(500); // Allow reflow
  take_screenshot({
    fullPage: false,
    path: `./screenshots/${vp.name}.png`
  });
}

コンポーネントの状態テスト

ユーザー操作なしでインタラクティブな状態をテストします。

// Hover state
execute_script(`
  const el = document.querySelector('#button');
  el.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
`);
take_screenshot({ fullPage: false, path: './hover.png' });

// Focus state
execute_script(`
  document.querySelector('#input').focus();
`);
take_screenshot({ fullPage: false, path: './focus.png' });

// Active/pressed state
execute_script(`
  const el = document.querySelector('#button');
  el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
`);
take_screenshot({ fullPage: false, path: './active.png' });

パフォーマンス指標

ウェブバイタルとパフォーマンスデータを収集します。

const metrics = execute_script(`
  return {
    fcp: performance.getEntriesByName('first-contentful-paint')[0]?.startTime,
    lcp: performance.getEntriesByType('largest-contentful-paint')[0]?.startTime,
    cls: performance.getEntriesByType('layout-shift')
      .reduce((sum, entry) => sum + (entry.hadRecentInput ? 0 : entry.value), 0),
    resources: performance.getEntriesByType('resource').length,
    totalSize: performance.getEntriesByType('resource')
      .reduce((sum, r) => sum + r.transferSize, 0)
  };
`);

アクセシビリティチェック

基本的なアクセシビリティ検証を行います。

const a11y = execute_script(`
  const issues = [];

  // Missing alt text
  document.querySelectorAll('img:not([alt])').forEach(img => {
    issues.push({ type: 'missing-alt', src: img.src });
  });

  // Missing form labels
  document.querySelectorAll('input:not([aria-label]):not([id])').forEach(input => {
    if (!input.closest('label')) {
      issues.push({ type: 'missing-label', name: input.name });
    }
  });

  // Empty links
  document.querySelectorAll('a').forEach(link => {
    if (!link.textContent.trim() && !link.getAttribute('aria-label')) {
      issues.push({ type: 'empty-link', href: link.href });
    }
  });

  return issues;
`);

標準的な監査ワークフロー

体系的なページ監査には、次のパターンを使用します。

function audit_page(url, name) {
  // Navigate
  navigate(url);
  wait(1000);

  // Screenshot (viewport only to avoid size errors)
  const screenshot_path = `./screenshots/${name}.png`;
  take_screenshot({ fullPage: false, path: screenshot_path });

  // Page metrics
  const height = execute_script('return document.documentElement.scrollHeight');
  const viewport = execute_script('return window.innerHeight');

  // Error detection
  const console_errors = execute_script('return window.__errors || []');
  const network_failures = execute_script(`
    return performance.getEntriesByType('resource')
      .filter(r => r.transferSize === 0 && r.duration > 0)
      .map(r => r.name);
  `);
  const layout_issues = execute_script(`
    return document.documentElement.scrollWidth > window.innerWidth
      ? ['horizontal-overflow']
      : [];
  `);

  return {
    name,
    url,
    screenshot_path,
    page_height: height,
    viewport_height: viewport,
    needs_scroll: height > viewport,
    console_errors,
    network_failures,
    layout_issues,
    has_issues: console_errors.length > 0 ||
                network_failures.length > 0 ||
                layout_issues.length > 0
  };
}

エラー処理

スクリーンショットの寸法エラー

fullPage: false を使用しているにもかかわらず寸法エラーが発生する場合、ページで特殊なビューポート設定が使用されている可能性があります。その場合は、代わりにファイルに保存してください。

try {
  take_screenshot({ fullPage: false });
} catch (error) {
  if (error.includes('8000 pixels')) {
    take_screenshot({ fullPage: false, path: './fallback.png' });
  }
}
ナビゲーションのタイムアウト
try {
  navigate(url);
  wait(5000);
} catch (error) {
  // Log failure and continue
  console.log(`Failed to load: ${url}`);
}
要素が見つからない場合
const exists = execute_script(`return !!document.querySelector('#target')`);
if (!exists) {
  take_screenshot({ fullPage: false, path: './missing-element.png' });
  // Handle accordingly
}

重要な注意事項

  1. 寸法エラーを避けるため、常に fullPage: false をデフォルトで使用してください
  2. 可能な場合は、API への送信ではなく、ファイルシステムにスクリーンショットを保存してください
  3. ナビゲーション後は、JavaScript の実行を待ってください(最低 1000ms)
  4. 壊れやすいセレクター方式ではなく、DOM クエリには execute_script を使用してください
  5. レスポンシブなアプリケーションでは、複数のビューポートをテストしてください
  6. 証拠は早めに取得してください。要素の状態が変わる前にスクリーンショットを撮ってください
  7. スクリーンショットの方法を決める前に、ページの寸法を確認してください

追加のツールカテゴリ

次のフラグを指定すると、追加のツールを有効にできます。

  • 拡張機能ツールを使用するには、--categoryExtensions フラグを指定します。
  • メモリツールを使用するには、--memoryDebugging フラグを指定します。
拡張機能のテスト

続行する前に確認してください:拡張機能ツール(install_extension、list_extensions など)は、MCP サーバーの起動時に --categoryExtensions フラグが指定されている場合にのみ使用できます。これらのツールがツール一覧にない場合は、作業を中止し、MCP サーバーの設定を更新するようユーザーに依頼してください。

{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["chrome-devtools-mcp@latest", "--categoryExtensions"]
    }
  }
}

更新後、変更を反映するには、ユーザーが MCP サーバー(または AI クライアント)を再起動する必要があります。

  1. インストール:展開済みの拡張機能へのパスを指定して install_extension を使用します。
  2. 識別:レスポンスから拡張機能 ID を取得するか、list_extensions を呼び出して確認します。
  3. アクションの実行:該当する場合は、trigger_extension_action を使用してポップアップまたはサイドパネルを開きます。
  4. サービスワーカーの確認:serviceWorkerId を指定して evaluate_script を使用し、拡張機能の状態を確認するか、バックグラウンドアクションを実行します。
  5. ページ動作の確認:拡張機能が動作するページに移動し、take_snapshot を使用して、コンテンツスクリプトが要素を挿入したか、ページを正しく変更したかを確認します。

コメント