1024 想请全组吃麦当劳,结果我先写了个拼单工具

1024 想请全组吃麦当劳,结果我先写了个拼单工具

起因:每次点下午茶,都有一个人在当财务

组里点下午茶基本是这样:群里接龙几十条,总有人被漏掉;门店券怎么用才最便宜,没人算得清;付完钱还得挨个说"你转我 24.9"。1024 程序员节快到了,大概又要来一遍。

刚好麦当劳中国开放了 MCP,也在办程序员节的开发比赛,我就趁机做了个小工具「麦麦拼单」(mcd-team-feast)。先说一句:我不是科班出身,这个项目基本是和 AI 一起 vibe 出来的,下面写的也都是边做边踩到的坑,大佬看了轻拍。

它做的事情很简单:开个团 → 链接丢群里,大家各点各的 → 它自己试券、挑最便宜的方案 → 每人该转多少算到分 → 出一张 git log 风格的账单卡。

接麦当劳 MCP:只读为主,金额单位是"分"

MCP 客户端是自己写的,零依赖,就是按 Streamable HTTP 走一遍 initialize → tools/list → tools/call,带上 Session Id。Token 只从本机环境变量读,不进仓库,网页版完全不需要。

真正用到的基本是只读工具:query-nearby-stores 找门店,query-meals 拉菜单,query-store-coupons 拿可用券,calculate-price 计价,另外 list-nutrition-foods 用来算热量。

几个踩到的点:

  • 金额单位是分 。calculate-price 返回的原价、优惠、实付都是整数分。这反而是好事,我整个项目内部都用分算,最后才转成元显示,浮点误差直接绕过去。
  • 券是挂在商品行上的 。不是"整单传一个券 ID",而是给某一份商品带上 couponId/couponCode。所以每张候选券都要拆出一份对应商品再去计价。
  • 活动价别重复扣 。最早的版本里,我把"菜单价和实付的差额"和券的优惠又加了一遍,结果优惠被算了两次,账单卡上省得特别夸张。后来改成以 calculate-price 的实付为准:各人菜单价之和减实付,就是能分摊的全部优惠,门店活动价单独列一行。
  • 菜单上有些价格要另外买卡才享受(随单购早餐卡之类),拼单场景一律按原价算。

券组合搜索 + 按分分账

券的数量不多,所以没上什么高级算法,就是老实枚举:最多 3 张券、整单券最多 1 张,每种组合都丢给官方 calculate-price 算一遍,取实付最低的。价格以官方为准,我自己不猜优惠规则,这样就不会出现"工具说 30,结账 35"的尴尬。

分账规则是按每人原价占比分摊优惠:每人的优惠用 Math.floor 取整到分,剩下的尾差由发起人兜底,保证每人应付加起来 = 实付,一分不差。这条守恒有单独的测试盯着。

真实跑过一次(只计价,没下单):上海一家门店 5 人下午茶,10 件咖啡甜品小食,原价 ¥159.90 ,门店活动价优惠 ¥19.20,实付 ¥140.70 ,人均 ¥28.14。

账单卡:git log、PR、小票三选一

算完总得有个能发群里的东西。我做了三种主题:git log 提交记录风、GitHub PR 风、普通小票风。卡片是纯函数生成的 SVG,CLI 和网页共用一套,字体做了子集化内嵌进去,导出 PNG 在不同设备上长得一样。中文和等宽字体混排对齐这块折腾了挺久。

PR 风 小票风

卡片底部还有一句梗签名 ,会按时段、人数、省钱比例、热量自动挑一句程序员梗,不满意可以换一句或者自己写。另外 feast blame 会评出今天的"钱包担当"和"热量担当",纯属娱乐。

实时拼单:开团 → 同步 → 锁单

一开始网页版是"链接模式":团的数据全编码在 URL 里,不经过服务器,但每个人改完都得把新链接发回群里,用起来有点累。

后来加了实时房间:团长开团拿到链接和二维码,成员填个昵称就能进来,谁在线、谁选好了、谁还在选,所有人实时看得到,团长还能设截止倒计时。到点了团长一键锁单,大家变成只读,看到最终分账;要改可以再解锁。

实现很朴素:服务端推送用 SSE,客户端操作用普通 POST,服务端是一个零依赖的 Node 文件。房间只存团名、昵称和点了什么,24 小时自动删除;断线会自动重连,同步服务连不上时自动退回链接模式,界面上会标明当前是哪种模式。想自己部署的话,仓库里有通用的部署模板。

做成 MCP Server,但故意不给下单工具

既然是 MCP 比赛,顺手把它自己也做成了一个 MCP Server(stdio),配一个 SKILL.md,在 Agent 里说一句"帮我们组拼一单麦当劳"就能开团、点餐、结算、出卡。

但这里我故意没暴露任何下单工具 。AI 帮你算账没问题,替你花钱还是算了。真要下单只能在终端手动执行 feast order --confirm <确认码>,确认码由门店、餐品和券组合哈希出来,团内容一变就失效,最后也只返回支付链接,付不付钱你自己决定。

几点体会

  1. 算钱的事交给官方接口 。自己模拟优惠规则一定会翻车,能调 calculate-price 就别猜。
  2. 金额全程用整数分,再写一条"总和守恒"的测试,能省很多心。
  3. 和 AI 一起写代码,测试比代码更重要。AI 改起东西来很勇,那个优惠算两遍的 bug 就是这么来的,后来全靠测试兜住。现在一共 30 个用例,全程不碰真实接口。
  4. 能分享的结果比功能列表好传播。大家对算法没什么兴趣,但会把一张好玩的账单卡转到群里。

链接

这是「麦当劳程序员节创意开发大赛」的参赛作品,非官方产品。网页版用的是演示菜单(虚构价格),不用登录、不用 Token 就能完整走一遍流程;命令行也可以一行跑 mock:

bash 复制代码
npx github:Jasonin2099/mcd-team-feast demo --mock --theme all

如果这周你们组也要点下午茶,可以拿去试试。觉得还行的话,顺手点个 Star 我会很开心,有问题或者新主题的点子也欢迎提 issue。

相关推荐
得帆低代码PaaS21 小时前
企业级 Agent 架构:MCP、Integration、数据与治理能力
大数据·人工智能·架构·ai agent·企业数字化·mcp
jerrywus1 天前
让 AI 帮你部署 Vercel,报错了也不用手动搬日志
前端·agent·mcp
艺杯羹1 天前
MCP本地服务集成避坑:从Stdio管道僵死到双向JSON-RPC稳健通信
人工智能·python·ai·系统架构·大语言模型·ai编程·mcp
用户8813034824071 天前
MCP 不只是 Tool:Resource 和 Prompt 怎么写、何时用,附 3 个实测踩坑(Python SDK v2)
mcp
vjmap2 天前
AI 智能体调用绘图工具画矢量地图:唯杰 AI 地图绘制上线,支持 MCP 接入 Cursor、Claude Code
gis·agent·mcp
Danny转行做跨境2 天前
AI搜索时代选品数据采集: MCP比爬虫稳在哪
跨境电商·mcp·sorftime
Danny转行做跨境2 天前
CLI 怎么批量拉亚马逊选品数据:61 个接口的实测
跨境电商·mcp·sorftime
小七-七牛开发者2 天前
Agent 支线知识:Personal Agent 如何跨应用完成任务?
ai·agent·工具调用·aiagent·mcp
梦想恒远3 天前
MCP 调不通却不报错:HTTP 200 之后的两种静默失败
mcp
Danny转行做跨境3 天前
亚马逊选品数据源实测: 一个 CLI 调 61 个接口
跨境电商·mcp·sorftime