makabaka0328 / mcd-compass
git clone https://github.com/makabaka0328/mcd-compass.git
—
+1
stars, 24h · #17,116
+62
stars, 7 days · #3,326
+62
stars, 30 days · #10,326
62
★ total · +62% this week
0
forks · 0 open issues
Star history (as recorded here)
LanguagePython
License—
Created2026-10-16 (7d ago)
Last push7d ago
Watchers0
OwnerUser
Links
README excerpt
# 麦麦罗盘 · mcd-compass > 基于 **麦当劳中国 MCP(McDonald's China MCP)** 的会员优惠**资产经营**助手。 > **算盘算这一单,罗盘算这一季。** > 把「活动日历 × 券资产 × 积分账户」当成一支**会过期、会错配、会静默失效**的资产池来打理。 麦当劳程序员节创意开发大赛参赛作品 · 非麦当劳官方产品。 📊 实跑资产台面:`docs/asset-board.html` · 实测发现:`docs/FINDINGS.md` · 指标口径:`docs/METRICS.md` · MCP 集成:`MCP_INTEGRATION.md` --- ## 一句话介绍 **用户问「我那 800 积分该换什么?这周的券要过期了吗?这个东西现在买还是再等等?」,它把散落在积分账户、券包、活动日历、麦麦商城四个角落的数据拉齐,输出一页可执行的资产台面。** 实测(2026-10-16,真实 MCP 返回): [code] 同样的积分,兑不同商品得到的消费额最多差 **5 倍** —— 而这不是折扣力度的差异,是**积分定价档位的差异**。 --- ## 它解决什么问题 麦当劳的优惠不是一次性折扣,而是三支**会随时间变化**的资产: | 资产 | 失效方式 | 典型损失 | |---|---|---| | 优惠券 | 到期作废、渠道不匹配、商品不匹配 | 券摆在卡包里没领、领了没用、用错渠道 | | 积分 | 本月/下月过期、兑换档位错配、只能换券不能抵现 | 过期归零;或同一份权益多花一倍积分 | | 活动窗口 | 只在新品日开卖、只卖 3 天、下周三才上线 | 买早了没优惠,等过头了活动结束 | **用户的损失大多不是「不会比价」,而是「券过期了」「积分兑错了档」「要买的东西明天才开始的活动」。** 罗盘的定位就在这个时间轴上:**它不下单比价,它经营资产。** | 角色 | 职责 | |---|---| | 麦当劳 MCP | 积分账户、券池、活动日历、在售商品、兑换档位、抽奖资源判定 —— **唯一数据与数值来源** | | 麦麦罗盘 | 归一化 → 分桶 → 排序 → 标记冲突与缺口 → 生成行动清单 —— **只做编排与确定性推导** | | 用户 | 决定想吃什么、决定要不要抽奖、确认领券与兑换 | --- ## 与「点餐比价类」助手的分工 这不是一个「转发请求」的壳,也不是一个「枚举组合取最小」的比价器。它回答的是**另外一组问题**: | | 点餐比价类助手 | 麦麦罗盘 | |---|---|---| | 时点 | 下单**那一刻** | 下单**之前**的一周 / 一个月 | | 单位 | 一单 | 一个账户 | | 输入 | 「我要 A+B+C,怎么最省」 | 「我手里有什么,先动哪个」 | | 核心动作 | 枚举候选组合 → 逐组实算 → 取最小 | 拉齐资产 → 按失效紧迫度与积分占用率排序 → 标记冲突 | | 输出 | 一个最优组合 | 一页资产台面 + 行动清单 | | 典型问题 | 「同样的东西怎么少花 ¥33」 | 「800 积分换什么最值」「这周哪张券会过期」 | 两者可以串联:罗盘先解决「什么时候买、用哪个渠道的券」,再交给比价逻辑解决「这一单怎么拼」。 --- ## 三大能力 + 一个决策门 ### ① 择时雷达 Timing Radar —— 「现在买,还是等?」 读 `campaign-calendar` 与 `now-time-info`,把**日期 → 活动**的扁平时间线**归一化成活动窗口**。 实测中「麦当劳 X PEACEMINUSONE」在 10/13、10/15、10/16 各出现一次 —— 直接罗列会让用户以为有三场活动。 罗盘按标题归一化合并日期,并从活动正文解析有效期区间(如 `10月8日至10月21日`): [code] ### ② 资产台账 Asset Ledger —— 「我有什么,先动谁?」 读 `available-coupons`、`auto-bind-coupons`、`query-my-coupons`、`query-my-account`。 实测账户是一个**零券零积分的冷启动状态**(可用 0 分 / 累计 86 分 / 已过期 86 分,卡包为空但有 7 张可领券)。 罗盘的判断是明确的:**第一动作是领券,不是比价**。 [code] ### ③ 兑换精算 Points ROI —— 「积分换什么最值?」 读 `mall-points-products` + `mall-product-detail`。 **先分池**:同一个工具返回两个完全不同的池子,混在一起排序会得出荒谬结论。 | pool | shopId | 特征 | 数量(实测) | |---|---|---|---| | 积分兑券池 | 2 | `point > 0`、`price = 0` | 24 项 | | 主题活动池 | 5 | `point = 0`、`price > 0`(现金购买派对/品鉴会) | 27 项 | **再排序**:按 `积分占用率 = points ÷ extTradePrice` 升序。这是纯 MCP 口径,无需任何外部假设。 **最后求最优解**:在用户给定的「想要清单」上跑有界背包精确解。 ### ④ 资源决策门 Lottery Gate —— 「现在抽、先攒、还是去换?」 读 `query-lottery-info`、`query-my-prizes`。 [code] **这一层最重要的设计取舍:不计算中奖期望值。** `query-lottery-info` 只返回奖品名称与类型,**不含任何中奖概率或权重字段**。任何形如 「期望收益 = Σ 奖品价值 × 概率」的算法都只能是编造。因此罗盘只复述服务端自己的 `drawDecision` 资源判定,把概率决策交还给 MCP。 --- ## 独有输出:资产台面(Asset Board) **不做加权合成分。** 券、积分、活动窗口三者的价值量纲不同(券没有到期日、积分没有单价、 活动没有折扣力度),强行合成一个「净值总分」只会得到看起来精确、实际上编造的数字。 因此台面采用**三段式**: | 段 | 含义 | 内容 | |---|---|---| | ① 立刻可动 | 今天就能执行的、确定的事 | 账户快照、可领券清单、积分占用率排行、兑换方案 | | ② 即将失效 | 有明确倒计时、会随时间贬值的事 | 临期积分、兑期将尽商品、活动窗口倒计时 | | ③ 需人工确认 | 数据有冲突或有缺口、罗盘不能替你决定的事 | 同名冲突组、数据缺口声明 | --- ## 真实性对照表 | 项目 | 性质 | 说明 | |---|---|---| | 积分账户、券池、活动日历、商城商品 | ✅ 真实 | 2026-10-16 通过 McD MCP 实跑返回,快照见 `engine/samples/` | | 积分占用率(7.25 ~ 36.53 分/元) | ✅ 真实 | 全部由 `points ÷ s