🚀 MCProxy
MCProxy 是一個基於 MCP(模型上下文協議)的項目,為 SaladCloud 提供遠程無頭瀏覽器會話服務。該項目允許 AI 代理控制運行在地理分佈式 SaladCloud 容器上的瀏覽器,可用於區域價格檢查、地理定位內容驗證以及特定位置的網頁自動化等場景。
🚀 快速開始
1. 安裝依賴
npm install
2. 構建項目
npm run build
3. 本地測試
使用 Docker 在本地啟動瀏覽器服務器:
docker compose up --build
倉庫中包含一個預配置好的 .mcp.json 文件,可用於與 Docker Compose 設置配合使用。若要與 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、城市、州/地區、國家、時區、互聯網服務提供商)。代理可以按位置引用會話(例如,“使用猶他州的會話”)。
- 隱身模式:通過 WebGL 欺騙、導航器覆蓋和逼真的瀏覽器指紋等高級反檢測技術。
- 人性化交互:點擊、輸入和滾動等操作可選擇模擬人類行為,避免被檢測為機器人。
- Cloudflare 自動等待:自動等待 Cloudflare 挑戰完成。
- Cookie 持久化:保存和恢復 Cookie 以進行會話管理和身份驗證。
- 逼真的用戶代理:使用最新的瀏覽器指紋數據自動生成逼真的用戶代理。
- 會話親和性:WebSocket 連接將會話固定到特定的容器副本。
- 心跳保活:每 30 秒發送一次心跳包以保持連接(Salad 網關的空閒超時時間為 100 秒)。
- 多區域支持:連接到不同的 Salad 部署,實現地理分佈式瀏覽。
- 版本兼容性:具備能力報告和自動版本不匹配檢測功能。
- 33 個 MCP 工具:提供完整的瀏覽器自動化功能,包括基於座標的點擊,適用於視覺代理。
📦 安裝指南
前提條件
- Docker(推薦)或 Node.js 20+
- SaladCloud 賬戶(用於生產部署)
AI 輔助設置
將以下提示覆制並粘貼到您的 AI 代理中,以幫助您配置 mcproxy:
Help me set up mcproxy for remote browser automation.
MCP Client: [Claude Desktop / Claude Code / Cursor / Windsurf / other]
SaladCloud Endpoint: [your endpoint URL, or "none" if you need to create one]
Setup steps:
1. Check if I have Docker installed
2. If Docker is available, use the pre-built images from ghcr.io/saladtechnologies/mcproxy
3. If Docker is not available, clone and build from https://github.com/SaladTechnologies/mcproxy
4. Configure the MCP server JSON for my client
5. Generate a secure AUTH_TOKEN
6. Test by creating a browser session
Notes:
- If my endpoint is HTTP/HTTPS, convert it to WSS (wss://...)
- If I don't have an endpoint, guide me to https://portal.salad.com to create a container group
- For local testing without SaladCloud, help me run a local browser server with Docker
使用預構建的 Docker 鏡像
GitHub 容器註冊表上提供了兩個組件的預構建 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 服務器使用標準輸入輸出進行通信,因此需要使用 -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
💻 使用示例
基本會話創建
Create a browser session at 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"
}
}
移動設備模擬
Create an iPhone 15 browser session and navigate to example.com.
Take a screenshot to see the mobile layout.
List available devices that include "iPad" in the name.
Create a session emulating an iPad Pro and check how the site renders.
人性化瀏覽
Create a session and navigate to the login page. Use humanized typing to
enter the username and password, then humanized click to submit the form.
This helps avoid bot detection.
Cloudflare 保護的網站
Navigate to this Cloudflare-protected site with wait_for_cloudflare enabled.
Wait up to 20 seconds for any challenges to complete automatically.
多瀏覽器測試
Create a Chromium session and a Firefox session at wss://my-salad-endpoint.salad.cloud.
Navigate both to example.com and take screenshots to compare rendering.
地理分佈式價格比較
Create 3 browser sessions at wss://my-salad-endpoint.salad.cloud (it will
connect to different replicas). List the sessions and tell me which locations
they're in.
Then use the session in California to check the price of "iPhone 15" on
apple.com, and use the session in Texas to check the same product. Compare
the prices including any tax differences.
按位置引用會話
List all my browser sessions.
Navigate to netflix.com using the Utah session.
Take a screenshot of the one in New York.
基於 Cookie 的會話持久化
Log into the website, then save the cookies. I'll use them later to
restore the session without logging in again.
📚 詳細文檔
配置
瀏覽器服務器(環境變量)
| 變量 |
默認值 |
描述 |
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 秒) |
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 |
導航到指定 URL,可選擇自動等待 Cloudflare 挑戰完成 |
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 - 150 毫秒)
- 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 |
等待導航完成 |
Cookie 管理
| 工具 |
描述 |
browser_get_cookies |
從會話中獲取 Cookie(可根據 URL 進行過濾) |
browser_set_cookies |
在會話中設置 Cookie(用於恢復身份驗證狀態) |
browser_clear_cookies |
清除會話中的所有 Cookie |
Cookie 持久化示例:
# 登錄後保存 Cookie
cookies = browser_get_cookies(session_id)
# 將 Cookie 存儲到某個位置...
# 稍後,恢復會話
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 協議進行通信。所需的環境變量:
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 內存
- 網絡:啟用容器網關
- 啟動探測器:在端口
8080 上執行 HTTP GET /ready
- 存活探測器:在端口
8080 上執行 HTTP GET /health
- 部署到您想要的區域
3. 記錄您的端點
每個容器組將有一個類似以下的端點:
wss://your-org-abc123.salad.cloud
在創建瀏覽器會話時使用這些端點。
🔧 技術細節
項目結構
mcproxy/
├── shared/ # 共享的 TypeScript 類型
│ └── src/
│ └── protocol.ts # WebSocket 消息類型 + 位置信息
├── browser-server/ # 遠程瀏覽器服務器
│ └── src/
│ ├── browser-manager.ts # Playwright + 隱身功能
│ ├── location-service.ts# IP 地理定位檢測
│ ├── ws-server.ts # WebSocket 服務器
│ ├── command-handler.ts # 命令執行
│ └── index.ts # 入口點
├── mcp-server/ # 本地 MCP 服務器
│ └── src/
│ ├── browser-client.ts # WebSocket 客戶端
│ ├── session-manager.ts # 會話管理 + 位置跟蹤
│ ├── tools/ # MCP 工具定義
│ └── index.ts # 入口點
├── docker-compose.yml # 本地開發
└── package.json # 單倉庫配置
構建
npm run build
npm run build:shared
npm run build:browser-server
npm run build:mcp-server
開發環境運行
npm run dev:browser-server
npm run dev:mcp-server
🔧 故障排除
連接超時
如果會話意外斷開連接:
- 檢查心跳間隔(默認 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 許可證。