内容
# mcd-party-quorum · 麦麦组局官
> 基于麦当劳 MCP 的派对组局助手。
> 把「想去麦当劳程序员节派对,但凑不够 5 个人」变成一张能直接甩进技术群的组局卡。
> Built with WorkBuddy · 麦当劳程序员创意开发大赛参赛作品
[](https://www.workbuddy.cn)
[](https://open.mcd.cn/mcp)
[](#只读护栏)
---
## 先说结论:官方文案只对了一半
麦当劳「程序员节派对」的活动须知写着活动时间 **2026-10-23 至 10-25**。
但这句话只对了一半。我逐店查了全部 9 个开放城市的真实可约日期:
| 城市 | 门店 | 可约天数 | 真实可约区间 | 与文案对比 |
|---|---|---:|---|---|
| 大连市 | 大连软件园得来速餐厅 | 3 | 10/23 – 10/25 | 一致 |
| 南京市 | 南京药谷大道餐厅 | 3 | 10/23 – 10/25 | 一致 |
| 无锡市 | 无锡蠡湖科技园餐厅 | 3 | 10/23 – 10/25 | 一致 |
| 苏州市 | 苏州腾飞新苏坊餐厅 | 3 | 10/23 – 10/25 | 一致 |
| 福州市 | 福州盛世茶亭餐厅 | 3 | 10/23 – 10/25 | 一致 |
| **佛山市** | 佛山魁奇一路餐厅 | **2** | **10/24 – 10/25** | 比文案**少一天** |
| 杭州市 | 杭州星耀中心餐厅 | 9 | 10/22 – 10/30 | 比文案宽 7 天 |
| **长沙市** | 长沙中电软件园餐厅 | 13 | **10/19** – 10/31 | 比文案**早开 4 天** |
| **西安市** | 西安宜家荟聚中心餐厅 | 12 | 10/24 – **11/29** | 比文案**延长到下个月** |
**9 个城市里,4 个的真实可约日期和官方文案不一样。** 而且两头都有坑:
- 佛山的朋友按文案规划以为有 3 天,实际只有 2 天,**晚一天查就错过了**。
- 西安的朋友以为活动只到 10/25,实际能约到 **11/29**,**按文案规划会白白放弃**。
这些数字全部来自麦当劳 MCP 的实时接口(`query-party-store-date`),不是爬来的,也不是编排的。
> 活动须知其实留了一句授权:「活动结束时间可能根据情况适当延长,具体活动餐厅可预约时间以活动预约页面为准。」
> 话是这么说 —— 但没人会为了吃顿汉堡把 9 个城市的门店逐一查一遍。**这正是这个技能存在的理由。**
---
## 它解决什么
麦当劳程序员节派对 ¥59/人,含巨无霸四件套 + 随机周边玩具 + 90 分钟沉浸式派对(谁是卧底、你画我猜、专属程序员挑战问答)。唯一的门槛是:**每场 5 人起订,最多 12 人。**
一个人想去是不够的。你需要拉人。而拉人之前,你得先能回答这几个问题:
- 我这个城市有吗?(**9 个开放城市里没有北上广深**)
- 哪家店最近?这一天还有场吗?余位多少?
- 还差几个人发车?凑够之后人均多少钱?
- 最晚什么时候必须定?(须知要求提前 3 天预订)
这些问题全部能从麦当劳 MCP 里查到 —— 只要你肯钻到第四层。`mcd-party-quorum` 做的就是这件事,然后把答案压成一张能截图转发的卡。
---
## 一张真实的组局卡
下面这张不是编的示例,是实网调用 + 脚本渲染的真实输出:
```
🍔 麦当劳 · 程序员节派对 · 组局卡
「码」上狂欢,在轻松氛围里卸下压力、收获快乐!
📍 无锡 · 麦当劳无锡蠡湖科技园餐厅
🗓 2026-10-23 11:00–12:30(约 90 分钟)
👥 已确认 3 人 · 最少 5 人 → 还差 2 人发车(上限 12,余位 12)
💰 人均 ¥59 · 3 人共 ¥177(每加 1 人 +¥59)
⏳ 预订死线(按须知「提前 3 天」估算):2026-10-20 23:59:59 → 还剩 47 小时 35 分
advisory,提示性;实际可约以预约页面 / 门店确认为准
📌 参与方式:回复 +1,凑满 5 人我发起预订。
📌 18 岁以上可参加;退改需提前 3 天申请。
📌 本技能不会代你下单。
```
注意卡上没有出现的三样东西:**手机号、会员号、券码。** 它也不会帮你把订单提交出去 —— 详见下方「只读护栏」。
---
## 快速开始
### 1. 申请麦当劳 MCP Token
打开 <https://open.mcd.cn/mcp>,手机号验证登录 → 控制台 → 激活 → 同意协议 → 复制 Token。
### 2. 配置 MCP
把下面这份配置放到 MCP 客户端的配置文件里,**把占位符换成你自己的 Token**:
```json
{
"mcpServers": {
"mcd-mcp": {
"type": "streamablehttp",
"url": "https://mcp.mcd.cn",
"headers": {
"Authorization": "Bearer ${MCD_MCP_TOKEN}"
}
}
}
}
```
仓库内另有可直接使用的 [`mcp-config.example.json`](./mcp-config.example.json)。
### 3. 安装技能
把 `mcd-party-quorum/` 整个目录放进你的技能的目录(例如 WorkBuddy 的 `~/.workbuddy/skills/`)。
**零第三方依赖**:只用 Python 标准库,不需要 `pip install` 任何东西。已验证在 Python 3.13(无 PyYAML)与 Python 3.12 下均可运行。
### 4. 自检
```bash
python scripts/run_scenarios.py --all # 27 个用例,全部进程内 Mock 执行
python scripts/mcp_client.py --selftest
```
---
## 使用示例
直接说人话就行:
> **你**:杭州有麦当劳程序员节派对吗?我们组 3 个人想去,还差几个?
> **你**:帮我把 PyTorch 组的周六团建定了,8 个人,人均别超 80。
> **你**:最晚什么时候必须定?
> **你**:长沙那家店 10 月 19 号能约吗?官方不是说 23 号才开始?
技能会逐层下钻(城市 → 门店 → 日期 → 场次),每一步都把选项摆出来等你选,**不替你拍板**。
---
## 目标用户
- **9 个开放城市里的技术人**(大连、南京、无锡、苏州、杭州、福州、长沙、佛山、西安)——想去但凑不够 5 个人
- **小组长 / Tech Lead / HR**——想搞人均 59 元的轻量团建,需要一键算清楚再发群
- **来逛仓库的开发者本人**——README 的第一个 demo 就是给自己组一局
不在开放城市也没关系:技能会直接告诉你当前开放哪 9 个城市,不会编造门店。
---
## 只读护栏
这是本项目最在意的一条线。**技能全程不调用任何会产生资金变动或资产变动的工具。**
| | |
|---|---|
| 明确禁用 | `party-order-create` `create-order` `mall-create-order` `draw-lottery` `cancel-order` `delivery-create-address` `auto-bind-coupons` |
| 技能止步于 | 把 `party-order-create` 需要的 11 个参数**全部装配好并展示给你**,然后说「下一步由你自己执行」 |
| 凭证 | 不持有、不落盘、不回显任何 Token / 会员号 / 券码 / 手机号 |
这不是靠提示词自觉,是**结构保证**:`scripts/mcp_client.py` 的 Gate 会对每个调用请求发票据,写工具无条件拦截(exit 3);四个核心脚本共用一套参数名守卫,凡是 `note_display_*` 派生的值试图进入计算通道,直接 exit 2。回归用例 `T-write-tools-zero`(22 项断言)与 `T-note-guard` 守着这两道门,而且这两条用例都做过变异验证 —— 把期望值改坏,它们会真的变红。
---
## 技术要点
麦当劳 MCP 的 `tools/list` 实际返回 **35 个工具**,官方 README 只公开了 27 个。本技能用到了其中 5 条未公开的派对链路:
```
mall-points-products 取上架的活动(shopId==5 走现金,shopId==2 走积分)
└─ mall-product-detail 取须知原文、SKU、成团人数
└─ query-party-city ← 未公开:该活动开放的城市
└─ query-party-store ← 未公开:城市内可办门店(可按经纬度排距离)
└─ query-party-store-date ← 未公开:该门店可约日期
└─ query-party-store-session ← 未公开:场次/余位/成团人数
```
**为什么必须逐层下钻**:可约日期是**门店级**的,不是城市级、也不是活动级的。上面那张 9 城表格就是证据 —— 同一个活动,不同门店能差出 12 天。
几个实调抓出来的坑,都写进了 `references/field-dictionary.md`:
- **同名 `price` 单位差 100 倍**:商品详情返回 `"59"`(元),场次接口返回 `5900`(分)。所有金额进统一的规范化层,内部用分,出口转元,且禁止向用户裸显 `5900`。
- **时间字段名不一致**:`mall-points-products` 返回 `upTime/downTime`,`mall-product-detail` 实际返回 `upDate/downDate` —— 连官方文档都写错了。抽取函数做双读回退,都缺就报错,不猜。
- **`note` 不得用于业务逻辑**:接口字段说明明确要求须知原文只能完整展示,不得提取数值做校验。所以「官方文案 vs 实时数据」是**并列对照 + ⚠️ 标注**,绝不宣称谁对谁错,并且附上「这通常是各门店自行排期的差异,并非数据错误」。
- **倒计时不吓唬人**:须知说提前 3 天预订,技能会算出死线并展示 —— 但**即使已经过了死线,照样正常出卡**,只是加一句「是否仍可预约请以门店为准」。用提示性字段去做拦截判断,等于换条路违规。
---
## 它不做什么
- **不代下单**。算清楚、装配好参数,然后交回给你自己执行。
- **不做营养、热量、减脂、节食建议**。本技能全程不启用 `list-nutrition-foods`,即使套餐里有巨无霸也不评价热量。
- **不做优惠券、积分、抽奖**。
- **不做通用点餐**。
- **不渲染程序员负面刻板印象**。须知原文「在轻松氛围里卸下压力、收获快乐」已经写得很好,引用就够了。
---
## 目录结构
```
mcd-party-quorum/
├── README.md / CONTEST_DECLARATION.md / MCP_INTEGRATION.md
├── mcp-config.example.json / workbuddy.md
└── mcd-party-quorum/ # ← 技能本体
├── SKILL.md
├── references/ # 状态机、字段字典、须知对照样例、降级话术、卡片模板
├── scripts/ # 9 个纯标准库脚本,均带 --selftest
└── tests/fixtures/ # 合成数据的回归用例
```
每个脚本都不依赖调用时的工作目录(用 `__file__` 解析路径),安装后从任何地方调用都一样。
---
## 参赛信息
本作品参加「麦当劳程序员创意开发大赛」(2026-10-09 – 10-25,主办:麦当劳中国 × WorkBuddy)。
本 MCP 集成说明见 [`MCP_INTEGRATION.md`](./MCP_INTEGRATION.md);参赛声明见 [`CONTEST_DECLARATION.md`](./CONTEST_DECLARATION.md);用 WorkBuddy 开发的对话上下文见 [`workbuddy.md`](./workbuddy.md)。
> 本项目是参赛者的独立作品,非麦当劳官方产品。输出仅供参考;餐品、价格、场次与供应状态以麦当劳官方渠道的实时结果为准。