简体中文 | English
xhs-mcp 提供统一的命令行入口 xhs-mcp,并内置 MCP 服务器子命令。用于小红书(xiaohongshu.com)的 Model Context Protocol(MCP)服务器与 CLI 工具,支持登录、发布、搜索、推荐等自动化能力(基于 Python + CloakBrowser 隐身 Chromium)。
本项目由原 TypeScript + Puppeteer 版本重写而来,完整保留了原有的全部功能:相同的 CLI 子命令与参数、相同的 MCP 工具名与 JSON Schema、相同的资源 URI、相同的输出 JSON 结构。
一处刻意的差异:登录态改为持久化浏览器 profile,不再使用
cookies.json(原方案每次开无痕上下文注入 cookie,属明显的自动化特征)。老配置会自动迁移,详见移植说明。
- 包名:
xhs-mcp - 运行 CLI(推荐):
uvx xhs-mcp <subcommand> - 启动 MCP:
uvx xhs-mcp mcp [--mode stdio|http] [--port 3000]
pip install xhs-mcp
# 或
uv tool install xhs-mcp要求 Python >= 3.10。
- 认证:登录、登出、状态检查
- 发布:图文和视频发布
- 图文发布:标题≤20字符(40显示单位)、内容≤1000、最多18图
- 视频发布:支持 MP4、MOV、AVI、MKV、WebM、FLV、WMV 格式
- ⭐ 支持图片 URL 自动下载(HTTP/HTTPS)
- ⭐ 标题宽度精确验证(CJK字符2单位,ASCII字符1单位)
- 支持本地图片路径
- 支持 URL 和本地路径混合使用
- 智能缓存机制,避免重复下载
- 发现:推荐、搜索、详情、评论
- 用户笔记:列表查看、删除管理
- 自动化:CloakBrowser 驱动(源码级隐身补丁 Chromium)、无头模式、持久化浏览器 profile 保持登录态
- 验证:发布功能验证脚本,支持 HTML 报告生成
xhs_auth_login、xhs_auth_logout、xhs_auth_statusxhs_discover_feeds、xhs_search_note、xhs_get_note_detailxhs_comment_on_notexhs_get_user_notes、xhs_delete_note(用户笔记管理)xhs_publish_content(统一发布接口:type、title、content、media_paths、tags)—— 异步,返回taskIdxhs_task_status、xhs_task_list(查询后台任务)- 图片发布:1-18个图片文件或URL
- 视频发布:恰好1个视频文件
- 混合使用:支持图片URL和本地路径混合
uvx xhs-mcp mcp
# 调试日志
XHS_ENABLE_LOGGING=true uvx xhs-mcp mcp首次运行提示:如果未下载 CloakBrowser 的隐身 Chromium,先执行
xhs-mcp browser # 自动检查并下载 Chromium(约 200MB),显示可执行路径输出示例:
{ "success": true, "message": "Chromium is ready", "data": { "installed": true, "executablePath": "/path/to/chromium" } }
验证 MCP 连接:
echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | uvx xhs-mcp mcp# 启动 HTTP 服务器(默认端口 3000)
xhs-mcp mcp --mode http
# 指定端口
xhs-mcp mcp --mode http --port 8080
# 调试模式
XHS_ENABLE_LOGGING=true xhs-mcp mcp --mode httpHTTP 服务器支持:
- Streamable HTTP (协议版本 2025-03-26) - 端点:
/mcp - SSE (协议版本 2024-11-05) - 端点:
/sse和/messages - 健康检查 - 端点:
/health
详细文档请参考:HTTP Transports
# 认证
xhs-mcp login --timeout 120
xhs-mcp logout
xhs-mcp status
# 浏览器依赖
xhs-mcp browser [--with-deps] # 检查并下载 Chromium,显示可执行路径
# 发现与检索
xhs-mcp feeds [-b /path/to/chromium]
xhs-mcp search -k 关键字 [-b /path/to/chromium]
# 当前用户笔记
xhs-mcp usernote list [-l 20] [--cursor <cursor>] [-b /path/to/chromium]
# 删除用户笔记
xhs-mcp usernote delete --note-id <id> [-b /path/to/chromium]
xhs-mcp usernote delete --last-published [-b /path/to/chromium]
# 互动
xhs-mcp comment --feed-id <id> --xsec-token <token> -n "Nice!" [-b /path/to/chromium]
# 发布
# 使用本地图片
xhs-mcp publish --type image --title 标题 --content 内容 -m path1.jpg,path2.png --tags a,b
# ⭐ 使用图片 URL(自动下载)
xhs-mcp publish --type image --title 标题 --content 内容 -m "https://example.com/img1.jpg,https://example.com/img2.png" --tags a,b
# 混合使用 URL 和本地路径
xhs-mcp publish --type image --title 标题 --content 内容 -m "https://example.com/img1.jpg,./local/img2.jpg" --tags a,b
# 发布视频
xhs-mcp publish --type video --title 视频标题 --content 视频描述 -m path/to/video.mp4 --tags a,b
# 查看可用工具
xhs-mcp tools [--detailed] [--json]
# 启动 MCP
xhs-mcp mcp [--mode stdio|http] [--port 3000].cursor/mcp.json:
{
"mcpServers": {
"xhs-mcp": {
"command": "uvx",
"args": ["xhs-mcp", "mcp"],
"env": { "XHS_ENABLE_LOGGING": "true" }
}
}
}.cursor/mcp.json:
{
"mcpServers": {
"xhs-mcp-http": {
"command": "uvx",
"args": ["xhs-mcp", "mcp", "--mode", "http", "--port", "3000"],
"env": { "XHS_ENABLE_LOGGING": "true" }
}
}
}或者使用 HTTP 客户端直接连接:
{
"mcpServers": {
"xhs-mcp-http": {
"url": "http://localhost:3000/mcp"
}
}
}| 变量 | 默认值 | 说明 |
|---|---|---|
XHS_ENABLE_LOGGING |
false |
设为 true 时向 stderr 输出调试日志 |
XHS_HEADLESS |
true |
默认无头模式 |
XHS_BROWSER_TIMEOUT |
30000 |
浏览器默认超时(毫秒) |
XHS_LOGIN_TIMEOUT |
300 |
登录超时(秒) |
XHS_SERVER_NAME |
xhs-mcp |
MCP 服务器名称 |
XHS_HOST |
127.0.0.1 |
默认主机 |
XHS_PORT |
8000 |
默认端口 |
XHS_LOG_LEVEL |
INFO |
日志级别 |
XHS_LOG_FILE |
false |
是否写入日志文件 |
XHS_BROWSER_ARGS |
空 | 追加的 Chromium 参数(逗号分隔),如 --no-sandbox |
XHS_HUMANIZE |
true |
行为拟人化(鼠标曲线、按键节奏、滚动)。关闭可大幅提速 |
XHS_USER_DATA_DIR |
~/.xhs-mcp/profile |
浏览器 profile 目录(登录态所在),见下 |
入口层 CLI · MCP stdio · MCP HTTP(SSE)
│ (只发请求,不碰浏览器)
实例管理层 BrowserSessionManager
│ 保证「一个 profile = 一个浏览器实例」
浏览器层 BrowserManager → CloakBrowser + Playwright
入口层只持有 service,不持有任何浏览器对象,也不自己启动浏览器;需要收尾时调用管理层的 shutdown_all(),而不是去 service 内部翻它用的浏览器。管理层按 profile 目录归一:
- 进程内:同一 profile 复用同一实例(引用计数),多 tab 并行
- 跨进程:浏览器启动时 Chromium 会把调试端口写入 profile 目录的
DevToolsActivePort;后来的进程读到它就接管已有实例,而不是再启一个然后失败 - 所有权:谁启动谁负责关闭;接管方退出时只断开连接 —— 所以终端跑一条
xhs-mcp status不会杀掉常驻 MCP 服务的浏览器 - 启动竞态:两个进程同时启动时,抢输的一方会自动改为接管赢家的实例
因此不管入口怎么增减,这一层不用改;下面的浏览器层也可以假定自己是该 profile 唯一的实例。
这一层没有开关。「一个 profile 一个实例」是它存在的意义,放个开关去关掉它只会把本来能用的场景变成 profile 抢锁失败。真的需要独立浏览器时,用不同的
XHS_USER_DATA_DIR—— 那才是语义正确的做法。
启用行为拟人化后,正文是逐字输入的(约 1.25 秒/字),发一条千字笔记要十几分钟 —— 没有任何 MCP 客户端会等这么久。因此发布和登录走后台队列:
- 队列串行执行:浏览器是共享资源,且小红书对短时间内连续发帖有风控,一次只跑一个长任务是有意为之。
- 只读操作(
status/feeds/search/ 详情)不进队列,仍然并发跑在各自的 tab 里。 - CLI 的
xhs-mcp publish仍然是阻塞式的 —— 终端里等着更自然,且进程退出队列也就没了。 - 任务只存在于进程内存中,服务重启后丢失。
登录态保存在一个真实的 Chromium 用户目录里(默认 ~/.xhs-mcp/profile),cookie / localStorage / IndexedDB 全部由浏览器自己管理:
xhs-mcp login # 扫一次码
xhs-mcp status # 之后直接复用,无需再扫为什么不用 cookie 文件:早期版本(以及被移植的 TypeScript 原版)把登录态存成 ~/.xhs-mcp/cookies.json,每次运行开一个全新的无痕上下文再把 cookie 注进去。真实用户的浏览器不可能每次都是崭新的隐私窗口 —— 这本身就是很强的自动化特征,容易触发风控。该模式已完全移除。
说明:
- 老用户无需重新登录:首次运行时若检测到旧的
cookies.json,会自动导入 profile 并把该文件退休(不再写入、不会重复应用)。 xhs-mcp logout删除整个 profile 目录。为防误删,只会删除带.xhs-mcp-profile标记文件的目录(该文件由本工具创建);若你把XHS_USER_DATA_DIR指向了真实的 Chrome profile,logout 会拒绝删除并报错。- 并发:进程内多 tab 并行(实测 3 个 tool call 同时下发全部成功,总耗时约等于最慢的那个而非累加);跨进程则由实例管理层接管同一实例,见上文架构。
- profile 目录约 10-50 MB。
xhs://cookies里的cookieCount读自磁盘上的 Chromium cookie 库;浏览器运行期间该值可能偏低(Chromium 在内存中缓冲、定期落盘),浏览器退出后即准确。此字段仅供参考,不影响任何行为。
- 图文发布:标题≤20、内容≤1000、图片≤18
- 视频发布:支持多种格式,文件大小建议≤500MB
- 避免同账号多端同时网页登录
- 合理控制发帖频率
- 图片 URL 自动下载到
./temp_images/目录(自动缓存) - 图片 URL 支持格式:JPEG、PNG、GIF、WebP、BMP
-b/--browser-path/browser_path参数保留但不生效:CloakBrowser 始终使用自带的隐身 Chromium,指向普通 Chrome 会破坏其指纹补丁。详见 移植说明。
- 完整使用指南 - 详细的使用说明和最佳实践
- HTTP 传输文档 - HTTP/SSE 模式配置
- 移植说明 - 从 TypeScript/Puppeteer 到 Python/CloakBrowser 的对照
- 运行所有测试:
pytest - 验证脚本:
python scripts/cli_validation.py- 发布功能验证测试,生成 HTML 报告
uv venv
uv pip install -e ".[dev]"
pytest
ruff check src tests基于 xhs-mcp(TypeScript + Puppeteer)重写为 Python + CloakBrowser;原项目基于 xiaohongshu-mcp。