Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 299品質スコア 94/100

mcp-client

任意のMCPサーバーに接続できるユニバーサルMCPクライアントです。段階的な情報開示に対応し、MCPサーバーをスキルとしてラップすることで、ツール定義によるコンテキストウィンドウの肥大化を防ぎます。外部MCPサーバー(Playwright、GitHub、ファイルシステムなど)との連携時、利用可能なツールの一覧表示、MCPツールの実行に使用できます。「MCPに接続」「MCPツール一覧表示」「MCPを呼び出し」「Playwrightを使用」「ブラウザナビゲート」「ブラウザスナップショット」などのキーワードをトリガーに動作します。

description の原文を見る

Universal MCP client for connecting to any MCP server with progressive disclosure. Wraps MCP servers as skills to avoid context window bloat from tool definitions. Use when interacting with external MCP servers (Playwright, GitHub, filesystem, etc.), listing available tools, or executing MCP tool calls. Triggers on "connect to MCP", "list MCP tools", "call MCP", "use Playwright", "browser navigate", "browser snapshot".

SKILL.md 本文

ユニバーサル MCP クライアント

ツール定義でコンテキストを圧迫することなく、任意の MCP サーバーに接続できます。

⚠️ PLAYWRIGHT ユーザーへ: 下記の「重要: Playwright ブラウザセッション動作」セクションをお読みください!

各 MCP 呼び出し = 新しいブラウザセッション。呼び出し後にブラウザが閉じます。 1 回の呼び出しでナビゲートして、別の呼び出しでクリックすることはできません。 複数ステップの操作には browser_run_code を使用してください。 状態に戻す必要がある場合(ログイン済みなど)は、最初からすべてのステップをやり直す必要があります。

仕組み

このクライアントは、すべての MCP ツールスキーマをコンテキストに読み込む代わりに、以下を行います:

  1. 設定から利用可能なサーバーをリストアップ
  2. 必要に応じてツールスキーマを問い合わせ
  3. JSON 引数でツールを実行

設定

設定ファイルの場所優先順位:

  1. MCP_CONFIG_PATH 環境変数
  2. .claude/skills/mcp-client/references/mcp-config.json
  3. 現在のディレクトリの .mcp.json
  4. ~/.claude.json

コマンド

# 設定済みサーバーをリストアップ
python scripts/mcp_client.py servers

# 特定のサーバーからツールをリストアップ
python scripts/mcp_client.py tools playwright

# ツールを呼び出す
python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}'

重要: Playwright ブラウザセッション動作

⚠️ セッションの問題

各 MCP 呼び出しは新しいブラウザセッションを作成します。呼び出し後にブラウザが閉じます。

これはつまり:

# ❌ 間違い - これらは別々のブラウザセッションで実行されます!
python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}'
python scripts/mcp_client.py call playwright browser_click '{"element": "Accept cookies"}'
python scripts/mcp_client.py call playwright browser_snapshot '{}'
# ^ スナップショットはクリック後のページではなく、新しいページをキャプチャします!

✅ 解決策: browser_run_code

browser_run_code を使用して、複数の Playwright ステップを 1 つのブラウザセッションで実行します:

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://example.com\");

    // クッキーバナーを待機してクリック
    const acceptBtn = page.getByRole(\"button\", { name: /accept/i });
    if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
      await acceptBtn.click();
      await page.waitForTimeout(1000);
    }

    // ページが安定するまで待機
    await page.waitForLoadState(\"networkidle\");

    // 分析用のスナップショットデータを返す
    const snapshot = await page.accessibility.snapshot();
    return JSON.stringify(snapshot, null, 2);
  "
}'

各アプローチを使う場合

シナリオツール理由
シンプルなページロード + スナップショットbrowser_navigate自動でスナップショットを返す
複数ステップのインタラクションbrowser_run_codeセッションを維持
クリック後に結果を確認browser_run_codeセッションが保持される
フォーム入力と送信browser_run_codeセッションが保持される
ホバーでメニュー表示browser_run_codeセッションが保持される

テスト発見のための Playwright ワークフロー

1. 基本的なページ探索(単一ステップ)

browser_navigate はナビゲーション結果とアクセシビリティスナップショットの両方を返します:

python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}'

出力に含まれるもの:

  • ページ URL とタイトル
  • 完全なアクセシビリティツリー(ロール、名前、状態付きの表示要素)
  • さらなるインタラクション用の要素参照

使用場面: インタラクションなしのシンプルなページロード

2. クッキーバナー付きページ(複数ステップ)

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://www.olx.ro\");

    // クッキー同意を処理
    try {
      const cookieBtn = page.getByRole(\"button\", { name: \"Accept\" });
      await cookieBtn.click({ timeout: 5000 });
      await page.waitForTimeout(1000);
    } catch (e) {
      // クッキーバナーがない
    }

    // アクセシビリティスナップショットを取得
    const snapshot = await page.accessibility.snapshot({ interestingOnly: false });
    return JSON.stringify(snapshot, null, 2);
  "
}'

3. サブページへのナビゲート(複数ステップ)

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://www.olx.ro\");

    // クッキーを閉じる
    const acceptBtn = page.getByRole(\"button\", { name: \"Accept\" });
    if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
      await acceptBtn.click();
      await page.waitForTimeout(500);
    }

    // ログインにナビゲート
    await page.goto(\"https://www.olx.ro/cont/\");

    // ログインドメインへのリダイレクトを待機
    await page.waitForURL(/login\\.olx\\.ro/, { timeout: 10000 });

    // フォーム構造を取得
    const snapshot = await page.accessibility.snapshot();
    return JSON.stringify({ url: page.url(), snapshot }, null, 2);
  "
}'

4. 要素インタラクションの探索(複数ステップ)

メニューやドロップダウンの動作を理解するために使用します:

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://www.olx.ro\");

    // クッキーを閉じる
    const acceptBtn = page.getByRole(\"button\", { name: \"Accept\" });
    if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
      await acceptBtn.click();
    }

    // カテゴリをクリックして何が起こるか確認
    const categoryLink = page.getByRole(\"link\", { name: /Auto, moto/i }).first();
    await categoryLink.click();

    // 結果を確認するため待機
    await page.waitForTimeout(1500);

    // クリック後の状態をキャプチャ
    const snapshot = await page.accessibility.snapshot();
    return JSON.stringify({
      url: page.url(),
      didNavigate: page.url().includes(\"auto\"),
      snapshot: snapshot
    }, null, 2);
  "
}'

5. フォームに入力して状態をキャプチャ

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://login.olx.ro\");

    // ログインフォームに入力
    await page.locator(\"input[type=email]\").fill(\"test@example.com\");
    await page.locator(\"input[type=password]\").fill(\"test123\");

    // ログインボタンをクリック
    await page.getByTestId(\"login-submit-button\").click();

    // レスポンスを待機
    await page.waitForTimeout(3000);

    // エラーメッセージをキャプチャ
    const errors = await page.locator(\"[class*=error], [role=alert]\").allTextContents();
    const snapshot = await page.accessibility.snapshot();

    return JSON.stringify({
      url: page.url(),
      errors: errors,
      snapshot: snapshot
    }, null, 2);
  "
}'

ページオブジェクトのセレクター取得

ベストプラクティス

1. アクセシビリティツリーを優先

browser_navigate または browser_run_code からのスナップショットには以下が含まれます:

  • ロール: button、link、textbox、combobox など
  • 名前: アクセシブル名(ラベル、aria-label、テキストコンテンツから)
  • 状態: disabled、checked、expanded など

これらを Playwright ロケーターにマップします:

// スナップショットから: { role: "button", name: "Căutare" }
page.getByRole('button', { name: /Căutare/i })

// スナップショットから: { role: "textbox", name: "Ce anume cauți?" }
page.getByRole('textbox', { name: /Ce anume cauți/i })

// スナップショットから: { role: "link", name: "Auto, moto și ambarcațiuni" }
page.getByRole('link', { name: /Auto, moto/i })

2. セレクター優先度

優先度メソッド使用場面
1getByRole()要素がセマンティックロール + アクセシブル名を持つ場合
2getByTestId()要素が data-testid 属性を持つ場合
3getByText()ユニークなテキストコンテンツ
4getByPlaceholder()プレースホルダー付きの入力
5locator('[attr="value"]')CSS 属性セレクター
6locator('.class')CSS クラス(脆弱、避ける)

3. 複数マッチへの対応

// 複数マッチする場合は .first() を使用
page.getByRole('link', { name: 'Category' }).first()

// 親コンテキストを使用
page.locator('nav').getByRole('link', { name: 'Category' })

// フィルターを使用
page.getByRole('button').filter({ hasText: /submit/i })

4. 複雑な場合は完全な DOM を取得

アクセシビリティツリーで不十分な場合、生の HTML を取得します:

python scripts/mcp_client.py call playwright browser_run_code '{
  "code": "
    await page.goto(\"https://example.com\");

    // 特定要素の HTML を取得
    const formHtml = await page.locator(\"form\").first().innerHTML();

    // またはすべてのボタンを属性付きで取得
    const buttons = await page.locator(\"button\").evaluateAll(btns =>
      btns.map(b => ({
        text: b.textContent,
        testid: b.dataset.testid,
        class: b.className,
        type: b.type
      }))
    );

    return JSON.stringify({ formHtml, buttons }, null, 2);
  "
}'

クイックリファレンス: Playwright MCP ツール

ツールセッション動作使用場面
browser_navigate新しいセッション、スナップショット返却シンプルなページロード
browser_run_code単一セッション、カスタムスクリプト複数ステップの操作
browser_click新しいセッション単一クリック(通常は単独では不便)
browser_type新しいセッション単一入力(通常は単独では不便)
browser_snapshotセッションがあれば再利用現在のページ状態を取得
browser_screenshotセッションがあれば再利用ビジュアルキャプチャ

ツール引数

browser_navigate

{"url": "https://example.com"}

browser_run_code

{
  "code": "await page.goto('https://example.com'); return await page.title();"
}

code は以下を満たす有効な JavaScript である必要があります:

  • page オブジェクト(Playwright ページ)を使用
  • 非同期操作に await を使用
  • 必要なデータを返す(JSON.stringify をオブジェクトに使用)

browser_click

{"element": "Submit button", "ref": "optional-element-ref"}

browser_type

{"element": "Email input", "text": "user@example.com"}

エラーハンドリング

エラー原因修正方法
"No MCP config found"設定ファイルがないmcp-config.json を作成
"Server not found"サーバーが設定にないサーバーを設定に追加
"Connection failed"サーバーが実行中でないMCP サーバーを起動
"Invalid JSON"不正なツール引数引数形式を確認
"Timeout"ページが遅いコード内でタイムアウトを増加
"Element not found"セレクターが間違いスナップショットで実際の名前を確認

セットアップ

  1. 設定例をコピー:

    cp .claude/skills/mcp-client/references/mcp-config.example.json \
       .claude/skills/mcp-client/references/mcp-config.json
    
  2. 設定には以下が含まれるべき:

    {
      "mcpServers": {
        "playwright": {
          "command": "npx",
          "args": ["@playwright/mcp@latest"]
        }
      }
    }
    
  3. 依存関係をインストール:

    pip install mcp fastmcp
    

設定例

references/mcp-config.example.json を参照

利用可能なサーバー

references/mcp-servers.md を参照:

  • Playwright(ブラウザオートメーション)
  • GitHub(リポジトリ操作)
  • ファイルシステム(ファイルアクセス)
  • Sequential Thinking(推論)
  • その他...

依存関係

pip install mcp fastmcp

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
majiayu000
リポジトリ
majiayu000/claude-skill-registry
ライセンス
MIT
最終更新
2026/5/4

Source: https://github.com/majiayu000/claude-skill-registry / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: majiayu000 · majiayu000/claude-skill-registry · ライセンス: MIT