🚀 MCProxy
SaladCloud用のMCP(Model Context Protocol)を介したリモートヘッドレスブラウザセッションです。
このプロジェクトは、AIエージェントが地理的に分散したSaladCloudコンテナ上で実行されるブラウザを制御できるようにします。地域別の価格チェック、地理的にターゲットされたコンテンツの検証、特定の場所からのWeb自動化などが利用例として挙げられます。
🚀 クイックスタート
1. 依存関係のインストール
npm install
2. ビルド
npm run build
3. ローカルテスト
Dockerでローカルでブラウザサーバーを起動します。
docker compose up --build
リポジトリには、Docker Composeセットアップで動作するように事前に構成された.mcp.jsonが含まれています。Claude Codeやその他のワークスペース構成をサポートするMCPクライアントで使用するには、このディレクトリから実行してください。
手動でテストするには:
MCPROXY_AUTH_TOKEN=dev-secret-token node mcp-server/dist/index.js
4. MCPインスペクターでテスト
MCPROXY_AUTH_TOKEN=dev-secret-token npx @modelcontextprotocol/inspector node mcp-server/dist/index.js
その後、ws://localhost:3000でセッションを作成します。
✨ 主な機能
- 複数ブラウザサポート:各セッションでChromium、Firefox、またはWebKit(Safari)を選択できます。
- モバイルデバイスエミュレーション:100種類以上のモバイルデバイス(iPhone、Pixel、iPad、Galaxyなど)を正確なビューポート、ユーザーエージェント、タッチサポートでエミュレートできます。
- 位置情報対応セッション:各セッションは地理的な位置情報(IP、都市、州/地域、国、タイムゾーン、ISP)を報告します。エージェントは位置情報でセッションを参照できます(例:「ユタ州のセッションを使用する」)。
- ステルスモード:WebGLスプーフィング、ナビゲーターオーバーライド、現実的なブラウザフィンガープリントによる高度な検出回避機能。
- 人間らしいインタラクション:クリック、タイピング、スクロールに人間らしい動作をオプションで使用して、ボット検出を回避します。
- Cloudflare自動待機:Cloudflareのチャレンジが完了するまで自動的に待機します。
- クッキーの永続化:セッション管理と認証のためにクッキーを保存して復元できます。
- 現実的なユーザーエージェント:最新のブラウザフィンガープリントデータを使用して現実的なユーザーエージェントを自動生成します。
- セッションアフィニティ:WebSocket接続はセッションを特定のコンテナレプリカに固定します。
- ハートビートキープアライブ:30秒ごとのピングで接続を維持します(Saladゲートウェイのアイドルタイムアウトは100秒)。
- 複数リージョンサポート:地理的に分散したブラウジングのために、異なるSaladデプロイメントに接続できます。
- バージョン互換性:機能報告と自動バージョン不一致検出機能。
- 33のMCPツール:ビジョンエージェント用の座標ベースのクリックを含む完全なブラウザ自動化機能。
📦 インストール
前提条件
- Docker(推奨)またはNode.js 20以上
- SaladCloudアカウント(本番デプロイ用)
AI支援によるセットアップ
このプロンプトをAIエージェントにコピーして貼り付けると、mcproxyの設定を支援してくれます。
リモートブラウザ自動化のためにmcproxyをセットアップしてください。
MCPクライアント: [Claude Desktop / Claude Code / Cursor / Windsurf / その他]
SaladCloudエンドポイント: [あなたのエンドポイントURL、または作成が必要な場合は「none」]
セットアップ手順:
1. Dockerがインストールされているか確認する
2. Dockerが利用可能な場合は、ghcr.io/saladtechnologies/mcproxyの事前構築済みイメージを使用する
3. Dockerが利用不可能な場合は、https://github.com/SaladTechnologies/mcproxyからクローンしてビルドする
4. クライアント用のMCPサーバーJSONを構成する
5. 安全なAUTH_TOKENを生成する
6. ブラウザセッションを作成してテストする
注意事項:
- エンドポイントがHTTP/HTTPSの場合は、WSS(wss://...)に変換する
- エンドポイントがない場合は、https://portal.salad.comにアクセスしてコンテナグループを作成するよう案内する
- SaladCloudを使用せずにローカルテストを行う場合は、Dockerでローカルブラウザサーバーを実行するよう支援する
事前構築済みDockerイメージの使用
両方のコンポーネントについて、GitHub Container Registryに事前構築済みのDockerイメージが用意されています。
Dockerイメージ
| コンポーネント |
イメージ |
プラットフォーム |
| ブラウザサーバー |
ghcr.io/saladtechnologies/mcproxy/browser-server:latest |
linux/amd64 |
| MCPサーバー |
ghcr.io/saladtechnologies/mcproxy/mcp-server:latest |
linux/amd64, linux/arm64 |
Dockerでブラウザサーバーを実行する
docker run -d \
--name mcproxy-browser-server \
-p 3000:3000 \
-e AUTH_TOKEN=your-secret-token \
ghcr.io/saladtechnologies/mcproxy/browser-server:latest
DockerでMCPサーバーを実行する
MCPサーバーは通信にstdioを使用するため、-iフラグを使用して対話的に実行されます。
docker run --rm -i \
--network=host \
-e MCPROXY_AUTH_TOKEN=your-secret-token \
-e MCPROXY_DEFAULT_ENDPOINT=ws://localhost:3000 \
ghcr.io/saladtechnologies/mcproxy/mcp-server:latest
Dockerを使用したMCPクライアントの構成
MCPクライアントをソースから実行する代わりに、Dockerイメージを使用するように構成します。
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"mcproxy": {
"command": "docker",
"args": [
"run", "--rm", "-i", "--network=host",
"-e", "MCPROXY_AUTH_TOKEN=your-secret-token",
"-e", "MCPROXY_DEFAULT_ENDPOINT=wss://your-salad-endpoint.salad.cloud",
"ghcr.io/saladtechnologies/mcproxy/mcp-server:latest"
]
}
}
}
Claude Code (.mcp.json):
{
"mcpServers": {
"mcproxy": {
"command": "docker",
"args": [
"run", "--rm", "-i", "--network=host",
"-e", "MCPROXY_AUTH_TOKEN=your-secret-token",
"-e", "MCPROXY_DEFAULT_ENDPOINT=wss://your-salad-endpoint.salad.cloud",
"ghcr.io/saladtechnologies/mcproxy/mcp-server:latest"
]
}
}
}
完全なローカルDockerセットアップ
Dockerを使用してすべてをローカルでテストするには(ビルド不要):
docker run -d \
--name mcproxy-browser-server \
-p 3000:3000 \
-e AUTH_TOKEN=test-token \
ghcr.io/saladtechnologies/mcproxy/browser-server:latest
docker stop mcproxy-browser-server && docker rm mcproxy-browser-server
📚 ドキュメント
ブラウザサーバー(環境変数)
| 変数 |
デフォルト |
説明 |
PORT |
3000 |
WebSocketサーバーのポート |
AUTH_TOKEN |
(必須) |
認証用の共有シークレット |
MAX_CONTEXTS |
10 |
コンテナごとの最大ブラウザコンテキスト数 |
CONTEXT_TTL_MS |
1800000 |
コンテキストのタイムアウト(30分) |
HEALTH_PORT |
8080 |
ヘルス/準備状態チェックのHTTPポート |
ヘルスチェックエンドポイント
ブラウザサーバーはHEALTH_PORT(デフォルト8080)でヘルスチェックエンドポイントを公開しています。
| エンドポイント |
説明 |
GET /health |
コンテキスト数を含むヘルスステータスを返します。レスポンス:{"status": "healthy", "contexts": 0, "maxContexts": 10} |
GET /ready |
準備状態プローブ。サーバーが接続を受け入れる準備ができたときに{"ready": true}を返します |
SaladCloud構成:
- 起動プローブ:ポート
8080でGET /ready - サーバーが初期化されたことを確認します
- 生存プローブ:ポート
8080でGET /health - サーバーが正常であることを確認します
MCPサーバー(環境変数)
| 変数 |
デフォルト |
説明 |
MCPROXY_AUTH_TOKEN または AUTH_TOKEN |
(必須) |
認証用の共有シークレット |
MCPROXY_HEARTBEAT_INTERVAL_MS |
30000 |
ハートビート間隔(30秒) |
MCPROXY_COMMAND_TIMEOUT_MS |
30000 |
コマンドのタイムアウト(30秒) |
🔧 技術詳細
アーキテクチャ
┌─────────────────┐ ┌─────────────────────────────────────────────────────┐
│ Agent/Client │ │ Your Machine │
│ (Claude, etc) │────▶│ ┌───────────────────────────────────────────────┐ │
└─────────────────┘ │ │ MCP Server (stdio) │ │
stdio │ │ - Manages WebSocket connections │ │
│ │ - 30s heartbeat keepalive │ │
│ │ - Session ID → connection mapping │ │
│ └──────┬─────────────────────┬──────────────────┘ │
└─────────│─────────────────────│──────────────────────┘
│ WSS │ WSS
┌─────────▼─────────┐ ┌───────▼───────────┐
│ SaladCloud │ │ SaladCloud │
│ (US Region) │ │ (EU Region) │
│ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Browser Srv │ │ │ │ Browser Srv │ │
│ │ + Browsers │ │ │ │ + Browsers │ │
│ └─────────────┘ │ │ └─────────────┘ │
└───────────────────┘ └───────────────────┘
MCPツール
セッション管理
| ツール |
説明 |
browser_create_session |
オプションのブラウザタイプとデバイスエミュレーションで新しいブラウザセッションを作成します。 |
browser_list_sessions |
ブラウザタイプと位置情報を含むすべてのアクティブなセッションをリストします。 |
browser_close_session |
セッションを閉じてリソースを解放します。 |
browser_list_devices |
モバイルエミュレーション用のすべての利用可能なデバイス名をリストします。 |
browser_get_capabilities |
サーバーの機能を取得し、バージョン不一致をチェックします。 |
browser_create_sessionのパラメータ:
endpoint(オプション):WebSocketエンドポイントURL(指定されていない場合はMCPROXY_DEFAULT_ENDPOINTを使用)
browser_type(オプション):chromium(デフォルト)、firefox、またはwebkit(Safari)
device(オプション):エミュレートするデバイス(例:"iPhone 15"、"Pixel 7"、"iPad Pro 11")
viewport(オプション):ピクセル単位の{ width, height }(デバイスが設定されている場合は無視されます)
userAgent(オプション):カスタムユーザーエージェント文字列(デバイスとランダムを上書きします)
randomUserAgent(オプション):ランダムな現実的なユーザーエージェントを使用します。
isMobile(オプション):モバイルブラウザをエミュレートします。
hasTouch(オプション):タッチイベントを有効にします。
ナビゲーション
| ツール |
説明 |
browser_navigate |
オプションのCloudflare自動待機を使用してURLに移動します。 |
browser_go_back |
履歴を戻ります。 |
browser_go_forward |
履歴を進みます。 |
browser_reload |
現在のページを再読み込みします。 |
browser_navigateのパラメータ:
session_id(必須):セッションID
url(必須):移動するURL
wait_until(オプション):load、domcontentloaded、またはnetworkidle
wait_for_cloudflare(オプション):Cloudflareのチャレンジが完了するまで自動的に待機します。
cloudflare_timeout(オプション):最大待機時間(ミリ秒)(デフォルト:15000)
インタラクション(セレクターベース)
| ツール |
説明 |
browser_click |
CSSセレクターで要素をクリックします。 |
browser_type |
セレクターで入力フィールドにテキストを入力します。 |
browser_select |
ドロップダウンオプションを選択します。 |
browser_hover |
要素の上にマウスをホバーします。 |
browser_scroll |
ページまたは要素をスクロールします。 |
インタラクション(座標ベース)
これらのツールは相対座標(0 - 1の範囲) を使用するため、ビジョンエージェントは解像度を気にせずにスクリーンショットに基づいてクリックできます。
x = 0は左エッジ、x = 1は右エッジ
y = 0は上エッジ、y = 1は下エッジ
| ツール |
説明 |
browser_click_at |
相対座標(0 - 1の範囲)でクリックします。 |
browser_double_click_at |
座標でダブルクリックします。 |
browser_move_mouse |
座標にマウスを移動します。 |
browser_drag |
ある位置から別の位置にドラッグします。 |
ビジョンエージェントの例のワークフロー:
1. browser_screenshot() # スクリーンショットを取得する
2. browser_click_at(0.5, 0.3) # 中央上部をクリックする
3. browser_keyboard_type("hello") # フォーカスしている場所にテキストを入力する
4. browser_keyboard_press("Enter") # 送信する
キーボード(人間らしいテキスト入力)
これらのツールは現在フォーカスされている要素にテキストを入力します(セレクターは必要ありません)。これはより人間らしい方法です。
| ツール |
説明 |
browser_keyboard_type |
現在のフォーカス位置にテキストを入力します。 |
browser_keyboard_press |
キーを押します(Enter、Tab、Escape、矢印、またはControl + aなどのコンボ) |
browser_keyboard_down |
キーを押し続けます(修飾キー用) |
browser_keyboard_up |
押し続けていたキーを離します。 |
人間らしいオプション:
ほとんどのインタラクションツールは、humanize: trueをサポートしており、自然で人間らしい動作を実現します。
- Click/Click_at:ターゲットに自然な曲線のマウス移動
- Type/Keyboard_type:キーストローク間にランダムな遅延(50 - 150ms)
- Scroll:自然なタイミングで小刻みにスムーズなスクロール
- Move_mouse/Drag:加速/減速を伴うベジェ曲線のパス
コンテンツ抽出
| ツール |
説明 |
browser_screenshot |
スクリーンショットを撮ります(base64 PNGを返し、ファイルに保存できます) |
browser_get_content |
HTMLコンテンツを取得します。 |
browser_get_text |
表示されているテキストを取得します。 |
browser_evaluate |
JavaScriptを実行します。 |
待機
| ツール |
説明 |
browser_wait_for_selector |
要素が表示されるまで待機します。 |
browser_wait_for_navigation |
ナビゲーションが完了するまで待機します。 |
クッキー管理
| ツール |
説明 |
browser_get_cookies |
セッションからクッキーを取得します(オプションでURLでフィルタリング可能) |
browser_set_cookies |
セッションにクッキーを設定します(認証状態の復元用) |
browser_clear_cookies |
セッションからすべてのクッキーをクリアします。 |
クッキーの永続化の例:
# ログイン後にクッキーを保存する
cookies = browser_get_cookies(session_id)
# クッキーをどこかに保存する...
# 後でセッションを復元する
browser_set_cookies(session_id, cookies)
browser_navigate(session_id, "https://example.com/dashboard")
CAPTCHA処理
| ツール |
説明 |
browser_check_captcha |
ページ上のCAPTCHAをチェックし、エージェント分析用のスクリーンショットを返します。 |
browser_solve_captcha |
画像を分析した後、CAPTCHAの解を送信します。 |
CAPTCHAのフロー:
browser_navigateが自動的にCAPTCHAを検出し、スクリーンショットを返します。
- エージェントがビジョン機能を使用してCAPTCHA画像を分析します。
- エージェントが解を指定して
browser_solve_captchaを呼び出します。
- 必要に応じて、
browser_check_captchaでページを再チェックできます。
サポートされているCAPTCHAの種類:reCAPTCHA、hCaptcha、Cloudflare Turnstile、FunCaptcha、および一般的な画像/テキストCAPTCHA。
MCPクライアントの構成
git clone https://github.com/SaladTechnologies/mcproxy.git
cd mcproxy
npm install
npm run build
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)または%APPDATA%\Claude\claude_desktop_config.json(Windows)に追加します。
{
"mcpServers": {
"mcproxy": {
"command": "node",
"args": ["/path/to/mcproxy/mcp-server/dist/index.js"],
"env": {
"MCPROXY_AUTH_TOKEN": "your-secret-token",
"MCPROXY_DEFAULT_ENDPOINT": "wss://your-salad-endpoint.salad.cloud"
}
}
}
}
Claude Code (VS Code拡張機能)
ワークスペースの.mcp.jsonまたはグローバル設定に追加します。
{
"mcpServers": {
"mcproxy": {
"command": "node",
"args": ["./mcp-server/dist/index.js"],
"env": {
"MCPROXY_AUTH_TOKEN": "your-secret-token",
"MCPROXY_DEFAULT_ENDPOINT": "wss://your-salad-endpoint.salad.cloud"
}
}
}
}
Cursor
CursorのMCP設定(~/.cursor/mcp.json)に追加します。
{
"mcpServers": {
"mcproxy": {
"command": "node",
"args": ["/path/to/mcproxy/mcp-server/dist/index.js"],
"env": {
"MCPROXY_AUTH_TOKEN": "your-secret-token",
"MCPROXY_DEFAULT_ENDPOINT": "wss://your-salad-endpoint.salad.cloud"
}
}
}
}
Windsurf
WindsurfのMCP構成に追加します。
{
"mcpServers": {
"mcproxy": {
"command": "node",
"args": ["/path/to/mcproxy/mcp-server/dist/index.js"],
"env": {
"MCPROXY_AUTH_TOKEN": "your-secret-token",
"MCPROXY_DEFAULT_ENDPOINT": "wss://your-salad-endpoint.salad.cloud"
}
}
}
}
その他のMCPクライアント
MCP互換のクライアントはすべてmcproxyを使用できます。サーバーは標準のMCPプロトコルを使用してstdioを介して通信します。必要な環境変数:
MCPROXY_AUTH_TOKEN:認証トークン(ブラウザサーバーのAUTH_TOKENと一致する必要があります)
MCPROXY_DEFAULT_ENDPOINT(オプション):デフォルトのWebSocketエンドポイント。これにより、browser_create_session呼び出しごとに指定する必要がなくなります。
SaladCloudへのデプロイ
1. Dockerイメージのビルドとプッシュ
docker build -t your-registry/mcproxy-browser:latest -f browser-server/Dockerfile .
docker push your-registry/mcproxy-browser:latest
2. SaladCloudでコンテナグループを作成する
- SaladCloudポータルにアクセスします。
- 新しいコンテナグループを作成します。
- 以下のように構成します。
- イメージ:
your-registry/mcproxy-browser:latest
- ポート:
3000
- 環境変数:
AUTH_TOKEN:あなたのシークレットトークン
MAX_CONTEXTS:10(コンテナリソースに基づいて調整)
- リソース:ブラウザ自動化には少なくとも2GBのRAMを推奨します。
- ネットワーキング:コンテナゲートウェイを有効にします。
- 起動プローブ:ポート
8080でHTTP GET /ready
- 生存プローブ:ポート
8080でHTTP GET /health
- 希望するリージョンにデプロイします。
3. エンドポイントをメモする
各コンテナグループには、次のようなエンドポイントがあります。
wss://your-org-abc123.salad.cloud
ブラウザセッションを作成するときにこれらのエンドポイントを使用します。
💻 使用例
設定が完了したら、Claudeに以下のように依頼できます。
基本的なセッション作成
wss://my-salad-endpoint.salad.cloudでブラウザセッションを作成してください。
Claudeは応答でブラウザタイプと位置情報を確認できます。
{
"sessionId": "abc-123",
"endpoint": "wss://my-salad-endpoint.salad.cloud",
"browserType": "chromium",
"location": {
"ip": "203.0.113.42",
"city": "Salt Lake City",
"region": "Utah",
"regionCode": "UT",
"country": "United States",
"countryCode": "US",
"timezone": "America/Denver",
"isp": "Example ISP"
}
}
モバイルデバイスエミュレーション
iPhone 15のブラウザセッションを作成し、example.comに移動してください。
スクリーンショットを撮ってモバイルレイアウトを確認してください。
名前に「iPad」が含まれる利用可能なデバイスをリストしてください。
iPad Proをエミュレートするセッションを作成し、サイトのレンダリングを確認してください。
人間らしいブラウジング
セッションを作成し、ログインページに移動してください。人間らしいタイピングでユーザー名とパスワードを入力し、人間らしいクリックでフォームを送信してください。
これにより、ボット検出を回避できます。
Cloudflareで保護されたサイト
wait_for_cloudflareを有効にして、このCloudflareで保護されたサイトに移動してください。
最大20秒間、チャレンジが自動的に完了するのを待ってください。
複数ブラウザテスト
wss://my-salad-endpoint.salad.cloudでChromiumセッションとFirefoxセッションを作成してください。
両方をexample.comに移動させ、レンダリングを比較するためにスクリーンショットを撮ってください。
地理的に分散した価格比較
wss://my-salad-endpoint.salad.cloudで3つのブラウザセッションを作成してください(異なるレプリカに接続されます)。
セッションをリストし、どの場所にあるかを教えてください。
次に、カリフォルニアのセッションを使用してapple.comで「iPhone 15」の価格を確認し、テキサスのセッションを使用して同じ製品の価格を確認してください。
税の違いを含めて価格を比較してください。
位置情報によるセッション参照
すべてのブラウザセッションをリストしてください。
ユタ州のセッションを使用してnetflix.comに移動してください。
ニューヨークのセッションのスクリーンショットを撮ってください。
クッキーベースのセッション永続化
ウェブサイトにログインしてから、クッキーを保存してください。後で再度ログインせずにセッションを復元するために使用します。
トラブルシューティング
接続タイムアウト
セッションが予期せず切断された場合:
- ハートビート間隔(デフォルト30秒)がSaladのアイドルタイムアウト(100秒)より短いことを確認してください。
- SaladCloudエンドポイントへのネットワーク接続を確認してください。
- コンテナログを確認してエラーをチェックしてください。
ボット検出
サイトが自動化を検出した場合:
- ステルスプラグインがほとんどのケースを自動的に処理します。
- クリック、タイプ、スクロールアクションで
humanize: trueを使用して、人間らしい動作を実現します。
- セッションを作成するときに
randomUserAgent: trueを試して、フィンガープリントをローテーションさせます。
- モバイルデバイスエミュレーション(
device: "iPhone 15")を使用する - モバイルブラウザはしばしばより信頼されます。
- Cloudflareで保護されたサイトの場合は、ナビゲート時に
wait_for_cloudflare: trueを使用します。
Cloudflareチャレンジ
Cloudflareのチャレンジが完了しない場合:
cloudflare_timeoutを増やします(デフォルトは15秒)。
- 一部のチャレンジにはインタラクションが必要です - インタラクティブなCAPTCHAをチェックしてください。
- 別のブラウザタイプ(FirefoxまたはWebKit)を試してみてください。
browser_check_captchaを使用して、存在するチャレンジのタイプを確認してください。
バージョン不一致
予期しない動作や機能が欠落している場合:
browser_get_capabilitiesを使用して、サーバーのバージョンとサポートされている機能を確認してください。
- ツールは、ブラウザサーバーとMCPサーバーのバージョンが不一致の場合に警告します。
- 古い方のコンポーネントを更新してください(応答に推奨事項が提供されます)。
networkidleを使用したナビゲーションエラー
wait_until: networkidleを使用してナビゲーションがnet::ERR_ABORTEDで失敗した場合:
- 動的なコンテンツや継続的なネットワークアクティビティのあるサイトは、「ネットワークアイドル」に到達しないことがあります。
- 代わりに
loadまたはdomcontentloadedを使用してください(デフォルトはdomcontentloaded)。
networkidleは静的なページまたはすべてのリソースが完全に読み込まれる必要がある場合に最適です。
- ほとんどのユースケースでは、デフォルトの
domcontentloadedが最も高速で信頼性が高いです。
スクリーンショットとファイル処理
browser_screenshotからのスクリーンショットはbase64で返され、MCP応答内にインラインで表示されます。
- インライン画像の表示は自動的に機能します -
present_filesや同様のツールを使用する必要はありません。
- オプションの
file_pathパラメータは、便利のためにディスクに保存しますが、base64応答が主要な出力です。
file_pathを使用する場合、ファイルはMCPサーバーを実行しているマシン(あなたのローカルマシン)に保存され、リモートブラウザサーバーではありません。
メモリ問題
ブラウザサーバーがメモリ不足になった場合:
- SaladCloudでコンテナのメモリ割り当てを増やします(重い自動化には4GB以上を推奨)。
MAX_CONTEXTSを減らして、同時実行するブラウザコンテキストを制限します。
- セッションが終了したら
browser_close_sessionで閉じます。
- 同じセッション内で異なるサイトを訪問する間に
browser_clear_cookiesを使用します。
📄 ライセンス
MIT