Discover restaurants on Tock (exploretock.com) via MCP — list cities, search a metro, and get a venue's details plus its bookable experiences, prices, party sizes, and open dates/times. Triggers on phrases like "search Tock for", "what's on Tock in Chicago", "find a Tock reservation at", "does Alinea have availability on Tock", "what experiences does <venue> offer on Tock", or "my Tock reservations". Requires tock-mcp installed and the fetchproxy browser extension running in a signed-in exploretock.com tab.
Browser
tock-fpx
Try itQuery Tock (exploretock.com — restaurant discovery, availability, and the signed-in user's reservations) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the tock-mcp server — list metros, search a metro's restaurants, get a venue's bookable calendar, and list reservations, all through a signed-in browser tab. Use when you want Tock data without the MCP, in a script, or on a machine where the MCP isn't installed.
What it does
Query Tock (exploretock.com — restaurant discovery, availability, and the signed-in user's reservations) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the tock-mcp server — list metros, search a metro's restaurants, get a venue's bookable calendar, and list reservations, all through a signed-in browser tab. Use when you want Tock data without the MCP, in a script, or on a machine where the MCP isn't installed.
The skill document
Tock via fpx (no MCP)
www.exploretock.com sits behind a Cloudflare managed challenge — a plain
curl/Node request 403s every path (cf-mitigated: challenge, a "Just a
moment..." interstitial), including /city and /{slug}. There is no
server-side login form and no consumer token exchange. fpx routes the
request through the user's own signed-in browser tab (the Transporter
extension), which has already cleared the challenge, so the same fetch
succeeds. Browsing (metros, search, venue detail, availability) needs no Tock
login at all — just an open, challenge-cleared tab; only the reservations
list needs the tab signed in.
This is the same data the tock_* MCP tools return, reached with one-shot CLI
calls instead of a running server. It is read-only — see "Why no
booking/cancel" below.
One-time setup
npm install -g @fetchproxy/cli # provides `fpx`
fpx profile add tock --domain exploretock.com
fpx pair -p tock # prints a pair code → approve in Transporter
Requirements: the Transporter browser extension installed, with an open
www.exploretock.com tab (signed in, for the reservations tool only), and its
Chrome Site access allowing exploretock.com. Pairing persists — after the
first approval every later fpx call reuses it.
Two call shapes
Tock has two different backends behind the same bridge:
-
SSR pages (
/city,/city/{slug},/{slug},/{slug}/search) — an ordinary GET returns full HTML with the entire dataset embedded as a JS object-literal assignment:window.$REDUX_STATE = {"app":{...}, "consumerPage":{...}, "calendar":{...}, ...}. It is not JSON — absent fields are the bare identifierundefined, sojqcan't parse the raw response. Use the bundledreferences/extract-redux-slice.mjs(a faithful port of the MCP's ownsrc/redux-state.ts) to pull one named slice out as real JSON, then pipe that tojq:fpx get 'https://www.exploretock.com/city' -p tock \ | node references/extract-redux-slice.mjs app \ | jq '.metros // . | length' -
Authenticated GraphQL (
/api/graphql/) — used only for the signed-in patron's reservations, which are lazy-loaded client-side and never appear in the SSR store. Clean JSON in and out — pipe straight tojq:fpx post-json 'https://www.exploretock.com/api/graphql/PatronReservationHistory?opname=PatronReservationHistory' \ @body.json -p tock | jq '.data.purchases'
Ready-to-run paths/bodies for both shapes, plus the exact GraphQL document and
jq recipes, are in references/requests.md.
The one rule: resolve the metro before searching
Tock's /city/{slug} search takes a metro slug (from /city's app
slice, e.g. "chicago"), never a free-text city name. A venue's own page path
is its domainName slug (from a search result, or the
exploretock.com/{slug} URL directly) — no numeric-id resolution needed
beyond that.
Exit codes (fetch verbs)
0— success. For GraphQL, a0HTTP status can still carry anerrorsarray in the body — checkjq '.errors // empty'.2— bridge unavailable: extension not connected or pairing pending → runfpx pair -p tock, confirm an exploretock.com tab is open.3— bot wall: the tab hasn't cleared the Cloudflare challenge → open/ refresh awww.exploretock.comtab and retry.4— upstream non-2xx from Tock (e.g. a bad slug → 404).
A non-JSON 2xx body on the GraphQL path is almost always a bot-challenge or
sign-in interstitial slipping through, not real data — don't blindly
JSON.parse it.
Why no booking/cancel
Tock's booking/checkout/cancel flow is a stateful protobuf transaction
(/api/ticket/*) authenticated by app-injected X-Tock-Authorization /
X-Tock-Session / X-Tock-Fingerprint request headers set by Tock's own JS
interceptor — not cookies. A bridge fetch (fpx included) only carries the
tab's cookies, so replaying the protobuf calls 404s
("Unknown business identifier"). Reconstructing those headers would mean
harvesting the user's live session secrets or forging an anti-bot device
fingerprint — both out of scope. This skill (like the MCP) stays read-only;
book/cancel on exploretock.com itself. Full detail: docs/TOCK-API.md in the
tock-mcp repo.
If a booking was made outside this skill (on the site, by hand or by UI
automation), treat it as confirmed only when a confirmation ID/URL/email
was captured and it shows up in a PatronReservationHistory re-query
afterward; otherwise report it as "attempted, unverified." The post-booking
modal is not proof (a stale-cart confirm is a silent no-op that still renders
it), and the reservations backend lags the Reservations tab by minutes — an
immediate empty re-read proves nothing.
Notes
fpx health -p tockshows bridge connection state when a call fails.- Reservations/profile calls need a signed-in tab; browsing does not.
- This project is developed and maintained by AI (Claude).
Related skills
Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without the MCP, in a script, or on a machine where the MCP isn't installed.
Query and manage OpenTable (opentable.com) restaurant reservations from a shell with the fpx CLI (@fetchproxy/cli) instead of running the opentable-mcp server — search restaurants, check slot availability, list reservations/favorites, and book/modify/cancel a table via one-shot GraphQL + REST calls through a signed-in browser tab. Use when you want OpenTable data or actions without the MCP, in a script, or on a machine where the MCP isn't installed.
Check restaurant availability and manage easyTable bookings (book.easytable.com/book/?id=<placeId>) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the easytable-mcp server — list booking areas/dates/times, look up a booking by phone, and cancel it, all one-shot through a signed-in browser tab. Use when you want easyTable access without the MCP, in a script, or on a machine where the MCP isn't installed.
Manage OpenTable restaurant reservations through natural language — search, book, modify, cancel, and save favorites.
Query etix.com (event ticketing) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the etix-mcp server — search events, venues, and performers, and pull event/venue detail, via one-shot calls through a signed-in browser tab. Use when you want Etix discovery data without the MCP, in a script, or on a machine where the MCP isn't installed.