
4 月 16 日,我合并了最后一个 PR。4 个 Docker 容器、16 个 MCP 工具、一个飞书 AI 日程助理。
一个月后,我删了其中 2 个容器。剩下 1 个 MCP 服务,接入 Hermes,1 小时搞定。
为什么删?因为发现那 4 个容器本质上就干了一件事,而这件事已经有人做好了。
我是 iOS 用户,服务器是 Linux。Apple 日历绑死 macOS CalDAV,对我没戏。Outlook 跨平台能用,iOS 装个 App 就行。
飞书当入口——发消息,AI 操作 Outlook 日历和待办。(之前写过一篇 给AI装两个MCP,我有了一个日程+出行助理[1],讲的是 MCP 工具本身。这篇文章讲的是架构怎么从 4 个容器缩到 1 个。)
听起来不复杂,对吧?但我搭了 4 个 Docker 容器才跑起来。
飞书用户
↓ WebSocket
消息网关 (FastAPI) — 文字/图片/语音/PDF,Whisper 转文字
↓ LangGraph SDK
Agent 后端 (LangGraph) — 工作流:确认→模型→工具→危险审查
↓ MCP 协议
MCP 服务 (FastMCP) — 16 个工具,日历/待办 CRUD,PostgreSQL 存 token
前端 (Next.js) — 独立 Web UI
4 个容器,每个有自己的依赖、日志、配置。每次更新小心翼翼,怕某个挂了。
想加新功能?改 MCP 服务加工具,改 agent 后端调提示词和工作流,可能还要改消息网关。三个地方。
想接别的平台?飞书 WebSocket 长连接重写一遍。
排查问题?看 4 个容器的日志。
后来我明白了:这 4 个容器拆开来看,本质上就干了一件事——把用户消息变成工具调用。
发一句"帮我创建一个明天下午 3 点的会议,顺便晚上六点提醒我去 XX 餐厅吃饭",AI 在 Outlook 日历里创建好事件,提前 15 分钟提醒。
发一张活动海报截图,AI 识别时间和内容,自动创建待办。
“这周三下午我有空吗?” AI 查日历,告诉你空闲时段。
发语音,Whisper 转文字后执行。通勤路上也能用。
5 月的一天,我看到了 OpenClaw/Hermes。
翻了一遍文档,心跳加速。
消息网关?它自带飞书、Telegram、CLI、Web。不用自己写。
Agent 逻辑?它本身就是,有 memory,有 Web UI。
MCP 工具调用?原生支持。
我 3 个月造的东西,它都有了。
剩下只有我的 MCP 服务——那 16 个日历和待办工具。那是真正独特的部分。
docker-compose.yml 里注释掉 langgraph-api 和 message-gateway。MCP 服务原封不动。改一下 Hermes config:
mcp_servers:
personal-planner:
connect_timeout: 30
enabled: true
timeout: 60
url: http://localhost:8003/mcp
完事。
迁移前:4 个容器,约 4GB 内存,只有飞书一个入口。加新工具改 3 个服务。
迁移后:1 个 MCP 服务,约 1GB 内存,飞书 + Telegram + CLI + Web 四个入口。加新工具只改 MCP 一个地方。
以前想加天气提醒:写新 LangGraph node,注册工作流,消息网关加消息类型,测试飞书格式,Docker build 部署。然后发现飞书 API 限频。
现在:加个 cron job,不写代码。想接高德地图?加个 MCP 配置。Traccar 有新事件通知我?webhook 配置。
正因为自己造过,才知道哪些轮子不该造。
消息网关是轮子,agent 框架是轮子,多平台接入是轮子。我的 MCP 服务不是——那是我的业务逻辑,是真正该花时间的地方。
但如果你还没开始造,先花 1 小时看看有没有现成的。
参考链接
[1] https://www.renhai.online/blog/ai/mcp-scheduling-assistant