360 Secure SkillHub
360 安全技能中心

resy

这是对接Resy餐厅预订平台的MCP技能,需提前安装配置resy-mcp服务,填入Resy账号密码鉴权(调用平台非公开Web API);支持按日期、人数、位置搜索可订餐厅、查询时段、预订/取消餐位、管理收藏、订阅热门餐位放号通知;适合通过自然语言处理各类Resy订位需求,如日常订位、查订单、蹲热门位,预订、取消操作带确认机制防误操作,返回结构化结果。

chrischall
chrischall
热度 63.05
最近更新 2026-10-10 07:29:04
分类:生活依赖:MCP 服务 / 第三方 API应用场景:日程安排 / 推荐

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add resy
Metadata
name
resy
description
Manage Resy restaurant reservations via MCP — search venues, book tables, list and cancel reservations, manage favorites, and subscribe to Priority Notify. Triggers on phrases like "book a table at", "find me a reservation", "what reservations do I have", "cancel my Resy", "add to my Resy hit list", or any request involving restaurant reservations on Resy. Requires resy-mcp installed and the resy server registered (see Setup below).

resy-mcp

MCP server for Resy — natural-language restaurant reservation management. Uses Resy's private web-app API with email + password auth.

⚠️ Resy does not publish an official API. This server uses the same private endpoints the Resy web app calls, with the public web-app api_key and user-level auth via email + password. Use at your own discretion.

Setup

Option A — npx (recommended)

Add to .mcp.json in your project or ~/.claude/mcp.json:

{
  "mcpServers": {
    "resy": {
      "command": "npx",
      "args": ["-y", "resy-mcp"],
      "env": {
        "RESY_EMAIL": "you@example.com",
        "RESY_PASSWORD": "yourpassword"
      }
    }
  }
}

Option B — from source

git clone https://github.com/chrischall/resy-mcp
cd resy-mcp
npm install && npm run build

Then add to .mcp.json:

{
  "mcpServers": {
    "resy": {
      "command": "node",
      "args": ["/path/to/resy-mcp/dist/bundle.js"],
      "env": {
        "RESY_EMAIL": "you@example.com",
        "RESY_PASSWORD": "yourpassword"
      }
    }
  }
}

Or place .env in the project directory with RESY_EMAIL= and RESY_PASSWORD=.

Authentication

  • RESY_EMAIL + RESY_PASSWORD are required. The client logs in lazily on first request via POST /3/auth/password, caches the returned token for the process lifetime, and re-logs automatically on 401 / 419 / auth-like 500 responses.
  • RESY_API_KEY is optional. If unset, the client uses the public web-app key baked into resy.com's JS bundle. Override only if Resy rotates it.

Tools

User

Tool Description
resy_get_profile(view?) Current user profile — name, email, phone, booking count, member-since. Payment method IDs are stripped.
resy_list_payment_methods(view?) List saved payment methods (id, brand, last_four, exp_month, exp_year, is_default). The id feeds resy_book's payment_method_id.

Venues

Tool Description
resy_search_venues(date, party_size, query?, lat?, lng?, limit?, radius_meters?, view?) Search venues with availability for a date + party size. Defaults to NYC geo.
resy_find_slots(venue_id, date, party_size, lat?, lng?) List bookable slots at a venue — each includes a short-lived config_token.
resy_get_venue(venue_id) Full venue details.

Reservations

Tool Description
resy_book(venue_id, date, party_size, desired_time?, slot_type?, terms_token?, allow_closest_time?, lat?, lng?, payment_method_id?, allow_duplicate?, confirmToken?) Composite: find fresh slot → details → book. It books ONLY the exact previewed slot. desired_time is "HH:MM" (24h); an unavailable time returns the available times unless allow_closest_time: true previews the nearest. slot_type picks a seating (Dining Room / Bar / Patio) when several share a time. On a client without prompts, the preview comes back as confirmation-required with a confirmToken bound to that slot's time, seating type and terms; after the user approves, repeat the call with the preview's time as desired_time and the confirmToken (see MCP_CONFIRM_MODE). On a client with prompts (unless the server sets MCP_CONFIRM_ELICITATION=off, which sends every client down the confirmToken path), call again with desired_time + slot_type + terms_token (a fingerprint of the seating type and cancellation/payment terms) from the preview and the user is prompted. If the slot, its type or its terms changed, nothing is booked and a fresh preview is returned. The booking refuses if you already hold a reservation at that venue that date (e.g. an earlier timed-out call that went through) unless allow_duplicate: true — checked before you are asked to confirm, so an approval is never wasted; with allow_duplicate: true the preview lists the existing reservation(s). Uses default payment method unless payment_method_id is supplied; either way the preview names the card (brand and last-4), and an id that is not one of your saved cards is refused.
resy_list_reservations(scope?) List reservations. scope: upcoming (default), past, or all. Each result includes the resy_token needed for cancellation.
resy_cancel(resy_token, confirmToken?) Cancel by resy_token (rr://…). Asks the user to confirm first (the Resy account, venue, date, time, party size, any fee): a prompt where the client supports one (unless MCP_CONFIRM_ELICITATION=off), otherwise a preview plus confirmToken that a repeat call passes back. Returns cancelled (always a boolean — true only when confirmed) and outcome (cancelled / not_cancelled / unknown), set from an explicit success/failure in Resy's response, and otherwise by checking whether the reservation is still listed. On outcome: "unknown" the reservation may still have been cancelled — check resy_list_reservations before retrying.

Favorites

Tool Description
resy_list_favorites(view?) List favorited venues ("hit list").
resy_add_favorite(venue_id) Add a venue to favorites.
resy_remove_favorite(venue_id) Remove from favorites.

Priority Notify

Tool Description
resy_list_notify(view?) List Priority Notify subscriptions.
resy_add_notify(venue_id, date, party_size, time_start?, time_end?) Subscribe to notifications when slots open. time_start / time_end are HH:MM (24h); default window 18:00–21:00.
resy_remove_notify(notify_id) Cancel a Priority Notify subscription.

Response shape (view)

Five read tools take view: "compact" | "full" — resy_get_profile, resy_list_payment_methods, resy_list_favorites, resy_list_notify and resy_search_venues — and compact is the default. The slim rung arrives without being asked for, because an efficiency a caller has to know about and request is one that usually is not requested.

Compact strips image and avatar URLs here, and nothing else. There is no field projection: this server holds no captured fixture or documented field list for Resy's payloads, and an invented one would return a record with holes in it that still reads like a verified answer. Media stripping is subtractive, so it cannot lose a field nobody knew about.

The surprise worth stating plainly: on four of those five tools, compact and full are byte-identical today. resy_get_profile is the ONE response in this whole server that carries a media URL — profile_image_url off /2/user — so it is the one place compact removes anything at all. The other four already hand back records this server assembled field by field, with no picture in them. The parameter is on them so that a field arriving later with an avatar inside it is stripped by default rather than after somebody notices.

profile_image_url is named in the drop list rather than left to the built-in rules, and that is what makes its removal deterministic. The key pattern anchors its noun at the START of a key (it knows profile_pic, not profile_image_url), which leaves only the value rule — and that fires just when a URL path ends in an image extension, which Resy's avatar pipeline need not do.

view: "full" returns the record untouched. There is no raw rung: full already IS the un-stripped response, so a third value could only alias it.

The other ten tools take no view:

  • resy_find_slots, resy_get_venue and resy_list_reservations build their answers field by field (formatSlot, formatVenue, formatReservation). No upstream payload survives into the response, and no media URL with it — there is nothing for the rung to remove.
  • resy_book, resy_cancel, resy_add_favorite, resy_remove_favorite, resy_add_notify, resy_remove_notify are writes. A write's response is a receipt — a resy_token, a confirmation, a status — with nothing to strip and everything to keep.
  • resy_healthcheck answers reachability and auth.

Workflows

Book a specific restaurant at a specific time:

resy_search_venues(query: "carbone", date: "2026-05-01", party_size: 2)
  → find venue_id
resy_book(venue_id, date: "2026-05-01", party_size: 2, desired_time: "19:00")
  → preview: time, slot_type, terms_token, fees, payment card; show it to the user

  client WITHOUT prompts (claude.ai, Claude Desktop), or any client when the
  server sets MCP_CONFIRM_ELICITATION=off: that preview is
  `confirmation-required` and carries a confirmToken. Once the user approves in chat:
resy_book(venue_id, date: "2026-05-01", party_size: 2,
          desired_time: "<preview's time>", confirmToken: "<token>")

  client WITH prompts (Claude Code), unless MCP_CONFIRM_ELICITATION=off: name the
  slot and the user is prompted:
resy_book(venue_id, date: "2026-05-01", party_size: 2, desired_time: "<preview's time>",
          slot_type: "<preview's slot_type>", terms_token: "<preview's terms_token>")

See what's available tonight near me:

resy_search_venues(date: "2026-04-20", party_size: 2, lat: 37.7749, lng: -122.4194)
  → returns venues with baked-in slot availability

Cancel a reservation:

resy_list_reservations() → find resy_token for the one to cancel
resy_cancel(resy_token)
  → a confirmation prompt (unless MCP_CONFIRM_ELICITATION=off), or a preview plus
    confirmToken to pass back once the user approves

Stalking a hard-to-get table:

resy_search_venues(query: "4 charles prime rib", ...) → venue_id
resy_add_notify(venue_id, date: "2026-05-31", party_size: 2, time_start: "19:00", time_end: "21:00")
# Resy emails you when a slot opens

Notes

  • Slot config_tokens expire within minutes of being fetched. resy_book re-fetches fresh slots internally — don't try to thread a stale token from resy_find_slots into a book call manually.
  • resy_book requires a payment method on file at resy.com/account. If none exists it throws a clear error.
  • Default geo is NYC (40.7128, -73.9876). Pass lat/lng for other cities.
  • Favorites and Priority Notify endpoint paths are reverse-engineered. If a call fails with 404, run npm run smoke locally against your credentials and adjust the path.
  • RESY_API_KEY env var overrides the baked-in public web-app key if Resy ever rotates it.