Skip to content
3436872746Public

About

No description, website, or topics provided.

Resources

Stars

143 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

mcd-swap

麦当劳点餐的约束求解工具。

给定热量上限、蛋白质下限和预算,枚举门店在售套餐的全部合法换购组合,输出满足约束的方案,并用官方 calculate-price 复核实付价。

demo

背景

麦当劳 App 按套餐售卖,选配只能在预设组合内调整。而实际需求常常是反向的:给定热量、蛋白质和预算,反推应该怎么选。

以单店为例:102 个在售 SKU,每份套餐 2–4 轮选配,每轮 6–25 个可替换项,合法组合共 18,928 种。人工枚举不现实。

流程

本工具把这些组合全部展开,按约束过滤排序,再对入选方案做价格复核。

安装与运行

Python 3.9+,无第三方依赖。

git clone https://github.com/3436872746/mcd-swap.git
cd mcd-swap

# Token 申请:https://open.mcd.cn/mcp → 登录 → 控制台 → 激活
export MCD_MCP_TOKEN=你的token

python -m mcd_swap --kcal 500 --protein 25 --budget 25 --top 2 --check

输出:

候选方案 7 个(58 个套餐可解析)

#1  人气经典随心配   ¥14.90  ✓官方计价 ¥14.90
    482 kcal | 蛋白质 29g | 脂肪 23g | 碳水 38g | 钠 1018mg
    阳光柠檬红茶中杯 → 小杯玉米杯 (+0.0元, -64kcal)

#2  精选超值随心配   ¥13.90  ✓官方计价 ¥13.90
    438 kcal | 蛋白质 26g | 脂肪 22g | 碳水 31g | 钠 997mg
    阳光柠檬红茶中杯 → 小杯玉米杯 (+0.0元, -64kcal)

每行方案的构成:

  • 套餐名与实付价
  • 热量、蛋白质、脂肪、碳水、钠
  • 相对该套餐默认配置的改动,以及改动带来的价格和热量变化

参数

参数 说明
--kcal N 热量上限;配合 --objective kcal_fit 时作为目标值
--protein N 蛋白质下限(克)
--budget N 预算上限(元)
--objective 排序方式:protein_per_yuan 单位价格蛋白质 / lean 蛋白质最高 / kcal_fit 最接近目标热量 / cheapest 最便宜
--top N 输出方案数
--check 调用 calculate-price 复核每个方案的实付价
--live 按当前时段重新拉取门店菜单后再计算

作为 MCP Server 使用

命令行只是外壳,核心是一个 stdio MCP Server,可直接接入支持 MCP 的客户端:

{
  "mcpServers": {
    "mcd-swap": {
      "command": "python3",
      "args": ["-m", "mcd_swap.server_main"],
      "env": { "MCD_MCP_TOKEN": "你的token" }
    }
  }
}

对外提供三个工具:

工具 用途
plan_meal 按热量、蛋白质、预算约束配餐,返回经官方复核的方案
find_store 按城市和关键词查询门店,获取 storeCode
item_nutrition 查询单个餐品的官方营养成分

价格校验

菜单接口返回的 currentPrice 并不总是可无条件使用的价格。部分套餐带有 discountType: 随单购麦金卡优惠,此时 currentPrice 是持卡会员价,非会员按 originalPrice 结算。初期直接使用 currentPrice,导致这部分套餐的报价与实际应付相差一倍以上。

现在的处理方式:

  1. 带会员条件的套餐单独标注,默认按非会员价计算。
  2. 每个输出方案都会把完整 roundList(含换购子项)发给 calculate-price,以官方计费结果为准。
  3. 官方换购差价 diffPrice 精确到元,本地估算可能与官方存在 0.5 元级差异,因此只有 --check 的结果可直接引用。

营养数据对齐

官方营养表包含 160 项,菜单包含 102 个 SKU,两侧命名不一致(营养表为「麦乐鸡5块」,套餐选配为「麦乐鸡-5块」)。项目内维护了一张别名表,位于 mcd_swap/nutrition.py。

未能对齐的餐品(如尚未收录进营养表的新品)不参与计算,也不会按零值处理。因此 102 个 SKU 中有 58 个可完整解析,对应 4,148 种换购组合。

数据来源

全部数据来自麦当劳中国官方 MCP Server(https://mcp.mcd.cn,Streamable HTTP),未使用爬虫:

工具 用途
query-nearby-stores 按城市或关键词定位门店,获取 storeCode
query-meals 门店在售餐品、现价、原价
query-meal-detail 每份套餐的选配轮次、候选项、默认项、换购差价
list-nutrition-foods 餐品营养成分:能量、蛋白质、脂肪、碳水、钠、钙
calculate-price 方案最终组合的实付价

data/ 目录保存上述接口的原样返回,未作二次加工,可据此复现每个结果。完整调用流程见 MCP_INTEGRATION.md。

已知限制

  • 与门店绑定:菜单、价格和供应状态均依赖门店。仓库快照对应上海黄浦华旭国际大厦店(storeCode=1450713),换店需修改 MCD_STORE 或先调用 find_store。
  • 与时段绑定:门店在正餐与早餐时段售卖不同的菜单,跨时段使用旧快照会导致套餐显示「商品已售罄或不可售」。此时加 --live 按当前时段重新拉取。
  • 营养覆盖不完整:58/102 个 SKU 可解析,其余为营养表尚未收录的新品。
  • 不下单:仅使用只读接口,不创建订单、不涉及支付。
  • 非营养建议:工具只做算术与约束求解。

适用场景

需要控制热量或蛋白质摄入、但仍在麦当劳就餐的用户,以及希望了解麦当劳 MCP 在菜单查询之外如何使用的开发者。

声明

本项目为麦当劳程序员节创意开发大赛参赛作品,由参赛者独立开发,非麦当劳官方产品。餐品信息、价格与供应状态以麦当劳官方渠道的实时结果为准。

About

No description, website, or topics provided.

Resources

Stars

143 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages