麦当劳干了件挺少见的事:把点餐、领券、查积分、看门店活动这些能力,整理成 30 多个标准接口开放出来,然后办了一场编程比赛。规则只有一条硬指标——谁的 GitHub 仓库 Star 多,谁排前面。
我花了一小时把比赛跑了一遍,也做了个自己的项目。这篇文章讲清三件事:MCP 到底是什么、这个比赛怎么参加、真去调这些接口会踩到哪些坑。
MCP 是什么:AI 世界的 USB-C
先说概念,因为这词最近到处都是,但很少有人讲明白。
你手机的充电口,从圆孔换到 Lightning、再统一到 USB-C,折腾了十几年。统一之前,每换一台设备就得换一根线。AI 现在调用外部能力,正好卡在这个"接口百花齐放"的阶段:想让 AI 帮你点外卖,得单独写一套外卖平台的对接;想让它查航班,又得写一套航司的对接。每接一个新系统,都要从头重来一遍。
MCP(Model Context Protocol,模型上下文协议)想解决的,就是这件事。它给"AI 调用外部工具"定了一个统一格式:不管是点外卖、查数据库还是读文件,都包装成同一种叫"工具"的东西。
打个比方会好懂:以前 AI 想用你的数据,得像进不同房间找不同的钥匙串;而 MCP 是给它一张万能门禁卡,门后面是什么它不用管,刷卡就能进。
它本身没什么玄机。服务端把能力列成一张清单——每个工具叫什么、要什么参数、干什么用;AI 读到清单后按需调用,把结果拿走。协议里最核心的动作,就"列清单"和"调工具"两个。
麦当劳这次开放了什么
开放的是点餐,但比想象的细。
这 30 多个工具大致分四类:点餐(麦乐送、到店自取、团餐、派对预约)、优惠券(领券、查我的券)、积分(查余额、商城兑换、抽奖)、信息查询(营养数据、活动日历、附近门店)。
真跑通之后,最直观的感受是:它基本就是把你手机 App 里能点的东西,翻译成了 AI 能读的格式。 你在 App 里能做的事——麦乐送下单、麦麦省领券、拿积分换东西——这里都有对应的接口。
这批工具天然分成两类:只读的和会花钱的。查积分、看奖品、列门店属于前者,随便调;抽奖、下单、用积分兑换属于后者,调一次就真的花掉你账户里的东西。分清这条线很重要——做工具的人得自己给自己上规矩。
比赛怎么参加:交什么、怎么排
我把官方仓库的规则逐条核过一遍,说到底就两件事:交一个仓库,发一条报名。
时间是从 10 月 9 日到 10 月 25 日。参赛要在 GitHub 上建一个公开仓库,再到官方仓库发一条 Issue 报名,格式有现成模板。仓库里必须齐的文件有这些:
| 文件 | 作用 |
|---|---|
| README.md | 项目介绍、安装方式、使用示例 |
| CONTEST_DECLARATION.md | 官方参赛声明,文件名和内容都不能改,直接用原版 |
| MCP_INTEGRATION.md | 写清用了哪些接口、怎么调、解决了什么问题 |
| mcp-config.example.json | 配置样例,必须脱敏,只能放环境变量占位符 |
| 源码 | 形式不限 |
| workbuddy.md | 想拿 WorkBuddy 的 3000 积分就交,文件名不能改 |
排名规则是这场比赛最特别的地方:不看代码质量、不看技术难度,只看 GitHub Star 数,前 100 名上榜。而且有个硬门槛——Star 为 0 不入榜。
翻译一下这条规则:你的东西不光要能跑,还得让人愿意点那个星星。 一个自己用着顺手的脚本,和一个别人看完就想转给朋友的东西,在这场比赛里是两个物种。
我翻了一下当天的赛场:开赛两小时,报名的项目从 4 个涨到 29 个,可其中 20 个是 0 星。也就是说大部分人交了作业,却没拿到哪怕一颗星——拿到 1 星就能上榜,门槛比想象中低得多。
奖励是真的实在。只要进了排行榜,哪怕排在最后一名,也能拿到【汉堡回车键玩具】和【程序员节实体徽章】各一份。往前排就更夸张:第 1 名是【巨无霸汉堡 ×50 次免费兑换券】,第 2 名 30 次,第 3 名 20 次,前三名还各拿 10240 点腾讯 WorkBuddy 积分;项目如果真用了 WorkBuddy 并交了 workbuddy.md,前 100 名再添 3000 积分。
翻译一下:一颗星,就能换一个汉堡形状的回车键玩具。 这个换算关系,比我下面要算的积分抽奖划算得多。
我做的项目:积分该抽还是该换
我挑了个当时还没人碰的角度:麦当劳的积分,拿去抽奖划算,还是直接兑换划算。
这问题看着像玄学,其实是一道能算完的算术题。
先给一个积分标个价
积分商城里每件商品都标着要多少积分,商品名里还带着市场售价——比如「6.9 元香芋派/菠萝派任选」要 50 积分。用售价除以积分,就是这件商品的"每积分回报"。
把所有商品都算一遍、取中位数,得到一个稳定的基准:1 积分大约值 0.138 元。用官方自己标的价来定价,比任何估算都实在。
再算抽奖的保本线
抽一次要 24 积分。这 24 积分如果拿去兑换,值 24 × 0.138 ≈ 3.31 元——这就是保本线:抽到的东西值不到 3.31 元,就是亏。
我把奖池里每件奖品逐件估价,标上"赚 / 亏 / 看用法"三类。"下单立减 3 元券"这种能直接算;"满减折扣券"算不了——省多少取决于你点什么,估了就是骗人,所以单独标成"看用法"。
拿抽奖天花板比兑换最好档
结论怎么下,我用了取巧但诚实的办法:比"抽奖的上限"和"兑换的最好档"。
奖池里最值钱的是 3 元券,24 积分抽到它,每积分回报 0.125 元;而直接兑换最好的一档是 0.138 元。连抽到最值钱的都跑不赢直接兑换——那还赌什么运气。
关键发现:官方不给你中奖概率
我原本想算"期望值"——平均抽一次能拿回多少钱。结果翻遍接口发现:官方只给奖品清单,一张概率表都没有。
没有概率,任何"平均收益"都是我编出来的。所以我砍掉了期望值,只算两件确定的事:保本线、奖池上限。这个决定反而让结论更硬——它不依赖任何假设,谁跑都是同一个数。
最后交出去的东西:五个只读接口、45 项单元测试、零第三方依赖(有 Python 就能跑,不用装任何东西),示例数据和真机跑出来的结论完全一致。
接 MCP 踩到的三个坑
会算还不够,得先把数据从接口里拿回来。这中间踩的坑挺真实,都记在了项目的接入文档里。
返回的不是纯 JSON,而是包了一层的 Markdown
麦当劳 MCP 给模型的响应,外面裹了一层给人看的 Markdown 说明(字段释义、格式说明),真正的数据挂在「## Original Response」这个标题后面。
我第一次直接解析 JSON,失败但不报错,静默降级成了空数据——报告照常生成,只是每个数字都对不上。这种"不报错的错"最难查,最后写了个三级降级的解析器才兜住。
活动日历是纯 Markdown,不是 JSON
别的接口都老老实实返回 JSON,唯独活动日历是一篇带标题的文档。得单独写正则,把它按日期切开,挑出"今天"那一节。
一个接口一种脾气,这就是接真实服务端的日常。
积分商城里混着「不是积分兑换」的商品
商城里有些商品标着 0 积分,看着像白送,其实是花钱买的派对、体验营,只是借了商城的壳摆在一起。
必须按积分数过滤掉,否则会把"1 积分值多少钱"这个基准算歪——分母里混进一堆免费的,中位数就废了。
这件事为什么值得在意
你可能觉得,一个点餐接口而已,有什么好聊的。
换个角度看:MCP 让 AI 从"知道很多事"变成"能做很多事"。 以前你问它"麦当劳哪个套餐划算",它只能凭记忆瞎猜;现在它能真的去查你的券、你的积分、你附近门店的活动,再给你答案。这一字之差,是"嘴"和"手"的距离。
这场比赛比的东西也有意思。同一个能力矩阵,有人做成了精算表格,有人做成了一张能截图的账单卡片。前者可能更硬核,后者更容易被人转发——而这场比赛偏偏只看转发。
还有个细节值得说:比赛排名只看 Star,而 Star 是全场唯一一个你没法靠写代码拿到的分数。代码写得再漂亮,它不会自动变成星星。它只在你把东西做得清楚到、有用到——让别人愿意替你跟朋友说一句"这个你看看"的时候,才会出现。