一群人一起点麦当劳时,帮你凑满减、算最优券组合、按人分账,并一键下单。
一个基于麦当劳 MCP 与 WorkBuddy Skill 的多人拼单助手。
办公室里五个人一起点麦当劳,实际流程往往是这样:
- 群里问一圈"你吃什么",拼出一份手写清单
- 打开菜单,把每个人点的东西加进购物车
- 纠结"我卡包里那几张券用哪张、用在哪个商品上最划算"
- 终于下单,然后拿出计算器按人头摊钱——共享的小食怎么摊?优惠归谁?
- 有人觉得算错了,群里再扯十分钟
第 3 步和第 4 步,本该是程序该干的事。
麦当劳的优惠券是绑定到具体商品的,所以"用哪张券"本质上是一个分配问题:几张券、几个商品,怎么配才能让总价最低?再加上会员价、随单购价、配送费分摊,手算根本算不过来。
麦麦拼单官把这两步自动化了。
麦当劳的券绑定到具体商品,而且一张订单只能用一张券(实测 600022)。所以真正的问题是:
手上有 N 个人要买的东西、M 张券,怎么拆成若干单(每单一张券)让总价最低?
这是一个二分图最大权匹配问题:左边是券、右边是"需求份",边权 = 该券顶替该份能省的金额。项目用匈牙利算法求精确最优的用券组合,再派生多套备选拆法,最后把 calculate-price 当唯一可信的价格预言机逐单真实试算,取真实最低总价。
商品原价(不用券) ¥118.00
★ 拆单用券后 ¥108.80 省 ¥9.20
──────────────────────────────────────────
单①「麦旋风任选」 经典麦旋风 ¥15.00 → ¥9.90
单②「薯薯任选」 薯条 ¥14.00 → ¥9.90
──────────────────────────────────────────
一单一券(接口限制);到店自取无配送费,拆单零成本
为什么是"拆单"而不是"多张券叠一单"? 因为这是实测结论 —— 官方文档里没写。 用真实券跑
calculate-price才拿到这条规则,项目的整个技术核心因此重写。
还有一条合规硬约束:只对"用户已确定要买的东西"匹配券。券商品不替代任何已购商品时不纳入优化——否则就是诱导加购,赛事规则明令禁止。
"A 不吃辣""B 不要酱""C 要换饮料"不是删商品就完事——要落到 query-meal-detail 的套餐替换与特调参数上,并遵守它隐晦的传参规则。
用分做整数运算 + 最大余额法取整,保证 sum(每人应付) == 订单总额,不会出现"最后差一分钱"的尴尬。
应付合计 ¥132.50
────────────────
A ¥33.60 B ¥37.31 C ¥24.09
D ¥21.00 E ¥16.50
────────────────
合计 ¥132.50 ← 与订单总额一致
不是 demo 级别的调用,而是处理了这些真实坑:
| 坑 | 处理 |
|---|---|
| 菜单价格单位是元,计价接口返回分 | 统一转换,不手算 |
| 菜单展示价可能是随单购价(需同时买卡) | 自动回退到原价,避免虚假承诺低价 |
门店打烊后菜单接口报 600057 |
下单前先校验营业状态 |
| 同一券 ID 对应多个券码 | 按 couponId 分组归一化 |
券绑定独立的券商品码,拿券套菜单同款报 600012 |
只点券商品码并联用券码 |
一单只能用一张券(600022) |
改用"拆单优化"建模,见下方亮点 1 |
| 券商品可能与它替代的菜单品规格不同(券给大薯条、你要的是中薯条) | "省了多少"区分订单口径(与账单对齐)与用户口径(对外讲省额),并说明规格变化 |
到店下单的 takeWayCode 不在工具 schema 里枚举(且 take-in-store 字面像堂食、实为外带) |
一律从 calculate-price 的 takeWayList 取,不硬编码 |
同一特调组内多个选项可能共用同一个 code(可乐的"标准/去冰/多冰/少冰"全是 200002) |
靠 selectedKey 区分,且每次从 query-meal-detail 现取,不写死 |
订单状态字段与文档不一致(orderStatus 是中文、status 数字对不上) |
判断状态只读 orderStatus 文本 |
| 下单后金额可能因活动变动而与试算不符 | order-summary 自动核对 realTotalAmount,不一致即提示可取消订单 |
| 限流 600 次/分钟 | 寻优设探测预算上限(默认 20 次) |
以上结论都在真实下单闭环中验证过:2026-10-09 至 10-10 实测三次 3 人拼单(含一次本店无可用券的情形),完整走完 门店 → 券机会 → 拆单优化 → 分账 → 下单,订单均在麦当劳 App 正常生成待支付,实付与下单前试算分毫不差(¥130.90 / ¥84.30 / ¥91.30 三单)。
- 一个麦当劳中国 MCP Token(在 麦当劳 MCP 开放平台 手机号登录后,于「控制台」申请)
- 已安装并支持自定义连接器的 WorkBuddy
第一步:配置 MCP 连接器
在 WorkBuddy 左侧边栏进入【专家·技能·连接器】→【连接器】→【自定义连接器】→【配置 MCP】,填入:
{
"mcpServers": {
"mcd-mcp": {
"type": "streamablehttp",
"url": "https://mcp.mcd.cn",
"headers": {
"Authorization": "Bearer YOUR_MCP_TOKEN"
}
}
}
}
⚠️ 把YOUR_MCP_TOKEN替换为你的真实 Token,然后保存并启用该连接器。
第二步:安装本 Skill
把本仓库目录复制到 WorkBuddy 的用户技能目录:
# macOS / Linux
cp -r mcd-group-order-mate ~/.workbuddy/skills/
# Windows (PowerShell)
Copy-Item -Recurse mcd-group-order-mate "$env:USERPROFILE\.workbuddy\skills\"重启会话后,技能即可被自动识别。
用户
我们办公室 5 个人中午一起点麦当劳,帮我拼个单
麦麦拼单官
好的~需要确认几件事:
- 到店自取还是外送?
- 每个人想吃什么、有没有忌口?
- 要不要来一份大家共享的小食?
用户
到店自取。A 要巨无霸三件套,B 也要巨无霸三件套,C 要麦辣鸡腿汉堡三件套再加一个麦旋风,D 要板烧鸡腿堡(去酱),E 一杯中可乐。共享小食来一份麦乐鸡。
麦麦拼单官
已定位到门店:麦当劳北京建外SOHO(A座)餐厅(storeCode
1950564,距你 269m,营业中)【麦麦拼单方案】北京建外SOHO店 · 5 人 · 到店自取 ────────────────────────────────── # 餐品 数量 单价 小计 1 巨无霸三件套 2 37.50 75.00 2 麦辣鸡腿汉堡三件套 1 33.50 33.50 3 板烧鸡腿堡(去酱) 1 23.50 23.50 4 经典麦旋风(C) 1 15.00 15.00 5 麦乐鸡(共享) 1 14.50 14.50 6 可乐(中杯,E) 1 9.50 9.50 ────────────────────────────────── 商品原价 171.00 ★ 券优化:「经典麦旋风」用「麦旋风任选」券 15.00 → 9.90 省 5.10 应付合计 165.90 ────────────────────────────────── 券只顶替本单已点的第 4 项,其余商品按原价;一单即可,无需拆单 (若多张券分别顶替不同商品,才需要拆单——一单只能用一张券)【麦麦拼单分账】 商品合计 ¥171.00 优惠 -¥5.10 应付合计 ¥165.90 ──────────────── A ¥40.40 B ¥40.40 C ¥46.30 D ¥26.40 E ¥12.40 ──────────────── 合计 ¥165.90确认无误的话,回复「下单」我就帮你创建订单~
以上为格式示例(金额为示意)。真实运行时所有数字都来自
calculate-price与create-order的返回。
需求收集
└─ 人数 / 偏好 / 取餐方式 ──→ beType、orderType
门店定位
└─ query-nearby-stores ──→ 校验营业状态 ──→ storeCode
菜单与券池
├─ query-meals ──→ 菜单 + 价格(校正随单购价)
├─ available-coupons ──→ 麦麦省可领券
└─ query-store-coupons ──→ 本店可用券池
方案生成
└─ query-meal-detail ──→ 套餐替换 / 特调(满足忌口)
券机会挖掘 ★
├─ now-time-info ──→ 定下单时刻
└─ coupon-opportunities ──→ 一次调用内完成:按时刻/渠道筛券 + 净收益排序(只列已确定要买的)
券与拆单优化 ★
├─ coupon_optimizer.split ──→ 最大权匹配(匈牙利)+ 多套候选拆法
├─ calculate-price × N ──→ 逐单真实试算(受预算约束)
└─ coupon_optimizer.select ──→ 取真实总价最低的拆法
分账
└─ split_bill ──→ 整数运算 + 最大余额法取整
确认下单
├─ create-order ──→ 用户确认后执行(takeWayCode 取自计价返回)
└─ order-summary ──→ 核对实付 == 试算价,不一致即提示可取消
mcd-group-order-mate/
├── SKILL.md # Skill 主入口:编排流程与规则
├── README.md # 本文件
├── MCP_INTEGRATION.md # MCP 集成说明(Tool 清单 / 流程 / 价值)
├── mcp-config.example.json # 脱敏的 MCP 配置示例
├── CONTEST_DECLARATION.md # 参赛声明
├── workbuddy.md # WorkBuddy 开发上下文(专项奖励核验用)
├── references/
│ ├── mcp-tool-map.md # 工具速查、传参规则、实测坑
│ └── output-templates.md # 输出模板
└── scripts/
├── mcd_utils.py # 单位换算 / 随单购价校正 / 券池归一化 / 券机会 / 下单核对
├── coupon_optimizer.py # 券与拆单优化(最大权匹配 + oracle 选择)
└── split_bill.py # 分账计算
python scripts/mcd_utils.py yuan-to-fen --value 33.5
python scripts/mcd_utils.py coupon-opportunities --input probes.json --demand 4810,1401 \
--now "2026-10-10 00:06" --channel pickup # 内含时刻/渠道筛券 + 合规过滤
python scripts/mcd_utils.py coupon-availability --input coupons.json # 可选:逐券时段明细
python scripts/coupon_optimizer.py split --input split_input.json
python scripts/coupon_optimizer.py select --input probe_results.json
python scripts/split_bill.py --input bill.json
python scripts/mcd_utils.py order-summary --input order_resp.json --expected-fen 13090- 办公室同事:一起点午饭,需要有人负责点单和算钱
- 朋友聚会 / 家庭点餐:人多、口味杂、要分摊
- 经常用券的人:手里券多,想知道"怎么用最划算"
- 不想当"人肉计算器"的那个人:每次拼单都被推举出来算账
Q:会不会自动帮我下单? 不会。创建订单前一定先展示方案并等待你明确确认。
Q:会不会擅自用我的券?
不会。领取麦麦省券(auto-bind-coupons)属于写操作,会先征求你的同意。
Q:价格是估算的吗?
不是。所有金额都来自 calculate-price 的真实返回,项目不做任何价格猜测。
Q:支持外送和团餐吗? 当前版本以「到店自取」为主链路,外送与团餐按同一参数映射扩展。
本项目为「麦当劳程序员创意开发大赛」参赛作品,由参赛者独立开发,非麦当劳官方产品。项目输出仅供参考,不构成医疗、营养或其他专业建议;餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。