npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iflow-mcp/mook-wenyu-xiaohongshumcp

v0.1.2

Published

小红书场景的人机浏览自动化 MCP 服务,基于 RoxyBrowser + Playwright 提供最小原子动作与多账号隔离

Readme

HushOps.Servers.XiaoHongShu — 自动化浏览/MCP 服务

Node TypeScript Playwright MCP License

面向“小红书(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

目录


能力总览

  • 多账号隔离: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_BASEURLROXY_API_HOST + ROXY_API_PORT
  • ROXY_DEFAULT_WORKSPACE_ID(可选,用于默认上下文)
  • SNAPSHOT_MAX_NODES(页面快照节点上限,默认 800)
  • HUMAN_PROFILEdefault/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 注释),两者用途不同。

安装与最小自检

  1. 安装依赖
npm install
  1. 配置环境变量
Copy-Item .env.example .env
# 编辑 .env,填写 ROXY_API_TOKEN,设置 ROXY_API_BASEURL 或 HOST/PORT
  1. 预检(可选)
npm run preflight
  1. 自检脚本(可选)
npm run check:env
  1. 工具面对照检查(可选)
npm run check:tools
  1. 编码巡检(可选,CI 推荐)
npm run check:encoding

启动与集成(stdio MCP)

  1. 构建(或直接 TS 运行)
npm run build
  1. 启动 MCP Server(stdio)
npm run mcp

MCP 工具清单(唯一标准)

浏览器与页面管理

  • 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-texta.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=falsehuman.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=falsehuman.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=falsehuman.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 page_screenshot → tools/call page_snapshot

故障排查

  • Roxy 401/403 或连接失败

    • 检查 ROXY_API_TOKEN 是否有效;ROXY_API_BASEURLROXY_API_HOST/PORT 是否可达
    • 若有内网/白名单限制,请确认客户端 IP 已允许
    • npm run check:envnpm 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
  • Windows 终端转义/路径问题

    • PowerShell 中 JSON/引号请使用反引号或正确转义:--payload='{\"url\":\"https://example.com\"}'
    • 建议优先使用提供的 npm 脚本参数而非手写长命令
  • 中文编码/乱码

    • 所有文件需为 UTF-8 无 BOM;运行 npm run check:encoding 自检

贡献

  • 欢迎 Issue/PR!在提交前请:
    • 代码校验:npm run lintnpm run format:check
    • 单元/集成测试:npm test
    • 保持中文注释与一致的命名/风格(见 AGENTS.md

开发建议:

  • 使用 scripts/ 下的诊断与演示脚本便捷复现问题
  • 对 MCP 工具的新增/修改,请同步更新 README.md 工具清单与 AGENTS.md

许可证

本项目采用 Apache-2.0 许可证,详见 LICENSE