Skip to content

About

No description, website, or topics provided.

Resources

Stars

105 stars

Watchers

0 watching

Forks

Repository files navigation

mcd-nearest-deal · 麦当劳最近在售点

不问"离我最近的门店是哪家",只回答"最近一家有我想要的东西、还用得上我那张券的门店在哪,要花多少钱"。

麦当劳程序员创意开发大赛参赛作品 · 基于麦当劳中国 MCP 服务开发


这个项目解决什么问题

打开麦当劳 App 点餐,通常要经历这么一串折腾:

  1. 想吃的巨无霸,家附近三家店,不知道哪家现在有卖
  2. 挑了一家点进去,发现早餐档刚过,巨无霸要等到十点半
  3. 换成套餐,翻半天券包,不确定这张"满 30 减 8"在这家店能不能用
  4. 到结算页才看到配送费 9 块,总价比预想多了十块
  5. 放弃,随便点了个别的

四步里每一步都在做信息核对,而且核对的是分散在不同接口里的三类信息:门店距离、门店在售状态、门店可用券。

mcd-nearest-deal 把这三件事串成一条链路:从最近的店开始,逐家验证"卖不卖",命中即停;锁店之后再取"门店券 ∩ 我的券"的交集;最后用 MCP 算价接口算出真实到手价,把 2–3 个方案并排给用户。下单是最后一步,且必须用户明确确认。

与常见方案的区别

大多数同类作品做的是"在已有门店里比价"或"在已有菜单里算卡路里"。本项目的落点在券与库存的交叉验证:一家店有券但不卖、有货但券不能用,这两种情况在实际点餐里比"哪家便宜两块"更常见,也更影响体验。

目标用户

用户 场景 他真正想知道的
上班族 午休 40 分钟,想快速解决一顿 公司楼下哪家店现在能买到,多少钱,几分钟能取
有券的人 券包里有十余张券,懒得逐张比 我这张券哪家店能用,怎么搭最划算
预算敏感学生 一天伙食预算固定 25 块以内能吃到什么,含不含配送费
家庭用户 一次点多人份 附近哪家店品类全,凑单能不能吃到满减

能做什么

  • 最近在售点定位:给地址或定位,返回最近的、确实在售目标餐品的门店,附距离与替代选项
  • 券可用性交叉核对:门店券与账户券取交集,避免"看着能用结算不行"
  • 组合搭配:按预算组 2–3 个方案,单点 / 套餐 / 凑满减各一
  • 真实算价:调 calculate-price 得到含配送费、优惠的应付金额,不只报原价
  • 多方案比价:附带脚本做确定性排序,标出差额与"最近≠最便宜"的提示
  • 确认后下单:复述门店、餐品、就餐方式、券、应付五项后,用户确认才创建订单
  • 订单查询与取消:查进度、查历史、取消未支付订单

不能做什么

明确划清边界,避免预期错位:

  • 不代付。订单支付链接由用户本人打开完成付款。项目不接触任何支付凭证。
  • 不推荐"最省"。只给"当前可查到的券与门店条件下"的较优解,不承诺全局最优。
  • 不做营养建议。营养数据可作为参考展示,但不构成医疗或膳食指导。
  • 不缓存个人数据。地址、手机号、券码、订单内容仅在单次任务内使用,不落盘。
  • 不覆盖非点餐场景。积分抽奖、商城兑换、活动预约虽在 MCP 能力范围内,但不是本技能主线,仅在用户明确要求时按对应工具处理。

安装

前置条件

  1. 一个麦当劳中国 MCP Token
    • 访问 https://open.mcd.cn/mcp
    • 右上角【登录】,手机号验证
    • 点【控制台】→【激活】→ 同意服务协议
    • 复制生成的 Token
  2. 一个支持 Streamable HTTP 的 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;保存后要回到连接器列表点【启用】,首次启用会弹"信任确认",点信任才会加载工具。任一遗漏都会得到 401。

脱敏后的示例见本仓库 mcp-config.example.json,其中只使用环境变量占位符。

第二步:安装技能

本仓库根目录即技能目录:SKILL.md 在根目录,references/、scripts/ 也在根目录下。安装就是把整个仓库放进 WorkBuddy 的技能目录,并且目录名必须是 mcd-nearest-deal(与 SKILL.md 里 name 字段一致):

# macOS / Linux
git clone https://github.com/<你的账号>/mcd-nearest-deal.git ~/.workbuddy/skills/mcd-nearest-deal

# Windows (PowerShell)
git clone https://github.com/<你的账号>/mcd-nearest-deal.git "$env:USERPROFILE\.workbuddy\skills\mcd-nearest-deal"

若从 GitHub 下载 zip:解压得到 mcd-nearest-deal-main/,重命名为 mcd-nearest-deal 后放进 ~/.workbuddy/skills/。目录名不一致时技能可能不被识别。

重启 WorkBuddy,在【技能】列表中应能看到「麦当劳最近在售点」。

第三步:验证

在对话框里说一句:

帮我在附近找家能买到早餐的麦当劳,看看券怎么用最划算

技能应依次调用 now-time-info、query-my-account、query-nearby-stores、query-meals,然后给出带距离与价格的方案。

提示:如果当前是早餐时段(约 10:30 前),问"巨无霸"会查不到——这不是故障,是正餐菜单还没上线。技能会说明时段并给早餐档的替代。

使用示例

示例一:指名餐品找店

用户

我想吃板烧鸡腿堡,公司附近哪家麦当劳现在能买到?我在上海市黄浦区南京东路 300 号。

技能行为

  1. now-time-info 确认当前时段(是否在早餐档)
  2. query-nearby-stores 按地址取候选门店,距离升序
  3. 对最近一家调 query-meals,检查板烧鸡腿堡是否在售
  4. 若在售,命中即停;若不在售,验下一家,并说明"最近的 A 店当前时段不售,B 店 400 米外有货"
  5. 输出门店名、地址、距离、当前是否在售

示例二:带预算搭配

用户

25 块以内,一个人吃,能用券就用券。

技能行为

  1. 建基线:时间 + 积分
  2. 选最近在售门店
  3. 组两个方案:单点主力餐品 / 单点 + 小食凑券门槛
  4. query-store-coupons ∩ query-my-coupons 取可用券
  5. 分别 calculate-price
  6. 用 scripts/compare_deals.py 排序输出对比表,标出实付差额
  7. 等用户选,确认后才下单

示例三:券在哪家能用

用户

我券包里有张满 30 减 8,附近哪家店能用?

技能行为

  1. query-my-coupons 确认这张券确实存在,读出它的真实门槛字段(不看券名推断)
  2. query-nearby-stores + 逐店 query-store-coupons,找出接受该券的门店
  3. 在可用门店里筛出"凑单到 30 元以上仍划算"的组合
  4. calculate-price 验证折扣是否真的生效(规则上说能叠加、实际不叠加的情况存在)
  5. 给出"券能用 + 凑单方案 + 真实到手价"

示例四:确认下单

技能的复述格式:

确认一下:
  门店      麦当劳(南京东路步行街店),南京东路 300 号 1 层
  方式      到店自取
  餐品      巨无霸套餐 ×1(可乐换无糖)、中薯 ×1
  用券      满 30 减 8
  应付      ¥34.50

确认后我就下单,付款链接会给你,支付前随时可取消。

用户回"可以"才调 create-order。用户回"随便"不算确认。

项目结构

根目录即技能目录,git clone 下来直接可用:

mcd-nearest-deal/                 # 仓库根目录 = 技能目录
├── SKILL.md                      # 技能主文件:五步工作流 + 核心约束
├── references/
│   ├── mcd-tools.md              # 工具分组、调用时机、错误码、待核对清单
│   └── order-rules.md            # 就餐方式配对、预约、券规则、算价、隐私
├── scripts/
│   └── compare_deals.py          # 多方案比价排序(无第三方依赖)
├── README.md                     # 本文件
├── CONTEST_DECLARATION.md        # 参赛声明(官方原文,未改动)
├── MCP_INTEGRATION.md            # MCP 接入与调用流程说明
├── mcp-config.example.json       # 脱敏配置示例
└── workbuddy.md                  # WorkBuddy 开发对话上下文

参赛要求文件(README.md、CONTEST_DECLARATION.md、MCP_INTEGRATION.md、mcp-config.example.json、workbuddy.md)与技能文件同处根目录,互不冲突:WorkBuddy 只读取 SKILL.md 及其引用的 references/、scripts/,其余文件不参与技能运行。

设计取舍

几个刻意的决定,说明为什么这么做:

为什么"命中即停"而不是查完全部门店。 查完所有店再排序,接口调用量与门店数线性相关,且用户只关心结论。逐家验证到第一家命中就停,平均只需 1–3 次 query-meals 调用,也天然满足 600 次/分钟的限流约束。

为什么券要查两层。 query-store-coupons 回答"这店收不收",query-my-coupons 回答"我有没有"。只查一层就会给出用户实际用不了的优惠。取交集是唯一正确的做法。

为什么金额只认 calculate-price。 原价减券面与实际应付之间常差配送费、包装费、餐品级折扣。手算看起来对,结算页会多出几块。所以技能里明令:calculate-price 成功前只能叫"预估"。

为什么把写操作单列成约束。 下单、领券、取消、抽奖都会改变账号状态。这类操作在自然语言驱动下最大的风险不是技术失败,而是"用户只是问问,AI 真给下单了"。约束条款写在 SKILL.md 最前面,优先于任何流程步骤。

为什么不硬编码枚举值。 beType、orderType、beCode 是这套接口里最容易出问题的地方:不同就餐方式下同一个字段语义不同,跨场景复用会静默下错单——接口返回成功,订单却下到了别处。所以规则是"全部从返回里读原值,同一次流程内复用,切换就餐方式必须重新取"。

已验证与未验证

2026-10-24 用真实 Token 与真实账号跑通了完整只读链路(时间 → 账号 → 门店 → 菜单 → 券 → 算价)。诚实标注当前状态:

项 状态
MCP 服务地址、协议、鉴权方式 ✅ 已核实
端点存活性 ✅ 已实测:https://mcp.mcd.cn 可访问,约 0.9s 响应
鉴权失败行为 ✅ 已实测:无 Token → 403;无效 Token → 401 当前鉴权码不存在或已失效!
33 个工具的名称与职责 ✅ 已核实(官方仓库 v1.0.9),且已程序化校验:文档引用的工具名 100% 存在于官方清单
now-time-info / query-my-account ✅ 已实测,返回真实时间与积分账户
query-nearby-stores ✅ 已实测两种 searchType 的差异:收藏查询距离恒为 0 且无营业状态;搜索查询有真实距离(米)与 businessStatus
query-meals ✅ 已实测,确认早餐/正餐是两套菜单(10:27 仅有早餐品)
query-store-coupons ∩ query-my-coupons ✅ 已实测交集逻辑:账户 4 张券,三店交集仅 1 张,另两店为空数组
calculate-price ✅ 已实测三组对比:到店无券 ¥11.90 / 到店带券 ¥9.90 / 外送 ¥17.90(含 ¥6.00 配送费)
外送链路 ✅ 已实测 delivery-query-addresses → delivery-query-stores → 算价,确认 beCode 在到店/外送下取值不同
券是否真生效的验证方法 ✅ 已实测:带券后 discount 从 710 分升至 910 分
比价脚本 ✅ 已用真实算价数据跑通排序、差额、节省比例
create-order 及之后的下单链路 ⚠️ 未实测:测试不应产生真实订单。写操作规则见 references/order-rules.md
query-meal-detail、营养查询、商城/抽奖/活动 ⚠️ 未实测,非主链路

references/mcd-tools.md 已按实测结果重写:标 ✅ 的字段名与返回结构可直接信任,标 ⚠️ 的首次调用时按报错回写。金额单位「分」、price 与 productPrice 的区别、beCode 的条件传参,这三处是最容易出错的地方,文档里都有实测例子。

合规与安全

  • 不含真实 Token、密钥、账号凭证;配置文件仅用 ${MCD_MCP_TOKEN} 占位符
  • 不含任何个人信息
  • 不采集、不上传用户数据;所有请求直达麦当劳 MCP 服务
  • 支付环节完全由用户操作,项目不接触支付凭证
  • 遵循《麦当劳 MCP 服务规则》与 WorkBuddy 软件许可协议

开发说明

本项目使用腾讯 WorkBuddy 开发,开发过程见 workbuddy.md。

MCP 集成细节见 MCP_INTEGRATION.md。

免责声明

本项目为麦当劳程序员创意开发大赛参赛作品,由参赛者独立开发,非麦当劳官方产品,与麦当劳中国无隶属或代理关系。

项目输出仅供参考,不构成医疗、营养或其他专业建议。餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。


© 2026 参赛者保留本项目原创内容的相关权利。麦当劳、巨无霸等相关商标归其权利人所有。

About

No description, website, or topics provided.

Resources

Stars

105 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages