基于麦当劳 MCP 的全渠道点餐优惠决策引擎——用一句话,算出全网最省的点餐方案。
你在 WorkBuddy / 任意 MCP 客户端里说「深圳宝安,巨无霸套餐,到店,怎么最省」, 它会自动遍历全渠道、全量优惠券组合,输出 Top3 最低到手价方案,一句话确认即可下单。
打开麦当劳 App 想点一份巨无霸,你会遇到:
- 菜单几十项,套餐与单品混杂,「巨无霸三件套 41 元」和「巨无霸 26.5 元 + 薯条」哪个更划算?
- 优惠券分散在三个体系:门店券、麦麦省券(需先领取)、积分券,App 里往往只显示「部分可用」
- 不知道能不能叠加:门店券和麦麦省券同时用会怎样?买张随单购卡到底亏不亏?
- 三渠道价格不明:到店自取、得来速车道取餐、麦乐送到家,哪个更划算?
结果就是:用户要么随手点一笔(浪费权益),要么在多个页面反复比对(决策成本高)。
把上述决策过程封装成一个优惠决策引擎:自然语言输入 → 意图与参数解析 → 全渠道全量券组合遍历 → 服务端真实价格验证 → Top3 方案输出 → 一键下单。
关键设计取舍:不本地估算优惠金额,而是把 calculate-price 作为唯一事实来源。
即使官方叠加规则变化,引擎依然给出正确结果,只是多几次调用——用少量调用换取 100% 的准确性。
| # | 能力 | 说明 |
|---|---|---|
| 1 | 🧠 自然语言意图解析 | 识别 6 类意图(指定餐品/预算推荐/活动查询/订单复购/积分兑换/通用),自动抽取餐品、预算、渠道、人数、位置,缺参主动追问 |
| 2 | 🧮 全量券组合遍历 | 跨类型券叠加规则引擎,遵守「同类型互斥、跨类型可叠加、活动券独立」规则,输出全局最优解 |
| 3 | 📊 三渠道并行比价 | 到店自取 / 得来速 / 麦乐送并行计算,按 价格 60% + 时间 25% + 距离 15% 加权评分 |
| 4 | 🛒 智能凑单建议 | 未达满减门槛时推荐最低价凑单品,并用收益校验确认凑单真的更便宜才推荐 |
| 5 | ⭐ 积分价值比算法 | 按「券面值 ÷ 所需积分」排序而非所需积分升序,优先消耗临期积分 |
| 6 | 📅 活动预判决策 | 解析活动文案估算折扣力度,对比当前最优价给出「现在买 / 等活动买」建议 |
| 7 | 🔁 订单复购 | 读取历史订单,按今天的优惠重新计算最省方案 |
| 8 | ⚡ 一键领券下单 | 自动领券 → 价格二次校验 → 创建订单 → 返回支付链接 |
| 9 | 🛡️ 稳定性保障 | 并行调用、TTL 缓存、指数退避、优雅降级、状态机约束,单轮调用 ≤ 15 次 |
项目内置了从麦当劳 MCP Server 真实响应采样的 Mock 数据,可直接跑通全链路:
node src/index.js --demo输出示例:
👤 用户:深圳宝安,巨无霸套餐,到店,怎么最省
💰 已匹配:巨无霸(¥26.50)
【方案1】到店自取巨无霸6元券
到手价 ¥20.50(原价 ¥26.50,省 ¥6.00)
标签:门店券、免配送费
【方案2】到店自取原价方案(无可用优惠)
到手价 ¥26.50(原价 ¥26.50,省 ¥0.00)
⭐ 积分建议:推荐兑换「点餐优惠券 12元」:900 积分换¥12.00券,
价值比0.0133 元/积分(全站最优)。兑换后剩余 736 积分
📊 本轮工具调用 9 次
node src/index.js --test输出:109 项断言全部通过,覆盖意图识别、金额单位、券叠加规则、价格引擎、多渠道比价、凑单、活动预判、积分兑换、下单执行、异常处理、状态机与端到端链路。
node src/index.js --config确认 Token 是否已生效,未配置时会给出逐步指引。
第 1 步:申请 MCP Token
访问 麦当劳 MCP 控制台 → 右上角【控制台】→【激活】→ 复制 Token。
第 2 步:配置 Token(零依赖,无需 npm install)
# 在项目根目录执行,复制配置模板
cp .env.example .env # Windows CMD: copy .env.example .env然后用编辑器打开 .env,把占位符替换成你的真实 Token:
MCP_TOKEN=你的真实token
.env已在.gitignore中被忽略,可安全存放本地 Token,不会被提交到仓库。
也可以临时用环境变量(优先级高于 .env,仅当前窗口有效):
# Windows PowerShell
$env:MCP_TOKEN = "your_mcp_token"
# macOS / Linux
export MCP_TOKEN="your_mcp_token"第 3 步:验证配置
node src/index.js --config🍔 麦麦极致省钱规划师 · 配置自检
────────────────────────────────────────────────────
MCP Server : https://mcp.mcd.cn
协议类型 : streamablehttp
MCP Token : a1b2c3****9f8e(长度 40)
────────────────────────────────────────────────────
✅ Token 已配置,可运行:node src/index.js
第 4 步:启动
node src/index.js🍔 麦麦极致省钱规划师 · 交互模式(输入 exit 退出)
👤 你:深圳南山,35块预算,两个人,到店
💰 按35元预算为2人搭配,合计约 ¥32.50。以下是实际可用优惠券算出的最低到手价:
【方案1】到店自取薯条买一送一券
到手价 ¥32.50(原价 ¥39.50,省 ¥7.00)
👉 说「下单方案1」创建订单 | 说「换个搭配」重新推荐
node src/index.js "深圳宝安巨无霸套餐到店怎么最省"
node src/index.js --order 1 --address ADDR12345 # 外送下单需指定地址在 WorkBuddy 中配置 MCP 连接器后,添加本仓库的 Skill 即可获得对话式体验。
node examples/usage.js内置 Mock 数据,无需 Token,9 个可运行示例覆盖全部场景。输出节选:
══════════════════════════════════════════════════════════════════
示例 1:一句话拿到最省方案
══════════════════════════════════════════════════════════════════
输入:深圳宝安,巨无霸,到店,怎么最省
识别意图:指定餐品最优
匹配商品:巨无霸
【方案1】巨无霸6元券
到手 ¥20.50(原价 ¥26.50,省 ¥6.00)
叠加1张券:巨无霸6元券,共省¥6.00,距离约0.7km
【方案2】原价方案(无可用优惠)
到手 ¥26.50(原价 ¥26.50,省 ¥0.00)
本轮工具调用:9 次
══════════════════════════════════════════════════════════════════
示例 3:多轮对话(下单闭环)
══════════════════════════════════════════════════════════════════
第1轮 >> 深圳宝安,巨无霸,到店,怎么最省
最优:巨无霸6元券 → ¥20.50
第2轮 >> 下单方案1
✅ 下单成功
订单号:MCD-20261017-8823
支付链接:https://pay.mcd.cn/...
# 交互模式(推荐,像聊天一样用)
node src/index.js
# 单次执行,直接出结果
node src/index.js "深圳南山,巨无霸,到店,怎么最省"
# 静默模式,只输出结果(适合脚本/录屏)
node src/index.js "深圳南山,巨无霸,到店,怎么最省" -q
# 用内置 Mock,不联网(无需 Token)
node src/index.js --offline "深圳南山,巨无霸,到店,怎么最省"
# 下单(外送需带地址)
node src/index.js --order 1
node src/index.js --order 1 --address ADDR12345支持的交互指令:
| 你说 | 效果 |
|---|---|
| 任意描述需求 | 出方案 |
下单方案1 |
创建订单,返回支付链接 |
换一家店 |
重新比价 |
再便宜点 |
查看凑单建议 |
exit / 退出 |
退出 |
import { createPlanner } from './src/factory.js';
const planner = createPlanner(); // 不传 offline = 连真实接口
// ① 一句话拿方案
const result = await planner.handle('深圳南山,巨无霸,到店,怎么最省');
if (result.type === 'plans') {
result.plans.forEach((p, i) => {
console.log(`方案${i + 1}: ${p.planName} → ¥${p.finalPrice / 100}`);
});
}
// ② 下单(注意:planner 是有状态的,上面的方案还在)
const order = await planner.order(1);
console.log(order.success ? order.payUrl : order.errorMsg);
// ③ 查订单状态
const status = await planner.queryOrder(order.orderId);const planner = createPlanner({ offline: true });
// planner 内部维护会话状态,可连续多轮交互
await planner.handle('深圳南山,巨无霸,到店,怎么最省'); // 第1轮:出方案
await planner.order(1); // 第2轮:下单
await planner.queryOrder(); // 第3轮:查状态
// 发起全新需求时,handle() 会自动复位会话,无需手动 reset
await planner.handle('再来一单');返回值结构:
result.type |
含义 | 关键字段 |
|---|---|---|
plans |
出方案了 | plans[]、matchedItems、comboAdvice、pointsAdvice |
clarification |
信息不足,需追问 | message、missingFields |
campaign |
活动建议 | advice.suggestion、advice.futureActivities |
points |
积分建议 | advice.bestCoupon、advice.pointValueRatio |
error |
执行异常 | message |
见 examples/usage.js,覆盖 9 个场景,全部可直接运行。
以下为离线 Mock 数据下的实际输出,真实结果以线上门店菜单与实时优惠为准。
👤 深圳宝安,巨无霸套餐,到店,怎么最省
💰 已匹配:巨无霸(¥26.50)
【方案1】到店自取巨无霸6元券 到手价 ¥20.50(省 ¥6.00)
【方案2】到店自取原价方案 到手价 ¥26.50
👤 30块预算,一个人,外送
💰 预算30元可选商品有限,已搭配最接近的方案。以下是实际可用优惠券算出的最低到手价:
【方案1】麦乐送薯条买一送一券 到手价 ¥32.50(省 ¥7.00)
【方案2】麦乐送原价方案 到手价 ¥57.50
注:以上为离线 Mock 数据下的演示输出,真实结果以线上门店菜单与实时优惠为准。
👤 最近巨无霸有活动吗
📅 「巨无霸 8 折限时活动」预计优惠约20%,明显优于当前方案(¥33.50),
建议等到活动开始再下单
👤 用积分兑换最划算的券
⭐ 推荐兑换「点餐优惠券 12元」:900 积分换¥12.00券,
价值比0.0133 元/积分(全站最优)。兑换后剩余 736 积分
👤 下单方案1
✅ 订单 MCD-20261017-8823|支付链接 https://pay.mcd.cn/...
请通过支付链接扫码或打开麦当劳 APP 完成支付
mcd-saver-planner/
├── README.md # 项目说明(本文件)
├── CONTEST_DECLARATION.md # 参赛声明(官方原文件,内容未改动)
├── MCP_INTEGRATION.md # MCP 集成说明:协议、工具、流程、业务价值
├── workbuddy.md # WorkBuddy 开发上下文记录
├── package.json
├── .env.example # Token 配置示例(占位符)
├── .gitignore
├── mock/ # 离线 Mock(真实响应采样)
│ ├── data.js # 门店 / 菜单 / 券 / 积分 / 活动数据
│ └── transport.js # Mock fetch 传输层
├── examples/
│ └── usage.js # 9 个可运行调用示例
└── src/
├── index.js # CLI 入口
├── factory.js # 规划器工厂(解耦 CLI 与测试)
├── config.js # 全局配置 + 枚举 + beType 传递规则
├── mcp/
│ ├── client.js # MCP Client:Streamable HTTP + JSON-RPC
│ └── tools.js # 18 个 Tool 的类型化封装
├── modules/
│ ├── intent.js # 模块 1:需求解析与参数补全
│ ├── couponRules.js # 券模型 + 叠加规则引擎
│ ├── priceEngine.js # 模块 2:最优优惠组合计算
│ ├── channelCompare.js # 模块 3:多渠道比价
│ ├── combo.js # 模块 4:智能凑单推荐
│ ├── campaign.js # 模块 5:活动预判决策
│ ├── points.js # 模块 6:积分最优兑换
│ ├── order.js # 模块 7:下单执行引擎
│ └── menuMatcher.js # 关键词 → 真实商品编码匹配
├── workflow/
│ ├── mainFlow.js # 主流程编排
│ ├── stateMachine.js # 会话状态机
│ └── testSuite.js # 验收测试(109 项断言)
└── utils/
├── cache.js # TTL 缓存
├── retry.js # 指数退避 + 限流 + 降级
├── logger.js # 分级日志
└── money.js # 金额单位归一化(内部统一「分」)
| 用户 | 痛点 | 本项目的价值 |
|---|---|---|
| 🧑 重度优惠党 | 手里有一堆券但不知道能用哪几张 | 自动遍历组合,找出叠加后最优解,权益不浪费 |
| 👨👩👧 家庭/多人用餐 | 预算有限,要搭配又要省 | 按人数与预算自动搭配,并算出实际最优到手价 |
| 🏃 赶时间上班族 | 来不及比价 | 一句话出方案,选完直接下单 |
| 💤 积分沉睡用户 | 积分放着慢慢过期 | 价值比算法找出最优兑换项,优先消耗临期积分 |
| 🧓 不熟悉 App 的用户 | 找不到券、不敢用券 | 自然语言交互,无需理解任何优惠规则 |
1. 并行拉取:门店券 / 麦麦省券 / 用户已持券
2. 券分类打标:门店券组 / 麦麦省券组 / 活动券组 / 积分券组
3. 生成可行组合:
- 空组合(不用券)永远保留,作为兜底基线
- 单券组合
- 跨类型组合(门店券 + 麦麦省券),跳过互斥与活动券
4. 逐个组合调用 calculate-price,以服务端返回为准
5. 组合数超限时按「券金额 + 是否多券叠加」剪枝,控制调用次数
6. 按最终到手价升序取 Top3
价格得分 = min-max 反向归一化(finalPrice) 权重 0.60
时间得分 = min-max 反向归一化(waitTime) 权重 0.25
距离得分 = min-max 反向归一化(distance) 权重 0.15
(外送渠道固定 0.5,避免与配送时效重复惩罚)
综合得分 = 0.60×价格 + 0.25×时间 + 0.15×距离
价值比 = 券面值 ÷ 所需积分 (单位:元/积分,越大越划算)
例:5元券/500积分=0.0100 12元券/900积分=0.0133 ✅ 30元券/3000积分=0.0100
按价值比降序而非所需积分升序,才能找到真正的最优解。
凑单后总价 = 当前总价 + 凑单品价格 − 券优惠额
仅当 凑单后总价 < 不用券总价 时才推荐
避免出现「为了用券反而多花钱」的负向体验。
| 约束 | 实现 |
|---|---|
| 单轮工具调用 ≤ 15 次 | 组合数上限 12 + 实时计数熔断 |
| 并发 ≤ 10,间隔 ≥ 100ms | runLimited() 分批执行 |
| 429 限流 | 指数退避 1s / 2s / 4s,最多 3 次;客户端滑动窗口预检 |
| 401 Token 失效 | 立即终止,不做无意义重试 |
| 缓存 | 菜单/活动 1 小时,用户券/积分 5 分钟 |
| 优雅降级 | 可选能力失败不影响主流程,返回已算结果并标注 |
| 状态机 | 严格流转,禁止跨状态跳转;新需求自动复位 |
开发中通过真实调用麦当劳 MCP Server 发现并处理了几个关键契约细节,详见 MCP_INTEGRATION.md:
- 优惠券绑定在商品项级——
couponId是items[]内的字段,多券叠加时必须挂到不同商品项 beCode强关联——得来速/外送/团餐场景必传,代码中统一由resolveChannel()处理- 金额单位不统一——价格返回「分」,菜单返回「元」,券类字段为「元」,内部统一为「分」
- 券的满减信息藏在标题里——
query-store-coupons不返回threshold/discount,需从title文案解析 itemsschema 兼容——同时兼容标准数组、嵌套对象、双层包裹三种形态
本项目为麦当劳程序员节创意开发大赛参赛作品。
- 赛事时间:2026 年 10 月 9 日 10:30 — 10 月 25 日 23:59
- 参赛声明:见 CONTEST_DECLARATION.md(官方原文件,未作任何修改)
- MCP 集成说明:见 MCP_INTEGRATION.md
报名 Issue 格式:
Issue标题:麦麦极致省钱规划师 - 全渠道优惠决策引擎
Issue正文:
【参赛申请】
项目名称:麦麦极致省钱规划师
项目地址:https://github.com/你的用户名/mcd-saver-planner
项目简介:基于麦当劳MCP的智能省钱决策引擎,自动遍历全渠道全量优惠组合,输出最低到手价点餐方案,支持多渠道比价、智能凑单、积分最优兑换、一键领券下单。
本项目为参赛者独立开发,非麦当劳官方产品。项目输出仅供参考,不构成医疗、营养或其他专业建议;餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。
MIT