Skip to main content
Glama
chrischall

easytable-mcp

by chrischall
README.md
# easytable-mcp

An MCP server for **easyTable** restaurant reservations. easyTable is a
restaurant table-booking system with a public per-restaurant widget at
`https://book.easytable.com/book/?id=<restaurantId>`.

Every request rides the user's own signed-in, Cloudflare-cleared
`book.easytable.com` browser tab via the
[`@fetchproxy/server`](https://github.com/chrischall/fetchproxy) bridge — the
site blocks server-side requests, and there is no login (the restaurant is
identified by its `id`).

> This project was developed and is maintained by AI (Claude Code). Use at your
> own discretion.

## Tools

| Tool | Kind |
| --- | --- |
| `easytable_list_types` | read — bookable areas/types for a restaurant |
| `easytable_list_dates` | read — bookable dates for an area + party size |
| `easytable_list_times` | read — available time slots |
| `easytable_find_bookings` | read — look up bookings by phone number |
| `easytable_create_booking` | write (confirmed) — make a reservation |
| `easytable_modify_booking` | write (confirmed) — change a reservation |
| `easytable_cancel_booking` | write (confirmed) — cancel a reservation |
| `easytable_healthcheck` | read — bridge connection status |

## Confirmations

Every write asks you to confirm it first. A client that can show a
confirmation prompt (Claude Code) shows one. Elsewhere the first call makes no
network call and returns a preview plus a `confirmToken`; only a repeat call
with the same arguments and that token books, changes or cancels. The token is
single-use, and a changed argument invalidates it.

| variable | default | |
|---|---|---|
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless `MCP_CONFIRM_ELICITATION=off`. An unrecognised value is treated as `refuse`. |
| `MCP_CONFIRM_ELICITATION` | `on` | `off` never sends a confirmation prompt, so every client gets the `MCP_CONFIRM_MODE` path. Set it for a client that declares it can show prompts but never does (the gated call hangs — opencode 2.0.x). Any other value stays `on`, with a stderr warning. |
| `MCP_CONFIRM_TTL_SECONDS` | `600` | How long a token stays valid. |
| `MCP_CONFIRM_SECRET` | random per process | Signing key; set it only if tokens must survive a server restart. |

## Setup

1. Install the ContextMint Bridge browser extension from its
   [releases](https://github.com/nullnet-app/contextmint-bridge/releases):
   in Chrome, unzip the `contextmint-bridge-chrome-*.zip` asset and load it
   unpacked (`chrome://extensions` → Developer mode → Load unpacked); in
   Safari, it ships inside the ContextMint app, which has no public download
   link yet, so use Chrome for now. ContextMint Bridge is the fetchproxy browser extension under its
   new name, from the same maintainer — fetchproxy's own
   [README](https://github.com/chrischall/fetchproxy#extension) points to it.
   Its source is public at
   [nullnet-app/contextmint-bridge](https://github.com/nullnet-app/contextmint-bridge):
   build it yourself, or check a release zip against the `.sha256` file
   published beside it
   (`shasum -a 256 -c contextmint-bridge-chrome-<version>.zip.sha256`).
2. Open a booking widget in Chrome: `https://book.easytable.com/book/?id=<id>`
   and let it finish loading.
3. The first tool call prints a one-time pair code to approve in ContextMint Bridge.

`create` and `modify` additionally read the widget's Cloudflare Turnstile token
from the loaded confirm step, so a booking-widget tab must be open when you
confirm one.

## Development

```sh
npm install
npm run build
npm test
```

See `docs/EASYTABLE-API.md` for the reverse-engineered request/response shapes
and `CLAUDE.md` for architecture notes.

## License

MIT

TDQS

A4/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct booking lifecycle action or availability query; create/modify/cancel/find are clearly differentiated, and list_dates/list_times/list_types have separate resource scopes. healthcheck is a diagnostic outlier but clearly separate from booking operations.

Naming Consistency4/5

All tools use the easytable_ prefix and snake_case; booking actions follow verb_noun (cancel_booking, create_booking, etc.) and availability tools follow list_noun. healthcheck is a minor deviation as a single compound noun rather than verb_noun.

Tool Count5/5

8 tools is well-scoped for a restaurant booking integration, covering booking lifecycle, availability lookups, and diagnostics without bloat. Each tool has a clear role and earns its place.

Completeness4/5

Covers create, modify, cancel, find bookings, and availability listing (types/dates/times) plus healthcheck. Minor gap: no get_booking tool to fetch full booking details (email/comment/company) needed by modify, though find_bookings summary plus user prompting may suffice.

Maintenance

ActivityActive
ResponsivenessResponsive