@iflow-mcp/mook-wenyu-xiaohongshumcp
v0.1.2
Published
小红书场景的人机浏览自动化 MCP 服务,基于 RoxyBrowser + Playwright 提供最小原子动作与多账号隔离
Readme
HushOps.Servers.XiaoHongShu — 自动化浏览/MCP 服务
面向“小红书(Little Red Book)”相关业务的人机浏览自动化与 MCP 服务。以 RoxyBrowser 提供的多账号隔离(持久化 Context)为基础,通过 Playwright CDP 接入实现稳定、最小的原子动作工具面;截图、快照与选择器健康数据统一沉淀到 artifacts/<dirId> 便于离线验证与审计。
快速开始(TL;DR)
- 做什么:提供稳定的原子浏览动作(打开/导航/点击/输入/截图/快照)与小红书专用采集工具面,支持多账号隔离。
- 为什么有用:最小依赖、MCP 标准工具、可离线验证的工件沉淀,便于在任意编排器中组合业务流程。
- 如何使用:准备 Node 环境与 Roxy API Token,安装依赖并启动 stdio MCP,或直接运行示例脚本。
# 1) 安装依赖
npm install
# 2) 准备环境变量(至少设置 ROXY_API_TOKEN 与 Roxy 连接)
Copy-Item .env.example .env
# 编辑 .env,填写 ROXY_API_TOKEN,设置 ROXY_API_BASEURL 或 ROXY_API_HOST/PORT
# 3) 预检(环境/官方桥接/Playwright 模块)
npm run preflight
# 4) 启动 stdio MCP(供客户端连接)
npm run mcp
# 5) 运行示例(打开并截图)
npm run run:example -- --dir-ids=user --url=https://example.com --limit=2更多命令、环境变量与工具清单见文档下方章节与 AGENTS.md。
目录
- 快速开始(TL;DR)
- 能力总览
- 环境要求
- 安装与最小自检
- 启动与集成(stdio MCP)
- MCP 工具清单
- RoxyBrowser 集成架构
- 常用脚本
- 目录结构
- 测试与质量
- 设计与限制
- 变更要点(0.2.x)
- 人机参数模板
- 有效停留策略
- 外部工作流最佳实践清单
- 故障排查
- 贡献
- 许可证
能力总览
- 多账号隔离:
dirId表示账号窗口;1 个dirId= 1 个持久化 BrowserContext;同 Context 可创建多 Page。 - 原子化工具(前缀+下划线命名):
browser_*、page_*、xhs_*、resources_*。 - Roxy 管理工具(仅用于管理):
roxy_*(工作区/窗口管理)默认注册,无需开关。 - 选择器韧性与拟人化:语义优先选择器(role/name/label/testId/text)→ CSS 兜底;人类化鼠标与输入(可按参数关闭)。
- 工件真源:截图、快照与选择器健康日志统一落盘
artifacts/<dirId>,支持 MCP 资源读取。
环境要求
- Node.js >= 18(建议 22.x)
- 可用的 RoxyBrowser 本地/远程 API 与有效
ROXY_API_TOKEN - 首次安装通过
postinstall自动安装 Playwright Chromium
关键环境变量:
ROXY_API_TOKEN(必填)ROXY_API_BASEURL或ROXY_API_HOST+ROXY_API_PORTROXY_DEFAULT_WORKSPACE_ID(可选,用于默认上下文)SNAPSHOT_MAX_NODES(页面快照节点上限,默认 800)HUMAN_PROFILE(default/cautious/rapid),决定鼠标/滚动/输入节律的默认值HUMAN_TRACE_LOG(可选,设为true将拟人化事件落盘到artifacts/<dirId>/human-trace.ndjson)
完整环境变量列表请参考 .env.example,包括:
- 连接配置:
ROXY_API_*,ROXY_DEFAULT_WORKSPACE_ID,ROXY_DIR_IDS - 并发与超时:
MAX_CONCURRENCY,TIMEOUT_MS - 选择器韧性:
SELECTOR_RETRY_*,SELECTOR_BREAKER_* - 小红书配置:
XHS_SCROLL_*,XHS_SELECT_MAX_SCROLLS,DEFAULT_URL - 日志:
LOG_LEVEL,LOG_PRETTY,MCP_LOG_STDERR - 拟人化:
HUMAN_PROFILE,HUMAN_TRACE_LOG
说明:
ENABLE_ROXY_ADMIN_TOOLS(自 0.2.x 起roxy_*管理工具默认注册,无需开关)- 断路器相关参数以
SELECTOR_BREAKER_*为主;POLICY_*作为全局策略限流/熔断兼容项仍保留(见.env.example注释),两者用途不同。
安装与最小自检
- 安装依赖
npm install- 配置环境变量
Copy-Item .env.example .env
# 编辑 .env,填写 ROXY_API_TOKEN,设置 ROXY_API_BASEURL 或 HOST/PORT- 预检(可选)
npm run preflight- 自检脚本(可选)
npm run check:env- 工具面对照检查(可选)
npm run check:tools- 编码巡检(可选,CI 推荐)
npm run check:encoding启动与集成(stdio MCP)
- 构建(或直接 TS 运行)
npm run build- 启动 MCP Server(stdio)
npm run mcpMCP 工具清单(唯一标准)
浏览器与页面管理
browser_open/browser_close- 打开/关闭浏览器窗口(dirId 映射持久化 Context)page_create/page_list/page_close- 创建/列出/关闭页面page_navigate- 导航到指定 URL
页面交互(支持拟人化)
page_click- 点击元素(支持语义定位:role/name/label/text/testId/selector)page_hover- 悬停元素page_scroll- 滚动页面(支持相对/绝对/元素滚动)page_type- 输入文本(支持 WPM 逐字延时)page_input_clear- 清空输入框
页面信息获取
page_screenshot- 截图(默认仅返回path文本;如需图片数据,传returnImage=true附带image/png)page_snapshot- 可访问性快照(a11y 树 + url/title + 统计信息)
小红书专用
xhs_session_check- 检查会话状态(基于 cookies 和首页加载)xhs_navigate_home- 导航到小红书首页并验证xhs_open_context- 确保浏览器上下文已打开,返回页面数量与首个页面 URL(若存在)xhs_note_extract_content- 提取笔记完整内容(标题/正文/标签/互动数据)
提示:
xhs_note_extract_content采用“API→DOM 兜底”的两段式提取。
- 优先拦截
\/api\/sns\/web\/v1\/feed获取详情;- 当导出链接(如
?xsec_token=...)未触发 API 时,自动从 DOM 解析#detail-title、#detail-desc .note-text、a.tag#hash-tag等;- 返回 JSON 会附带
extraction_method=api|dom,便于上游统计命中率(消费方可忽略额外字段)。
小红书快捷工具(语义化)
xhs_close_modal- 关闭当前笔记详情模态(Esc→关闭按钮→遮罩)xhs_navigate_discover- 导航到“发现”推荐流(含 homefeed 接口软校验)xhs_search_keyword- 站内搜索关键词(拟人化输入 + 接口软校验)xhs_collect_search_results- 在站内搜索后收集前 N 条笔记结果(优先 API 回执,DOM 兜底)xhs_keyword_browse- 关键词浏览(轻量滚动,提升可见文本覆盖)xhs_select_note- 在当前页(首页/发现/搜索)按关键词匹配卡片并点击,优先点击封面,标题兜底;成功判定为“模态优先,其次 URL 进入详情”,返回openedPath="modal"|"url"xhs_note_like/xhs_note_unlike- 点赞 / 取消点赞当前笔记(需模态已打开)xhs_note_collect/xhs_note_uncollect- 收藏 / 取消收藏当前笔记(需模态已打开)xhs_user_follow/xhs_user_unfollow- 关注 / 取关当前笔记作者(需模态已打开)xhs_comment_post- 发表评论(拟人化输入 + 接口软校验,需模态已打开)
示例(命令行脚本):
# 导航到发现页(stdio MCP)
npm run mcp -- --tool xhs_navigate_discover --dirId user
# 站内搜索关键词
npm run mcp:call:search -- --dirId=user --keyword=美食
# 关闭笔记模态(若已打开)
npm run mcp -- --tool xhs_close_modal --dirId user
# 点赞/取关/评论(需笔记详情模态已打开)
npm run mcp -- --tool xhs_note_like --dirId user
npm run mcp -- --tool xhs_user_unfollow --dirId user
npm run mcp -- --tool xhs_comment_post --dirId user --text="写得不错!"资源管理
resources_listArtifacts- 列出 artifacts/ 下的所有文件resources_readArtifact- 读取 artifacts 文件(自动识别图片/文本)
高权限管理工具(默认已注册)
roxy_workspaces_list- 获取工作区列表roxy_windows_list- 获取浏览器窗口列表roxy_window_create- 创建新浏览器窗口
诊断与监控
server_capabilities- 查看适配器信息(adapter/roxyBridge/adminTools)server_ping- 连通性检查与心跳
MCP 资源(Resources)
xhs://artifacts/{dirId}/index- 列出指定 dirId 的所有 artifacts 文件xhs://snapshot/{dirId}/{page}- 获取指定页面的 a11y 快照
示例(默认开启拟人化;两种方式关闭:human=false 或 human.enabled=false,可按需细化参数):
- 打开窗口:
browser_open,{"dirId":"user"} - 打开上下文:
xhs_open_context,{"dirId":"user"}→ 返回{"ok":true,"data":{"opened":true,"pages":1,"url":"https://..."}} - 导航:
page_navigate,{"dirId":"user","url":"https://example.com"} - 语义点击(拟人化):
- 快速关闭:
{"dirId":"user","target":{"text":"登录"},"human":false} - 细化参数:
{"dirId":"user","target":{"text":"登录"},"human":{"enabled":true,"steps":24,"randomness":0.2}}
- 快速关闭:
- 输入(拟人化):
page_type,{"dirId":"user","target":{"role":"textbox","name":"标题"},"text":"今天好开心","human":{"enabled":true,"wpm":180}} - 截图:
page_screenshot(默认仅返回路径;如需图片数据,传returnImage=true) - 快照:
page_snapshot→ 返回url/title/a11y摘要 + 统计
示例参数(速查)
以下为常用工具的入参与返回片段示例(仅展示关键字段,实际返回含标准包裹结构)。
# 浏览器与页面
browser_open {"dirId":"user"}
page_create {"dirId":"user","url":"https://example.com"}
page_list {"dirId":"user"}
page_close {"dirId":"user","pageIndex":0}
page_navigate {"dirId":"user","url":"https://example.com","pageIndex":0}
# 页面交互(语义定位 + 拟人化可选)
page_click {"dirId":"user","target":{"role":"button","name":"登录"}}
page_click(关闭拟人) {"dirId":"user","target":{"text":"登录"},"human":false}
page_hover {"dirId":"user","target":{"selector":".menu-item[data-id='settings']"}}
page_type {"dirId":"user","target":{"role":"textbox","name":"标题"},"text":"今天好开心","human":{"wpm":180}}
page_input_clear {"dirId":"user","target":{"role":"textbox","name":"搜索"}}
page_scroll {"dirId":"user","deltaY":1200,"human":{"segments":6,"perSegmentMs":120}}
# 页面信息获取
page_screenshot {"dirId":"user","fullPage":true,"returnImage":true}
page_snapshot {"dirId":"user","pageIndex":0,"maxNodes":800}page_snapshot 返回示例(节选):
{
"ok": true,
"data": {
"url": "https://example.com",
"title": "Example",
"a11y": { "role": "document", "name": "", "children": [/* ...裁剪... */] },
"stats": { "nodeCount": 801, "roleCounts": {"button": 12}, "landmarks": ["navigation","main"], "clickableCount": 37 }
}
}# 小红书(XHS)
xhs_open_context {"dirId":"user"}
xhs_navigate_home {"dirId":"user"}
xhs_search_keyword {"dirId":"user","keyword":"美食"}
xhs_collect_search_results {"dirId":"user","keyword":"美食","limit":10}
xhs_keyword_browse {"dirId":"user","keywords":["美食","穿搭"]}
xhs_select_note {"dirId":"user","keywords":["咖啡","拉花"]}
xhs_comment_post {"dirId":"user","text":"写得不错!"}
xhs_note_extract_content {"dirId":"user","noteUrl":"https://www.xiaohongshu.com/explore/xxxxxxxx"}xhs_note_extract_content 返回示例(节选,含兜底标记):
{
"ok": true,
"data": {
"note_id": "xxxxxxxx",
"url": "https://www.xiaohongshu.com/explore/xxxxxxxx",
"title": "……",
"content": "……",
"tags": ["…"],
"author_nickname": "…",
"interact_stats": {"likes": 0, "collects": 0, "comments": 0, "shares": 0},
"extracted_at": "2025-11-10T10:00:00.000Z",
"extraction_method": "api" | "dom"
}
}# 资源管理
resources_listArtifacts {"dirId":"user"}
resources_readArtifact {"dirId":"user","path":"test/page-1.png"}
# 管理工具(高权限)
roxy_workspaces_list {"page_index":1,"page_size":20}
roxy_windows_list {"workspaceId":"123","dirIds":"user"}
roxy_window_create {"workspaceId":"123","windowName":"xhs-user","defaultOpenUrl":["https://www.xiaohongshu.com/explore"]}RoxyBrowser 集成架构
- 直接通过 RoxyBrowser REST API 获取 CDP WebSocket 端点
- 使用 Playwright 官方的
chromium.connectOverCDP()方法连接浏览器 - 每个
dirId对应一个持久化 BrowserContext(由 RoxyBrowser 管理) - RoxyBrowserManager 负责连接管理、Context 缓存和生命周期控制
- 能力探针:调用
server_capabilities可查看{ adapter:"roxyBrowser", version, integration, adminTools }
常用脚本
- 检查环境:
npm run check:env - 工具面对照检查:
npm run check:tools - 选择器健康报告:
npm run report:selectors - 本地演示:
npm run demo:local - Roxy 创建窗口(管理工具):
npm run roxy:create-window
目录结构
.
├─ src/
│ ├─ cli.ts # CLI 入口(示例/调试)
│ ├─ mcp/server.ts # MCP Server(stdio)入口
│ ├─ config/ # 配置解析与校验(zod schema)
│ ├─ services/ # RoxyBrowser 管理、日志、资源等服务
│ ├─ adapter/ # Playwright/CDP 适配层
│ ├─ selectors/ # 选择器语义解析与韧性定位
│ └─ humanization/ # 拟人化运动/输入节律
├─ scripts/ # 自检、报告、诊断与演示脚本
├─ tests/ # 单元/集成/守卫测试(Vitest)
├─ artifacts/ # 截图/快照/健康日志等工件
├─ docs/ # 模块文档
├─ .env.example # 环境变量示例
└─ README.md # 使用向文档(本文件)说明:以 AGENTS.md 作为架构与开发协作细则的真源;本 README 仅承载「使用与上手」。
测试与质量
- 全量测试:
npm test - 指定用例:
npx vitest run tests/unit/selectors/resilient.test.ts --reporter=verbose - MCP stdout 守卫:
tests/mcp/stdout.guard.test.ts确保 stdio 日志仅走 stderr 或文件 - Roxy 相关集成测试:在 Roxy 可用且必要环境变量存在时运行
设计与限制
- 工具层最小化、稳定化:仅提供原子动作与页面管理,业务流程上移。
- 多账号隔离:
dirId对应持久化 Context;连接与清理由容器协调。 - 拟人化与韧性:默认开启拟人化;选择器语义优先,失败与时延沉淀 p95 指标;可通过
human=false或human.enabled=false显式关闭。 - 编码与日志:所有文件 UTF-8 无 BOM;MCP stdio 禁止 stdout 日志(仅 stderr/文件)。
变更要点(0.2.x)
- 仅保留前缀+下划线命名
browser_*/page_*作为唯一标准;移除 roxy_* 浏览别名以降低心智负担。 - 高权限管理类
roxy_*默认注册(无需环境变量开关)。 - 架构升级:移除适配层抽象,直接使用 Playwright CDP 连接 RoxyBrowser。
- 页面快照节点上限受
SNAPSHOT_MAX_NODES保护。
人机参数模板(快速参考)
- 档位(使用
profile一键选择节律,亦可与下方细化参数叠加):
// 默认节律(平衡型)
{"human": {"profile": "default"}}
// 稳健型(更慢、更稳)
{"human": {"profile": "cautious"}}
// 效率型(更快、更灵敏)
{"human": {"profile": "rapid"}}- 点击/悬停(鼠标移动曲线与抖动)
{"human": {"steps": 24, "randomness": 0.2, "overshoot": true, "overshootAmount": 12, "microJitterPx": 1.2, "microJitterCount": 2}}- 滚动(分段滚动与停顿)
{"human": {"segments": 6, "perSegmentMs": 120, "jitterPx": 20, "microPauseChance": 0.25, "microPauseMinMs": 60, "microPauseMaxMs": 160, "macroPauseEvery": 4, "macroPauseMinMs": 120, "macroPauseMaxMs": 260}}- 输入(每分钟字数,逐字延时)
{"human": {"wpm": 180}}- 关闭拟人化(一次调用)
{"human": false}
// 或:{"human": {"enabled": false}}说明:
- 不传
enabled时,对象形态默认开启拟人化;human=false或human.enabled=false才会关闭。 profile提供预设节律,细化参数可按需叠加覆盖。
有效停留策略(外部编排工作流)
- 图文有效阅读:建议随机停留 3.2–6.0s(≥3s),可加一次小滚动提升自然度
- 视频早期有效观看:建议随机停留 5–10s(≥5s),必要时在流程层触发播放
外部工作流(MCP 客户端)调用序列示意:
// 1) 打开或聚焦目标页
tools/call: page_click { dirId, target: {...}, human: true }
// 2) 等待主要内容可见(由外部工作流自行 wait/sleep)
sleep(random(3200, 6000)) // 图文;视频建议 random(5000, 10000) 并先触发播放
// 3) 可选小幅滚动(提升自然度)
tools/call: page_scroll { dirId, human: { segments: 4, perSegmentMs: 120 } }
// 4) 返回或继续下一步说明:
- 本服务只提供稳定的原子动作,不内置语义流程(wait/停留)。
- 外部工作流负责编排等待、重试与业务逻辑;如需更自然的微动作,调用时传入
human即可(默认已开启)。
外部工作流最佳实践清单
工具调用顺序(常见骨架)
- 打开/聚焦上下文 → 页面创建/列表 → 导航(如需要) → 定位并点击/悬停/输入 →(图文≥3s/视频≥5s)有效停留 → 截图/快照/落盘 → 下一步或返回。
等待与确认
- 首选“可见性/可交互”准则:点击前等待关键内容可见(例如标题、正文、播放器按钮)。
- 轻等待与抖动:使用外部
sleep(random(300,600)ms)等短暂停顿衔接原子动作,避免“连发”。
证据确认:在关键节点调用
page_snapshot抽取url/title/a11y,作为“已到达/已可见”的低成本证据。重试与回退
- 选择器容错:优先语义定位(role/name/label/testId/text),必要时回退 CSS;失败可改用文本/正则匹配变体。
- 动作级重试(1–2 次):定位失败/超时 → 刷新/轻滚动再定位;持续失败则降级退出,避免无限重试。
节流与熔断
- 客户端侧设置 QPS 上限与指数退避(jitter),避免“突发连点”。
- 并发与隔离:
dirId映射持久化 Context;跨账号并行时保证每个dirId的动作队列化,避免页面竞态。
拟人化策略
- 默认开启(无需传参);全局档位
HUMAN_PROFILE=default/cautious/rapid控制节律风格;按次可human=false关闭或用对象细化(steps/randomness/wpm/segments…)。 - 输入建议使用逐字延时(WPM),标点增加额外停顿(本模块已内置)。
- 默认开启(无需传参);全局档位
有效停留(仅外部编排)
- 图文:随机停留 3.2–6.0s(≥3s),可加一次小幅滚动(0.25–0.5 视口高)。
- 视频:随机停留 5–10s(≥5s);若未自动播放先触发播放,再计时。
证据与归档
截图:
page_screenshot(文本 + image/png);命名规则可带上步骤号与毫秒时间戳。资源:
resources_listArtifacts/resources_readArtifact直接读取artifacts/<dirId>下的文件。快照:关键操作后调用
page_snapshot留存 a11y 树摘要与统计(clickableCount 等)。错误分类与处理
- 定位错误(selector/locator)→ 先回退轻滚动/切换候选 → 再次定位。
- 动作错误(action)→ 检查元素遮挡/不可交互 → 轻移动/微停顿 → 再尝试;必要时切换为非拟人化点击。
- 导航错误(navigate)→ 回退至上一步 URL,再行导航。
诊断与能力自检
启动前/运行中可调用
server_capabilities检查{ adapter, roxyBridge, adminTools }。- 可开启
HUMAN_TRACE_LOG=true将关键拟人化事件落盘到artifacts/<dirId>/human-trace.ndjson(仅在需要时)。
- 可开启
参考调用片段(MCP 客户端)
进入详情:
- tools/call
page_click→ 外部sleep(random(3200,6000))(图文) - 视频播放:
- tools/call
page_click(播放按钮)→ 外部sleep(random(5000,10000))
- tools/call
- 证据:
- tools/call
page_screenshot→ tools/callpage_snapshot
- tools/call
- tools/call
故障排查
Roxy 401/403 或连接失败
- 检查
ROXY_API_TOKEN是否有效;ROXY_API_BASEURL或ROXY_API_HOST/PORT是否可达 - 若有内网/白名单限制,请确认客户端 IP 已允许
- 用
npm run check:env与npm run preflight快速定位
- 检查
Playwright 浏览器未安装/版本不匹配
- 运行
npx playwright install chromium或重新执行npm install(触发postinstall) - 确认 Node 版本满足
>=18(建议 22.x)
- 运行
MCP stdout 日志造成客户端协议干扰
- 本项目在 MCP 模式下默认仅使用 stderr/文件日志;如需调试,请设置
MCP_LOG_STDERR=true - 参考测试用例
tests/mcp/stdout.guard.test.ts
- 本项目在 MCP 模式下默认仅使用 stderr/文件日志;如需调试,请设置
Windows 终端转义/路径问题
- PowerShell 中 JSON/引号请使用反引号或正确转义:
--payload='{\"url\":\"https://example.com\"}' - 建议优先使用提供的 npm 脚本参数而非手写长命令
- PowerShell 中 JSON/引号请使用反引号或正确转义:
中文编码/乱码
- 所有文件需为 UTF-8 无 BOM;运行
npm run check:encoding自检
- 所有文件需为 UTF-8 无 BOM;运行
贡献
- 欢迎 Issue/PR!在提交前请:
- 代码校验:
npm run lint、npm run format:check - 单元/集成测试:
npm test - 保持中文注释与一致的命名/风格(见
AGENTS.md)
- 代码校验:
开发建议:
- 使用
scripts/下的诊断与演示脚本便捷复现问题 - 对 MCP 工具的新增/修改,请同步更新
README.md工具清单与AGENTS.md
许可证
本项目采用 Apache-2.0 许可证,详见 LICENSE。
