DealHunter MCP
by gjjisadog
README.md
# DealHunter MCP
适合飞牛 NAS / Linux Docker 的低价情报和指定商品价格监控系统。Python 3.11+、单仓库模块化单体;Web、MCP、worker 共用业务服务。规则负责价格与通知判断,模型仅补充偏好解释。
**交付状态:P0/P1/P2 核心实现和本地测试完成;P3 安全加固已有测试,真实平台与容器验收仍有待配置项。** 2026-10-25 的 RSSHub 公共实例探测返回 403,没有真实优惠采集成功的声明。PriceBuddy、通知、LLM 需要你的服务/账号。完整证据见 [验收记录](docs/ACCEPTANCE.md) 和 [能力矩阵](docs/CAPABILITIES.md)。
## 快速启动
在项目根目录执行(不要覆盖现有 `.env`):
```sh
python3 scripts/init_env.py
docker compose up -d --build
docker compose ps
```
后台:[http://127.0.0.1:8000](http://127.0.0.1:8000),健康检查 `/healthz`,MCP 地址 `http://127.0.0.1:8000/mcp/`。在本机安全查看 `.env` 中生成的 `READ_TOKEN` / `WRITE_TOKEN`,后台连接时输入其一。密钥不输出到终端、不放进 URL。首次启动数据库为空,不自动创建模拟商品或订阅。
Compose 包含 app、单实例 worker、RSSHub 三个服务;PriceBuddy 为可选外部服务。数据保存在 `dealhunter_dealhunter-data` 命名卷中。默认只绑定宿主回环地址,RSSHub 和 worker 不暴露端口。**不要用 `docker compose down -v` 停机,它会删除数据卷。** 日志每服务限制 3 × 10 MB。
没有 Python 的 NAS 可用官方 Python 容器初始化环境文件,详见 [飞牛安装与备份恢复](docs/NAS.md)。
## 功能与使用顺序
1. 用写入 Token 连接后台,在「监控与订阅」新增关键词或品类榜订阅。默认发现间隔 15 分钟;「立即检查」只向 worker 排队。
2. 在「系统设置」创建通知渠道,再编辑规则关联渠道标识。测试通知也是异步队列,发送结果查看通知日志。
3. 已有 PriceBuddy 时配置 URL 与 API Token,先在 PriceBuddy 添加商品、配置商家,再在此添加同一商品 URL;可指定 PriceBuddy 商品 ID,避免同 URL 匹配多个商品。
4. 商品监控默认每 60 分钟。设置目标、降价百分比或缺货后补货条件。选择 `listed`(来源标价)或 `effective`(已验证到手价),货币必须一致。
5. 在好价详情查看 7/30/90 天历史、同 SKU 已记录店铺报价、规则解释;反馈「值得买/不值得买」。每天默认 08:00(Asia/Shanghai)推送前一日精选。
RSSHub 路由使用 `/smzdm/keyword/:keyword` 和 `/smzdm/ranking/pinlei/:rank_id/24`。品类榜支持全部、食品、数码、运动、家电、白菜、服饰、百货。没有把「好文分类」当成有价格的商品流。
## 数据与价格边界
- `Decimal` 运算,SQLite 金额以文本保存;JSON 金额返回字符串。来源报价、券额、运费、已验证到手价分别存储。来源没有提供的信息为 `null`。
- RSS 是第三方报价线索;未核验资格、运费和库存。条件未知不会触发数值目标。PriceBuddy 价格也不是已验证结算到手价;选 `effective` 时没有有效样本就不触发。
- 同一 RSS 文章在多个订阅/来源出现只保留一个价格证据,记录来源溯源;明确型号/SKU 不同不合并。跨店合并只接受适配器提供的商品身份与完全一致的型号和 SKU;不靠模糊标题猜测。
- 价格历史只记录实际证据;PriceBuddy 日级历史按来源日期导入,不伪造缺失记录。统计区分来源报价和已验证到手价,给出窗口、样本量、观测天数;始终声明覆盖不完整。
- 目标价按阈值进入事件通知,降价比较上一条可比观测,补货要求先观察到缺货。相同事件/渠道有持久化幂等键;静默时段延后发送,冷却期间延后事件。
- 支持能力不等于真实平台验收。403、验证码、未知格式、空配置均不会被伪装为采集成功。不提供自动购买、下单或支付。
## MCP 连接
使用官方 `mcp==2.3.0` 的 `MCPServer`,支持 Streamable HTTP 与本地 stdio。FastAPI lifespan 管理 `session_manager.run()`,HTTP 使用无状态模式防止会话间权限复用。13 个工具均提供输入与结构化输出 schema。只读 Token 可以浏览;订阅创建/修改需写 Token;删除还必须传 `confirmation="DELETE <id>"`。
Codex 配置示例(将 `DEALHUNTER_READ_TOKEN` 注入启动 Codex 的环境):
```toml
[mcp_servers.dealhunter]
url = "http://127.0.0.1:8000/mcp/"
bearer_token_env_var = "DEALHUNTER_READ_TOKEN"
disabled_tools = ["create_keyword_watch", "create_product_watch", "update_watch", "remove_watch"]
```
字段按 [OpenAI Docs 官方 MCP 文档](https://learn.chatgpt.com/docs/extend/mcp?surface=cli) 核对。完整工具参数、Claude Code、stdio 和 NAS 桥接示例见 [MCP.md](docs/MCP.md)。本项目使用预配置 Bearer Token,没有实现 OAuth 登录服务器。
## 本地开发
```sh
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.lock
.venv/bin/python -m pip install -e '.[dev]'
python3 scripts/init_env.py
.venv/bin/dealhunter api
# 另一个终端:
.venv/bin/dealhunter worker
```
本地开发时把 `RSSHUB_BASE_URL` 改成可访问的 RSSHub 地址;`rsshub` 主机名只在 Compose 网络中解析。源码部署支持 macOS/Linux;单实例锁使用 POSIX `flock`,不支持原生 Windows worker。
```sh
.venv/bin/pytest -q
.venv/bin/ruff check src tests scripts
.venv/bin/ruff format --check src tests scripts
node --check src/dealhunter/api/static/app.js
.venv/bin/python -m build --wheel
```
`requirements.lock` 固定已测试的运行时及传递依赖;开发工具由 `[dev]` 安装。CI 包含 Python 3.11/3.12/3.13 与 amd64/arm64 镜像构建任务。当前仅实际运行 Python 3.13 本地测试和两个 Linux 架构的 Python 3.12 wheel 解析下载;未把 CI 文件或依赖下载当作镜像运行成功。
## 文档导航
| 文档 | 内容 |
|---|---|
| [ARCHITECTURE](docs/ARCHITECTURE.md) | 业务边界、数据流、评分、调度与安全 |
| [RESEARCH](docs/RESEARCH.md) | 七个上游仓库的源码、接口、部署和许可证调研 |
| [CONFIGURATION](docs/CONFIGURATION.md) | 环境变量、渠道格式、API 示例 |
| [NAS](docs/NAS.md) | 飞牛/Linux 部署、局域网/VPN、升级、备份与恢复 |
| [MCP](docs/MCP.md) | 工具及 Codex/Claude Code/stdio 连接 |
| [CAPABILITIES](docs/CAPABILITIES.md) | 已实现、待配置、未支持、当前故障 |
| [ACCEPTANCE](docs/ACCEPTANCE.md) | 实际测试和真实源手工验收、Docker 重启验收 |
| [PROGRESS](docs/PROGRESS.md) | P0 → P1 → P2 → P3 执行记录 |
项目原创代码使用 [MIT 许可证](LICENSE)。没有复制参考项目的业务代码;第三方服务/依赖保留其自身许可证。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues