MCP大师
一种基于MCP的工具,通过与MCP集成的聊天代理进行自然对话,提供一套工具来发现餐厅、检查可用性和预订。
注: 生态系统中已经存在三个用于Resy预订的MCP服务器(参见现有技术),但没有一个结合了谷歌地点发现、天气集成、用餐同伴跟踪和Resy的真实预订 和 OpenTable——这个差距就是这个项目的价值主张。
它做什么
You: "Book me a quiet Italian place near home for Saturday at 7"
Claude: I found 3 Italian spots within 10 min walk of your home:
1. Carbone (4.7★) - 6:30 PM, 9:15 PM on Resy
2. L'Artusi (4.5★) - 7:00 PM on OpenTable
3. Via Carota (4.6★) - 8:45 PM on Resy
Your wife has a peanut allergy - I've verified these don't
have nut-heavy menus. Which would you like?
You: "L'Artusi at 6:30"
Claude: ✓ Booked! Carbone, Saturday 6:30 PM, 2 people
Confirmation: RESY-ABC123
Add to Google Calendar: https://calendar.google.com/calendar/render?...主要特点
| 特性 | 描述 |
|---|---|
| 智能发现 | Google Places评分+评论,根据您的偏好过滤 |
| 多平台预订 | Resy(自动)、OpenTable(自动) |
| 饮食意识 | 记住你的限制和你的用餐伙伴 |
| 团体用餐 | 节省人员(及其限制)和团体,便于预订 |
| 近期跟踪 | 如果你昨天吃了,我不会推荐墨西哥菜 |
| 天气感知 | 冬季/雨天不建议室外座位 |
| 访问历史 | 追踪你去过的地方,重新显示你的最爱 |
| 日历同步 | 只需单击一下即可将预订添加到Google日历 |
| 成本跟踪 | 监控您的API使用成本 |
| 坚韧的 | 使用回退、断路器、优雅回退重试 |
| 远程托管 | Docker+Cloudflare隧道,可通过HTTPS从任何设备访问 |
快速开始
1.先决条件
- Python 3.11+
- 克劳德桌面 安装
- Google Cloud API密钥(启用了Places API)
2.克隆和安装
git clone
cd restaurant-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
playwright install chromium3.运行安装程序
交互式设置将所有机密加密到本地数据库中,并生成您的Claude Desktop配置:
source .venv/bin/activate
python -m src.setup系统将提示您:
- Google API密钥 (必填)--谷歌云控制台→ 地点API(新增)
- OpenWeather API密钥 (可选)--openweathermap.org(免费套餐:1000/天)
- 重新保存凭据 (可选)--用于自动预订Resy
- OpenTable会话 (可选)--用于OpenTable预订的CSRF令牌+浏览器Cookie
该脚本输出一个准备粘贴的Claude Desktop配置,其中包含一个 RESTAURANT_MCP_KEY 有人是。
Extracting OpenTable Session Values
OpenTable的API需要经过身份验证的浏览器会话Cookie才能绕过机器人程序保护。如果不执行此步骤,OpenTable可用性检查和预订将失败。
在...期间 python -m src.setup,当您提供OpenTable电子邮件时,系统将提示您输入:
- OpenTable x-csrf-token --来自浏览器DevTools
- OpenTable Cookie标头 --来自浏览器DevTools
如何获取这些值(Cookie过期时重新运行安装程序,通常每隔几天一次):
- 打开https://www.opentable.com在Chrome和 登录
- 打开DevTools(
Cmd+Option+I在macOS上,F12在Windows上) - 去 网络 标签
- 导航到任何餐厅页面(例如搜索“Carbone”并单击它)
- 在“网络”列表中,单击任何请求
www.opentable.com - 查找任何请求
/dapi/端点(POST)并复制x-csrf-token标题值 - 在 标头 选项卡,复制完整
Cookie标题值 - 将cookie值保存到可以在
src.setup命令。这是由于浆料尺寸太大。
为什么需要这个? OpenTable使用Cloudflare bot保护来阻止普通HTTP请求。通过存储浏览器的会话Cookie,MCP服务器可以将API调用作为经过身份验证的会话。Cookie在静止时使用与所有其他凭据相同的Fernet加密进行加密。
4.配置克劳德桌面
将步骤3的JSON输出复制到Claude Desktop MCP配置文件中:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json
配置应该如下所示:
{
"mcpServers": {
"restaurant": {
"command": "/path/to/restaurant-mcp/.venv/bin/python",
"args": ["-m", "src"],
"cwd": "/path/to/restaurant-mcp",
"env": {
"RESTAURANT_MCP_KEY": "your-generated-master-key"
}
}
}
}用设置输出中的实际路径替换路径。
5.(可选)通过Docker远程托管
要从Claude.ai、Claude Code或移动设备访问,请在家庭服务器/NAS/Pi上运行服务器:
# Copy env template and fill in values from setup
cp .env.example .env
# Edit .env — add MCP_AUTH_TOKEN, RESTAURANT_MCP_KEY, and TUNNEL_TOKEN
# Build and start
docker compose up --build -d
# Verify
curl http://localhost:8000/health
# → {"status":"ok"}然后配置Claude Desktop进行远程访问:
{
"mcpServers": {
"restaurant": {
"url": "https://mcp.yourdomain.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_MCP_AUTH_TOKEN"
}
}
}
}或克劳德代码:
claude mcp add restaurant --transport streamable-http \
--url https://mcp.yourdomain.com/mcp \
--header "Authorization: Bearer YOUR_TOKEN"看 远程主机规范 有关Cloudflare Tunnel的完整设置说明。
6.重新启动克劳德桌面
退出并重新打开Claude Desktop。您应该看到可用的餐厅工具(聊天输入中的锤子图标)。
7.首次运行——设置您的个人资料
与克劳德开始对话:
You: "Help me set up my restaurant preferences"
Claude: Let's get you set up! First, what's your home address?
(I'll use this as "near home" when you search)
You: "123 Main St, New York, NY 10001"
Claude: Got it. Where do you work?
You: "456 Park Ave, New York, NY 10022"
Claude: What are your favorite cuisines?
You: "Italian, Japanese, Mexican"
Claude: Any dietary restrictions?
You: "None for me"
Claude: ✓ Profile saved! You're all set.8.添加用餐伙伴
You: "Add my wife — she has a nut allergy and a seed allergy"
Claude: ✓ Saved! I'll remember her allergies when searching restaurants.
You: "Create a group called 'date night' with my wife"
Claude: ✓ Group 'date night' created. Merged restrictions: nut allergy, seed allergy.安全模型
| 层 | 保护 |
|---|---|
| 安装脚本 | python -m src.setup --通过输入密码 getpass (没有回应),从不聊天 |
| 单一秘密 | 一把万能钥匙(RESTAURANT_MCP_KEY)替换6+个分散的秘密 |
| 静态加密 | 通过PBKDF2派生密钥的Fernet(AES-128-CBC);SQLite中的所有配置 app_config 桌子 |
| 传统模式 | .env 仍然支持file+OS密钥环/基于文件的Fernet密钥 |
| 重新设置密码 | 身份验证后不持久——只存储电子邮件+身份验证令牌 |
| OpenTable会话 | CSRF令牌+加密存储的浏览器Cookie;无需密码 |
| 文件权限 | 凭据目录0o700,所有文件0o600 |
安装可选 keyring 操作系统密钥环支持的依赖关系(传统模式):
pip install -e ".[security]"示例提示
发现
- “查找家附近的意大利餐厅”
- “今晚上班附近吃什么好?”
- “给我看看步行距离内评价很高的寿司店”
- “在联合广场附近找到适合6人就餐的餐厅”
预订
- “查看Carbone周六晚上7点的可用性,2人派对”
- “预订L'Artusi,周五8点,四人聚会”
- “我有什么预订?”
- “取消我在Via Carota的预订”
团体用餐
- “本周六找一家餐厅约会”
- “寻找一个适合全家居住的地方——记住每个人的过敏反应”
建议
- “今晚我们该试试什么?我们已经一周没出去了”
- “推荐一些新东西——我厌倦了意大利菜”
- “今天户外用餐吃什么好?” *(自动检查天气)*
历史和偏好
- “我们昨晚去Lilia的日志——太棒了,5颗星”
- “上个月我们在哪里吃饭?”
- “更新我的偏好——将泰国菜添加到我最喜欢的菜肴中”
- “TGI星期五的黑名单——永远不要再提了”
成本跟踪
- “这个月我在API调用上花了多少钱?”
MCP工具(共22个)
| 工具 | 目的 |
|---|---|
setup_preferences | 首次运行配置文件设置(家庭、工作、美食、饮食) |
get_my_preferences | 查看当前首选项 |
update_preferences | 更改特定首选项 |
manage_person | 添加/更新/删除用餐同伴 |
list_people | 显示所有已保存的同伴 |
manage_group | 创建/更新/删除组 |
list_groups | 显示所有已保存的组 |
manage_blacklist | 封锁/取消封锁餐馆 |
search_restaurants | 按菜肴、位置、评级查找餐厅 |
check_availability | 检查Resy+OpenTable上的时隙 |
make_reservation | 预订餐桌(带日历链接) |
cancel_reservation | 取消预订 |
my_reservations | 查看即将到来的预订 |
store_resy_credentials | 保存重新登录(加密) |
store_opentable_credentials | 保存OpenTable登录(加密) |
log_visit | 记录餐厅参观情况 |
rate_visit | 对过去的访问进行评分 |
visit_history | 查看用餐历史 |
get_recommendations | 获取个性化建议 |
search_for_group | 为团体寻找餐厅(合并饮食需求) |
api_costs | 查看API使用成本和缓存统计数据 |
API成本
| API | 成本 | 使用 |
|---|---|---|
| Google Places | 约17美元/1000次详细通话 | 初步发现 |
| OpenWeatherMap | 免费(1000/天) | 天气背景 |
| Resy | 免费(非官方) | 预订 |
| OpenTable | 免费(DAPI+浏览器会话) | 预订 |
大量使用的估计每月成本: 3-8美元(带缓存)
使用 api_costs 随时监控你的支出。
建筑
技术栈
- 语言: Python 3.11+
- 框架: FastMCP --根据类型提示自动生成工具模式
- 运输: stdio(本地)或可流式传输的http(远程托管)
- 储存: SQLite(本地,WAL模式)与aiosqlite
- 认证: 通过FastMCP的承载令牌
TokenVerifier(恒定时间比较) - 浏览器自动化: 剧作家(用于身份验证+OpenTable)
- API: Google Places(新增)、OpenWeatherMap、Resy(非官方)、OpenTable(自动化)
- 日历: 谷歌日历URL生成(零配置)
- 集装箱化: Docker+Cloudflare远程托管隧道
- 韧性: 韧性(重试)、自定义断路器、内存缓存(LRU+TTL)
弹性特征
- 使用指数回退重试 --瞬态错误(429,5xx)会自动重试最多3次
- 断路器 --每个服务(Resy、Google Places、OpenTable、Weather),以防止攻击失败的API
- 三层预订回退 -Resy API->OpenTable Playwright->带有手动说明的深度链接
- 内存缓存 -具有用于搜索结果的TTL的LRU缓存,降低API成本
- 用户友好错误 --所有异常都映射到可操作的消息,供Claude中继
项目结构
restaurant-mcp/
├── .ai/
│ ├── AGENTS.md # Agent instructions
│ └── ENGINEERING-STANDARDS.md # Code patterns, testing mandate
├── docs/
│ ├── specs/ # EPICs, architecture plan, research
│ └── adr/ # Architecture Decision Records
├── scripts/
│ ├── validate.sh # Full validation: lint + test + coverage
│ ├── test.sh # Run tests with coverage
│ └── lint.sh # Ruff linting only
├── src/
│ ├── server.py # FastMCP entry point + health endpoint
│ ├── auth.py # Bearer token verifier for remote access
│ ├── config.py # Environment configuration
│ ├── models/ # Pydantic data models
│ ├── storage/ # SQLite + encrypted credentials
│ ├── clients/ # API clients + resilience + cache
│ ├── matching/ # Cross-platform venue ID resolution
│ └── tools/ # MCP tool definitions
├── tests/ # 1193 tests, 100% branch coverage
├── data/ # Runtime: DB, logs, credentials (gitignored)
├── Dockerfile # Container build for remote hosting
├── docker-compose.yml # MCP + Cloudflare Tunnel orchestration
├── pyproject.toml
├── .env.example
└── README.md发展
# Activate virtual environment
source .venv/bin/activate
# Run full validation (lint + tests + coverage + import check)
bash scripts/validate.sh
# Run tests only
bash scripts/test.sh
# Run linter only
bash scripts/lint.sh测试: 1193个单元测试,100%分支覆盖(fail_under = 100 强制执行)。
集成测试
按需集成测试对实时Resy和OpenTable API进行全栈测试:
# Run all integration tests
python -m pytest tests/integration/ -m integration -v
# Resy only
python -m pytest tests/integration/test_resy_integration.py -m integration -v
# OpenTable only (requires session cookies — see step 9 above)
python -m pytest tests/integration/test_opentable_integration.py -m integration -v
# With a specific restaurant / date
INTEGRATION_RESTAURANT="Lilia" INTEGRATION_DATE="2026-03-15" \
python -m pytest tests/integration/ -m integration -v集成测试不包括在 validate.sh 默认的pytest运行。它们需要凭证存储中的真实凭证(通过设置 python -m src.setup).
现有技术
几个MCP餐厅预订服务器已经存在,这些服务器可以作为参考实现:
| 存储库 | 语言 | 它的作用 |
|---|---|---|
| jrklein343 svg/餐厅mcp | TypeScript | 最完整的——统一的Resy+OpenTable搜索,直接Resy预订, snipe_reservation 工具 |
| musemen/resy mcp服务器 | Python | 专注于Claude Desktop——加密存储、多帐户、日历导出(ICS) |
| agupta01/reso-mcp | Python | PyPI发布(pip install resy-mcp),仅限轻量级Resy |
| samwang0723/mcp预订 | TypeScript | 基于情绪过滤的谷歌地图发现(仅限模拟预订) |
我们补充: 完整的Google Places集成、可感知天气的户外座位、用餐同伴饮食跟踪、带评论的访问历史以及真正的双平台预订(Resy+OpenTable)。
文档
| 文档 | 描述 |
|---|---|
| 代理商.md | 代理指令——人工智能工程师的主要切入点 |
| 工程标准.md | 代码模式、架构规则、测试任务 |
| EPICS-INDEX.md | 主EPIC指南——依赖关系图、工具清单 |
| 建筑_平面.md | 高级架构、API环境、数据模型 |
| ADR-001 | EPIC-08弹性实施决策 |
| ADR-004 | 远程托管:Docker、流式http、承载认证 |
风险和缓解措施
| 风险 | 缓解 |
|---|---|
| Resy API脆性 | 3-6个月的破损周期;3层后退(API->剧作家->深度链接) |
| Resy阻止非官方的API | 请求率低;OpenTable回退 |
| Resy身份验证令牌过期 | 通过Playwright登录自动刷新 |
| OpenTable机器人检测 | 实际延迟(>30s);Playwright浏览器自动化 |
| Google API成本飙升 | 具有5分钟TTL的机内LRU缓存;成本跟踪 api_costs 工具 |
| 帐户停用 | 仅限个人账户;无商业模式 |
法律考虑
这 纽约餐厅预订反盗版法 (S.9365A,2025年2月生效)禁止第三方服务在没有书面餐厅协议的情况下列出或出售餐厅预订。罚款:1000美元/违规/天。
对于本项目: 个人使用自动化并没有被明确禁止,但Resy和OpenTable的服务条款都禁止自动访问。这是个人工具,不是商业服务。
未来想法
- \[\]洛杉矶扩张(纽约市稳定后)
- \[\]与合作伙伴共享偏好(双用户模式)
- \[\]餐厅交易跟踪(纽约市餐厅周等)
- \[\]Tock整合(带票用餐体验)
- \[\]Yelp集成(官方MCP服务器支持预订)
- \[\]用于自动同步的Google日历API(OAuth2)(当前基于URL-)
- \[\]用于跨会话持久性的SQLite缓存层
______________________________________________________________________
状态: 所有8个EPIC均已完成。通过Docker+Cloudflare隧道进行远程托管。1193次测试,100%分支覆盖。Resy和OpenTable的集成测试。
