内容
# 麦门语文课 · mcd-chinese-class
> 选几样麦当劳,挑一篇课文 —— **看你的订单被改写成什么。**
**🎬 在线体验(不用装任何东西,打开就能玩):**
**https://miaoyhcat.github.io/mcd-chinese-class/**
<img src="images/demo.png" alt="麦门语文课 · 把订单改写成《背影》" width="620">
---
## 这是什么
别人把麦当劳数据做成计算器,这个做成**语文课本**。
你点了一份「巨无霸 + 中薯条 + 可乐」,它把这一单改写成《背影》:
> 我与那巨无霸不相见已二年余了,我最不能忘记的是它的背影。
>
> 我说道:“爸爸,你走吧。”他望车外看了看,说:“我买几个巨无霸去。你就在此地,不要走动。”
>
> 我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到柜台边,慢慢探身下去,尚不大难。可是他穿过点餐的人群,要爬上那边月台,就不容易了。他用两手攀着上面,两脚再向上缩;他手里那袋薯条晃来晃去的样子,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。
每一篇都按原课文的结构改写,把这一单的餐品名字嵌进原句里。
不玩梗的地方也认真:**正文只出现餐品名,不带订单号、时间、门店这些可识别信息**。
> 1. 文中“我买几个巨无霸去”一句单独成段,有什么表达效果?
> 2. 作者描写父亲越过柜台、攀上月台的细节,用了哪些动词?这样写有什么好处?
> 3. 本文题为《背影》,如果改成《巨无霸》,表达效果会有什么变化?
## 十六篇课文
| 课文 | 作者 | 调性 |
|---|---|---|
| 《背影》 | 朱自清 | 深情 |
| 《荷塘月色》 | 朱自清 | 抒情 |
| 《春》 | 朱自清 | 抒情 |
| 《从百草园到三味书屋》 | 鲁迅 | 童趣 |
| 《孔乙己》 | 鲁迅 | 冷峻 |
| 《故乡》 | 鲁迅 | 沉郁 |
| 《社戏》 | 鲁迅 | 怀旧 |
| 《阿Q正传》 | 鲁迅 | 讽刺 |
| 《范进中举》 | 吴敬梓 | 讽刺 |
| 《岳阳楼记》 | 范仲淹 | 议论 |
| 《桃花源记》 | 陶渊明 | 记叙 |
| 《陋室铭》 | 刘禹锡 | 短章 |
| 《爱莲说》 | 周敦颐 | 托物言志 |
| 《出师表》 | 诸葛亮 | 表 |
| 《核舟记》 | 魏学洢 | 说明 |
| 《变色龙》 | 契诃夫 | 讽刺 |
按文体分布:现代散文 4 篇、现代小说 5 篇、文言文 6 篇、外国小说 1 篇。
## 生成分享图片
页面上点「生成课文图片」会**在浏览器里用 Canvas 画一张竖版 PNG**(1080 宽,适配手机),
标题、文体、正文、订单摘要都在上面。
- **不请求任何外部服务** —— 订单内容不出本机
- 正文长到超过一屏会自动**分页导出**,而不是把字缩到看不清
- 导出的图里只有餐品名,**不含订单号、时间、门店**
## 目标用户
- 想吃麦当劳时想找点乐子的人
- 想发朋友圈 / 小红书但缺一张图的人
- 语文老师(真的,这份材料可以拿来当“改写”的课堂引子)
- 任何还记得《背影》全文的人
## 在线体验
打开 **https://miaoyhcat.github.io/mcd-chinese-class/** 就能玩:
1. 点几样你吃的(也可以直接打字)
2. 挑一篇课文
3. 生成,复制或导出图片,发出去
整个页面是**单文件、零依赖、零网络请求**的,双击 `docs/index.html` 也能离线打开。
## 本地使用(命令行)
不需要安装任何第三方库,只用 Python 标准库。
```bash
# 内置样例,不需要任何 Token,跑起来就先看效果
python mcd_chinese.py --demo
# 自己指定餐品
python mcd_chinese.py --items "板烧鸡腿堡,大薯条,雪碧"
# 指定课文
python mcd_chinese.py --items "巨无霸,可乐" --lesson kongyiji
# 看看有哪些课文可选
python mcd_chinese.py --list
# 输出 Markdown / JSON(便于二次加工)
python mcd_chinese.py --demo --md
python mcd_chinese.py --demo --json
```
### 点完餐,课文就出来了
配置麦当劳 MCP Token 后,程序会读**你最近一笔订单**,把那里面的餐品改编成课文:
```bash
# 申请 Token:https://open.mcd.cn/mcp
export MCD_MCP_TOKEN="你的token" # Windows PowerShell: $env:MCD_MCP_TOKEN="..."
# 点完餐跑一次
python mcd_chinese.py --mcp
# 或者挂着盯单:下单之后自动出课文,不用再手动跑
python mcd_chinese.py --watch # 默认每 20 秒查一次,--interval 可调
```
`--mcp` 会在生成前把「读了哪一笔」打到屏幕边上(时间 / 门店 / 金额),
方便确认拿到的就是你刚点的那单:
```
[订单] 2026-10-14 12:30:00 · 南京东城汇店 · 31.00 元
```
会自动跳过已取消的订单;近 90 天的订单里,永远取最近的一笔。
点的是套餐也没关系 —— 套餐里的薯条、可乐会被展开,一样能进课文。
> 用真实 Token 联调过:握手、35 个工具的列表、只读白名单拦截、
> `order-list` 的字段结构都已确认。细节和「哪些还没验证」见
> [MCP_INTEGRATION.md](MCP_INTEGRATION.md)。
## 麦当劳 MCP 接入
本项目通过麦当劳官方 MCP Server 的 **`order-list`** 工具读取订单历史,全程**只读**。
- 接入地址:`https://mcp.mcd.cn`(Streamable HTTP)
- 用到的工具:`order-list`(订单历史)
- 未使用任何写操作:不下单、不支付、不领券、不兑换积分
- 客户端 `mcd_mcp.py` 内置**只读白名单**,即使有人改了调用代码,写操作也会在客户端被挡下
详细的调用流程、协议细节和踩坑记录见 **[MCP_INTEGRATION.md](MCP_INTEGRATION.md)**。
## 为什么不用大模型
生成过程是**确定性**的:同一份订单永远得到同一篇课文。
这不是偷懒 —— 恰恰是因为不依赖 LLM,它才能:
1. **离线可用**:网页版双击就能开,不需要联网也不需要 API Key
2. **零成本**:不会因为别人来玩就烧掉你的 token
3. **可复现**:出问题能精确定位到哪条模板
4. **当 Skill 用**:AI Agent 也可以直接调用它,输出稳定
## 项目结构
```
mcd-chinese-class/
├── mcd_chinese.py # 主程序:分类餐品 → 选课文 → 渲染
├── mcd_mcp.py # 麦当劳 MCP 最小客户端(标准库,只读白名单)
├── lessons.json # 课文模板库(占位符驱动,可自行加课文)
├── build_web.py # 把模板内联进 HTML,产出单文件演示页
├── docs/index.html # 构建产物:GitHub Pages 演示页(自包含)
├── web/template.html # 演示页源模板
└── SKILL.md # Agent Skill 定义(给 AI 客户端用)
```
## 自己加一篇课文
`lessons.json` 是数据驱动的,加一篇只要追加一个对象:
```json
{
"id": "shexi",
"title": "社戏",
"author": "鲁迅",
"tag": "小说 · 怀旧",
"opening": "我们鲁镇的习惯,本来是凡有出嫁的女儿,倘自己还未当家,夏间便大抵回到母家去消夏。",
"body": ["……{main}……", "……{side}……"],
"ending": "真的,一直到现在,我实在再没有吃到那夜似的好{side}。"
}
```
可用占位符:`{main}` 主食 · `{side}` 小食 · `{drink}` 饮品 · `{items}` 全部餐品 · `{count}` 件数 · `{store}` 门店。
改完跑一次 `python build_web.py` 重新生成演示页。
## 免责声明
- 本项目是**麦当劳程序员节创意开发大赛参赛作品**,由参赛者独立开发,**非麦当劳官方产品**。
- 课文均为**戏仿**,与原作、原作者的立场无关,也不代表任何对原作的评价。
- 餐品信息、价格及供应状态以麦当劳官方渠道的实时结果为准。
- 本项目不含任何真实 Token、密钥或他人个人信息,配置一律走环境变量。
## 开源协议
[MIT](LICENSE)