{"id":"c8787724-9c43-4b60-8a57-1dce66ceea1e","entityType":"agent","slug":"clawhub-chrischall-opentable-mcp","name":"Tmp.XuBXJbJg0f","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chrischall-opentable-mcp","canonicalPath":"/agent/clawhub-chrischall-opentable-mcp","generatedAt":"2026-10-10T08:44:56.005Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":null},"description":"Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on... Skill: Tmp.XuBXJbJg0f Owner: chrischall Summary: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on... Tags: latest:0.15.0 Version history: v0.15.0 | 2026-07-07T23:57:45.007Z | auto - Removed the skill-card.md file from the project. - No functional or behavioral changes to the skill itself. - Documentation and u","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.7K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:opentable-mcp","sourceUrl":"https://clawhub.ai/chrischall/opentable-mcp","homepage":"https://clawhub.ai/chrischall/skills/opentable-mcp","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chrischall/opentable-mcp","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chrischall/skills/opentable-mcp","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":65,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":null},"stars":null,"forks":null,"downloads":1747,"packageName":null,"latestVersion":"0.15.0","tractionLabel":"1.7K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T03:10:09.846Z","lastCrawledAt":"2026-10-10T03:10:09.846Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T03:10:09.846Z","lastVerifiedAt":null,"highlights":[{"version":"0.15.0","createdAt":"2026-07-07T23:57:45.007Z","changelog":"- Removed the skill-card.md file from the project. - No functional or behavioral changes to the skill itself. - Documentation and usage of the skill remain unchanged.","fileCount":3,"zipByteSize":6216},{"version":"0.14.3","createdAt":"2026-06-15T14:34:22.020Z","changelog":"- Removed the file: skill-card.md - No changes to core functionality or user-facing features - Documentation and available tools remain unchanged","fileCount":3,"zipByteSize":6215},{"version":"0.14.2","createdAt":"2026-06-13T00:54:40.060Z","changelog":"- Removes the file skill-card.md. - No changes to functionality or tools; documentation and workflow remain unchanged.","fileCount":3,"zipByteSize":6073},{"version":"0.14.1","createdAt":"2026-06-04T04:29:36.149Z","changelog":"- Removed the sample file: skill-card.md - No user-facing features or functionality changed in this version.","fileCount":3,"zipByteSize":6284},{"version":"0.14.0","createdAt":"2026-05-29T20:17:44.968Z","changelog":"No user-facing changes in this release. - Version bump: 0.14.0 released with no modifications to documentation or code.","fileCount":3,"zipByteSize":6261},{"version":"0.13.0","createdAt":"2026-05-29T12:19:52.898Z","changelog":"opentable-mcp v0.13.0 - No code or documentation changes detected in this version. - Behavior and SKILL.md are unchanged from the previous release.","fileCount":3,"zipByteSize":6293},{"version":"0.12.0","createdAt":"2026-05-28T16:43:42.013Z","changelog":"- Removed the sample file skill-card.md from the project. - No changes to tools or main functionality.","fileCount":3,"zipByteSize":6303},{"version":"0.11.0","createdAt":"2026-05-27T23:26:37.303Z","changelog":"- Removed the sample file skill-card.md. - No changes to core functionality or documentation beyond file removal.","fileCount":3,"zipByteSize":6269}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:opentable-mcp","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T08:44:56.001Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-opentable-mcp/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":null},"readme":"Skill: Tmp.XuBXJbJg0f\n\nOwner: chrischall\n\nSummary: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on...\n\nTags: latest:0.15.0\n\nVersion history:\n\nv0.15.0 | 2026-07-07T23:57:45.007Z | auto\n\n- Removed the skill-card.md file from the project.\n- No functional or behavioral changes to the skill itself.\n- Documentation and usage of the skill remain unchanged.\n\nv0.14.3 | 2026-06-15T14:34:22.020Z | auto\n\n- Removed the file: skill-card.md\n- No changes to core functionality or user-facing features\n- Documentation and available tools remain unchanged\n\nv0.14.2 | 2026-06-13T00:54:40.060Z | auto\n\n- Removes the file skill-card.md.\n- No changes to functionality or tools; documentation and workflow remain unchanged.\n\nv0.14.1 | 2026-06-04T04:29:36.149Z | auto\n\n- Removed the sample file: skill-card.md\n- No user-facing features or functionality changed in this version.\n\nv0.14.0 | 2026-05-29T20:17:44.968Z | auto\n\nNo user-facing changes in this release.\n\n- Version bump: 0.14.0 released with no modifications to documentation or code.\n\nv0.13.0 | 2026-05-29T12:19:52.898Z | auto\n\nopentable-mcp v0.13.0\n\n- No code or documentation changes detected in this version.\n- Behavior and SKILL.md are unchanged from the previous release.\n\nv0.12.0 | 2026-05-28T16:43:42.013Z | auto\n\n- Removed the sample file skill-card.md from the project.\n- No changes to tools or main functionality.\n\nv0.11.0 | 2026-05-27T23:26:37.303Z | auto\n\n- Removed the sample file skill-card.md.\n- No changes to core functionality or documentation beyond file removal.\n\nv0.10.4 | 2026-05-26T17:09:50.992Z | auto\n\nopentable-mcp 0.10.4\n\n- No code or documentation changes detected in this version.\n- Functionality, setup instructions, and usage remain the same as the previous release.\n\nv0.9.2 | 2026-05-21T20:11:32.796Z | auto\n\nopentable-mcp 0.9.2\n\n- No code changes in this release.\n- Documentation and SKILL details remain unchanged.\n- All existing features and workflows are retained.\n\nv0.9.1 | 2026-05-21T17:17:39.390Z | auto\n\n**Migrated to fetchproxy browser extension for improved interoperability.**\n\n- Replaced the dedicated companion Chrome extension with the fetchproxy browser extension shared across MCPs.\n- Updated setup instructions to install and use fetchproxy from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy).\n- Clarified extension install process and browser compatibility.\n- Added documentation for experience-mandatory reservations and modifying existing bookings.\n- Minor improvements to structure and clarity throughout SKILL.md.\n\nv0.9.0 | 2026-05-19T17:20:48.486Z | auto\n\nVersion 0.9.0\n\n- No code or file changes were detected in this release.\n- Documentation and usage instructions remain the same as the previous version.\n- No new features or bug fixes included.\n\nv0.8.0 | 2026-05-08T18:39:57.863Z | auto\n\n- Removed Chrome companion extension and related scripts, documentation, and configuration files from the repository (66 files deleted).\n- Skill documentation and tool descriptions remain unchanged.\n- Usage now assumes external installation of the companion Chrome extension; setup instructions are still included for reference.\n\nv0.7.0 | 2026-04-22T04:10:08.160Z | auto\n\nopentable-mcp v0.7.0\n\n- Improved logic for parsing booking details state, with updates to `src/parse-booking-details-state.ts`.\n- Enhanced reservations handling in `src/tools/reservations.ts`.\n- Added and updated tests for booking details state parsing and reservation tools.\n- Updated dependencies and configuration in manifest and package files.\n\nv0.6.0 | 2026-04-22T04:01:06.725Z | auto\n\n- Improved tooling and core implementation; updated several source and test files.\n- Minor documentation and metadata changes in manifest and package files.\n- No new user-facing features or breaking changes.\n\nv0.5.0 | 2026-04-22T03:41:36.215Z | auto\n\n- Major docs update: SKILL.md rewritten with detailed setup, usage, and tool documentation.\n- Improved onboarding and usage clarity for both MCP server and Chrome extension.\n- Added comprehensive tool descriptions, including booking, search, favorites management, and authentication flows.\n- Included example workflows for common tasks: booking, cancellation, and managing favorites.\n- Clarified authentication mechanism—no environment variables or password handling required.\n- Audience-focused triggers and plain-language examples for skill use.\n\nArchive index:\n\nArchive v0.15.0: 3 files, 6216 bytes\n\nFiles: skill-card.md (2494b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.15.0:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.15.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.15.0\",\n  \"publishedAt\": 1783468665007\n}\n\nFile v0.15.0:skill-card.md\n\n## Description:\n\nManage OpenTable reservations via MCP: search restaurants, check slot availability, book tables, list or cancel reservations, and manage favorites while using a signed-in OpenTable browser session.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and agent developers use this skill to connect an agent to OpenTable reservation workflows through an MCP server. It helps search restaurants, inspect availability, preview booking policies, book or modify reservations, cancel upcoming reservations, and manage saved restaurants.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The MCP server and browser extension operate through a signed-in OpenTable session and can access reservation and profile data.\n\nMitigation: Use a dedicated browser profile where possible and install only after verifying the package, extension publisher, and version.\n\nRisk: Booking, modification, cancellation, and favorites tools can make real account changes.\n\nMitigation: Require explicit user confirmation before committing booking, modification, cancellation, or favorites changes.\n\nRisk: Some reservations may include cancellation policies or payment-card holds.\n\nMitigation: Run booking or modification preview first when required and surface cancellation policy and payment details before asking the user to confirm.\n\n## Reference(s):\n\n- [OpenTable MCP package](https://www.npmjs.com/package/opentable-mcp)\n- [OpenTable MCP source](https://github.com/chrischall/opentable-mcp)\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy)\n- [OpenTable](https://www.opentable.com/)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, configuration, MCP tool calls, markdown]\n\n**Output Format:** [Markdown guidance with JSON configuration snippets, shell commands, and MCP tool-call patterns]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires the opentable-mcp package, the fetchproxy browser extension, and a signed-in OpenTable browser tab.]\n\n## Skill Version(s):\n\n0.15.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.14.3: 3 files, 6215 bytes\n\nFiles: skill-card.md (2478b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.14.3:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.14.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.14.3\",\n  \"publishedAt\": 1781534062020\n}\n\nFile v0.14.3:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP by searching restaurants, checking availability, booking tables, listing or canceling reservations, and managing favorites through a signed-in browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent manage OpenTable restaurant discovery and reservation workflows from the user's signed-in OpenTable browser session. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can perform real booking, modification, favorite, and cancellation actions through a signed-in OpenTable browser session. <br>\nMitigation: Require clear user confirmation before booking, modifying, or canceling reservations, especially when cancellation policies or card holds may apply. <br>\nRisk: The skill can access OpenTable profile and reservation data from the signed-in browser session. <br>\nMitigation: Use it only in trusted agent sessions and limit shared reservation or profile details to what the user requested. <br>\nRisk: Booking and slot tokens are short-lived, so delayed actions may fail or act on stale availability. <br>\nMitigation: Refresh availability shortly before committing a booking or modification and surface preview details before final action. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [fetchproxy browser extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Guidance, Configuration, Shell commands, API Calls] <br>\n**Output Format:** [Markdown with JSON and bash code blocks] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Includes MCP setup snippets and tool-call guidance for reservation workflows.] <br>\n\n## Skill Version(s): <br>\n0.14.3 (source: server evidence release.version) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.14.2: 3 files, 6073 bytes\n\nFiles: skill-card.md (2083b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.14.2:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.14.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.14.2\",\n  \"publishedAt\": 1781312080060\n}\n\nFile v0.14.2:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP, including restaurant search, slot availability, booking, reservation listing and cancellation, and favorites management through a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to search restaurants, check OpenTable availability, book or modify tables, cancel reservations, and manage saved restaurants from an agent workflow. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can book, modify, or cancel reservations through a signed-in OpenTable session without consistently requiring confirmation. <br>\nMitigation: Before booking, modifying, or canceling, require the agent to show the restaurant, date, time, party size, cancellation or no-show policy, any card hold or fee, and ask for explicit confirmation immediately before the action. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, API Calls, Configuration] <br>\n**Output Format:** [MCP tool calls and text responses] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Reservation actions depend on an active signed-in OpenTable browser session and short-lived booking tokens.] <br>\n\n## Skill Version(s): <br>\n0.14.2 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.14.1: 3 files, 6284 bytes\n\nFiles: skill-card.md (2782b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.14.1:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.14.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.14.1\",\n  \"publishedAt\": 1780547376149\n}\n\nFile v0.14.1:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations through an MCP server that searches restaurants, checks availability, books or modifies tables, lists or cancels reservations, and manages favorites using a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent manage OpenTable restaurant discovery, reservation booking, modifications, cancellations, profile lookup, and saved restaurants through the user's signed-in browser session. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can act through a live signed-in OpenTable account, including booking, modifying, canceling reservations, and changing favorites. <br>\nMitigation: Require explicit user confirmation before every booking, modification, cancellation, or favorite change. <br>\nRisk: Some reservations may involve cancellation policies or card holds. <br>\nMitigation: Surface booking preview details, cancellation policies, and saved-card last-four information before committing any reservation action. <br>\nRisk: The server security assessment says the skill does not consistently require confirmation before account-changing actions. <br>\nMitigation: Install only if comfortable with this account access posture, and configure the agent workflow to pause for confirmation before account-changing MCP calls. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [Source repository](https://github.com/chrischall/opentable-mcp) <br>\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with MCP tool names, JSON configuration snippets, and shell commands] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Outputs may include reservation details, cancellation policies, saved-card last-four information, confirmation numbers, security tokens, restaurant metadata, and setup guidance.] <br>\n\n## Skill Version(s): <br>\n0.14.1 (source: server evidence release.version) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.14.0: 3 files, 6261 bytes\n\nFiles: skill-card.md (2682b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.14.0:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.14.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.14.0\",\n  \"publishedAt\": 1780085864968\n}\n\nFile v0.14.0:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP by searching restaurants, checking slot availability, booking tables, listing or canceling reservations, and managing favorites through a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent search restaurants, check availability, manage favorites, and book, modify, or cancel OpenTable reservations through a signed-in browser session. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can use a signed-in OpenTable session to book, modify, cancel, or favorite reservations without consistently requiring final user confirmation. <br>\nMitigation: Require explicit confirmation before every booking, modification, cancellation, or favorite change, and show the restaurant name, date, time, party size, and action before committing. <br>\nRisk: The MCP server and companion browser extension operate with access to the user's signed-in OpenTable session. <br>\nMitigation: Install only when that access is acceptable, keep the browser session under the user's control, and pause use when the OpenTable session or extension state is not expected. <br>\nRisk: Some bookings may involve saved-card holds, no-show fees, cancellation policies, or short-lived booking tokens. <br>\nMitigation: Use the preview flow before committing and show the cancellation policy, card or fee warning, restaurant name, date, time, and party size for user confirmation. <br>\n\n\n## Reference(s): <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [fetchproxy browser extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Guidance, Configuration, API calls] <br>\n**Output Format:** [Markdown guidance with JSON configuration examples and MCP tool call results] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires opentable-mcp, the fetchproxy browser extension, and an authenticated opentable.com browser session.] <br>\n\n## Skill Version(s): <br>\n0.14.0 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.13.0: 3 files, 6293 bytes\n\nFiles: skill-card.md (2715b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.13.0:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.13.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.13.0\",\n  \"publishedAt\": 1780057192898\n}\n\nFile v0.13.0:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP: search restaurants, check slot availability, book tables, list or cancel reservations, and manage favorites from a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and agents use this skill to manage OpenTable restaurant reservations through an MCP server connected to the user's signed-in OpenTable browser tab. It is intended for reservation search, booking, cancellation, modification, profile lookup, and favorites management. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can use a signed-in browser session to book, modify, cancel, and change favorites in a live OpenTable account. <br>\nMitigation: Require explicit user confirmation before every booking, cancellation, modification, and favorite change. <br>\nRisk: Some reservations can involve saved payment cards, cancellation policies, no-show fees, or short-lived booking tokens. <br>\nMitigation: Show the booking preview, cancellation policy, card last four, dining area, party size, date, and time to the user before committing the action. <br>\nRisk: The release depends on the npm package and fetchproxy extension operating through the user's authenticated browser session. <br>\nMitigation: Install and use it only when the user trusts the npm package and browser extension, and keep the OpenTable tab signed in under the intended browser profile. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown with JSON and shell command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May produce reservation details, cancellation policies, saved-card last-four display, confirmation numbers, security tokens, and MCP configuration snippets.] <br>\n\n## Skill Version(s): <br>\n0.13.0 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.12.0: 3 files, 6303 bytes\n\nFiles: skill-card.md (2747b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.12.0:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.12.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.12.0\",\n  \"publishedAt\": 1779986622013\n}\n\nFile v0.12.0:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP, including restaurant search, slot availability, booking, reservation listing and cancellation, and favorites management through a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent manage OpenTable restaurant reservations from natural-language requests. It is intended for tasks such as searching restaurants, checking availability, booking or modifying tables, canceling reservations, and managing saved restaurants. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can book, modify, cancel, and favorite real OpenTable reservations through the user's signed-in browser session. <br>\nMitigation: Before any booking, modification, cancellation, or favorite change, verify the restaurant, date and time, party size, cancellation policy, and saved-card hold or fee details with the user. <br>\nRisk: Credit-card-required slots can involve no-show fees or card holds. <br>\nMitigation: Use the preview step first and surface the cancellation policy and saved-card details before committing the booking. <br>\nRisk: Reservation and booking tokens are short-lived, so stale slot details can fail or produce outdated availability. <br>\nMitigation: Refresh slot availability shortly before committing a booking or modification, especially after user deliberation. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp source](https://github.com/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [fetchproxy browser extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [API Calls, Shell commands, Configuration, Guidance, Text] <br>\n**Output Format:** [MCP tool calls, JSON configuration snippets, shell commands, and concise text guidance] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires opentable-mcp, fetchproxy, and an active signed-in opentable.com browser tab.] <br>\n\n## Skill Version(s): <br>\n0.12.0 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.11.0: 3 files, 6269 bytes\n\nFiles: skill-card.md (2711b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.11.0:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.11.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.11.0\",\n  \"publishedAt\": 1779924397303\n}\n\nFile v0.11.0:skill-card.md\n\n## Description: <br>\nManages OpenTable reservations through an MCP server that can search restaurants, check availability, book or cancel reservations, modify bookings, and manage favorites from a signed-in browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent search OpenTable restaurants, inspect slot availability, preview booking policies, book or modify reservations, cancel bookings, and manage favorites through the user's signed-in OpenTable browser session. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can act through a signed-in OpenTable browser session to make, modify, or cancel real reservations. <br>\nMitigation: Before committing a booking, modification, cancellation, or favorite change, verify the restaurant, date, time, party size, and intended action with the user. <br>\nRisk: Some bookings may involve cancellation policies, saved-card holds, or fee exposure. <br>\nMitigation: Use the preview flow when required and surface the cancellation policy, saved-card hold, and any fee exposure before booking or modifying a reservation. <br>\nRisk: Reservation and booking tokens are short-lived, so stale tokens can fail or point to unavailable slots. <br>\nMitigation: Fetch fresh availability shortly before booking or modifying, especially after user deliberation. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [opentable-mcp project link](https://github.com/chrischall/opentable-mcp) <br>\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown with inline JSON and shell command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May produce reservation confirmations, cancellation details, policy summaries, configuration snippets, and user-facing booking guidance.] <br>\n\n## Skill Version(s): <br>\n0.11.0 (source: ClawHub release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.10.4: 3 files, 6248 bytes\n\nFiles: skill-card.md (2636b), SKILL.md (12164b), _meta.json (133b)\n\nFile v0.10.4:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not surfaced in v1. | n/a |\n\nWhen `booking_type === \"experience_mandatory\"`, do **not** treat the\nreturn as a confirmed reservation — it's still instant-confirm, but\nthe booking_token's `experience` block tells the agent which\nExperience the user committed to (community-table dining, chef's\ncounter, etc.). Mention the Experience name in the user-facing\nconfirmation.\n\n## Modifying a reservation\n\nTo change date/time/party_size/dining_area/experience on an existing reservation, use `opentable_modify_preview` + `opentable_modify`. Mirrors book's preview→commit pattern.\n\n1. Call `opentable_find_slots` for the NEW time you want.\n2. Call `opentable_modify_preview` with:\n   - The existing reservation's `restaurant_id`, `confirmation_number`, `security_token` (from `opentable_list_reservations` or the original `opentable_book` result).\n   - The NEW slot's `date`, `time`, `party_size`, `reservation_token`, `slot_hash`, `dining_area_id`, and (for Experience-mandatory restaurants) `experience_id`.\n3. Surface the returned `cancellation_policy` and any CC re-hold details to the user.\n4. Call `opentable_modify` with the `modify_token` from preview + the same identifying args. Returns `was_modified: true` and the preserved `confirmation_number`.\n\nDon't use cancel + book to \"modify\" — same-day cancel-then-rebook trips OpenTable's double-booking check and risks losing the slot to another diner.\n\n## Workflows\n\n**Book a specific restaurant for a specific evening (no-CC slot):**\n```\nopentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token\n```\n\n**Book a CC-required slot (prime-time at a busy restaurant):**\n```\nopentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate.\n```\n\n**\"What's available tonight for 2 at a nice Italian spot?\":**\n```\nopentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate\n```\n\n**Cancel an upcoming reservation:**\n```\nopentable_list_reservations(scope: \"upcoming\")\n  → find the one to cancel, read confirmation_number + security_token\nopentable_cancel(restaurant_id, confirmation_number, security_token)\n```\n\n**Save a restaurant for later:**\n```\nopentable_search_restaurants(term: \"carbone\")\n  → pick the restaurant_id\nopentable_add_favorite(restaurant_id)\n```\n\n## Notes\n\n- **CC-required bookings must go through preview first.** Restaurants that hold your card for a no-show fee (common at prime-time tables) require `opentable_book_preview` before `opentable_book`. The preview surfaces the cancellation policy and the saved card last-4; the `booking_token` it returns is opaque, stateless, and expires with OpenTable's ~60–90 s slot lock. If the user has no default payment method on opentable.com, preview throws a link to the account settings page. Plain `opentable_book` (no token) refuses CC-required slots with a pointer to preview.\n- **Slot tokens are short-lived.** `reservation_token` + `slot_hash` from `find_slots` typically expire within a minute or two. Call `find_slots` just before `book`, and if the user is deliberating, re-fetch.\n- **`dining_area_id` is mandatory for book.** OpenTable's `/r/<numeric-id>` routes 404 — there's no way to auto-resolve the default dining room. Always call `opentable_get_restaurant(slug)` first and pick a room from `diningAreas[]`.\n- **`/user/favorites` has a read-after-write lag.** A fresh `add_favorite` may not show up in `list_favorites` for ~10 s. The 204 response from add/remove is authoritative.\n- **Extension must be running.** If the MCP server throws \"fetchproxy extension offline — install it and open an opentable.com tab\", the user needs to: install the fetchproxy extension (https://github.com/chrischall/fetchproxy), open an opentable.com tab, and sign in. The popup has a green/yellow/red status indicator.\n- **Service worker sleep.** Chrome MV3 SWs sleep after ~30 s idle. Cold wake adds ~2-5 s to the first request. Subsequent calls are fast.\n- **Persisted-query hashes.** `find_slots`, `book`, `cancel`, and `search` use Apollo persisted queries pinned by sha256Hash. If OpenTable redeploys and returns `PersistedQueryNotFound`, re-capture by reading `window.__APOLLO_CLIENT__.queryManager.mutationStore['1'].mutation.documentId` from DevTools on the relevant opentable.com page (see `CLAUDE.md` → \"Conventions\").\n\nFile v0.10.4:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.10.4\",\n  \"publishedAt\": 1779815390992\n}\n\nFile v0.10.4:skill-card.md\n\n## Description: <br>\nManage OpenTable reservations via MCP by searching restaurants, checking availability, booking tables, listing or canceling reservations, and managing favorites through a signed-in OpenTable browser session. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chrischall](https://clawhub.ai/user/chrischall) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal users and developers use this skill to let an agent help find, book, modify, cancel, and manage OpenTable reservations through opentable-mcp and the fetchproxy browser extension. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can act through the user's signed-in OpenTable browser session. <br>\nMitigation: Before any booking, modification, cancellation, or favorite change, require the agent to restate the restaurant, date, time, party size, and relevant terms, then obtain explicit user confirmation. <br>\nRisk: Some reservations may involve card holds, no-show fees, cancellation policies, or other booking terms. <br>\nMitigation: Use the preview step for card-required or modified bookings and surface cancellation policy and card-hold details before committing. <br>\nRisk: Reservation slot tokens are short-lived and may expire while a user decides. <br>\nMitigation: Refresh slot availability immediately before committing a booking or modification when the user has delayed confirmation. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/chrischall/opentable-mcp) <br>\n- [opentable-mcp npm package](https://www.npmjs.com/package/opentable-mcp) <br>\n- [opentable-mcp source repository](https://github.com/chrischall/opentable-mcp) <br>\n- [fetchproxy browser extension](https://github.com/chrischall/fetchproxy) <br>\n- [OpenTable](https://www.opentable.com/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, configuration, shell commands, guidance] <br>\n**Output Format:** [Markdown with JSON and shell command snippets] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May include restaurant search results, reservation details, cancellation status, favorite changes, and setup configuration for the MCP server.] <br>\n\n## Skill Version(s): <br>\n0.10.4 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v0.9.2: 2 files, 4974 bytes\n\nFiles: SKILL.md (12164b), _meta.json (132b)\n\nFile v0.9.2:SKILL.md\n\n---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it detects the sign-in interstitial.\n\n## Tools\n\n### Discovery\n| Tool | Description |\n|------|-------------|\n| `opentable_search_restaurants(term?, location?, date?, time?, party_size?, latitude?, longitude?, metro_id?)` | Search by free-text + optional location / date / party size. Returns cuisine, neighborhood, price band, rating, URL slug. No bookable slots — call `find_slots` for those. |\n| `opentable_get_restaurant(restaurant_id)` | Full detail for one restaurant by URL slug (e.g. `\"state-of-confusion-charlotte\"`). Includes `diningAreas[]` — you need one of their ids to book. **Numeric ids 404 here; always pass the slug.** |\n| `opentable_find_slots(restaurant_id, date, time, party_size)` | List bookable slots for a restaurant on a date + party size. Each slot has a short-lived `reservation_token` + `slot_hash` (book within a minute or two of fetching). |\n\n### User\n| Tool | Description |\n|------|-------------|\n| `opentable_list_reservations(scope?)` | List reservations. `scope`: `upcoming` (default), `past`, `all`. Each entry has the `confirmation_number` + `security_token` needed to cancel. |\n| `opentable_get_profile` | Authenticated user's profile: name, email, phones, loyalty points, home metro, member-since. No payment data. |\n\n### Bookings\n| Tool | Description |\n|------|-------------|\n| `opentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)` | Preview a booking: runs slot-lock + fetches /booking/details, returns the cancellation policy, the saved card that would be held/charged, and a short-lived `booking_token`. REQUIRED before `opentable_book` for CC-required slots; safe to call for others. Holds the slot for ~60-90s. |\n| `opentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id, booking_token?)` | Book a slot. For CC-required slots, pass the `booking_token` from `opentable_book_preview` — the tool errors out pointing you at preview if you don't. For non-guaranteed slots, `booking_token` is optional (but harmless). Returns `confirmation_number` + `security_token` (save both — they're required for cancel). |\n| `opentable_cancel(restaurant_id, confirmation_number, security_token)` | Cancel by the triple returned from `book` or `list_reservations`. |\n\n### Favorites\n| Tool | Description |\n|------|-------------|\n| `opentable_list_favorites` | List saved restaurants. |\n| `opentable_add_favorite(restaurant_id)` | Add a restaurant (numeric id) to Saved Restaurants. |\n| `opentable_remove_favorite(restaurant_id)` | Remove from Saved Restaurants. |\n\n## Non-instant bookings\n\nOpenTable restaurants fall into three categories. Check\n`opentable_get_restaurant.bookable` and the per-slot `booking_type`\nbefore invoking `opentable_book`.\n\n| `bookable` | `booking_type` | What it means | Action |\n|---|---|---|---|\n| true | `instant` | Standard restaurant, one-click book. | Today's path: optional preview, then `opentable_book`. |\n| true | `experience_mandatory` | Restaurant requires picking an Experience (prix-fixe, tasting menu, etc.) before booking. Slot carries one or more `experience_ids`. | Call `opentable_get_restaurant` to see the per-area `bookableExperiences`. Call `opentable_book_preview` with both `dining_area_id` AND `experience_id`. Then `opentable_book` with the returned `booking_token`. |\n| false | n/a | Listing-only: OpenTable shows the page but reservations go through the restaurant directly. | Surface the restaurant's `phone` and `url` to the user; do NOT call `opentable_book`. |\n| true | `request` | (Reserved) Request-to-book. Not su","readmeExcerpt":"Skill: Tmp.XuBXJbJg0f Owner: chrischall Summary: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on... Tags: latest:0.15.0 Version history: v0.15.0 | 2026-07-07T23:57:45.007Z | auto - Removed the skill-card.md file from the project. - No functional or behavioral changes to the skill itself. - Documentation and u","codeSnippets":[],"executableExamples":[{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}"},{"language":"bash","snippet":"git clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build"},{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}"},{"language":"text","snippet":"opentable_search_restaurants(term: \"state of confusion\", location: \"Charlotte\")\n  → note the restaurant_id (numeric) + URL slug\nopentable_get_restaurant(restaurant_id: \"state-of-confusion-charlotte\")\n  → pick dining_area_id from diningAreas[]\nopentable_find_slots(restaurant_id, date: \"2026-05-01\", time: \"19:00\", party_size: 2)\n  → pick a slot, grab reservation_token + slot_hash\nopentable_book(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → save confirmation_number + security_token"},{"language":"text","snippet":"opentable_find_slots(...)                                   # pick one\nopentable_book_preview(restaurant_id, date, time, party_size, reservation_token, slot_hash, dining_area_id)\n  → shows cancellation_policy (e.g. \"$50/guest no-show fee, cancel 24h ahead for no charge\")\n  → shows payment_method (e.g. Mastercard •••• 4242)\n  → returns booking_token\n\n   [Surface the policy + card to the user. Let them confirm in plain English.]\n\nopentable_book(..., booking_token: <from preview>)          # commits\n  → save confirmation_number + security_token\n\nIf opentable_book is called on a CC-required slot without booking_token, it\nerrors out with \"call opentable_book_preview first\". That's the gate."},{"language":"text","snippet":"opentable_search_restaurants(term: \"italian\", date: \"2026-04-20\", time: \"19:00\", party_size: 2, latitude: <lat>, longitude: <lng>)\n  → scan results, pick candidates\nopentable_find_slots(restaurant_id, date, time, party_size)  # for each candidate"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: opentable-mcp\ndescription: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on phrases like \"book a table on OpenTable\", \"find me a reservation at\", \"what OpenTable reservations do I have\", \"cancel my OpenTable\", \"add to my OpenTable favorites\", \"what's available for dinner tonight at\", or any request involving OpenTable restaurant reservations. Requires opentable-mcp installed and the fetchproxy browser extension running in a signed-in opentable.com tab.\n---\n\n# opentable-mcp\n\nMCP server for OpenTable — natural-language restaurant reservation management. Every request is relayed through the user's signed-in browser tab via the [fetchproxy](https://github.com/chrischall/fetchproxy) extension, so there's no cookie paste, no bot-wall dance, and no password handling.\n\n- **npm:** [npmjs.com/package/opentable-mcp](https://www.npmjs.com/package/opentable-mcp)\n- **Source:** [github.com/chrischall/opentable-mcp](https://github.com/chrischall/opentable-mcp)\n\n> OpenTable does not publish an official API. This server calls the same endpoints the opentable.com web app uses. Auth lives in the user's browser (OpenTable's passwordless email-OTP session). Use at your own discretion.\n\n## Setup\n\nThe MCP server is half of the picture — the other half is the [fetchproxy](https://github.com/chrischall/fetchproxy) browser extension that actually talks to OpenTable from your signed-in tab. Both are required.\n\n### 1. Install the MCP server\n\n#### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"opentable-mcp\"]\n    }\n  }\n}\n```\n\n#### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/opentable-mcp\ncd opentable-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"opentable\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/opentable-mcp/dist/bundle.js\"]\n    }\n  }\n}\n```\n\n### 2. Install the fetchproxy extension\n\nopentable-mcp shares a single browser extension with every other fetchproxy-based MCP. Install it once from [github.com/chrischall/fetchproxy](https://github.com/chrischall/fetchproxy):\n\n1. Install the fetchproxy extension (Chrome Web Store / Safari `.dmg`).\n2. Sign in to `https://www.opentable.com/` in the same browser profile.\n\nThe extension's toolbar badge turns green when the WebSocket + tab + auth are all good.\n\nFull extension walkthrough: see [fetchproxy](https://github.com/chrischall/fetchproxy).\n\n## Authentication\n\nNo env vars. Auth is whatever cookies your signed-in opentable.com tab has. If Akamai rotates `_abck` or OpenTable's SSO expires, visit opentable.com and click through whatever prompt appears — subsequent MCP calls will use the fresh cookies automatically.\n\nThe server throws `SessionNotAuthenticatedError` (with a clear message) if it det"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"opentable-mcp\",\n  \"version\": \"0.15.0\",\n  \"publishedAt\": 1783468665007\n}"},{"path":"skill-card.md","content":"## Description:\n\nManage OpenTable reservations via MCP: search restaurants, check slot availability, book tables, list or cancel reservations, and manage favorites while using a signed-in OpenTable browser session.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and agent developers use this skill to connect an agent to OpenTable reservation workflows through an MCP server. It helps search restaurants, inspect availability, preview booking policies, book or modify reservations, cancel upcoming reservations, and manage saved restaurants.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The MCP server and browser extension operate through a signed-in OpenTable session and can access reservation and profile data.\n\nMitigation: Use a dedicated browser profile where possible and install only after verifying the package, extension publisher, and version.\n\nRisk: Booking, modification, cancellation, and favorites tools can make real account changes.\n\nMitigation: Require explicit user confirmation before committing booking, modification, cancellation, or favorites changes.\n\nRisk: Some reservations may include cancellation policies or payment-card holds.\n\nMitigation: Run booking or modification preview first when required and surface cancellation policy and payment details before asking the user to confirm.\n\n## Reference(s):\n\n- [OpenTable MCP package](https://www.npmjs.com/package/opentable-mcp)\n- [OpenTable MCP source](https://github.com/chrischall/opentable-mcp)\n- [fetchproxy extension](https://github.com/chrischall/fetchproxy)\n- [OpenTable](https://www.opentable.com/)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, configuration, MCP tool calls, markdown]\n\n**Output Format:** [Markdown guidance with JSON configuration snippets, shell commands, and MCP tool-call patterns]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires the opentable-mcp package, the fetchproxy browser extension, and a signed-in OpenTable browser tab.]\n\n## Skill Version(s):\n\n0.15.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on... Skill: Tmp.XuBXJbJg0f Owner: chrischall Summary: Manage OpenTable reservations via MCP — search restaurants, check slot availability, book tables, list/cancel reservations, and manage favorites. Triggers on... Tags: latest:0.15.0 Version history: v0.15.0 | 2026-07-07T23:57:45.007Z | auto - Removed the skill-card.md file from the project. - No functional or behavioral changes to the skill itself. - Documentation and u","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1189,"uniquenessScore":46,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T03:10:09.846Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:44:56.005Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}