Skip to main content
Glama
chrischall

easytable-mcp

by chrischall

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 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

Related MCP server: Rizerve MCP Server

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 sends nothing and returns a preview plus a confirmToken; only a repeat call with the same arguments and that token books, changes or cancels. A cancel looks the booking up first, so its preview shows which reservation it is, and an id that isn't one of that mobile's bookings is refused. 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: 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 points to it. Its source is public at 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.

Environment

No environment variables are required. These optional knobs mirror the .mcpb manifest's settings (the MCP_CONFIRM_* family is under Confirmations):

variable

default

EASYTABLE_WS_PORT

37149

Concentrator port for the fetchproxy browser bridge. Every fetchproxy MCP on one machine shares it, so move it for all of them or none (local testing, or a hosted registration's bridge port).

FETCHPROXY_WS_HOST

127.0.0.1

Bridge bind interface, a literal IP only (anything else is ignored). Keep on loopback; it exists for a hosted child in its own network namespace.

FETCHPROXY_IDENTITY_DIR

~/.fetchproxy/identity/

Where the bridge's long-term identity keypair is stored, an absolute path only (anything else is ignored). For a host that runs a separate child per caller.

EASYTABLE_DEBUG

unset

Set to a truthy value to log the bridge role and per-request debug lines to stderr.

Development

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

Available Tools

8 tools
easytable_cancel_bookingA
DestructiveIdempotent

Cancel an existing booking. Look up the booking id first with easytable_find_bookings (it needs the mobile the booking was made with). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). The first call only looks the booking up (a read); it cancels nothing.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
mobileYesMobile the booking was made with, E.164 (e.g. +46701234567).
bookingIdYesBooking id from easytable_find_bookings.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and idempotentHint=true but say nothing about confirmation flow. The description adds high-value context beyond them: the first call is a non-destructive lookup ("it cancels nothing"), the token must never be invented or reused, and the token is ignored when elicitation is supported. No contradiction with the annotations, which correctly mark the overall operation as a write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool does and the prerequisite before the longer confirmation caveat, and every sentence carries information. The confirmation paragraph is dense with parentheticals and a mode-flag reference, which costs some readability but not correctness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing the phase-1 response shape (preview plus confirmToken) and the terminal behavior. Combined with the total confirmation protocol, an agent has everything needed to call it safely and correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, and the description adds real operational meaning: it ties bookingId and mobile to their source (easytable_find_bookings, E.164 mobile used at booking time) and constrains confirmToken to the fallback path only. It stops short of explaining field formats, which it reasonably delegates to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ("Cancel an existing booking") and immediately distinguishes itself from sibling easytable_find_bookings by naming it as the prerequisite lookup step rather than an alternative cancel path. An agent can tell what this tool does and what it does not do without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the precondition (fetch bookingId via easytable_find_bookings, which itself needs the mobile) and the confirmation protocol, including the two-step fallback when the client lacks elicitation. It also names the governing mode flag (MCP_CONFIRM_MODE), leaving no branch to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_create_bookingA
Destructive

Create a restaurant booking. Reads the Cloudflare Turnstile token from your signed-in booking-widget tab (via the bridge) and submits it with the reservation — so a book.easytable.com/book/?id= tab must be open and loaded. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). The first call makes NO network call.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
dateYesBooking date, ISO YYYY-MM-DD (from easytable_list_dates).
langNoWidget language code (en, se, da, …). Defaults to en.en
nameYesGuest name on the booking.
timeYesTime slot HH:MM, 24h (from easytable_list_times).
typeYesBooking area/type id from easytable_list_types.
emailNoGuest email.
eventNoOptional event id.
mobileYesGuest mobile in E.164 (e.g. +46701234567).
commentNoFree-text note / special requests.
companyNoOptional company name.
personsYesParty size.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the annotations: the first call makes NO network call, confirmation is requested before submitting, and without elicitation support the tool returns a preview plus confirmToken that must be echoed back only after explicit user approval. This is exactly the kind of side-effect and safety sequencing the destructiveHint/idempotentHint annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three front-loaded sentences with no filler, and the critical prerequisite and no-network-on-first-call facts come early. Sentences are long and dotted with parentheticals, which slightly hurts scanability but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world mutation with no output schema, the description covers preconditions, confirmation flow, and the failure/fallback response shape (preview + confirmToken). It does not describe the eventual success response or post-booking behavior, which is a minor gap given no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 13 parameters including field provenance. The description only clarifies confirmToken's role, which is also documented in the schema, so it adds little beyond the structured fields. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Create a restaurant booking") and immediately disambiguates from the modify/cancel/find siblings by describing the create-specific Turnstile/token submission path. An agent can identify the tool's job and scope without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a hard precondition (a loaded book.easytable.com/book/?id=<id> tab must be open) and explains the two-step confirmation path versus the elicitation path, which tells the agent exactly how to sequence calls. It stops short of naming required predecessor siblings like easytable_list_types/dates/times, though the schema references them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_find_bookingsA
Read-only

Look up a restaurant's existing bookings made with a given mobile number. Returns each booking's id (for easytable_cancel_booking) plus a summary.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
langNoWidget language code (e.g. en, se, da, de, fr). Defaults to en.en
mobileYesMobile number the booking was made with, in E.164 (e.g. +46701234567).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safe-read profile is covered. The description adds useful context by stating what is returned (each booking's id plus a summary), which is genuine value beyond the annotations, though it doesn't address empty-result behavior or auth/rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences; the core lookup action is front-loaded and the second sentence delivers the return-value and cross-tool routing information with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully characterizes the return (id plus summary), and required inputs are fully covered by the schema. It omits edge-case behavior such as what happens when no bookings match the mobile number, leaving a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents restaurant id, mobile (E.164), and lang. The description only restates the mobile-number input, adding no syntax or format detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (look up) plus resource (existing bookings) scoped to a restaurant and a given mobile number. It clearly differentiates from siblings like create/modify/cancel by naming the lookup role and pointing to easytable_cancel_booking as the consumer of the returned ids.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies the when-to-use context by noting the returned id feeds into easytable_cancel_booking, making the lookup-then-cancel flow apparent. However, it gives no explicit when-not or alternative-selection guidance (e.g. when to use this versus a broader listing call).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_healthcheckVerify the ContextMint Bridge connection end-to-endA
Read-onlyIdempotent

Round-trips a small public book.easytable.com URL (/robots.txt) through ContextMint Bridge (your signed-in browser tab) and returns diagnostics: the bridge's role (host/peer/null), port, version, the extension link (linked / pair pending / not attached / never answered), the elapsed round-trip time, and a plain-English hint distinguishing 'bridge never came up' from 'extension not connected' from 'this browser can't serve a capability' from 'real book.easytable.com-side problem'. Read-only, no auth required. Call this when a real tool fails and you want to know which hop broke.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover safety/read/idempotency, but the description goes well beyond them: it discloses the exact diagnostic fields returned, the four distinguishable failure states, and that the call is read-only with no auth required. That is exactly the kind of behavioral context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, then the returned data, then the trigger condition. The middle enumeration sentence is comma-heavy but every clause adds distinct diagnostic value, so it is dense rather than padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and no output schema, the description fully carries the burden by describing both the invocation and the return payload, including how to interpret failure modes. Nothing an agent needs in order to call or interpret this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there are no parameter semantics to explain and the baseline of 4 applies. Nothing in the description is needed here, and nothing is missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (round-trip /robots.txt through ContextMint Bridge) and enumerates exactly what it produces (role, port, version, extension link state, elapsed time, hints). It is unmistakably a diagnostics tool and trivially distinguishable from the booking-oriented siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent when to call it: 'when a real tool fails and you want to know which hop broke.' That trigger is clear and actionable. It stops short of naming exclusions or alternatives (e.g., when NOT to reach for it), so it lands just below the full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_list_datesA
Read-only

List bookable dates for a restaurant area and party size. Each entry has an ISO date and whether it is available.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
langNoWidget language code (e.g. en, se, da, de, fr). Defaults to en.en
typeYesBooking area/type id from easytable_list_types.
personsYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is already covered. The description adds value beyond that by disclosing the shape of the result — each entry carries an ISO date plus an availability flag — which is meaningful since there is no output schema. It says nothing about date-range limits, pagination, or auth, so it is not fully rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler, with the core capability front-loaded. The second sentence about entry contents could arguably be folded in, but it earns its place by defining the return shape in the absence of an output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter read-only discovery tool with no output schema, the description covers the essential purpose and the entry format. It is silent on how far ahead dates are listed, whether results are windowed or complete, and how this call relates to easytable_list_times, which an agent sequencing a booking flow would want to know.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 75%, with id, lang, and type documented in the schema (including the helpful link-format hint for id) and only persons left bare. The description's 'restaurant area and party size' maps loosely onto type and persons but adds no format or constraint detail beyond what the schema already provides, so the baseline 3 is right.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'List bookable dates' — scoped to a restaurant area and party size, which is enough to separate it from easytable_list_times and easytable_find_bookings. It stops short of naming those siblings explicitly, so the differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context (bookable dates for an area and party size) implies this is a discovery step used before easytable_list_times or easytable_create_booking, but no when-to-use, prerequisites, or alternatives are stated. Adequate but leaves the agent to infer the call sequence from the sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_list_timesA
Read-only

List available time slots for a restaurant area, date, and party size. Times are returned as HH:MM.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
dateYesDate to check, ISO YYYY-MM-DD (from easytable_list_dates).
langNoWidget language code (e.g. en, se, da, de, fr). Defaults to en.en
typeYesBooking area/type id from easytable_list_types.
personsYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds value by stating the return format ("Times are returned as HH:MM"). It stops there: no note on whether only bookable slots are returned, whether results are paginated, empty-result behavior, or any rate limits for this live availability lookup.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and scope, and no filler. Both sentences carry information (the second covers the return format), though the phrasing is brief enough to feel thin rather than dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a fully enumerated parameter set and no output schema, the description covers purpose and value format adequately. The chain of calls needed to obtain id/type is documented in the schema rather than the description, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 80%, so the schema already documents id, date, lang and type (including cross-references to easytable_list_dates and easytable_list_types). The description only loosely maps "restaurant area, date, and party size" onto type/date/persons, adding nothing beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ("List") plus a precise resource ("available time slots") scoped by restaurant area, date and party size. It is clearly distinct from siblings like easytable_list_dates and easytable_list_types by resource, but the description never names those siblings or the ordering relationship with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the input dimensions (area/date/party size), so an agent can infer it must gather those first. There is no explicit when-to-use/when-not guidance and no mention of alternatives or prerequisites, so this stays at the minimum-viable level.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_list_typesA
Read-only

List the bookable areas/types for a restaurant (e.g. "Boka Inne", "Boka baren"). Returns each area's type id for use in the other availability tools.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
langNoWidget language code (e.g. en, se, da, de, fr). Defaults to en.en

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds the useful fact that the output is a type id intended for downstream calls, but says nothing about pagination, failure modes, or auth requirements. Adequate but not rich given annotations carry the main burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste, with the core purpose front-loaded and the downstream-use note appended. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully discloses what is returned (each area's type id) and why it matters. It leaves minor gaps around result ordering and error behavior, but is complete enough for a simple read-only lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (id, lang) are already fully documented in the schema, including the book.easytable.com link hint. The description contributes no additional parameter meaning, making the baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the bookable areas/types for a restaurant') and grounds it with concrete examples ('Boka Inne', 'Boka baren'). It implicitly separates itself from siblings by framing the output as type ids consumed by the other availability tools, though it never names list_dates/list_times directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: this is a prerequisite lookup whose returned type id feeds 'the other availability tools', which tells an agent when in the workflow to call it. It stops short of explicit exclusions or when-not-to-use guidance, so it does not reach 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

easytable_modify_bookingA
Destructive

Modify an existing booking (date/time/party size/details). Like create, it reads the Turnstile token from your signed-in widget tab. Get the existing booking id from easytable_find_bookings. The change replaces the whole booking: email, comment and company are required — pass the booking's current values to keep them (ask the user if unknown), or '' to clear them; the newsletter opt-in is reset. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call returns a preview and a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). The first call makes NO network call.

NameRequiredDescriptionDefault
idYesRestaurant id — the `id` in a book.easytable.com/book/?id=<id> link.
dateYesBooking date, ISO YYYY-MM-DD (from easytable_list_dates).
langNoWidget language code (en, se, da, …). Defaults to en.en
nameYesGuest name on the booking.
timeYesTime slot HH:MM, 24h (from easytable_list_times).
typeYesBooking area/type id from easytable_list_types.
emailYesGuest email. REQUIRED — the booking's current email, or '' to remove it (also drops the confirmation mail).
eventNoOptional event id.
mobileYesGuest mobile in E.164 (e.g. +46701234567).
commentYesFree-text note / special requests. REQUIRED — the booking's current comment (e.g. allergy notes), or '' to remove it.
companyYesCompany name. REQUIRED — the booking's current company, or '' for none.
personsYesParty size.
existingYesId of the existing booking to modify (from easytable_find_bookings).
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag destructive/idempotent hints; the description adds substantially more — whole-booking replacement semantics, that email/comment/company must be re-passed or explicitly cleared, that the newsletter opt-in is reset, and that phase 1 makes NO network call. The confirmToken contract (never reused, never invented, ignored under elicitation) is also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the paragraph flows from purpose to prerequisites to mutation semantics to confirmation. A few phrases are duplicative of the schema (e.g. 'never invented, never reused'), but density is justified by the two-phase confirmation protocol.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter destructive mutation with no output schema, the description covers prerequisites, replacement semantics, token sourcing and both confirmation modes. It omits what the successful response looks like and any error/auth edge cases, which are minor given no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes beyond per-field text by explaining the cross-cutting replacement rule for email/comment/company ('pass the booking's current values to keep them... or '' to clear them') and the instruction to ask the user when values are unknown. It is genuinely additive despite the already-rich schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Modify an existing booking (date/time/party size/details).' It is immediately distinguishable from siblings easytable_create_booking, easytable_cancel_booking and easytable_find_bookings, and it names find_bookings as the id source.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operational context: obtain the booking id from easytable_find_bookings, the Turnstile token comes from the signed-in widget tab, and the confirmation path is spelled out per client capability. It stops short of explicit when-not-to-use guidance (e.g. when to cancel or create instead), so it is not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.2.7
    • Changedeasytable_create_booking3 fields changed
      • changedInput schema / properties / time / description
        Previous value: -"Time slot HH:MM (from easytable_list_times)."New value: +"Time slot HH:MM, 24h (from easytable_list_times)."
      • removedInput schema / properties / time / minLength
        Removed value: -1
      • addedInput schema / properties / time / pattern
        Added value: +"^([01]?\\d|2[0-3]):[0-5]\\d$"
    • Changedeasytable_modify_booking3 fields changed
      • changedInput schema / properties / time / description
        Previous value: -"Time slot HH:MM (from easytable_list_times)."New value: +"Time slot HH:MM, 24h (from easytable_list_times)."
      • removedInput schema / properties / time / minLength
        Removed value: -1
      • addedInput schema / properties / time / pattern
        Added value: +"^([01]?\\d|2[0-3]):[0-5]\\d$"
  2. 3 tool updatesv1.2.0
    • Changedeasytable_cancel_booking2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedeasytable_create_booking2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedeasytable_modify_booking2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
  3. 1 tool updatev1.1.3
    • Changedeasytable_modify_booking8 fields changed
      • changedInput schema / properties / comment / description
        Previous value: -"Free-text note / special requests."New value: +"Free-text note / special requests. REQUIRED — the booking's current comment (e.g. allergy notes), or '' to remove it."
      • changedInput schema / properties / company / description
        Previous value: -"Optional company name."New value: +"Company name. REQUIRED — the booking's current company, or '' for none."
      • addedInput schema / properties / email / anyOf
        Added value: +[
        +  {
        +    "format": "email",
        +    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
        +    "type": "string"
        +  },
        +  {
        +    "const": "",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / email / description
        Previous value: -"Guest email."New value: +"Guest email. REQUIRED — the booking's current email, or '' to remove it (also drops the confirmation mail)."
      • removedInput schema / properties / email / format
        Removed value: -"email"
      • removedInput schema / properties / email / pattern
        Removed value: -"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
      • removedInput schema / properties / email / type
        Removed value: -"string"
      • changedInput schema / required
        Previous value: -[
        -  "id",
        -  "type",
        -  "date",
        -  "time",
        -  "persons",
        -  "name",
        -  "mobile",
        -  "existing"
        -]New value: +[
        +  "id",
        +  "type",
        +  "date",
        +  "time",
        +  "persons",
        +  "name",
        +  "mobile",
        +  "email",
        +  "comment",
        +  "company",
        +  "existing"
        +]
  4. 8 tool updatesv1.0.0
    • Changedeasytable_cancel_booking1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_create_booking1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_find_bookings1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_healthcheck1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_list_dates1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_list_times1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_list_types1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedeasytable_modify_booking1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  5. 2 tool updatesv0.4.1
    • Changedeasytable_create_booking1 field changed
      • changedInput schema / properties / email / pattern
        Previous value: -"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"New value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
    • Changedeasytable_modify_booking1 field changed
      • changedInput schema / properties / email / pattern
        Previous value: -"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"New value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
  6. 8 tool updatesv0.0.0
    • First observedeasytable_cancel_booking
    • First observedeasytable_create_booking
    • First observedeasytable_find_bookings
    • First observedeasytable_healthcheck
    • First observedeasytable_list_dates
    • First observedeasytable_list_times
    • First observedeasytable_list_types
    • First observedeasytable_modify_booking

TDQS

A4.1/5.0

Scored across 8 tools

Disambiguation4/5

Each tool has a distinct action: booking CRUD (find/create/modify/cancel), availability lookups (list_types/list_dates/list_times), and diagnostics (healthcheck). The three list_* tools are related but clearly differentiated by what they enumerate (areas, dates, times), and descriptions reinforce their distinct purposes.

Naming Consistency5/5

All tools use a consistent easytable_ namespace with a predictable verb_noun pattern (find_bookings, cancel_booking, create_booking, modify_booking, list_types, list_dates, list_times). Only healthcheck is a bare noun, a trivial deviation that doesn't break the pattern.

Tool Count5/5

Eight tools is well-scoped for a restaurant-booking server, covering the booking lifecycle plus availability and a bridge diagnostic. No redundant or padding tools.

Completeness4/5

Full booking lifecycle is covered (create/read/modify/cancel) plus the availability trio needed to book. Gaps are minor: no restaurant-discovery/search tool to find a venue id, but the widget-tab workflow suggests that's handled externally.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    An MCP server for restaurant discovery and booking across Resy and OpenTable via natural language. It integrates Google Places data with dietary preferences, visit history, and weather awareness to provide personalized dining recommendations and group reservation management.
    23
    -
  • F
    license
    A
    quality
    D
    maintenance
    MCP server for the Rizerve direct booking platform. Enables managing properties, bookings, availability, iCal sync, analytics, and webhooks through AI assistants.
    19
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server that transforms Gurunavi into a browser-driven semantic proxy, providing restaurant search, details, and reservation management through normalized interfaces with safety controls.
    MIT