---
slug: "tmp-a5ojnmrz8j"
source_type: "clawhub"
source_url: "https://clawhub.ai/skills/easytable-fpx"
repo: ""
source_file: "description"
---
---
name: easytable-fpx
description: >-
  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.
---

# easyTable via fpx (no MCP)

easyTable fronts every `book.easytable.com` endpoint — reads and writes alike
— with a Cloudflare check that 403s any plain `curl`/Node request. `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
requests succeed. There's no easyTable login: a restaurant is identified only
by its `id` (a.k.a. `place`) from its widget URL
`https://book.easytable.com/book/?id=<placeId>`.

This is the same data/actions the `easytable_*` MCP tools use, reached with
one-shot CLI calls instead of a running server.

## One-time setup

```sh
npm install -g @fetchproxy/cli               # provides `fpx`
fpx profile add easytable --domain easytable.com
fpx pair -p easytable                        # prints a pair code → approve in Transporter
```

Requirements: the **Transporter** extension installed, with an open
`https://book.easytable.com/book/?id=<placeId>` tab left to finish loading
(its Turnstile check solves itself), and Chrome **Site access** allowing
`easytable.com`. Pairing persists after the first approval.

## Core call

Reads are GET requests that return **HTML fragments** (not JSON) — the
widget loads them into a container div. Send the `X-Requested-With` header
the widget sends, and pipe the fragment to `grep`/`sed` rather than `jq`:

```sh
fpx get 'https://book.easytable.com/book/ajax/types.asp?id=1fdfc&lang=en' \
  -p easytable -H 'X-Requested-With: XMLHttpRequest'
```

Ready-to-run URLs + extraction recipes for every read, plus the cancel write
and the create/modify payload shape, are in
`references/easytable-requests.md`. Exhaustive parsing lives in the repo at
`src/parse.ts` / `docs/EASYTABLE-API.md` — the recipes here are compact
greps against the same markup those parsers target.

## The one rule: resolve the `type` first

Dates and times are scoped to a booking area. Always list types first, take
the `type` id, then feed it to dates/times:

```sh
fpx get 'https://book.easytable.com/book/ajax/types.asp?id=1fdfc&lang=en' \
  -p easytable -H 'X-Requested-With: XMLHttpRequest' \
  | grep -oE '<a[^>]*type=[0-9]+[^>]*>[^<]*</a>'
# <a href="#type=13991">Boka Inne</a>
```

Same pattern for cancelling: resolve the booking id via `cancel-search.asp`
(by mobile number) before calling the cancel endpoint.

## Creating or modifying a booking — not fully doable through fpx

`easytable_create_booking`/`easytable_modify_booking` need a live Cloudflare
**Turnstile token**, read from the widget's hidden
`input[name="cf-turnstile-response"]`. The MCP harvests it with a bespoke
`read_dom` verb wired into *this repo's own* fetchproxy transport
(`bridge-fetchproxy.ts`) — the stock `fpx` CLI has no DOM-read command (only
`get`/`post-json`/`request`/`cookies`/`local-storage`/`session-storage`/
`indexeddb`/`session`), so it cannot harvest that token.

The other three page-derived values (`bookingToken`, `cancellationtime`,
`lcid`) ARE plain server-rendered text, so `fpx get` + `grep` gets them fine
— see `references/easytable-requests.md` for the full payload shape and a
manual-token workaround (read the Turnstile input yourself from the browser
console). Treat create/modify as a manual/hybrid flow, not a clean one-shot.

## Exit codes (fetch verbs)

- `0` — success. Write endpoints answer HTTP 200 even on a *rejected*
  booking (`Status:0` in the body) — always check the parsed `Status`, not
  just the exit code.
- `2` — bridge unavailable: extension not connected or pairing pending → run
  `fpx pair -p easytable`, confirm an easytable tab is open.
- `3` — bot wall: the tab hasn't cleared Cloudflare → open/refresh a
  `book.easytable.com` tab and retry.
- `4` — upstream non-2xx from easyTable.

## Notes

- No easyTable account or API key involved — this is the user's own action
  on their own signed-in browser session.
- `fpx health -p easytable` shows bridge connection state when a call fails.
- Don't fire real create/cancel calls just to "test" the flow — a
  `confirm`-equivalent action here books/cancels a real table at a real
  restaurant.
- This project is developed and maintained by AI (Claude).
