mcpField
S
stagehand-automation

stagehand-automation

github.com/adaptationio開発76 回インストール
リポジトリ

stagehand-automation について

Stagehand v3 を基盤とするブラウザー自動化スキルです。自然言語での操作、構造化データの抽出、ページ状態の確認に対応し、DOM 変更時には要素の指定を調整できます。

主な機能

  1. 01自然言語によるブラウザー操作
  2. 02スキーマ検証付きデータ抽出
  3. 03ページ要素と状態の確認
  4. 04DOM 変更に応じた要素指定
  5. 05Playwright との併用

活用シーン

  1. 01UI 改修に強い E2E テストの作成
  2. 02ウェブサイトからの構造化情報抽出
  3. 03複雑なフォーム入力の自動化
  4. 04複数サイトにまたがるワークフローの実行

MCP 対応

Stagehand は MCP サーバーとして起動でき、Claude Desktop などの MCP 対応クライアントからブラウザーを操作できます。

インストール

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

$npx skills add https://github.com/adaptationio/skrillz --skill stagehand-automation

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

同梱ファイルreferences/api-reference.mdreferences/troubleshooting.md

詳細

Stagehand の自動化

概要

Stagehand v3 は、脆弱な従来型の自動化と、インテリジェントで自己修復する機能をつなぐ、最先端の AI ブラウザー自動化フレームワークです。Chrome DevTools Protocol(CDP)を基盤としており、v2 より 44% 高速で、Claude とシームレスに連携します。

主な革新点:DOM が変更されても、テストが壊れるのではなく、AI が適応します。

コア API:

  • act() - 自然言語でアクションを実行します
  • extract() - ページから構造化データを抽出します
  • observe() - 要素とページの状態を特定します

クイックスタート(10 分)

1. Stagehand をインストールする
npm install @browserbase/stagehand zod
2. Claude API を設定する
# Add to .env
ANTHROPIC_API_KEY=your_api_key_here
3. 最初の自動化を作成する
import { Stagehand } from "@browserbase/stagehand";
import { z } from "zod";

async function main() {
  const stagehand = new Stagehand({
    env: "LOCAL",
    modelName: "claude-sonnet-4-20250514",
    modelClientOptions: {
      apiKey: process.env.ANTHROPIC_API_KEY,
    },
  });

  await stagehand.init();
  await stagehand.page.goto("https://news.ycombinator.com");

  // AI-powered action - survives UI changes!
  await stagehand.act({ action: "click on the first story link" });

  // Extract structured data
  const data = await stagehand.extract({
    instruction: "extract the story title and author",
    schema: z.object({
      title: z.string(),
      author: z.string(),
    }),
  });

  console.log(data);
  await stagehand.close();
}

main();
4. 実行する
npx ts-node your-script.ts

コア API

act() - アクションを実行する

自然言語でアクションを実行します:

// Click elements
await stagehand.act({ action: "click the login button" });

// Fill forms
await stagehand.act({ action: "fill in the email field with '[email protected]'" });
await stagehand.act({ action: "enter password 'securepass123'" });

// Navigate
await stagehand.act({ action: "scroll down to the pricing section" });
await stagehand.act({ action: "click the 'Sign Up' button in the header" });

// Complex actions
await stagehand.act({
  action: "select 'Premium' from the plan dropdown and click Continue"
});

自己修復:ボタン ID が #login-btn から #auth-signin に変わっても、Stagehand は自動的に適応します。

extract() - 構造化データを取得する

スキーマ検証を行いながらデータを抽出します:

import { z } from "zod";

// Simple extraction
const title = await stagehand.extract({
  instruction: "get the main page title",
  schema: z.object({
    title: z.string(),
  }),
});

// Complex extraction
const products = await stagehand.extract({
  instruction: "extract all products with name, price, and availability",
  schema: z.object({
    products: z.array(z.object({
      name: z.string(),
      price: z.number(),
      inStock: z.boolean(),
    })),
  }),
});

// Extract from specific area
const cartItems = await stagehand.extract({
  instruction: "get items in the shopping cart",
  schema: z.object({
    items: z.array(z.object({
      name: z.string(),
      quantity: z.number(),
      price: z.number(),
    })),
    total: z.number(),
  }),
});
observe() - ページの状態を分析する

ページの要素と状態を把握します:

// Find elements
const elements = await stagehand.observe({
  instruction: "find all clickable buttons on this page"
});

// Check state
const loginState = await stagehand.observe({
  instruction: "is the user logged in? Look for profile icons or logout buttons"
});

// Identify form fields
const formFields = await stagehand.observe({
  instruction: "identify all form input fields and their labels"
});

自己修復パターン

従来型と Stagehand の比較
// TRADITIONAL (Playwright) - Breaks when DOM changes
await page.click('#submit-btn-v2');  // Fails if ID changes
await page.click('.btn-primary:nth-child(2)');  // Fails if order changes

// STAGEHAND - Self-healing
await stagehand.act({ action: "click the submit button" });  // Always works
await stagehand.act({ action: "click the primary action button" });  // Adapts
自己修復が有効になる場合
  1. ID/クラスの変更:ボタン ID が #old-id から #new-id に変わる
  2. 構造の変更:要素が DOM ツリー内で移動する
  3. テキストの変更:ボタンのテキストが「Submit」から「Send」に変わる
  4. スタイルの変更:CSS クラスが再編成される
キャッシュ(パフォーマンスの最適化)

Stagehand v3 は検出した要素をキャッシュします:

// First call: AI analyzes page, finds element (slow)
await stagehand.act({ action: "click login" });

// Second call: Uses cached selector (fast)
await stagehand.act({ action: "click login" });

// Cache invalidated when page changes significantly

ハイブリッドアプローチ:Playwright + Stagehand

従来の速度と AI の回復力を組み合わせます:

import { Stagehand } from "@browserbase/stagehand";
import { test, expect } from "@playwright/test";

test('hybrid test', async () => {
  const stagehand = new Stagehand({ env: "LOCAL" });
  await stagehand.init();

  // Use Playwright for stable, fast operations
  await stagehand.page.goto('https://app.example.com');
  await stagehand.page.fill('[data-testid="email"]', '[email protected]');

  // Use Stagehand for dynamic/fragile elements
  await stagehand.act({ action: "click the login button" });

  // Use Playwright for assertions
  await expect(stagehand.page).toHaveURL(/dashboard/);

  // Use Stagehand for complex extraction
  const dashboardData = await stagehand.extract({
    instruction: "get user stats from dashboard",
    schema: z.object({
      totalOrders: z.number(),
      accountBalance: z.number(),
    }),
  });

  expect(dashboardData.totalOrders).toBeGreaterThan(0);
});

Claude との連携

モデルの選択
// Claude Sonnet 4 (recommended - balance of speed/quality)
const stagehand = new Stagehand({
  modelName: "claude-sonnet-4-20250514",
  modelClientOptions: {
    apiKey: process.env.ANTHROPIC_API_KEY,
  },
});

// Claude Opus (highest quality, slower)
const stagehand = new Stagehand({
  modelName: "claude-opus-4-20250514",
});

// Claude Haiku (fastest, simpler tasks)
const stagehand = new Stagehand({
  modelName: "claude-3-5-haiku-20241022",
});
コストの最適化
// Use Haiku for simple actions (cheaper)
const simpleStagehand = new Stagehand({
  modelName: "claude-3-5-haiku-20241022",
});
await simpleStagehand.act({ action: "click login" });

// Use Sonnet for complex extraction
const complexStagehand = new Stagehand({
  modelName: "claude-sonnet-4-20250514",
});
const data = await complexStagehand.extract({
  instruction: "extract all product details with nested specifications",
  schema: complexSchema,
});
推定コスト
操作モデル推定コスト
シンプルな act()Haiku~$0.001
複雑な act()Sonnet~$0.005
シンプルな extract()Haiku~$0.002
複雑な extract()Sonnet~$0.01

MCP との連携

Model Context Protocol 経由で Stagehand を Claude Desktop とともに使用します:

// Stagehand MCP server enables Claude to control browsers
// from Claude Desktop or any MCP-compatible client

import { StagehandMCPServer } from "@browserbase/stagehand/mcp";

const server = new StagehandMCPServer();
server.start();

// Now Claude can call:
// - stagehand.act({ action: "..." })
// - stagehand.extract({ instruction: "..." })
// - stagehand.observe({ instruction: "..." })

エラー処理

try {
  await stagehand.act({
    action: "click the non-existent button",
    timeout: 10000,  // 10 second timeout
  });
} catch (error) {
  if (error.message.includes('timeout')) {
    console.log('Element not found within timeout');
  } else if (error.message.includes('multiple')) {
    console.log('Multiple matching elements found - be more specific');
  } else {
    throw error;
  }
}

// Retry pattern
async function actWithRetry(stagehand, action, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await stagehand.act({ action });
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(r => setTimeout(r, 1000));
    }
  }
}

ベストプラクティス

1. 指示を具体的にする
// BAD - ambiguous
await stagehand.act({ action: "click button" });

// GOOD - specific
await stagehand.act({ action: "click the blue 'Add to Cart' button below the product image" });
2. コンテキストを使う
// Provide context for better accuracy
await stagehand.act({
  action: "in the navigation menu, click on 'Settings'"
});

await stagehand.act({
  action: "in the user dropdown in the top right, click 'Logout'"
});
3. Playwright と組み合わせて高速化する
// Fast: Use Playwright for data-testid elements
await stagehand.page.click('[data-testid="submit"]');

// Resilient: Use Stagehand for dynamic elements
await stagehand.act({ action: "dismiss the cookie banner" });
4. スキーマ検証
// Always use Zod schemas for type safety
const schema = z.object({
  title: z.string().min(1),
  price: z.number().positive(),
  inStock: z.boolean(),
});

const data = await stagehand.extract({
  instruction: "get product details",
  schema,
});
// data is fully typed!

ユースケース

  1. 自己修復する E2E テスト:UI の再設計後も動作するテスト
  2. ウェブスクレイピング:あらゆるウェブサイトからデータを抽出
  3. フォームの自動化:複雑なフォームを自動入力
  4. AI チャットボットのテスト:会話型 UI と対話
  5. 複数サイトにまたがるワークフロー:複数サイトのプロセスを自動化

参考資料

  • references/stagehand-v3-guide.md - API リファレンスの全容
  • references/claude-integration.md - API の設定とモデルの選択
  • references/self-healing-patterns.md - 高度なパターン

Stagehand v3 は、AI を活用した自己修復機能をブラウザー自動化にもたらします。壊れるのではなく、適応するテストを実現します。

コメント