隐身浏览器服务

一个提供隐身网络浏览能力的双浏览器引擎服务,支持自动绕过机器人检测,适用于数据抓取、内容提取和自动化研究。

  • by Axe240-commits
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 Axe240-commits/stealth-browser-mcp

使用说明

隐形浏览器MCP服务器

一种使用双浏览器引擎提供隐形网页浏览功能的模型上下文协议(MCP)服务器-- Patchright (铬)和 迷彩 (Firefox)-具有自动机器人检测旁路。

专为配合使用而设计 克劳德代码 以及其他MCP兼容的AI代理。

特性

  • 双引擎架构 --Patchright(Chromium)作为主要引擎,Camoufox(Firefox)作为后备,具有更强的抗指纹识别能力
  • 自动机器人块检测 --检测Cloudflare、验证码和其他机器人保护;在以下情况下自动重试Firefox engine: auto
  • 通过Xvfb实现头部模式 --运行真实的浏览器窗口(非无头)以击败指纹检测
  • 18个MCP工具 --浏览、交互、提取、抓取、爬行、结构化数据提取、会话管理、持久配置文件状态保存/加载/列表/删除、X/Twitter搜索提取助手、启发式主题研究摘要、线程阅读器、深度主题研究和保存的报告包
  • 三层内容提取 --trafilatura→ 可读性→ innertext回退链
  • SSRF硬化 --DNS解析验证阻止本地主机、私有IP、云元数据、, file://
  • 会话池 --每个引擎最多5个独立的BrowserContext会话,空闲时间为10分钟
  • 智能截断 --段落边界截断为50K个字符的大页面
  • 验证码检测 --检测Cloudflare旋转栅门、reCAPTCHA、hCaptcha;结构化报告 captcha_detected 旗帜
  • 自动清理 --空闲会话在10分钟后被驱逐,崩溃的浏览器自动重启

工具

browse

导航到一个URL,并将页面内容作为干净的标记返回。

参数 类型 必填 说明
url string yes 要导航到的URL(仅限http/https)
session_id string no 重用现有会话。如果省略,则创建一个新的
wait_for string no 提取前要等待的CSS选择器
engine string 否 auto (默认), chromium,或 firefox

退货: url, title, content, session_id, truncated, captcha_detected, extraction_method, timing_ms, status_code, engine

interact

在会话中与当前页面交互。

参数 类型 必填 说明
session_id string yes 以前的会话 browse 呼叫
action string yes 以下之一: click, type, select, hover, scroll
selector string yes 目标元素的CSS选择器
value string 否 必填 type 和 select.为 scroll,像素量

退货: success, session_id, action_performed, page_url, timing_ms

extract

在不重新导航的情况下从当前页面重新提取内容。用这个代替 browse 当你已经在页面上的时候。

参数 类型 必填 说明
session_id string yes 要提取的会话
mode string 否 auto (默认), article,或 text (原始内文本)

退货: content, session_id, url, extraction_method, truncated

close_session

关闭浏览器会话并释放其资源。

参数 类型 必填 说明
session_id string yes 要关闭的会话

退货: status, session_id

save_session_state

将活动会话的Cookie和本地存储保存到指定的配置文件中。

参数 类型 必填 说明
session_id string yes 要持久的会话
profile_name string yes 要保存的安全配置文件名

退货: status, session_id, profile_name, storage_state_path, meta

load_session_state

从以前保存的配置文件创建新会话。

参数 类型 必填 说明
profile_name string yes 已保存的配置文件名称
session_id string no 可选自定义会话ID
engine string 否 chromium (默认)或 firefox

退货: status, session_id, profile_name, engine, meta

list_saved_profiles

列出磁盘上保存的持久配置文件。

退货: profiles, count

delete_saved_profile

从磁盘中删除已保存的配置文件。

参数 类型 必填 说明
profile_name string yes 已保存的配置文件名称

退货: status, profile_name

search_x

打开X搜索结果页面进行查询,并返回结构化推文卡片。

参数 类型 必填 说明
query string yes 搜索查询
mode string 否 latest (默认)或 top
max_items int no 要提取的最大推文数(1-50,默认值20)
scroll_rounds int no 其他滚动/收集轮次(0-10,默认为0)
session_id string no 重用现有会话
profile_name string no 将持久登录配置文件加载到新会话中
engine string 否 auto (默认), chromium,或 firefox

退货: query, mode, search_url, session_id, tweets, extracted_count, scroll_rounds_completed, captcha_detected, engine

extract_x_search_results

从现有X搜索会话的当前页面中提取结构化推文卡。

参数 类型 必填 说明
session_id string yes X搜索页面上已存在活动会话
max_items int no 要提取的最大推文数(1-50,默认值20)

退货: session_id, tweets, extracted_count, page_url, page_title

research_x_topic

运行X搜索,并从提取的推文中生成一个轻量级的启发式主题摘要。

参数 类型 必填 说明
query string yes 搜索查询
mode string 否 latest (默认)或 top
max_items int no 要提取的最大推文数(1-50,默认值20)
scroll_rounds int no 其他滚动/收集轮次(0-10,默认为0)
session_id string no 重用现有会话
profile_name string no 将持久登录配置文件加载到新会话中
engine string 否 auto (默认), chromium,或 firefox

退货: 一切从 search_x 加 research, normalized,以及 report_markdown

read_x_thread

打开推文/线程URL,从详细页面中提取可见的主推文和回复。

参数 类型 必填 说明
url string yes X推特/线程URL
max_items int no 要提取的最大可见推文数(1-50,默认值20)
session_id string no 重用现有会话
profile_name string no 将持久登录配置文件加载到新会话中
engine string 否 auto (默认), chromium,或 firefox

退货: main_tweet, replies, reply_count_extracted,以及页面元数据

research_x_topic_deep

运行X搜索,选择一些高信号推文,加载他们的线程页面,并生成更丰富的深度研究摘要。

参数 类型 必填 说明
query string yes 搜索查询
mode string 否 latest (默认)或 top
max_items int no 要收集的最大搜索推文数
scroll_rounds int no 其他搜索滚动
deep_dive_count int no 要检查的线程URL数(默认值3)
thread_items int no 每个线程要提取的最大推文数
session_id string no 重用现有会话
profile_name string no 将持久登录配置文件加载到新会话中
engine string 否 auto (默认), chromium,或 firefox

退货: deep_dive_candidates, threads, deep_research, normalized,以及 report_markdown 除了基本搜索输出之外

save_x_research_report

运行主题研究(普通或深度)并将JSON+markdown报告包保存到磁盘。

参数 类型 必填 说明
query string yes 搜索查询
deep bool 否 如果为真,则使用深度研究工作流程
mode string 否 latest (默认)或 top
max_items int no 要收集的最大推文数
scroll_rounds int no 其他搜索滚动
deep_dive_count int no 线程深度挖掘计数
thread_items int no 每个线程的最大推文数
session_id string no 重用现有会话
profile_name string no 将持久登录配置文件加载到新会话中
engine string 否 auto (默认), chromium,或 firefox
report_name string no 可选自定义输出名称

退货: 研究成果+ saved_report 路径

list_saved_x_reports

从磁盘中列出已保存的研究报告包。

退货: reports, count

scrape_webpage

导航到URL,提取请求格式的内容,并自动关闭会话。

参数 类型 必填 说明
url string yes 要抓取的URL(仅限http/https)
output_format string 否 markdown (默认), text, html,或 links
session_id string no 重用会话。如果省略,则创建自动关闭的临时会话
wait_for string no 提取前要等待的CSS选择器
engine string 否 auto (默认), chromium,或 firefox

退货: url, title, content, session_id, status_code, timing_ms, extraction_method, engine

extract_structured_data

从网页中提取结构化DOM数据(元数据、链接、表、JSON-LD等)。

参数 类型 必填 说明
url string yes 要提取的URL(仅限http/https)
session_id string no 重用会话。如果省略,则创建临时会话
include 列出 否 要包含的节。默认值:全部。选项: metadata, og_tags, json_ld, headings, links, tables, forms
wait_for string no 提取前要等待的CSS选择器
engine string 否 auto (默认), chromium,或 firefox

退货: url, title, session_id, timing_ms, engine+请求的数据段

crawl_pages

从URL开始,通过BFS抓取多个页面。

参数 类型 必填 说明
url string yes 起始URL(仅限http/https)
max_pages int no 可抓取的最大页面数(1-20,默认值5)
link_pattern string no 用于过滤链接href的正则表达式
output_format string 否 markdown (默认), text, html,或 links
same_domain bool no 只关注相同的域链接(默认值:true)
engine string 否 auto (默认), chromium,或 firefox

退货: pages (列表 {url, title, content, status_code}), total_pages, total_timing_ms, engine

安装

先决条件

系统库 (Ubuntu/Debian/WSL2):

sudo apt-get install -y libnspr4 libnss3 libatk1.0-0 libatk-bridge2.0-0 \
  libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
  libpango-1.0-0 libcairo2 libasound2t64 xvfb

Python 3.12+ 和 紫外线 (推荐)或pip。

设置

git clone https://github.com/Axe240-commits/stealth-browser-mcp.git
cd stealth-browser-mcp
chmod +x setup.sh
./setup.sh

或手动:

uv venv
uv pip install -e ".[dev]"
.venv/bin/python -m patchright install chromium

验证

# Run tests
.venv/bin/python -m pytest tests/ -v

# Start server (will wait for MCP stdio input)
.venv/bin/python -m stealth_browser

使用克劳德代码注册

添加 ~/.claude/mcp_servers.json:

{
  "stealth-browser": {
    "type": "stdio",
    "command": "/path/to/stealth-browser-mcp/.venv/bin/python",
    "args": ["-m", "stealth_browser"]
  }
}

然后在中添加权限 ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "mcp__stealth-browser__browse",
      "mcp__stealth-browser__interact",
      "mcp__stealth-browser__extract",
      "mcp__stealth-browser__close_session",
      "mcp__stealth-browser__save_session_state",
      "mcp__stealth-browser__load_session_state",
      "mcp__stealth-browser__list_saved_profiles",
      "mcp__stealth-browser__delete_saved_profile",
      "mcp__stealth-browser__search_x",
      "mcp__stealth-browser__extract_x_search_results",
      "mcp__stealth-browser__research_x_topic",
      "mcp__stealth-browser__read_x_thread",
      "mcp__stealth-browser__research_x_topic_deep",
      "mcp__stealth-browser__save_x_research_report",
      "mcp__stealth-browser__list_saved_x_reports",
      "mcp__stealth-browser__scrape_webpage",
      "mcp__stealth-browser__extract_structured_data",
      "mcp__stealth-browser__crawl_pages"
    ]
  }
}

重新启动克劳德代码。工具将立即可用。

建筑

┌─────────────────────────────────────────────────┐
│  Claude Code / MCP Client                       │
│                                                 │
│  browse ─ interact ─ extract ─ close_session    │
│  scrape_webpage ─ extract_structured_data       │
│  crawl_pages                                    │
└────────────────┬────────────────────────────────┘
                 │ stdio (JSON-RPC)
┌────────────────▼────────────────────────────────┐
│  server.py — FastMCP Server (7 tools)           │
│  ├── security.py — SSRF validation (every URL)  │
│  ├── session.py — per-session lock + state      │
│  ├── browser_manager.py — dual engine pool      │
│  ├── extractor.py — 3-tier content extraction   │
│  ├── dom_extractor.py — structured DOM data     │
│  └── config.py — configuration                  │
└───────┬─────────────────┬───────────────────────┘
        │                 │
┌───────▼──────┐  ┌───────▼──────┐
│  Patchright   │  │  Camoufox    │
│  (Chromium)   │  │  (Firefox)   │
│  Primary      │  │  Fallback    │
└───────┬──────┘  └───────┬──────┘
        │                 │
┌───────▼─────────────────▼───────────────────────┐
│  Xvfb :99 — 1920x1080 (headed mode)            │
└─────────────────────────────────────────────────┘

双引擎和自动回退

随着 engine: auto (默认),每个请求:

  1. 尝试 修补漆(铬) 首先——快速、低开销
  2. 检查机器人程序块信号:HTTP 403、标题关键字(“请稍等”、“需要注意”)、空内容
  3. 如果被阻止,将自动重试 迷彩(Firefox) 具有更强的抗指纹识别能力

对于 crawl_pages,引擎切换发生在第一页,并在爬行的其余部分保持不变。

内容提取管道

trafilatura (best for articles, tables, links)
    ↓ fallback if < 200 chars
readability-lxml + html2text (complex HTML)
    ↓ fallback if < 200 chars
page.inner_text('body') (SPAs, JS-rendered content)

会话管理

  • 两个持久浏览器 在MCP服务器启动时启动(Chromium+Firefox)
  • 每 browse() 不打电话 session_id 创建新 BrowserContext (~100ms)
  • 会话是隔离的(单独的Cookie、存储、状态)
  • 马克斯 5个并发会话,如果容量最大,最年长的被驱逐
  • 空闲会话在之后被驱逐 10分钟
  • 每个会话的所有操作都通过序列化 asyncio.Lock
  • 每个会话跟踪其引擎类型(chromium 或 firefox)

安全(SSRF保护)

每个URL在导航前都经过验证:

  1. 方案检查 --只有 http 和 https 允许
  2. DNS解析 --主机名解析为实际IP
  3. IP验证 --根据专用/保留范围检查所有已解析的IP
  4. 重定向验证 --在每次跳转时重新验证重定向

此 路 不通:

  • localhost, 127.0.0.1, ::1
  • 私人范围(10.x, 172.16.x, 192.168.x)
  • 云元数据(169.254.169.254)
  • 链接本地、多播、保留IP
  • file://, data://, javascript://, ftp://

AI代理的使用技巧

  • 使用 extract 重读同一页——不要打电话 browse 再次
  • 使用 browse 仅用于实际导航(新URL或页面更改)
  • 重用 session_id 跨相关业务
  • 总是打电话 close_session 当释放资源时
  • 使用 scrape_webpage 进行一次刮擦(自动关闭会话)
  • 使用 crawl_pages 从起始URL抓取多个页面
  • 默认导航使用 domcontentloaded (快速、可靠)——使用 wait_for 如果你需要一个特定的元素

项目结构

stealth-browser-mcp/
├── pyproject.toml              # Dependencies, build config
├── setup.sh                    # One-command setup
├── src/stealth_browser/
│   ├── __init__.py
│   ├── __main__.py             # Entry: python -m stealth_browser
│   ├── server.py               # MCP server, 7 tools, lifespan
│   ├── browser_manager.py      # Dual engine lifecycle, context pool
│   ├── session.py              # Session state, locking, actions
│   ├── extractor.py            # 3-tier content extraction
│   ├── dom_extractor.py        # Structured DOM data extraction
│   ├── security.py             # SSRF-hardened URL validation
│   ├── config.py               # Configuration dataclass
│   └── proxy.py                # Stub (Phase 2: Tor)
└── tests/
    ├── test_security.py        # URL/IP validation tests
    ├── test_extractor.py       # Extraction mode/fallback tests
    ├── test_dom_extractor.py   # DOM structured data tests
    └── test_server_helpers.py  # Server helper function tests

配置

默认值 config.py --不需要配置文件:

设置 默认值 说明
headless False 头部模式(Xvfb)可实现更好的隐形效果
use_xvfb True 自动启动Xvfb用于头部模式
max_sessions 5 最大并发浏览器会话数
session_timeout_minutes 10 空闲会话驱逐超时
navigation_timeout_ms 30000 页面加载超时
wait_until domcontentloaded 导航等待策略
max_content_length 50000 内容截断限制(字符)
block_media True 阻止图像/字体/媒体以提高速度
camoufox_enabled True 启用Firefox回退引擎
crawl_max_pages_limit 20 爬行盖
crawl_per_page_max 10000 每个已爬网页面的内容限制

依赖项

包装 用途
主控程序 MCP服务器框架(Anthropic)
patchright 隐形剧作家叉子(铬合金)
迷彩 防指纹Firefox(回退引擎)
特拉菲拉图拉 文章/内容提取
可读性lxml 回退HTML提取
html2text HTML到markdown的转换

故障排除

浏览器无法启动: error while loading shared libraries

Chromium需要默认情况下未安装在最小Linux/WSL2上的系统库:

error while loading shared libraries: libnspr4.so: cannot open shared object file

解决方案:

sudo apt-get install -y libnspr4 libnss3 libatk1.0-0 libatk-bridge2.0-0 \
  libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
  libpango-1.0-0 libcairo2 libasound2t64 xvfb

迷彩服无法启动

迷彩服需要 xvfb 对于头部模式:

sudo apt-get install -y xvfb

如果迷彩仍然失败,它会优雅地回落——仅Chromium模式仍然有效。

克劳德代码中未显示MCP服务器

服务器必须在中注册 ~/.claude/mcp_servers.json:

{
  "stealth-browser": {
    "type": "stdio",
    "command": "/absolute/path/to/.venv/bin/python",
    "args": ["-m", "stealth_browser"]
  }
}

添加后, 重新启动克劳德代码 --MCP服务器仅在启动时加载。

工具显示“权限被拒绝”

将所有7个工具添加到 ~/.claude/settings.json 权限(请参阅上面的注册部分)。

页面内容为空或太短

  • 尝试 extract 随着 mode="text" 适用于SPA/JS密集页面
  • 添加 wait_for 带有CSS选择器的参数,用于等待动态内容
  • 尝试 engine: firefox --一些网站对迷彩效果更好
  • 默认 domcontentloaded 不等待延迟加载的内容——传递一个在页面完全呈现后出现的选择器

机器人在两个引擎上都被阻塞了

如果 engine: auto 如果网站回退到Firefox并仍被阻止,则可能需要:

  • 不同的IP/代理(第2阶段)
  • 手动验证码解决
  • 特定Cookie/身份验证

未找到会话

在10分钟不活动或达到5个会话限制后,会话将被驱逐。如果你得到 "Session 'xyz' not found",创建一个新的 browse.

第二阶段(计划中)

  • screenshot 工具——用于验证码/同意调试
  • evaluate_js 工具——目标DOM查询
  • session_info 工具--列出活动会话和状态
  • 每次工具调用硬超时保护
  • 代理/Tor选择加入支持

许可证

麻省理工学院