goofish-cli
<div align="center">
# goofish-cli
**闲鱼 CLI · 原生支持 MCP · 为 AI Agent 而生**
*Goofish (Xianyu) automation CLI · MCP-ready · Built for AI Agents*
[](https://github.com/fancyboi999/goofish-cli/actions/workflows/ci.yml)
[](https://pypi.org/project/goofish-cli/)
[](https://pypi.org/project/goofish-cli/)
[](./LICENSE)
[](https://modelcontextprotocol.io)
[](https://github.com/fancyboi999/goofish-cli)
</div>
https://github.com/user-attachments/assets/ae20ae2f-ccdf-4d3e-a947-69182d4c4eff
<p align="center">
<em>▶️ 播放不了?<a href="media/goofish-cli-promo.mp4">点这里下载高清 MP4(1:32)</a></em>
</p>
`goofish-cli` 把闲鱼(Xianyu/Goofish)的核心运营能力抽成一套结构化命令,
**同一份定义**同时输出给四种消费者:
- 👨💻 **人类**:`goofish item get 12345 --format table`
- 🤖 **AI Agent(Claude Code / Cursor / Codex)**:`uvx goofish-cli` → 自动注册成 MCP tool
- 🧩 **Claude Skills**(v0.3):5 个内置 skill,`goofish skills install` 一行装到 `~/.claude/skills/`
- **OpenClaw**:ClawHub bundle 一次安装 MCP server + 5 个 skills
> 架构思想来自 [opencli](https://github.com/jackwener/opencli) 的 single-registry 设计。
---
## 特别鸣谢
<p align="center">
<a href="https://www.ipwo.net/?ref=githubgoofishcli">
<img src="media/ipwo-banner.png" alt="IPWO 住宅代理:稳定连接、全球节点、多协议支持" width="95%">
</a>
</p>
<p align="center">
<a href="https://www.ipwo.net/?ref=githubgoofishcli"><ins>IPWO</ins></a> 拥有 9000 万+ 活跃住宅 IP 资源,覆盖 195+ 个国家和地区。<br>
提供动态住宅代理、静态住宅代理及不限量住宅代理。<br>
适用于网页抓取、数据采集、浏览器自动化、跨境业务等场景。<br>
我们订阅使用 Claude / Claude Code 时采用住宅 IP,长期使用稳定。<br>
支持<a href="https://www.ipwo.net/?ref=githubgoofishcli"><ins>免费测试</ins></a>,<strong>9 折优惠码:</strong><code>0203</code>
</p>
---
## ✨ 核心特性
- 🔐 **17 个命令覆盖核心链路**:发布、下架、查询、图片上传、AI 类目识别、默认地址、IM 收发 + 会话列表、skills 安装
- 📡 **真·实时 IM**:WebSocket 长连 + 自动重连 + **三类事件分类输出**
- `event=message`(收到消息)· `event=read`(已读回执)· `event=new_msg`(轻量通知)
- 🛡 **内置风控护栏**:账号与业务桶限流(经营 1 次/分钟、媒体 9 次/分钟)+ RGV587 自动熔断
- 🧠 **AI-first I/O**:`--format json/yaml/table/md/csv`,给 LLM 喂 JSON、给人看表格
- ⚡ **一次定义,三种入口**:CLI / MCP / Skill 共享同一 registry
- ✅ **真实端到端验证**:每个命令都跑过真实账号
---
## 🚀 60 秒上手
```bash
# 1. 安装
pip install goofish-cli # 或 uv pip install goofish-cli
# 2. 导入 cookie(从浏览器 DevTools → Application → Cookies 导出)
goofish auth login ~/Downloads/goofish-cookies.json
# 3. 验证登录态
goofish auth status
# → {"unb":"<masked-unb>","tracknick":"<masked-tracknick>","nick":"...","valid":true}
# 4. 干活
goofish item get 1045171414271
goofish message watch # 实时接收消息
goofish message send <cid> <toid> --text "在的" # 发消息
```
### 不占用桌面的沙箱模式
需要运行中的本机 Docker Desktop / Docker Engine。安装支持沙箱的版本后,先在终端执行:
```sh
goofish sandbox --help
goofish sandbox start
# 手动打开输出的观察链接,默认 http://127.0.0.1:16080/vnc.html?autoconnect=1&resize=scale
goofish sandbox login # 在虚拟桌面里扫码并确认
goofish sandbox run auth status --format json
goofish sandbox run search items '机械键盘' --limit 3
```
让 AI 客户端也使用沙箱时,将原有 `goofish` MCP 配置替换为:
```json
{
"mcpServers": {
"goofish": {
"command": "goofish",
"args": ["sandbox", "mcp"]
}
}
}
```
客户端必须能找到 `goofish` 和 `docker`;桌面客户端找不到命令时,将 `command` 改为 `command -v goofish` 输出的绝对路径,并检查客户端 PATH 中是否有 Docker。Codex 使用 TOML,见 [MCP 客户端配置](docs/mcp-setup.md#独立桌面模式)。不要同时保留原来的本机 Goofish server;直接运行 `uvx goofish-cli` 仍使用本机模式。
首次启动会下载并构建镜像。Chromium 在容器虚拟桌面里常驻,登录态保存在独立卷;命令不会自动打开宿主机浏览器。平台要求验证时,执行 `goofish sandbox browse --item-id <商品ID>`,在观察页面人工完成。升级后用 `stop`、`start --rebuild` 更新镜像,状态卷保留。
如果 `sandbox --help` 不识别命令,当前安装的发行版尚未包含沙箱功能。源码安装、完整的登录/恢复步骤和限制见[沙箱指南](docs/sandbox.md)。
---
## 🧩 Claude Skills(v0.3 新增)
v0.3 起内置 5 个 Claude Skill,装完之后 Claude Code / Cursor 里的 Agent 在识别到
闲鱼任务就会自动加载对应 skill 的知识库,**不再靠 zero-shot 试错**。
```bash
# 装到 ~/.claude/skills/(默认)
goofish skills install
# 或者只看有哪些 skill,不拷贝
goofish skills install --list
# 或者装到自定义目录 + 覆盖已有的
goofish skills install --dest ./skills --force
```
### 5 个 skill 分工
| Skill | 什么时候激活 | 核心能力 |
|---|---|---|
| `goofish-overview` | 用户首次提闲鱼 / 问这工具能干啥 | 总入口,dispatch 到其他 4 个 skill |
| `goofish-publish-item` | 发商品 / 上架 / 挂闲置 | 类目识别 → 标题 5 段式 → 风控扫描 → 图片检查 → 确认发布 |
| `goofish-reply-buyer` | 回消息 / 看未读 / 议价 | 拉未读 → 意图 5 分类 → 议价三档(小刀/大刀/屠龙刀)→ 用户确认发送 |
| `goofish-risk-guard` | 发布前 / 发送前 / 被限流了 | 违禁词表、外联词正则、发布红线、x5sec 恢复指引(被其他 skill 频繁引用) |
| `goofish-shop-diagnosis` | 店铺没流量 / 曝光掉了 | 买家视角搜索 + 历史对比 → 归因清单 + 修复建议(纯读不写) |
skill 的源文件在仓库的 `skills/` 目录下(每个 skill 一个子目录,含 `SKILL.md`
+ `references/*.md` 知识库)。也可以走 Claude Code Plugin Marketplace 安装:
```bash
claude /plugin marketplace add fancyboi999/goofish-cli
```
---
## OpenClaw / ClawHub
OpenClaw `2026.6.1` 及以上可把本仓库作为 compatible bundle 加载。已发布到
[ClawHub](https://clawhub.ai/plugins/openclaw-goofish),安装:
<!-- x-release-please-start-version -->
```bash
openclaw plugins install clawhub:openclaw-goofish
# 登录态由用户在终端初始化,不交给 Agent 覆盖
uvx --from goofish-cli==0.6.0 goofish auth login --qr
openclaw plugins inspect goofish --json
openclaw gateway restart
```
<!-- x-release-please-end -->
本地开发无需发布:
```bash
openclaw plugins install -l .
openclaw plugins inspect goofish --json
```
重启后新会话会获得 5 个 skills,以及 `goofish__auth_status`、
`goofish__item_get` 等 MCP tools。bundle 默认不暴露需要操作者执行或会长期阻塞的
`auth_login`、`auth_reset_guard`、`message_watch`、`skills_install`。
运行 MCP server 需要 PATH 中有 [`uv`](https://docs.astral.sh/uv/)。完整说明见
[MCP 接入指南](./docs/mcp-setup.md)。
---
## 📟 命令详略与真实输出
<details open>
<summary><b><code>goofish list-commands</code></b> — 注册表全景</summary>
```bash
$ goofish list-commands --format table
```
| 命令 | 说明 | 写操作 |
|---|---|:-:|
| `auth login` | 从 JSON 文件或 cookie 字符串导入登录态 | ❌ |
| `auth status` | 检查登录态是否有效 | ❌ |
| `auth reset-guard` | 手动解除风控熔断 | ❌ |
| `item get` | 查询闲鱼商品详情 | ❌ |
| `item publish` | 发布商品(自动识别类目 + 默认地址) | ✅ |
| `item delete` | 下架/删除商品 | ✅ |
| `media upload` | 上传图片到闲鱼 CDN | ✅ |
| `category recommend` | AI 识别商品类目 | ❌ |
| `location default` | 获取默认发布地址 | ❌ |
| `message list-chats` | 会话列表(默认 HTTP + 短时 WS,补最近消息并按活动时间倒序) | ❌ |
| `search items` | 搜索闲鱼商品(浏览器路径 Playwright + 系统 Chrome) | ❌ |
| `item view` | 浏览器视角看商品详情(字段完整,抗风控;`item get` 的姊妹版) | ❌ |
| `message history` | 拉取会话历史消息 | ❌ |
| `message send` | 发送文本/图片 | ✅ |
| `message watch` | 常驻 IM 长连(JSONL 输出) | ❌ |
</details>
会话读取使用真实消息时间,而非会话创建时间:
```bash
goofish message list-chats --format json
goofish message history <cid> --limit 20 --timeout 30 --format json
```
`list-chats` 默认 `--watch-secs 5`,在一个已就绪的连接中补齐真人会话的最近消息页;
`--watch-secs 0` 关闭 WS 会话发现,结果可能遗漏 HTTP 未返回的会话。
`--timeout` 限制摘要读取阶段。历史输出保留 `cid`、`message_id` 和毫秒时间 `created_at`,
`--limit 0` 保留完整翻页行为,其他正数只读最近 N 条。
`metadata_status` 标明摘要是当前、为空、不完整或读取失败;无法确定的时间为 `null`。
`has_more` 只代表 HTTP 分页,`enumeration_complete=false` 表明短时同步不能证明全部历史会话已覆盖。
接口契约与异常边界见 [会话同步](docs/conversation-sync.md)。
<details>
<summary><b><code>goofish auth status</code></b> — 登录态健康检查</summary>
```json
{
"unb": "<masked-unb>",
"tracknick": "<masked-tracknick>",
"nick": "闲鱼用户昵称",
"valid": true,
"h5_token_exp": "2026-04-21T20:30:00+08:00"
}
```
</details>
<details>
<summary><b><code>goofish message watch</code></b> — 三类事件 JSONL 流</summary>
```bash
$ goofish message watch
```
实时输出(小号给主号发 3 条 + 主号读了所有消息):
```jsonl
{"event":"message","cid":"<masked-cid>","send_user_id":"<masked-user-id>","send_user_name":"小号昵称","send_message":"测试消息1"}
{"event":"message","cid":"<masked-cid>","send_user_id":"<masked-user-id>","send_user_name":"小号昵称","send_message":"测试消息2"}
{"event":"message","cid":"<masked-cid>","send_user_id":"<masked-user-id>","send_user_name":"小号昵称","send_message":"测试消息3"}
{"event":"read","cid":"<masked-cid>","msg_ids":["<masked-msg-id-1>","<masked-msg-id-2>","<masked-msg-id-3>"],"status":1,"ts":"<masked-timestamp>"}
```
| 事件 | 字段 |
|---|---|
| `message` | cid · send_user_id · send_user_name · send_message · content_type |
| `read` | cid · msg_ids[] · status · ts |
| `new_msg` | cid · msg_id · ts(服务端只推指针,需 `message history` 拉正文) |
**自动跳过噪音**:`/s/para`(对方正在输入)、`contentType=8`(会话激活心跳)。
</details>
<details>
<summary><b><code>goofish message send</code></b> — 主动发消息</summary>
```bash
$ goofish message send <masked-cid> <masked-user-id> \
--text "在的 claude 测试成功 ✅" --item-id 1045171414271
```
```json
{"ok": true, "mid": "<masked-message-id>", "cid": "<masked-cid>"}
```
</details>
<details>
<summary><b><code>goofish item publish</code></b> — 发布商品(含风控护栏)</summary>
```bash
goofish item publish "男士毛呢大衣 驼色长款" \
"全新未拆封 原价 2999 现 999" ./a.png ./b.png 999 --format json
```
流程:上传图片 → 推荐类目 → 默认地址 → 提交。已有上传收据可通过
`--images-json '[{"url":"https://example.alicdn.com/image.png","width":1024,"height":1024}]'`
复用,省略本地图片参数;已确认类目和地址分别通过 `--category-json`、`--location-json`
传入对应工具返回的完整 DTO。
返回 `item_id`、`status="accepted"` 和 `requires_readback=true`;使用
`goofish item get <item_id>` 和自己的商品列表确认保存。失败也保留已上传图片和准备信息;
`submission_unknown` 必须先核对商品列表,不自动重复发布。
发布与下架共用账号的 `item.write` 预算,默认 1 次/分钟;媒体上传独立计数,默认
9 次/分钟。一个多图商品只消耗一次商品预算。
</details>
---
## 🔌 接入 Claude Code(MCP)
以下为本机模式;需要隔离桌面时,使用上面的沙箱 MCP 配置,客户端位置见 [MCP 接入指南](docs/mcp-setup.md)。
在项目根目录 `.mcp.json` 配置:
```json
{
"mcpServers": {
"goofish": {
"command": "uvx",
"args": ["goofish-cli"]
}
}
}
```
Claude 会自动把全部命令看成 tool:`mcp__goofish__item_get` / `mcp__goofish__item_publish` / `mcp__goofish__message_watch`... 你在对话里直接说"帮我看下 itemId=xxx 的详情",Claude 就会调用。
---
## 🎯 项目亮点
| 能力 | 说明 |
|---|---|
| 11 个核心 mtop 接口 | 发布/下架/查询/图片/类目/地址/IM 全覆盖 |
| CLI + `--format` 多格式输出 | `json` / `yaml` / `table` / `md` / `csv`,人机两用 |
| MCP Server | `uvx goofish-cli` 一行接入 Claude Code / Cursor |
| WebSocket 批量 push 全量解码 | 一帧多条消息全部还原,不丢单 |
| WebSocket 自动重连 | 断线自退避重连,长跑无感知 |
| 已读回执 / typing / 新消息通知分类 | `/s/sync` 元事件结构化为三类 JSONL |
| 全局限流 + 风控熔断 | 账号业务预算 + RGV587 自动熔断 |
| 回归验证 | `pytest` + `ruff check src tests` |
| 包分发 | `pip install goofish-cli` / `uvx goofish-cli` |
---
## 🗺 Roadmap
- [x] v0.1:12 个命令 + MCP + IM 三类事件
- [x] v0.2:`goofish message list-chats`(会话列表 + sessionType 分类:1 真人 / 3 系统 / 6 互动 / 23 通知;`--watch-secs` 支持合并 WS `ackDiff(pts=0)` 历史推送补齐 h5 接口漏掉的会话)
- [x] v0.2:浏览器自动化链路(吸纳 [OpenCLI](https://github.com/jackwener/opencli) 精华)—— Playwright + 系统 Chrome 驱动 `goofish search items` / `goofish item view`,抗风控 & 完整字段
- [x] v0.2.3 / v0.2.4:session 自动续命(passport 快速进入)+ `auth login --qr` 扫码兜底
- [x] v0.3:Claude Skills 包装(5 个 skill:overview / risk-guard / publish-item / reply-buyer / shop-diagnosis)+ `goofish skills install`
- [ ] v0.4:`goofish message create-chat`(主动与陌生用户建会话)
- [ ] v0.4:`goofish order`(订单状态查询 / 发货)
- [ ] v0.4:历史数据落盘(SQLite / JSONL),给 shop-diagnosis 做时序归因
- [ ] v0.5:支持发视频消息
---
## 🛠 开发
```bash
git clone https://github.com/fancyboi999/goofish-cli
cd goofish-cli
uv venv --python 3.11
uv pip install -e ".[dev]"
uv run pytest # 33 测全绿
uv run ruff check src tests # 零告警
```
详细请看 [CONTRIBUTING.md](./CONTRIBUTING.md) 和 [docs/architecture.md](./docs/architecture.md)。
---
## ⚠️ 合规声明
本工具**仅用于用户自有账号**的自动化运营。**严禁**:
- 欺诈 / 刷单 / 虚假交易
- 针对闲鱼平台的 SaaS 化转售
- 违反闲鱼、淘宝、阿里巴巴用户协议的行为
工具不提供:绕过滑块验证、批量设备 ID 伪造、自动化规避封号。遇到风控请人工处理(见 [docs/compliance.md](./docs/compliance.md))。
---
## 📜 License
Apache-2.0 © 2026 fancy。详见 [LICENSE](./LICENSE) 和 [NOTICE](./NOTICE)。
TDQS
Scored across 17 tools
Most tools target distinct resources and actions, but item_get and item_view both retrieve item details and could be confused despite the API-vs-browser distinction. The messaging and auth tools are clearly separated.
Most names follow a consistent snake_case resource_action pattern (auth_status, item_publish, message_send), with a few deviations such as search_items and skills_install. The set remains readable and predictable overall.
Seventeen tools is slightly above the ideal range but reasonable for a CLI covering auth, item management, messaging, media, category, location, and skills. Each domain group is small and the tools mostly earn their place.
The surface covers login, search, list, view, publish, delete, media, category, location, and messaging well, but lacks an obvious item update/edit operation. Agents can work around this only by deleting and republishing, which is a notable gap.