内容
# 麦麦今日省钱卡 · mcd-daily-saver
<p>
<a href="https://github.com/Cesare-N/mcd-daily-saver/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/Cesare-N/mcd-daily-saver?style=flat-square&color=FFC72C&labelColor=DA291C&label=Star&logo=github&logoColor=white"></a>
<a href="https://github.com/M-China/mcd-developer-innovation-challenge"><img alt="M-CODE" src="https://img.shields.io/badge/%E5%8F%82%E8%B5%9B-M--CODE%20%E9%BA%A6%E5%BD%93%E5%8A%B3%E7%A8%8B%E5%BA%8F%E5%91%98%E8%8A%82%E5%88%9B%E6%84%8F%E5%BC%80%E5%8F%91%E5%A4%A7%E8%B5%9B-FFC72C?style=flat-square&labelColor=2A1A12"></a>
</p>
> 用麦当劳官方 MCP,每天早上 10 秒告诉你三件事:**今天有什么活动、能领什么券、这一单怎么买最省。**
<p>
⭐ <strong>如果这个项目帮你省下过几块钱,欢迎点个 Star。</strong>
比赛按 Star 数排名,你的一个 Star 就是实实在在的支持 —— 点右上角的 ⭐ <code>Star</code> 就行。
</p>
麦当劳程序员节创意开发大赛(M-CODE)参赛作品。
本项目**不包含任何人的 Token 或密钥**——每个人用自己的 Token 跑,数据只在自己机器上流转。
---
## 它解决什么问题
麦当劳 App 里券、活动、积分、门店规则分散在好几个页面:想知道"今天中午这顿怎么点最划算",得在券包、活动页、结算页之间来回翻。
这个工具把这件事变成**一页纸**:打开就看到结论,不用翻。
**一句话**:把「今天怎么吃麦当劳最省」变成一个 10 秒能看完的页面。
---
## 展示截图
| 首屏三张卡(左右滑动切换) | 比一比哪个买法最省 |
|---|---|
|  |  |
| 你自己的 Token,自己填 | 只读版整页(可离线打开、可分享) |
|---|---|
|  |  |
> 截图均为真实运行结果(数据来自麦当劳 MCP 实时查询)。
---
## 三种卡片,三个角度
首屏是三张可滑动的卡,不是同一件事复制三份:
1. **今天这么点最划算**(麦红)——今天可用券里券后价最低的一张,含有效期
2. **别浪费**(黄金)——今天到期的券,提醒你别作废
3. **还有**(深棕)——今天能用几张券
---
## 它真的能比价吗?——能比的与不能比的
**能自动比的(麦当劳自家买法)**
- **取餐方式**:堂食 / 外带 / 得来速(该门店支持哪些就比哪些)
- **可用券**:查该门店当前可用券,算券后价
- **门店规则**:门店级满减 / 满折
**不能比的(诚实说明)**
- **美团、饿了么、淘宝闪购的价格拿不到。** 麦当劳 MCP 只覆盖麦当劳自家业务,本项目**不做也不猜测**其他平台价格。
- **麦乐送 / 得来速在部分门店比不了**:需要门店返回 `beCode`,拿不到时页面会明确写「该门店未返回 beCode,无法计算」,**不会用假数字凑**。
宁可少显示,不给你错数字。
---
## 目标用户
- **每天吃麦当劳、想少花几块的上班族**:早上看一眼今天哪张券最值。
- **手里券多但记不住有效期的人**:到期提醒 + 一键领取。
- **想了解麦当劳 MCP 能做什么的开发者**:一份完整、可跑通、不吹牛的示例工程。
---
## 你需要准备什么
| 需要 | 说明 |
|---|---|
| **Node.js ≥ 18** | 项目零运行时依赖,只用 Node 内置能力 |
| **你自己的麦当劳 MCP Token** | 免费申请,见下方 |
**申请 Token 的步骤**
1. 打开 <https://open.mcd.cn/mcp>
2. 右上角「登录」,用手机号验证
3. 登录后点右上角「控制台」→ 点「激活」→ 同意服务协议
4. 复制得到的 Token(形如 `xxxxxxxxxxxxxxxxxxxxxxxx`)
> ⚠️ Token 等于你的账号访问凭证,**不要提交到任何仓库、不要发给别人**。
---
## 安装
```bash
git clone https://github.com/<你的账号>/mcd-daily-saver.git
cd mcd-daily-saver
cp .env.example .env
# 编辑 .env,把 MCD_MCP_TOKEN 换成你自己的 Token
```
项目零第三方运行时依赖,**不需要 `npm install`**。
---
## 使用示例
### 方式一:生成的只读页(可离线打开、可分享)
```bash
export MCD_MCP_TOKEN=你的Token # 或写进 .env
npm run build # 生成 dist/index.html
```
打开 `dist/index.html`,数据已内联,**可离线查看、可直接发给朋友**。
命令行会同时打印一份摘要:
```text
服务器时间 2026-10-10 09:12:03 周六
今日结论 9.9元中杯冰美式 券后 ¥9.9
可用券 3 张(其中 2 张此刻可用)
今天到期 1 张
活动条数 30 条
积分 217.8 可用 / 1233.8 累计
```
### 方式二:本地交互版(能真领券、能算价、能下单)
```bash
npm run app # 生成交互版页面
npm run serve # 启动本地服务 → http://127.0.0.1:8787
```
打开页面后:
1. **在页面里填你自己的 Token**(不进命令行、不进文件、不进日志)
2. 点「连接」→ 看到今日省钱卡
3. 点「一键领取今天的券」→ 真实领取到你的麦当劳账户
4. 「点餐」区按 5 步走:**门店 → 菜单 → 套餐内容/可换项 → 算价 → 下单**
5. 「④b 比一比哪个买法最省」→ 看各买法到手价
> **下单会产生真实扣款。** 提交前页面会弹二次确认,确认后才发起。
### 方式三:只验连通性
```bash
npm run probe
# ✅ MCP 连通,可用工具 35 个:list-nutrition-foods, create-order, ...
```
---
## 用到了哪些麦当劳 MCP 工具
| 工具 | 用途 |
|---|---|
| `now-time-info` | 服务器时间(一律以官方时间为准,不用本机时间) |
| `campaign-calendar` | 活动日历:进行中 / 往期 / 未来 |
| `query-my-coupons` | 我的券包(含券后价、有效期、标签) |
| `available-coupons` | 麦麦省可领券列表 |
| `auto-bind-coupons` | **一键领取**当前可领的券 |
| `query-my-account` | 积分账户 |
| `query-nearby-stores` | 搜索附近 / 收藏门店 |
| `query-meals` | 门店菜单 |
| `query-meal-detail` | 套餐组成与**可替换项** |
| `calculate-price` | 算价(含优惠、取餐方式) |
| `query-store-coupons` | 该门店可用券 |
| `query-promotions` | 门店满减 / 满折规则 |
| `create-order` | 创建订单(返回支付链接) |
完整的调用流程、时序与业务价值见 **[MCP_INTEGRATION.md](MCP_INTEGRATION.md)**。
---
## 隐私与安全
这个项目在凭证处理上做了三件事,你可以自己验证:
1. **代码里没有任何 Token。** 全仓库不含账号、密钥、密码;`.env` 与 `dist/` 都在 `.gitignore` 里。
2. **本地服务只监听 `127.0.0.1`。** 同一局域网的其他设备也访问不到;Token 只从请求头读取,**不写日志、不落盘**。
3. **Token 只存在内存里。** 页面刷新即失效,另有一键「断开并清除 Token」。
配套措施:接口只放行**工具白名单**、请求体限 512KB、路径防目录穿越、错误信息自动遮蔽疑似凭证。
---
## 常见问题
**Q:会用到我的账号花钱吗?**
只有你点「生成订单」并确认后才会创建订单,而且**付款要在麦当劳官方渠道完成**。其余操作(查数据、领免费券)不产生费用。
**Q:为什么领券按钮点了显示"今天已经领取过了"?**
麦当劳麦麦省每天限领一次,属正常限制,不是报错。
**Q:为什么麦乐送比不了价?**
部分门店不返回 `beCode`,麦当劳接口在 `beType=2/5` 时强制要求它。拿不到就如实标注,不用假数据填。
**Q:数据是实时的吗?**
是。每次运行都现场调 MCP,页面底部会显示查询时刻。项目**不内置任何离线或模拟数据**;没有 Token 时会明确报错退出,不会拿本地数据冒充结果。
---
## 开发
```bash
npm test # 单元测试(解析器 / 推荐引擎 / 比价)
npm run build # 生成只读版
npm run app # 生成交互版
npm run serve # 本地服务
```
目录结构:
```
src/
mcp.mjs MCP 客户端(Token 逐次传入,不读全局默认值)
parse.mjs 把 MCP 的 Markdown 返回解析成结构化数据
plan.mjs 推荐引擎:今天这么点最划算 + 三张卡
compare.mjs 比价引擎:自家买法对比
render.mjs 只读版页面生成
render-app.mjs 交互版页面生成
index.mjs CLI 入口
server.mjs 本地服务(仅 127.0.0.1)
test/ 单元测试(用实测真实返回做 fixture)
docs/plans/ 设计稿
mcp-config.example.json 脱敏 MCP 配置示例(仅环境变量占位符)
scripts/ 参赛规则自检脚本
```
---
## 免责声明
本项目为**麦当劳程序员节创意开发大赛参赛作品**,由参赛者独立开发,**非麦当劳官方产品**。
项目输出仅供参考,不构成医疗、营养或其他专业建议;餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。
参赛声明见 [CONTEST_DECLARATION.md](CONTEST_DECLARATION.md)。
## 许可证
[MIT](LICENSE)