麦当劳营养膳食专家(McDonald's Nutrition Diet Expert)
身材管控期也想吃麦当劳?这个专家会帮你根据每日消耗搭配麦麦套餐。
一个基于 SP 矩阵理论 的个人饮食搭配可视化选型工具,基于麦当劳官方 MCP Server 打通「营养计算 → SP 选型 → 套餐推荐 → 门店点餐 → 领券下单 → 健康记录」的完整闭环。
〇、目标用户与使用示例
目标用户
使用示例
以下所有数值均为真实接口实测输出(
POST /api/recommend),非示意。
示例 1 · 减脂期午餐(女 28 岁 / 165cm / 58kg / 中等活动 / 减脂)
目标:全天 1625 kcal · 蛋白 116g · 碳水 189g · 脂肪 45g · 钠上限 2000 mg
单餐目标 552 kcal(1625 × 34%)
方案一(评分 0.8214)
637 kcal · 蛋白 44g · 钠 1878 mg · 占全天 39.2%
· 主餐 麦辣鸡腿汉堡 485 kcal
· 饮品 无糖可口可乐中杯 0 kcal
· 小食 蜜汁BBQ风味薄皮脆汁鸡-带骨里脊 152 kcal
⚠ 钠 1878 mg,已达上限 94%
⚠ 热量比单餐目标高 84 kcal,训练日可接受,休息日建议减一份小食
方案二(评分 0.8162)—— 本餐钠负担最低
580 kcal · 蛋白 33g · 钠 1049 mg · 占全天 35.7%
· 主餐 双层吉士汉堡 429 kcal
· 饮品 优品豆浆小杯 151 kcal
方案三(评分 0.7963)
642 kcal · 蛋白 39g · 钠 1474 mg · 占全天 39.5%
· 主餐 双层吉士汉堡 429 kcal
· 饮品 无糖可口可乐中杯 0 kcal
· 小食 麦乐鸡5块 213 kcal
💡 系统的价值不止于「给出一套餐」,更在于同时告诉你取舍在哪:方案一蛋白最足但钠到 94%,方案二钠只有一半但蛋白少 11g —— 用户可以自己权衡,而不是在「不知道热量」和「只知道热量」之间二选一。
示例 2 · 增肌日午餐(男 25 岁 / 178cm / 82kg / 高强度活动 / 增肌)
目标:全天 3502 kcal · 蛋白 148g · 碳水 535g · 脂肪 86g · 钠上限 2000 mg
单餐目标 1191 kcal
方案一(评分 0.7392)—— 含甜点
1341 kcal · 蛋白 55g · 钠 1838 mg · 占全天 38.3%
· 主餐 芝士安格斯厚牛堡 696 kcal
· 小食 麦麦脆汁鸡-琵琶腿 328 kcal
· 饮品 可乐大杯 224 kcal
· 甜点 圆筒冰淇淋 93 kcal
⚠ 钠 1838 mg,已达上限 92%
方案二(评分 0.7193)—— 推荐
1028 kcal · 蛋白 54g · 钠 1744 mg · 占全天 29.4%
· 主餐 芝士安格斯厚牛堡 696 kcal
· 小食 麦麦脆汁鸡-带骨里脊 332 kcal
· 饮品 无糖可口可乐中杯 0 kcal
方案三(评分 0.7144)—— 系统主动标红
1130 kcal · 蛋白 47g · 钠 2149 mg
⚠ 钠摄入 2149 mg,已超出 2000 mg 上限(超出 149 mg)。
这是本方案最需要你知晓的取舍点:建议把含糖饮料换成无糖、
并避免同一天再叠加其他高钠食物。
💡 注意方案三:系统没有藏起这个超标项。它在
warnings里主动把超出量算给你看,而不是给一个看起来很美的组合 —— 这正是「可解释」的含义。
示例 3 · 领券点餐闭环(Web 界面)
1. 建档 → 身高体重年龄 → 自动出全天目标与 SP 目标点
2. SP 矩阵 → 156 个餐品按四象限散点分布,金色十字 = 我的目标点
3. 套餐推荐 → 三套方案,含每样餐品的贴合度百分比
4. 门店点餐 → 点击门店 → 进店菜单,每个条目带象限角标 + 贴合度
→ 套餐自动展开内含单品
5. 领券 → 「我的卡包」显示已持有的券(显示券码)+ 可领取券
6. 下单 → 购物车实时计价 → 提交订单
7. 健康记录 → 吃完记一笔 → 体重趋势 + 热量缺口 + 象限分布回看
示例 4 · 独立 Web 应用运行
git clone https://github.com/ChinaOpenClaw/mcd-nutrition-expert.git
cd mcd-nutrition-expert/skills/mcd-nutrition-expert
cp .env.example .env # 填入你的 MCP Token
pip install -r requirements.txt
python scripts/server.py # → http://127.0.0.1:8899
示例 5 · 作为 WorkBuddy Skill 调用
见 workbuddy.md。核心触发语:
「帮我按 SP 矩阵推荐一套麦当劳套餐」
「我今天想吃麦当劳,算一下该怎么点」
「看看我的热量缺口够不够吃这一套」
一、核心洞察:为什么需要它
控卡期吃麦当劳,真正的痛点不是「不知道吃什么」,而是:
二、SP 矩阵理论的应用
2.1 从战略定位到饮食定位
经典 SP(Sweet Point)矩阵用「竞争强度」与「市场地位」划分战略象限。迁移到饮食选型,映射为两个营养密度维度:
2.2 四象限
钠负担高
│
┌─────────────┼─────────────┐
│ │ │
│ 解馋区 │ 双刃区 │
│ (低密度高钠) │ (高密度高钠) │
营养密度低┼─────────────┼────────── 营养密度高
│ │ │
│ 填充区 │ 主力区 ★ │
│ (低密度低钠) │ (高密度低钠) │
└─────────────┼─────────────┘
│
钠负担低
上图方位与
docs/screenshots/03-sp-matrix.png实际界面一致(X 轴向右为营养密度递增,Y 轴向上为钠负担递增)。 实测 156 个有效样本的分布:主力区 47 / 解馋区 46 / 填充区 53 / 双刃区 10。
2.3 贴合度 fit
每个餐品相对「你的目标点」计算归一化欧氏距离,映射到 0–100% 的贴合度:
fit = 1 - dist / 1.4
目标点由用户档案推导(蛋白+碳水密度、钠密度),因此同一个餐品对不同人的贴合度完全不同——这正是 SP 矩阵作为「个人化选型工具」的价值。
2.4 界面实录
散点图每个点是一个餐品,金色十字是你的目标点;右侧按贴合度排序,直接给出「最该点的那一个」。
菜单里每个条目都带 SP 象限角标与贴合度百分比;健康页把每日摄入与目标画在同一张图上,缺口一目了然。
三、功能全景
① 建档 · 营养目标计算
- BMR:Mifflin-St Jeor 公式;若用户填写体脂率则切换到 Katch-McArdle(瘦体重法)修正
- TDEE:BMR × FAO/WHO 活动系数(sedentary 1.2 / light 1.375 / moderate 1.55 / active 1.725 / athlete 1.9)
- 四种目标模式:
② SP 矩阵可视化选型
- 原生 Canvas 绘制散点矩阵(零第三方依赖,离线可用)
- 象限底色 + 动态分界线(P50×0.6 + P75×0.4)
- 散点半径随贴合度变化,金色十字为你的目标点
- 四象限直方图统计
③ 套餐推荐求解器
结构角色模型(取代朴素分类笛卡尔积):
主餐(唯一) → 小食(≤1) → 饮品(唯一) → 甜点(≤1)
硬约束组合:
- 主餐占本餐热量 40%–85%
- 角色级热量上限(比例 ∪ 真实规格绝对上限的较大值)
- 配菜必须带蛋白(≥6g)或足量主食(≥120 kcal)——防止「玉米杯」挤掉真正的蛋白源
- 减脂/塑形模式禁止甜点
- 钠 ≤ 全日上限 × 1.25
多目标加权打分:
局部搜索改进:加一份 / 减一份 / 换一份三邻域迭代 + 多样性去重。
实测输出(25 岁男性 / 175cm / 70kg / 轻度活动 / 减脂,全天目标 1841 kcal、单餐目标 626 kcal):
方案 1 719 kcal(占全天 39%)· 蛋白 44g · 钠 1981mg
板烧鸡腿堡 + 麦麦脆汁鸡-琵琶腿 + 无糖可口可乐中杯
方案 2 611 kcal(占全天 33%)· 蛋白 43g · 钠 1993mg
麦辣鸡腿汉堡 + 无糖可口可乐中杯 + 蒜了吧黄油风味薄皮脆汁鸡-带骨里脊
方案 3 555 kcal(占全天 30%)· 蛋白 46g · 钠 1802mg
双层吉士汉堡 + 蒜了吧黄油风味薄皮脆汁鸡-带骨里脊 + 无糖可口可乐中杯
三套方案都满足「主餐唯一 + 饮品唯一 + 小食 ≤1 + 甜点 ≤1」的结构约束, 且饮品位固定落在零卡选项上——这是控卡期的关键:热量与钠的波动全部来自主餐与小食的选择。
④ 门店点餐(点击门店进入店内)
- 门店列表 → 点击进店 → 分类 tab → 菜单网格
- 每个菜单条目都带 SP 象限标签 + 贴合度 + 营养四宫格(热量/蛋白/脂肪/钠)
- 套餐条目自动展开内含单品(「含:龙焰鸡腿堡 / 中薯条 / 可乐中杯」)
- 新品未收录营养表时按品类关键词近似估算,并显式标注「新品估算」
- 购物车 sticky bar → 实时计价(分/元双口径换算)→ 下单 → 自动记入健康档案
⑤ 优惠券与下单
- 可领取 / 我的卡包 / 本店可用三段式
- 一键领券(
auto-bind-coupons) - 计价与下单走
calculate-price/create-order,正确处理productCode+quantity契约与「分」单位
⑥ 健康可视化记录
- SQLite 三表分离:
daily_log(日汇总)/meal_log(明细)/profile(档案) - KPI 卡 + 体重折线 + 热量收支双线 + 象限分布条形图
- 自动补齐空日期,连续性趋势不断裂
四、技术架构
┌─────────────────────────────────────────────┐
│ web/index.html (单文件前端 · 原生 Canvas) │
│ ①建档 ②SP矩阵 ③套餐推荐 ④门店点餐 ⑤健康可视化 │
└──────────────────┬──────────────────────────┘
│ HTTP / JSON
┌──────────────────▼──────────────────────────┐
│ scripts/server.py FastAPI + uvicorn │
│ /api/health /api/target /api/matrix │
│ /api/recommend /api/stores /api/menu │
│ /api/coupons /api/cart /api/order │
│ /api/records /api/records/weight /api/account│
└──────────────────┬──────────────────────────┘
│
┌───────────────┼────────────────┐
│ │ │
┌──▼──────────┐ ┌──▼─────────┐ ┌────▼──────────┐
│nutrition_ │ │combo_ │ │sp_matrix.py │
│engine.py │ │solver.py │ │ SP 四象限 │
│ BMR/TDEE │ │ 约束求解 │ │ 贴合度 │
│ 目标计算 │ │ 局部搜索 │ └───────────────┘
└─────────────┘ └────┬───────┘
│
┌──────────────┐ ┌───▼─────────┐ ┌──────────────┐
│mcp_client.py │ │health_store │ │ │
│ MCP 客户端 │ │ SQLite │ │ │
└──────┬───────┘ └───┬─────────┘ └──────────────┘
│ │
┌──────▼─────────────▼──────────┐
│ 麦当劳官方 MCP Server │
│ https://mcp.mcd.cn (35 个工具) │
└──────────────────────────────────┘
模块职责
菜单 SP 覆盖率
门店菜单里约 56% 的条目是「三件套 / 四件套 / 分享餐」,官方营养表只收录单品。
项目通过 query-meal-detail 拉取套餐内含单品、按热量加权聚合出套餐自身的 SP 坐标,
配合五级名称匹配(精确 → 去后缀 → 去前缀修饰 → 双向包含 → 品类关键词回退),
把菜单的 SP 标注覆盖率从 31/87(35%)提升到 86/98(88%)。
未被营养表收录的新品,按同品类中位单品近似并显式标注「新品估算」,不假装精确。
五、快速开始
环境要求
- Python 3.10+
- 麦当劳 MCP Server 访问 Token
安装
git clone https://github.com/ChinaOpenClaw/mcd-nutrition-expert.git
cd mcd-nutrition-expert/skills/mcd-nutrition-expert
pip install fastapi uvicorn
配置
cp .env.example .env
# 编辑 .env,填入你的 MCP Token
MCD_MCP_URL=https://mcp.mcd.cn
MCD_MCP_TOKEN=your_token_here
运行
cd scripts
python -m uvicorn server:app --host 127.0.0.1 --port 8899
浏览器打开 http://127.0.0.1:8899 即可。
离线自测
cd scripts
python combo_solver.py --selftest # 求解器自检(内嵌样例数据)
python nutrition_engine.py --demo # 营养目标计算演示
六、目录结构
mcd-nutrition-expert/
├── CONTEST_DECLARATION.md # 参赛声明(原文,内容不可改)
├── MCP_INTEGRATION.md # MCP 集成说明(含 5 个真实踩坑记录)
├── mcp-config.example.json # 脱敏 MCP 配置示例(仅环境变量占位符)
├── workbuddy.md # WorkBuddy Skill 使用说明
├── README.md
├── deck/
│ └── index.html # 项目讲解视频幻灯片源(14 页,红金主题)
├── tools/ # 讲解视频生产流水线(可复现)
│ ├── make_sp_svg.py # 用真实接口数据渲染 SP 矩阵 SVG
│ ├── render_deck.js # Playwright + chromium 渲染 14 张幻灯片
│ ├── narration.py # 14 段旁白文案(与幻灯片一一对应)
│ ├── pronunciation_overrides.py # 多音字读音覆盖表(单一数据源)
│ ├── tts_stepaudio.py # StepAudio 2.5 TTS 引擎(Key 走环境变量)
│ ├── resynth.py # 只重合成指定段落(改文案后省配额)
│ ├── assemble_narration.py # 分段音频 → 单轨 wav + timeline.json
│ ├── build_video.py # 幻灯片 + 音轨 → 1080p 成片
│ ├── check_quadrants.py # 象限语义门禁(前端/视频 vs 后端判定)
│ ├── verify_sp_canvas.js # 浏览器内逐点校验 Canvas 象限归属
│ └── make_social_preview.py # 生成 GitHub 社交预览图
├── docs/
│ ├── ARCHITECTURE.md # 架构与算法说明
│ ├── API.md # 接口清单
│ ├── 项目简介.md # 申报与答辩素材源(一句话/150/350/800 字四版)
│ ├── 项目简介-纯文本.txt # 纯文本版,便于粘贴到 Issue / 表单
│ ├── screenshots/ # 前端五视图实录
│ └── video/ # 讲解视频产物
│ ├── assets/sp-matrix.svg # 真实数据 SP 矩阵图
│ ├── slides/ # 14 张 1080p 幻灯片
│ └── audio/ # 旁白音轨(gitignore)
└── skills/mcd-nutrition-expert/
├── SKILL.md # Skill 定义
├── .env.example # Token 占位符
├── scripts/ # 六个核心模块 + 截图脚本
├── web/index.html # 单文件前端
├── references/ # 参考资料
└── data/health.db # 本地 SQLite(gitignore)
七、项目讲解视频
tools/ 下是一条完整可复现的流水线,从真实接口数据到 1080p 成片:
要点:
- 音画严格对齐 —— 第 4 步产出
timeline.json,第 5 步按段时长裁切画面 - 画面完全静止,仅做 0.30s 淡入 / 0.34s 淡出,不做推镜,避免逐帧亚像素抖动
- 多音字读音受控 ——
pronunciation_overrides.py维护 157 条读音覆盖 (矩阵/阈值/中位数/解馋/膳食/打烊/琵琶腿…),StepAudio 的pronunciation_map原生生效 - ffmpeg 自动探测 —— 支持
MCD_FFMPEG环境变量、@ffmpeg-installer、PATH 三级回退
TTS 凭据:第 3 步需要自备 StepAudio 兼容网关的 API Key,仓库内不保存任何明文凭据。
export HCNSEC_API_KEY="sk-..." # bash $env:HCNSEC_API_KEY = "sk-..." # PowerShell改文案后若只想重合成个别段落,可用
python tools/resynth.py 3单独重跑第 3 段。
象限语义门禁 —— SP 矩阵有「后端判定」与「前端/视频绘制」两条语义线,必须始终一致。
tools/check_quadrants.py 从真实接口取数,逐点校验散点落入的底色矩形与后端 quadrant 是否匹配:
python tools/check_quadrants.py
# [1] SVG 视频素材
# ✓ SVG:156 个散点全部落在与后端判定一致的象限内
# [2] 前端 Canvas
# ✓ 前端 drawSP() 象限坐标与后端语义一致(主力区、双刃区、解馋区、填充区)
象限语义(与 scripts/sp_matrix.py 判定逻辑一一对应):
八、隐私与安全
- Token 只从环境变量读取,不写入代码库,不出现在任何提交中
- API Key 同样只从环境变量读取 ——
tools/tts_stepaudio.py不含任何明文凭据, 未设置HCNSEC_API_KEY时直接报错退出,不发起无意义的网络请求 - 仓库历史已做凭据清洗(
git filter-branch),当前所有提交均不含明文密钥 .env/data/*.db已加入.gitignore- 健康档案(体重、饮食记录)仅存储在本地 SQLite,不上传任何服务器
- 所有 MCP 调用均通过
mcp_client.py统一出口,便于审计
九、致谢
- 麦当劳程序员节创意开发大赛提供的 MCP Server 与 35 个官方工具
- 官方营养数据(160 个餐品的完整营养成分)
- SP 矩阵理论(Sweet Point 战略定位矩阵)的思想迁移
免责声明:本项目为赛事参赛作品,由参赛者独立开发,非麦当劳官方产品。输出仅供参考,不构成医疗、营养或其他专业建议。餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。



